<commit_before>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// NOTE: If you change this file you must run "./mkbuiltin"
// to update builtin.c.boot.  This is not done automatically
// to avoid depending on having a working compiler binary.

// +build ignore

package PACKAGE

// emitted by compiler, not referred to by go programs

func new(typ *byte) *any
func panicindex()
func panicslice()
func throwreturn()
func throwinit()
func panicwrap(string, string, string)

func panic(interface{})
func recover(*int32) interface{}

func printbool(bool)
func printfloat(float64)
func printint(int64)
func printuint(uint64)
func printcomplex(complex128)
func printstring(string)
func printpointer(any)
func printiface(any)
func printeface(any)
func printslice(any)
func printnl()
func printsp()
func goprintf()

// filled in by compiler: int n, string, string, ...
func concatstring()

// filled in by compiler: Type*, int n, Slice, ...
func append()
func appendslice(typ *byte, x any, y []any) any
func appendstr(typ *byte, x []byte, y string) []byte

func cmpstring(string, string) int
func slicestring(string, int, int) string
func slicestring1(string, int) string
func intstring(int64) string
func slicebytetostring([]byte) string
func slicerunetostring([]rune) string
func stringtoslicebyte(string) []byte
func stringtoslicerune(string) []rune
func stringiter(string, int) int
func stringiter2(string, int) (retk int, retv rune)
func copy(to any, fr any, wid uint32) int
func slicestringcopy(to any, fr any) int

// interface conversions
func convI2E(elem any) (ret any)
func convI2I(typ *byte, elem any) (ret any)
func convT2E(typ *byte, elem any) (ret any)
func convT2I(typ *byte, typ2 *byte, elem any) (ret any)

// interface type assertions  x.(T)
func assertE2E(typ *byte, iface any) (ret any)
func assertE2E2(typ *byte, iface any) (ret any, ok bool)
func assertE2I(typ *byte, iface any) (ret any)
func assertE2I2(typ *byte, iface any) (ret any, ok bool)
func assertE2T(typ *byte, iface any) (ret any)
func assertE2T2(typ *byte, iface any) (ret any, ok bool)
func assertI2E(typ *byte, iface any) (ret any)
func assertI2E2(typ *byte, iface any) (ret any, ok bool)
func assertI2I(typ *byte, iface any) (ret any)
func assertI2I2(typ *byte, iface any) (ret any, ok bool)
func assertI2T(typ *byte, iface any) (ret any)
func assertI2T2(typ *byte, iface any) (ret any, ok bool)

func ifaceeq(i1 any, i2 any) (ret bool)
func efaceeq(i1 any, i2 any) (ret bool)
func ifacethash(i1 any) (ret uint32)
func efacethash(i1 any) (ret uint32)

func equal(typ *byte, x1, x2 any) (ret bool)

// *byte is really *runtime.Type
func makemap(mapType *byte, hint int64) (hmap map[any]any)
func mapaccess1(mapType *byte, hmap map[any]any, key any) (val any)
func mapaccess2(mapType *byte, hmap map[any]any, key any) (val any, pres bool)
func mapassign1(mapType *byte, hmap map[any]any, key any, val any)
func mapassign2(mapType *byte, hmap map[any]any, key any, val any, pres bool)
func mapiterinit(mapType *byte, hmap map[any]any, hiter *any)
func mapdelete(mapType *byte, hmap map[any]any, key any)
func mapiternext(hiter *any)
func mapiter1(hiter *any) (key any)
func mapiter2(hiter *any) (key any, val any)

// *byte is really *runtime.Type
func makechan(chanType *byte, hint int64) (hchan chan any)
func chanrecv1(chanType *byte, hchan <-chan any) (elem any)
func chanrecv2(chanType *byte, hchan <-chan any) (elem any, received bool)
func chansend1(chanType *byte, hchan chan<- any, elem any)
func closechan(hchan any)

func selectnbsend(chanType *byte, hchan chan<- any, elem any) bool
func selectnbrecv(chanType *byte, elem *any, hchan <-chan any) bool
func selectnbrecv2(chanType *byte, elem *any, received *bool, hchan <-chan any) bool

func newselect(size int) (sel *byte)
func selectsend(sel *byte, hchan chan<- any, elem *any) (selected bool)
func selectrecv(sel *byte, hchan <-chan any, elem *any) (selected bool)
func selectrecv2(sel *byte, hchan <-chan any, elem *any, received *bool) (selected bool)
func selectdefault(sel *byte) (selected bool)
func selectgo(sel *byte)
func block()

func makeslice(typ *byte, nel int64, cap int64) (ary []any)
func growslice(typ *byte, old []any, n int64) (ary []any)
func sliceslice1(old []any, lb uint64, width uint64) (ary []any)
func sliceslice(old []any, lb uint64, hb uint64, width uint64) (ary []any)
func slicearray(old *any, nel uint64, lb uint64, hb uint64, width uint64) (ary []any)

func closure() // has args, but compiler fills in

func memequal(eq *bool, size uintptr, x, y *any)
func memequal8(eq *bool, size uintptr, x, y *any)
func memequal16(eq *bool, size uintptr, x, y *any)
func memequal32(eq *bool, size uintptr, x, y *any)
func memequal64(eq *bool, size uintptr, x, y *any)
func memequal128(eq *bool, size uintptr, x, y *any)

// only used on 32-bit
func int64div(int64, int64) int64
func uint64div(uint64, uint64) uint64
func int64mod(int64, int64) int64
func uint64mod(uint64, uint64) uint64
func float64toint64(float64) int64
func float64touint64(float64) uint64
func int64tofloat64(int64) float64
func uint64tofloat64(uint64) float64

func complex128div(num complex128, den complex128) (quo complex128)
<commit_msg>gc: correct comment in runtime.go<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// NOTE: If you change this file you must run "./mkbuiltin"
// to update builtin.c.  This is not done automatically
// to avoid depending on having a working compiler binary.

// +build ignore

package PACKAGE

// emitted by compiler, not referred to by go programs

func new(typ *byte) *any
func panicindex()
func panicslice()
func throwreturn()
func throwinit()
func panicwrap(string, string, string)

func panic(interface{})
func recover(*int32) interface{}

func printbool(bool)
func printfloat(float64)
func printint(int64)
func printuint(uint64)
func printcomplex(complex128)
func printstring(string)
func printpointer(any)
func printiface(any)
func printeface(any)
func printslice(any)
func printnl()
func printsp()
func goprintf()

// filled in by compiler: int n, string, string, ...
func concatstring()

// filled in by compiler: Type*, int n, Slice, ...
func append()
func appendslice(typ *byte, x any, y []any) any
func appendstr(typ *byte, x []byte, y string) []byte

func cmpstring(string, string) int
func slicestring(string, int, int) string
func slicestring1(string, int) string
func intstring(int64) string
func slicebytetostring([]byte) string
func slicerunetostring([]rune) string
func stringtoslicebyte(string) []byte
func stringtoslicerune(string) []rune
func stringiter(string, int) int
func stringiter2(string, int) (retk int, retv rune)
func copy(to any, fr any, wid uint32) int
func slicestringcopy(to any, fr any) int

// interface conversions
func convI2E(elem any) (ret any)
func convI2I(typ *byte, elem any) (ret any)
func convT2E(typ *byte, elem any) (ret any)
func convT2I(typ *byte, typ2 *byte, elem any) (ret any)

// interface type assertions  x.(T)
func assertE2E(typ *byte, iface any) (ret any)
func assertE2E2(typ *byte, iface any) (ret any, ok bool)
func assertE2I(typ *byte, iface any) (ret any)
func assertE2I2(typ *byte, iface any) (ret any, ok bool)
func assertE2T(typ *byte, iface any) (ret any)
func assertE2T2(typ *byte, iface any) (ret any, ok bool)
func assertI2E(typ *byte, iface any) (ret any)
func assertI2E2(typ *byte, iface any) (ret any, ok bool)
func assertI2I(typ *byte, iface any) (ret any)
func assertI2I2(typ *byte, iface any) (ret any, ok bool)
func assertI2T(typ *byte, iface any) (ret any)
func assertI2T2(typ *byte, iface any) (ret any, ok bool)

func ifaceeq(i1 any, i2 any) (ret bool)
func efaceeq(i1 any, i2 any) (ret bool)
func ifacethash(i1 any) (ret uint32)
func efacethash(i1 any) (ret uint32)

func equal(typ *byte, x1, x2 any) (ret bool)

// *byte is really *runtime.Type
func makemap(mapType *byte, hint int64) (hmap map[any]any)
func mapaccess1(mapType *byte, hmap map[any]any, key any) (val any)
func mapaccess2(mapType *byte, hmap map[any]any, key any) (val any, pres bool)
func mapassign1(mapType *byte, hmap map[any]any, key any, val any)
func mapassign2(mapType *byte, hmap map[any]any, key any, val any, pres bool)
func mapiterinit(mapType *byte, hmap map[any]any, hiter *any)
func mapdelete(mapType *byte, hmap map[any]any, key any)
func mapiternext(hiter *any)
func mapiter1(hiter *any) (key any)
func mapiter2(hiter *any) (key any, val any)

// *byte is really *runtime.Type
func makechan(chanType *byte, hint int64) (hchan chan any)
func chanrecv1(chanType *byte, hchan <-chan any) (elem any)
func chanrecv2(chanType *byte, hchan <-chan any) (elem any, received bool)
func chansend1(chanType *byte, hchan chan<- any, elem any)
func closechan(hchan any)

func selectnbsend(chanType *byte, hchan chan<- any, elem any) bool
func selectnbrecv(chanType *byte, elem *any, hchan <-chan any) bool
func selectnbrecv2(chanType *byte, elem *any, received *bool, hchan <-chan any) bool

func newselect(size int) (sel *byte)
func selectsend(sel *byte, hchan chan<- any, elem *any) (selected bool)
func selectrecv(sel *byte, hchan <-chan any, elem *any) (selected bool)
func selectrecv2(sel *byte, hchan <-chan any, elem *any, received *bool) (selected bool)
func selectdefault(sel *byte) (selected bool)
func selectgo(sel *byte)
func block()

func makeslice(typ *byte, nel int64, cap int64) (ary []any)
func growslice(typ *byte, old []any, n int64) (ary []any)
func sliceslice1(old []any, lb uint64, width uint64) (ary []any)
func sliceslice(old []any, lb uint64, hb uint64, width uint64) (ary []any)
func slicearray(old *any, nel uint64, lb uint64, hb uint64, width uint64) (ary []any)

func closure() // has args, but compiler fills in

func memequal(eq *bool, size uintptr, x, y *any)
func memequal8(eq *bool, size uintptr, x, y *any)
func memequal16(eq *bool, size uintptr, x, y *any)
func memequal32(eq *bool, size uintptr, x, y *any)
func memequal64(eq *bool, size uintptr, x, y *any)
func memequal128(eq *bool, size uintptr, x, y *any)

// only used on 32-bit
func int64div(int64, int64) int64
func uint64div(uint64, uint64) uint64
func int64mod(int64, int64) int64
func uint64mod(uint64, uint64) uint64
func float64toint64(float64) int64
func float64touint64(float64) uint64
func int64tofloat64(int64) float64
func uint64tofloat64(uint64) float64

func complex128div(num complex128, den complex128) (quo complex128)
<|endoftext|>


<commit_before>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// godoc: Go Documentation Server

// Web server tree:
//
//	http://godoc/		main landing page
//	http://godoc/doc/	serve from $GOROOT/doc - spec, mem, tutorial, etc.
//	http://godoc/src/	serve files from $GOROOT/src; .go gets pretty-printed
//	http://godoc/cmd/	serve documentation about commands (TODO)
//	http://godoc/pkg/	serve documentation about packages
//				(idea is if you say import "compress/zlib", you go to
//				http://godoc/pkg/compress/zlib)
//
// Command-line interface:
//
//	godoc packagepath [name ...]
//
//	godoc compress/zlib
//		- prints doc for package compress/zlib
//	godoc crypto/block Cipher NewCMAC
//		- prints doc for Cipher and NewCMAC in package crypto/block

package main

import (
	"bytes"
	"flag"
	"fmt"
	"http"
	"io"
	"log"
	"os"
	pathutil "path"
	"runtime"
	"time"
)

const defaultAddr = ":6060" // default webserver address

var (
	// periodic sync
	syncCmd   = flag.String("sync", "", "sync command; disabled if empty")
	syncMin   = flag.Int("sync_minutes", 0, "sync interval in minutes; disabled if <= 0")
	syncDelay delayTime // actual sync delay in minutes; usually syncDelay == syncMin, but delay may back off exponentially

	// network
	httpAddr   = flag.String("http", "", "HTTP service address (e.g., '"+defaultAddr+"')")
	serverAddr = flag.String("server", "", "webserver address for command line searches")

	// layout control
	html   = flag.Bool("html", false, "print HTML in command-line mode")
	genAST = flag.Bool("src", false, "print exported source in command-line mode")

	// command-line searches
	query = flag.Bool("q", false, "arguments are considered search queries")
)

func serveError(c *http.Conn, r *http.Request, relpath string, err os.Error) {
	contents := applyTemplate(errorHTML, "errorHTML", err) // err may contain an absolute path!
	servePage(c, "File "+relpath, "", contents)
}

func exec(c *http.Conn, args []string) (status int) {
	r, w, err := os.Pipe()
	if err != nil {
		log.Stderrf("os.Pipe(): %v\n", err)
		return 2
	}

	bin := args[0]
	fds := []*os.File{nil, w, w}
	if *verbose {
		log.Stderrf("executing %v", args)
	}
	pid, err := os.ForkExec(bin, args, os.Environ(), *goroot, fds)
	defer r.Close()
	w.Close()
	if err != nil {
		log.Stderrf("os.ForkExec(%q): %v\n", bin, err)
		return 2
	}

	var buf bytes.Buffer
	io.Copy(&buf, r)
	wait, err := os.Wait(pid, 0)
	if err != nil {
		os.Stderr.Write(buf.Bytes())
		log.Stderrf("os.Wait(%d, 0): %v\n", pid, err)
		return 2
	}
	status = wait.ExitStatus()
	if !wait.Exited() || status > 1 {
		os.Stderr.Write(buf.Bytes())
		log.Stderrf("executing %v failed (exit status = %d)", args, status)
		return
	}

	if *verbose {
		os.Stderr.Write(buf.Bytes())
	}
	if c != nil {
		c.SetHeader("content-type", "text/plain; charset=utf-8")
		c.Write(buf.Bytes())
	}

	return
}

// Maximum directory depth, adjust as needed.
const maxDirDepth = 24

func dosync(c *http.Conn, r *http.Request) {
	args := []string{"/bin/sh", "-c", *syncCmd}
	switch exec(c, args) {
	case 0:
		// sync succeeded and some files have changed;
		// update package tree.
		// TODO(gri): The directory tree may be temporarily out-of-sync.
		//            Consider keeping separate time stamps so the web-
		//            page can indicate this discrepancy.
		fsTree.set(newDirectory(*goroot, maxDirDepth))
		fallthrough
	case 1:
		// sync failed because no files changed;
		// don't change the package tree
		syncDelay.set(*syncMin) //  revert to regular sync schedule
	default:
		// sync failed because of an error - back off exponentially, but try at least once a day
		syncDelay.backoff(24 * 60)
	}
}

func usage() {
	fmt.Fprintf(os.Stderr,
		"usage: godoc package [name ...]\n"+
			"	godoc -http="+defaultAddr+"\n")
	flag.PrintDefaults()
	os.Exit(2)
}

func loggingHandler(h http.Handler) http.Handler {
	return http.HandlerFunc(func(c *http.Conn, req *http.Request) {
		log.Stderrf("%s\t%s", c.RemoteAddr, req.URL)
		h.ServeHTTP(c, req)
	})
}

func remoteSearch(query string) (res *http.Response, err os.Error) {
	search := "/search?f=text&q=" + http.URLEscape(query)

	// list of addresses to try
	var addrs []string
	if *serverAddr != "" {
		// explicit server address - only try this one
		addrs = []string{*serverAddr}
	} else {
		addrs = []string{
			defaultAddr,
			"golang.org",
		}
	}

	// remote search
	for _, addr := range addrs {
		url := "http://" + addr + search
		res, _, err = http.Get(url)
		if err == nil && res.StatusCode == http.StatusOK {
			break
		}
	}

	if err == nil && res.StatusCode != http.StatusOK {
		err = os.NewError(res.Status)
	}

	return
}

func main() {
	flag.Usage = usage
	flag.Parse()

	// Check usage: either server and no args, or command line and args
	if (*httpAddr != "") != (flag.NArg() == 0) {
		usage()
	}

	if *tabwidth < 0 {
		log.Exitf("negative tabwidth %d", *tabwidth)
	}

	initHandlers()
	readTemplates()

	if *httpAddr != "" {
		// HTTP server mode.
		var handler http.Handler = http.DefaultServeMux
		if *verbose {
			log.Stderrf("Go Documentation Server\n")
			log.Stderrf("version = %s\n", runtime.Version())
			log.Stderrf("address = %s\n", *httpAddr)
			log.Stderrf("goroot = %s\n", *goroot)
			log.Stderrf("tabwidth = %d\n", *tabwidth)
			if !fsMap.IsEmpty() {
				log.Stderr("user-defined mapping:")
				fsMap.Fprint(os.Stderr)
			}
			handler = loggingHandler(handler)
		}

		registerPublicHandlers(http.DefaultServeMux)
		if *syncCmd != "" {
			http.Handle("/debug/sync", http.HandlerFunc(dosync))
		}

		// Initialize directory tree with corresponding timestamp.
		// Do it in two steps:
		// 1) set timestamp right away so that the indexer is kicked on
		fsTree.set(nil)
		// 2) compute initial directory tree in a goroutine so that launch is quick
		go func() { fsTree.set(newDirectory(*goroot, maxDirDepth)) }()

		// Start sync goroutine, if enabled.
		if *syncCmd != "" && *syncMin > 0 {
			syncDelay.set(*syncMin) // initial sync delay
			go func() {
				for {
					dosync(nil, nil)
					delay, _ := syncDelay.get()
					if *verbose {
						log.Stderrf("next sync in %dmin", delay.(int))
					}
					time.Sleep(int64(delay.(int)) * 60e9)
				}
			}()
		}

		// Start indexing goroutine.
		go indexer()

		// The server may have been restarted; always wait 1sec to
		// give the forking server a chance to shut down and release
		// the http port.
		// TODO(gri): Do we still need this?
		time.Sleep(1e9)

		// Start http server.
		if err := http.ListenAndServe(*httpAddr, handler); err != nil {
			log.Exitf("ListenAndServe %s: %v", *httpAddr, err)
		}

		return
	}

	// Command line mode.
	if *html {
		packageText = packageHTML
		searchText = packageHTML
	}

	if *query {
		// Command-line queries.
		for i := 0; i < flag.NArg(); i++ {
			res, err := remoteSearch(flag.Arg(i))
			if err != nil {
				log.Exitf("remoteSearch: %s", err)
			}
			io.Copy(os.Stdout, res.Body)
		}
		return
	}

	// determine paths
	path := flag.Arg(0)
	if len(path) > 0 && path[0] == '.' {
		// assume cwd; don't assume -goroot
		cwd, _ := os.Getwd() // ignore errors
		path = pathutil.Join(cwd, path)
	}
	relpath := path
	abspath := path
	if len(path) > 0 && path[0] != '/' {
		abspath = absolutePath(path, pkgHandler.fsRoot)
	} else {
		relpath = relativePath(path)
	}

	// TODO(gri): Provide a mechanism (flag?) to select a package
	//            if there are multiple packages in a directory.
	info := pkgHandler.getPageInfo(abspath, relpath, "", *genAST, true)

	if info.PAst == nil && info.PDoc == nil && info.Dirs == nil {
		// try again, this time assume it's a command
		if len(path) > 0 && path[0] != '/' {
			abspath = absolutePath(path, cmdHandler.fsRoot)
		}
		info = cmdHandler.getPageInfo(abspath, relpath, "", false, false)
	}

	if info.PDoc != nil && flag.NArg() > 1 {
		args := flag.Args()
		info.PDoc.Filter(args[1:])
	}

	if err := packageText.Execute(info, os.Stdout); err != nil {
		log.Stderrf("packageText.Execute: %s", err)
	}
}
<commit_msg>godoc: export pprof debug information<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// godoc: Go Documentation Server

// Web server tree:
//
//	http://godoc/		main landing page
//	http://godoc/doc/	serve from $GOROOT/doc - spec, mem, tutorial, etc.
//	http://godoc/src/	serve files from $GOROOT/src; .go gets pretty-printed
//	http://godoc/cmd/	serve documentation about commands (TODO)
//	http://godoc/pkg/	serve documentation about packages
//				(idea is if you say import "compress/zlib", you go to
//				http://godoc/pkg/compress/zlib)
//
// Command-line interface:
//
//	godoc packagepath [name ...]
//
//	godoc compress/zlib
//		- prints doc for package compress/zlib
//	godoc crypto/block Cipher NewCMAC
//		- prints doc for Cipher and NewCMAC in package crypto/block

package main

import (
	"bytes"
	"flag"
	"fmt"
	"http"
	_ "http/pprof"
	"io"
	"log"
	"os"
	pathutil "path"
	"runtime"
	"time"
)

const defaultAddr = ":6060" // default webserver address

var (
	// periodic sync
	syncCmd   = flag.String("sync", "", "sync command; disabled if empty")
	syncMin   = flag.Int("sync_minutes", 0, "sync interval in minutes; disabled if <= 0")
	syncDelay delayTime // actual sync delay in minutes; usually syncDelay == syncMin, but delay may back off exponentially

	// network
	httpAddr   = flag.String("http", "", "HTTP service address (e.g., '"+defaultAddr+"')")
	serverAddr = flag.String("server", "", "webserver address for command line searches")

	// layout control
	html   = flag.Bool("html", false, "print HTML in command-line mode")
	genAST = flag.Bool("src", false, "print exported source in command-line mode")

	// command-line searches
	query = flag.Bool("q", false, "arguments are considered search queries")
)

func serveError(c *http.Conn, r *http.Request, relpath string, err os.Error) {
	contents := applyTemplate(errorHTML, "errorHTML", err) // err may contain an absolute path!
	servePage(c, "File "+relpath, "", contents)
}

func exec(c *http.Conn, args []string) (status int) {
	r, w, err := os.Pipe()
	if err != nil {
		log.Stderrf("os.Pipe(): %v\n", err)
		return 2
	}

	bin := args[0]
	fds := []*os.File{nil, w, w}
	if *verbose {
		log.Stderrf("executing %v", args)
	}
	pid, err := os.ForkExec(bin, args, os.Environ(), *goroot, fds)
	defer r.Close()
	w.Close()
	if err != nil {
		log.Stderrf("os.ForkExec(%q): %v\n", bin, err)
		return 2
	}

	var buf bytes.Buffer
	io.Copy(&buf, r)
	wait, err := os.Wait(pid, 0)
	if err != nil {
		os.Stderr.Write(buf.Bytes())
		log.Stderrf("os.Wait(%d, 0): %v\n", pid, err)
		return 2
	}
	status = wait.ExitStatus()
	if !wait.Exited() || status > 1 {
		os.Stderr.Write(buf.Bytes())
		log.Stderrf("executing %v failed (exit status = %d)", args, status)
		return
	}

	if *verbose {
		os.Stderr.Write(buf.Bytes())
	}
	if c != nil {
		c.SetHeader("content-type", "text/plain; charset=utf-8")
		c.Write(buf.Bytes())
	}

	return
}

// Maximum directory depth, adjust as needed.
const maxDirDepth = 24

func dosync(c *http.Conn, r *http.Request) {
	args := []string{"/bin/sh", "-c", *syncCmd}
	switch exec(c, args) {
	case 0:
		// sync succeeded and some files have changed;
		// update package tree.
		// TODO(gri): The directory tree may be temporarily out-of-sync.
		//            Consider keeping separate time stamps so the web-
		//            page can indicate this discrepancy.
		fsTree.set(newDirectory(*goroot, maxDirDepth))
		fallthrough
	case 1:
		// sync failed because no files changed;
		// don't change the package tree
		syncDelay.set(*syncMin) //  revert to regular sync schedule
	default:
		// sync failed because of an error - back off exponentially, but try at least once a day
		syncDelay.backoff(24 * 60)
	}
}

func usage() {
	fmt.Fprintf(os.Stderr,
		"usage: godoc package [name ...]\n"+
			"	godoc -http="+defaultAddr+"\n")
	flag.PrintDefaults()
	os.Exit(2)
}

func loggingHandler(h http.Handler) http.Handler {
	return http.HandlerFunc(func(c *http.Conn, req *http.Request) {
		log.Stderrf("%s\t%s", c.RemoteAddr, req.URL)
		h.ServeHTTP(c, req)
	})
}

func remoteSearch(query string) (res *http.Response, err os.Error) {
	search := "/search?f=text&q=" + http.URLEscape(query)

	// list of addresses to try
	var addrs []string
	if *serverAddr != "" {
		// explicit server address - only try this one
		addrs = []string{*serverAddr}
	} else {
		addrs = []string{
			defaultAddr,
			"golang.org",
		}
	}

	// remote search
	for _, addr := range addrs {
		url := "http://" + addr + search
		res, _, err = http.Get(url)
		if err == nil && res.StatusCode == http.StatusOK {
			break
		}
	}

	if err == nil && res.StatusCode != http.StatusOK {
		err = os.NewError(res.Status)
	}

	return
}

func main() {
	flag.Usage = usage
	flag.Parse()

	// Check usage: either server and no args, or command line and args
	if (*httpAddr != "") != (flag.NArg() == 0) {
		usage()
	}

	if *tabwidth < 0 {
		log.Exitf("negative tabwidth %d", *tabwidth)
	}

	initHandlers()
	readTemplates()

	if *httpAddr != "" {
		// HTTP server mode.
		var handler http.Handler = http.DefaultServeMux
		if *verbose {
			log.Stderrf("Go Documentation Server\n")
			log.Stderrf("version = %s\n", runtime.Version())
			log.Stderrf("address = %s\n", *httpAddr)
			log.Stderrf("goroot = %s\n", *goroot)
			log.Stderrf("tabwidth = %d\n", *tabwidth)
			if !fsMap.IsEmpty() {
				log.Stderr("user-defined mapping:")
				fsMap.Fprint(os.Stderr)
			}
			handler = loggingHandler(handler)
		}

		registerPublicHandlers(http.DefaultServeMux)
		if *syncCmd != "" {
			http.Handle("/debug/sync", http.HandlerFunc(dosync))
		}

		// Initialize directory tree with corresponding timestamp.
		// Do it in two steps:
		// 1) set timestamp right away so that the indexer is kicked on
		fsTree.set(nil)
		// 2) compute initial directory tree in a goroutine so that launch is quick
		go func() { fsTree.set(newDirectory(*goroot, maxDirDepth)) }()

		// Start sync goroutine, if enabled.
		if *syncCmd != "" && *syncMin > 0 {
			syncDelay.set(*syncMin) // initial sync delay
			go func() {
				for {
					dosync(nil, nil)
					delay, _ := syncDelay.get()
					if *verbose {
						log.Stderrf("next sync in %dmin", delay.(int))
					}
					time.Sleep(int64(delay.(int)) * 60e9)
				}
			}()
		}

		// Start indexing goroutine.
		go indexer()

		// The server may have been restarted; always wait 1sec to
		// give the forking server a chance to shut down and release
		// the http port.
		// TODO(gri): Do we still need this?
		time.Sleep(1e9)

		// Start http server.
		if err := http.ListenAndServe(*httpAddr, handler); err != nil {
			log.Exitf("ListenAndServe %s: %v", *httpAddr, err)
		}

		return
	}

	// Command line mode.
	if *html {
		packageText = packageHTML
		searchText = packageHTML
	}

	if *query {
		// Command-line queries.
		for i := 0; i < flag.NArg(); i++ {
			res, err := remoteSearch(flag.Arg(i))
			if err != nil {
				log.Exitf("remoteSearch: %s", err)
			}
			io.Copy(os.Stdout, res.Body)
		}
		return
	}

	// determine paths
	path := flag.Arg(0)
	if len(path) > 0 && path[0] == '.' {
		// assume cwd; don't assume -goroot
		cwd, _ := os.Getwd() // ignore errors
		path = pathutil.Join(cwd, path)
	}
	relpath := path
	abspath := path
	if len(path) > 0 && path[0] != '/' {
		abspath = absolutePath(path, pkgHandler.fsRoot)
	} else {
		relpath = relativePath(path)
	}

	// TODO(gri): Provide a mechanism (flag?) to select a package
	//            if there are multiple packages in a directory.
	info := pkgHandler.getPageInfo(abspath, relpath, "", *genAST, true)

	if info.PAst == nil && info.PDoc == nil && info.Dirs == nil {
		// try again, this time assume it's a command
		if len(path) > 0 && path[0] != '/' {
			abspath = absolutePath(path, cmdHandler.fsRoot)
		}
		info = cmdHandler.getPageInfo(abspath, relpath, "", false, false)
	}

	if info.PDoc != nil && flag.NArg() > 1 {
		args := flag.Args()
		info.PDoc.Filter(args[1:])
	}

	if err := packageText.Execute(info, os.Stdout); err != nil {
		log.Stderrf("packageText.Execute: %s", err)
	}
}
<|endoftext|>


<commit_before>// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"fmt"
	"internal/obscuretestdata"
	"internal/testenv"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"testing"
	"text/template"
)

var testnmpath string // path to nm command created for testing purposes

// The TestMain function creates a nm command for testing purposes and
// deletes it after the tests have been run.
func TestMain(m *testing.M) {
	os.Exit(testMain(m))
}

func testMain(m *testing.M) int {
	if !testenv.HasGoBuild() {
		return 0
	}

	tmpDir, err := os.MkdirTemp("", "TestNM")
	if err != nil {
		fmt.Println("TempDir failed:", err)
		return 2
	}
	defer os.RemoveAll(tmpDir)

	testnmpath = filepath.Join(tmpDir, "testnm.exe")
	gotool, err := testenv.GoTool()
	if err != nil {
		fmt.Println("GoTool failed:", err)
		return 2
	}
	out, err := exec.Command(gotool, "build", "-o", testnmpath, "cmd/nm").CombinedOutput()
	if err != nil {
		fmt.Printf("go build -o %v cmd/nm: %v\n%s", testnmpath, err, string(out))
		return 2
	}

	return m.Run()
}

func TestNonGoExecs(t *testing.T) {
	t.Parallel()
	testfiles := []string{
		"debug/elf/testdata/gcc-386-freebsd-exec",
		"debug/elf/testdata/gcc-amd64-linux-exec",
		"debug/macho/testdata/gcc-386-darwin-exec.base64",   // golang.org/issue/34986
		"debug/macho/testdata/gcc-amd64-darwin-exec.base64", // golang.org/issue/34986
		// "debug/pe/testdata/gcc-amd64-mingw-exec", // no symbols!
		"debug/pe/testdata/gcc-386-mingw-exec",
		"debug/plan9obj/testdata/amd64-plan9-exec",
		"debug/plan9obj/testdata/386-plan9-exec",
		"internal/xcoff/testdata/gcc-ppc64-aix-dwarf2-exec",
	}
	for _, f := range testfiles {
		exepath := filepath.Join(testenv.GOROOT(t), "src", f)
		if strings.HasSuffix(f, ".base64") {
			tf, err := obscuretestdata.DecodeToTempFile(exepath)
			if err != nil {
				t.Errorf("obscuretestdata.DecodeToTempFile(%s): %v", exepath, err)
				continue
			}
			defer os.Remove(tf)
			exepath = tf
		}

		cmd := exec.Command(testnmpath, exepath)
		out, err := cmd.CombinedOutput()
		if err != nil {
			t.Errorf("go tool nm %v: %v\n%s", exepath, err, string(out))
		}
	}
}

func testGoExec(t *testing.T, iscgo, isexternallinker bool) {
	t.Parallel()
	tmpdir, err := os.MkdirTemp("", "TestGoExec")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(tmpdir)

	src := filepath.Join(tmpdir, "a.go")
	file, err := os.Create(src)
	if err != nil {
		t.Fatal(err)
	}
	err = template.Must(template.New("main").Parse(testexec)).Execute(file, iscgo)
	if e := file.Close(); err == nil {
		err = e
	}
	if err != nil {
		t.Fatal(err)
	}

	exe := filepath.Join(tmpdir, "a.exe")
	args := []string{"build", "-o", exe}
	if iscgo {
		linkmode := "internal"
		if isexternallinker {
			linkmode = "external"
		}
		args = append(args, "-ldflags", "-linkmode="+linkmode)
	}
	args = append(args, src)
	out, err := exec.Command(testenv.GoToolPath(t), args...).CombinedOutput()
	if err != nil {
		t.Fatalf("building test executable failed: %s %s", err, out)
	}

	out, err = exec.Command(exe).CombinedOutput()
	if err != nil {
		t.Fatalf("running test executable failed: %s %s", err, out)
	}
	names := make(map[string]string)
	for _, line := range strings.Split(string(out), "\n") {
		if line == "" {
			continue
		}
		f := strings.Split(line, "=")
		if len(f) != 2 {
			t.Fatalf("unexpected output line: %q", line)
		}
		names["main."+f[0]] = f[1]
	}

	runtimeSyms := map[string]string{
		"runtime.text":      "T",
		"runtime.etext":     "T",
		"runtime.rodata":    "R",
		"runtime.erodata":   "R",
		"runtime.epclntab":  "R",
		"runtime.noptrdata": "D",
	}

	if runtime.GOOS == "aix" && iscgo {
		// pclntab is moved to .data section on AIX.
		runtimeSyms["runtime.epclntab"] = "D"
	}

	out, err = exec.Command(testnmpath, exe).CombinedOutput()
	if err != nil {
		t.Fatalf("go tool nm: %v\n%s", err, string(out))
	}

	relocated := func(code string) bool {
		if runtime.GOOS == "aix" {
			// On AIX, .data and .bss addresses are changed by the loader.
			// Therefore, the values returned by the exec aren't the same
			// than the ones inside the symbol table.
			// In case of cgo, .text symbols are also changed.
			switch code {
			case "T", "t", "R", "r":
				return iscgo
			case "D", "d", "B", "b":
				return true
			}
		}
		if runtime.GOOS == "windows" {
			return true
		}
		if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" {
			return true // On darwin/arm64 everything is PIE
		}
		return false
	}

	dups := make(map[string]bool)
	for _, line := range strings.Split(string(out), "\n") {
		f := strings.Fields(line)
		if len(f) < 3 {
			continue
		}
		name := f[2]
		if addr, found := names[name]; found {
			if want, have := addr, "0x"+f[0]; have != want {
				if !relocated(f[1]) {
					t.Errorf("want %s address for %s symbol, but have %s", want, name, have)
				}
			}
			delete(names, name)
		}
		if _, found := dups[name]; found {
			t.Errorf("duplicate name of %q is found", name)
		}
		if stype, found := runtimeSyms[name]; found {
			if runtime.GOOS == "plan9" && stype == "R" {
				// no read-only data segment symbol on Plan 9
				stype = "D"
			}
			if want, have := stype, strings.ToUpper(f[1]); have != want {
				t.Errorf("want %s type for %s symbol, but have %s", want, name, have)
			}
			delete(runtimeSyms, name)
		}
	}
	if len(names) > 0 {
		t.Errorf("executable is missing %v symbols", names)
	}
	if len(runtimeSyms) > 0 {
		t.Errorf("executable is missing %v symbols", runtimeSyms)
	}
}

func TestGoExec(t *testing.T) {
	testGoExec(t, false, false)
}

func testGoLib(t *testing.T, iscgo bool) {
	t.Parallel()
	tmpdir, err := os.MkdirTemp("", "TestGoLib")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(tmpdir)

	gopath := filepath.Join(tmpdir, "gopath")
	libpath := filepath.Join(gopath, "src", "mylib")

	err = os.MkdirAll(libpath, 0777)
	if err != nil {
		t.Fatal(err)
	}
	src := filepath.Join(libpath, "a.go")
	file, err := os.Create(src)
	if err != nil {
		t.Fatal(err)
	}
	err = template.Must(template.New("mylib").Parse(testlib)).Execute(file, iscgo)
	if e := file.Close(); err == nil {
		err = e
	}
	if err == nil {
		err = os.WriteFile(filepath.Join(libpath, "go.mod"), []byte("module mylib\n"), 0666)
	}
	if err != nil {
		t.Fatal(err)
	}

	args := []string{"install", "mylib"}
	cmd := exec.Command(testenv.GoToolPath(t), args...)
	cmd.Dir = libpath
	cmd.Env = append(os.Environ(), "GOPATH="+gopath)
	out, err := cmd.CombinedOutput()
	if err != nil {
		t.Fatalf("building test lib failed: %s %s", err, out)
	}
	pat := filepath.Join(gopath, "pkg", "*", "mylib.a")
	ms, err := filepath.Glob(pat)
	if err != nil {
		t.Fatal(err)
	}
	if len(ms) == 0 {
		t.Fatalf("cannot found paths for pattern %s", pat)
	}
	mylib := ms[0]

	out, err = exec.Command(testnmpath, mylib).CombinedOutput()
	if err != nil {
		t.Fatalf("go tool nm: %v\n%s", err, string(out))
	}
	type symType struct {
		Type  string
		Name  string
		CSym  bool
		Found bool
	}
	var syms = []symType{
		{"B", "mylib.Testdata", false, false},
		{"T", "mylib.Testfunc", false, false},
	}
	if iscgo {
		syms = append(syms, symType{"B", "mylib.TestCgodata", false, false})
		syms = append(syms, symType{"T", "mylib.TestCgofunc", false, false})
		if runtime.GOOS == "darwin" || runtime.GOOS == "ios" || (runtime.GOOS == "windows" && runtime.GOARCH == "386") {
			syms = append(syms, symType{"D", "_cgodata", true, false})
			syms = append(syms, symType{"T", "_cgofunc", true, false})
		} else if runtime.GOOS == "aix" {
			syms = append(syms, symType{"D", "cgodata", true, false})
			syms = append(syms, symType{"T", ".cgofunc", true, false})
		} else {
			syms = append(syms, symType{"D", "cgodata", true, false})
			syms = append(syms, symType{"T", "cgofunc", true, false})
		}
	}

	for _, line := range strings.Split(string(out), "\n") {
		f := strings.Fields(line)
		var typ, name string
		var csym bool
		if iscgo {
			if len(f) < 4 {
				continue
			}
			csym = !strings.Contains(f[0], "_go_.o")
			typ = f[2]
			name = f[3]
		} else {
			if len(f) < 3 {
				continue
			}
			typ = f[1]
			name = f[2]
		}
		for i := range syms {
			sym := &syms[i]
			if sym.Type == typ && sym.Name == name && sym.CSym == csym {
				if sym.Found {
					t.Fatalf("duplicate symbol %s %s", sym.Type, sym.Name)
				}
				sym.Found = true
			}
		}
	}
	for _, sym := range syms {
		if !sym.Found {
			t.Errorf("cannot found symbol %s %s", sym.Type, sym.Name)
		}
	}
}

func TestGoLib(t *testing.T) {
	testGoLib(t, false)
}

const testexec = `
package main

import "fmt"
{{if .}}import "C"
{{end}}

func main() {
	testfunc()
}

var testdata uint32

func testfunc() {
	fmt.Printf("main=%p\n", main)
	fmt.Printf("testfunc=%p\n", testfunc)
	fmt.Printf("testdata=%p\n", &testdata)
}
`

const testlib = `
package mylib

{{if .}}
// int cgodata = 5;
// void cgofunc(void) {}
import "C"

var TestCgodata = C.cgodata

func TestCgofunc() {
	C.cgofunc()
}
{{end}}

var Testdata uint32

func Testfunc() {}
`
<commit_msg>cmd/nm: don't rely on an erroneous install target in tests<commit_after>// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"fmt"
	"internal/obscuretestdata"
	"internal/testenv"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"testing"
	"text/template"
)

var testnmpath string // path to nm command created for testing purposes

// The TestMain function creates a nm command for testing purposes and
// deletes it after the tests have been run.
func TestMain(m *testing.M) {
	os.Exit(testMain(m))
}

func testMain(m *testing.M) int {
	if !testenv.HasGoBuild() {
		return 0
	}

	tmpDir, err := os.MkdirTemp("", "TestNM")
	if err != nil {
		fmt.Println("TempDir failed:", err)
		return 2
	}
	defer os.RemoveAll(tmpDir)

	testnmpath = filepath.Join(tmpDir, "testnm.exe")
	gotool, err := testenv.GoTool()
	if err != nil {
		fmt.Println("GoTool failed:", err)
		return 2
	}
	out, err := exec.Command(gotool, "build", "-o", testnmpath, "cmd/nm").CombinedOutput()
	if err != nil {
		fmt.Printf("go build -o %v cmd/nm: %v\n%s", testnmpath, err, string(out))
		return 2
	}

	return m.Run()
}

func TestNonGoExecs(t *testing.T) {
	t.Parallel()
	testfiles := []string{
		"debug/elf/testdata/gcc-386-freebsd-exec",
		"debug/elf/testdata/gcc-amd64-linux-exec",
		"debug/macho/testdata/gcc-386-darwin-exec.base64",   // golang.org/issue/34986
		"debug/macho/testdata/gcc-amd64-darwin-exec.base64", // golang.org/issue/34986
		// "debug/pe/testdata/gcc-amd64-mingw-exec", // no symbols!
		"debug/pe/testdata/gcc-386-mingw-exec",
		"debug/plan9obj/testdata/amd64-plan9-exec",
		"debug/plan9obj/testdata/386-plan9-exec",
		"internal/xcoff/testdata/gcc-ppc64-aix-dwarf2-exec",
	}
	for _, f := range testfiles {
		exepath := filepath.Join(testenv.GOROOT(t), "src", f)
		if strings.HasSuffix(f, ".base64") {
			tf, err := obscuretestdata.DecodeToTempFile(exepath)
			if err != nil {
				t.Errorf("obscuretestdata.DecodeToTempFile(%s): %v", exepath, err)
				continue
			}
			defer os.Remove(tf)
			exepath = tf
		}

		cmd := exec.Command(testnmpath, exepath)
		out, err := cmd.CombinedOutput()
		if err != nil {
			t.Errorf("go tool nm %v: %v\n%s", exepath, err, string(out))
		}
	}
}

func testGoExec(t *testing.T, iscgo, isexternallinker bool) {
	t.Parallel()
	tmpdir, err := os.MkdirTemp("", "TestGoExec")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(tmpdir)

	src := filepath.Join(tmpdir, "a.go")
	file, err := os.Create(src)
	if err != nil {
		t.Fatal(err)
	}
	err = template.Must(template.New("main").Parse(testexec)).Execute(file, iscgo)
	if e := file.Close(); err == nil {
		err = e
	}
	if err != nil {
		t.Fatal(err)
	}

	exe := filepath.Join(tmpdir, "a.exe")
	args := []string{"build", "-o", exe}
	if iscgo {
		linkmode := "internal"
		if isexternallinker {
			linkmode = "external"
		}
		args = append(args, "-ldflags", "-linkmode="+linkmode)
	}
	args = append(args, src)
	out, err := exec.Command(testenv.GoToolPath(t), args...).CombinedOutput()
	if err != nil {
		t.Fatalf("building test executable failed: %s %s", err, out)
	}

	out, err = exec.Command(exe).CombinedOutput()
	if err != nil {
		t.Fatalf("running test executable failed: %s %s", err, out)
	}
	names := make(map[string]string)
	for _, line := range strings.Split(string(out), "\n") {
		if line == "" {
			continue
		}
		f := strings.Split(line, "=")
		if len(f) != 2 {
			t.Fatalf("unexpected output line: %q", line)
		}
		names["main."+f[0]] = f[1]
	}

	runtimeSyms := map[string]string{
		"runtime.text":      "T",
		"runtime.etext":     "T",
		"runtime.rodata":    "R",
		"runtime.erodata":   "R",
		"runtime.epclntab":  "R",
		"runtime.noptrdata": "D",
	}

	if runtime.GOOS == "aix" && iscgo {
		// pclntab is moved to .data section on AIX.
		runtimeSyms["runtime.epclntab"] = "D"
	}

	out, err = exec.Command(testnmpath, exe).CombinedOutput()
	if err != nil {
		t.Fatalf("go tool nm: %v\n%s", err, string(out))
	}

	relocated := func(code string) bool {
		if runtime.GOOS == "aix" {
			// On AIX, .data and .bss addresses are changed by the loader.
			// Therefore, the values returned by the exec aren't the same
			// than the ones inside the symbol table.
			// In case of cgo, .text symbols are also changed.
			switch code {
			case "T", "t", "R", "r":
				return iscgo
			case "D", "d", "B", "b":
				return true
			}
		}
		if runtime.GOOS == "windows" {
			return true
		}
		if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" {
			return true // On darwin/arm64 everything is PIE
		}
		return false
	}

	dups := make(map[string]bool)
	for _, line := range strings.Split(string(out), "\n") {
		f := strings.Fields(line)
		if len(f) < 3 {
			continue
		}
		name := f[2]
		if addr, found := names[name]; found {
			if want, have := addr, "0x"+f[0]; have != want {
				if !relocated(f[1]) {
					t.Errorf("want %s address for %s symbol, but have %s", want, name, have)
				}
			}
			delete(names, name)
		}
		if _, found := dups[name]; found {
			t.Errorf("duplicate name of %q is found", name)
		}
		if stype, found := runtimeSyms[name]; found {
			if runtime.GOOS == "plan9" && stype == "R" {
				// no read-only data segment symbol on Plan 9
				stype = "D"
			}
			if want, have := stype, strings.ToUpper(f[1]); have != want {
				t.Errorf("want %s type for %s symbol, but have %s", want, name, have)
			}
			delete(runtimeSyms, name)
		}
	}
	if len(names) > 0 {
		t.Errorf("executable is missing %v symbols", names)
	}
	if len(runtimeSyms) > 0 {
		t.Errorf("executable is missing %v symbols", runtimeSyms)
	}
}

func TestGoExec(t *testing.T) {
	testGoExec(t, false, false)
}

func testGoLib(t *testing.T, iscgo bool) {
	t.Parallel()
	tmpdir, err := os.MkdirTemp("", "TestGoLib")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(tmpdir)

	gopath := filepath.Join(tmpdir, "gopath")
	libpath := filepath.Join(gopath, "src", "mylib")

	err = os.MkdirAll(libpath, 0777)
	if err != nil {
		t.Fatal(err)
	}
	src := filepath.Join(libpath, "a.go")
	file, err := os.Create(src)
	if err != nil {
		t.Fatal(err)
	}
	err = template.Must(template.New("mylib").Parse(testlib)).Execute(file, iscgo)
	if e := file.Close(); err == nil {
		err = e
	}
	if err == nil {
		err = os.WriteFile(filepath.Join(libpath, "go.mod"), []byte("module mylib\n"), 0666)
	}
	if err != nil {
		t.Fatal(err)
	}

	cmd := exec.Command(testenv.GoToolPath(t), "build", "-buildmode=archive", "-o", "mylib.a", ".")
	cmd.Dir = libpath
	cmd.Env = append(os.Environ(), "GOPATH="+gopath)
	out, err := cmd.CombinedOutput()
	if err != nil {
		t.Fatalf("building test lib failed: %s %s", err, out)
	}
	mylib := filepath.Join(libpath, "mylib.a")

	out, err = exec.Command(testnmpath, mylib).CombinedOutput()
	if err != nil {
		t.Fatalf("go tool nm: %v\n%s", err, string(out))
	}
	type symType struct {
		Type  string
		Name  string
		CSym  bool
		Found bool
	}
	var syms = []symType{
		{"B", "mylib.Testdata", false, false},
		{"T", "mylib.Testfunc", false, false},
	}
	if iscgo {
		syms = append(syms, symType{"B", "mylib.TestCgodata", false, false})
		syms = append(syms, symType{"T", "mylib.TestCgofunc", false, false})
		if runtime.GOOS == "darwin" || runtime.GOOS == "ios" || (runtime.GOOS == "windows" && runtime.GOARCH == "386") {
			syms = append(syms, symType{"D", "_cgodata", true, false})
			syms = append(syms, symType{"T", "_cgofunc", true, false})
		} else if runtime.GOOS == "aix" {
			syms = append(syms, symType{"D", "cgodata", true, false})
			syms = append(syms, symType{"T", ".cgofunc", true, false})
		} else {
			syms = append(syms, symType{"D", "cgodata", true, false})
			syms = append(syms, symType{"T", "cgofunc", true, false})
		}
	}

	for _, line := range strings.Split(string(out), "\n") {
		f := strings.Fields(line)
		var typ, name string
		var csym bool
		if iscgo {
			if len(f) < 4 {
				continue
			}
			csym = !strings.Contains(f[0], "_go_.o")
			typ = f[2]
			name = f[3]
		} else {
			if len(f) < 3 {
				continue
			}
			typ = f[1]
			name = f[2]
		}
		for i := range syms {
			sym := &syms[i]
			if sym.Type == typ && sym.Name == name && sym.CSym == csym {
				if sym.Found {
					t.Fatalf("duplicate symbol %s %s", sym.Type, sym.Name)
				}
				sym.Found = true
			}
		}
	}
	for _, sym := range syms {
		if !sym.Found {
			t.Errorf("cannot found symbol %s %s", sym.Type, sym.Name)
		}
	}
}

func TestGoLib(t *testing.T) {
	testGoLib(t, false)
}

const testexec = `
package main

import "fmt"
{{if .}}import "C"
{{end}}

func main() {
	testfunc()
}

var testdata uint32

func testfunc() {
	fmt.Printf("main=%p\n", main)
	fmt.Printf("testfunc=%p\n", testfunc)
	fmt.Printf("testdata=%p\n", &testdata)
}
`

const testlib = `
package mylib

{{if .}}
// int cgodata = 5;
// void cgofunc(void) {}
import "C"

var TestCgodata = C.cgodata

func TestCgofunc() {
	C.cgofunc()
}
{{end}}

var Testdata uint32

func Testfunc() {}
`
<|endoftext|>


<commit_before>/**
Copyright (c) 2016 The ConnectorDB Contributors
Licensed under the MIT license.
**/
package connectordb

import (
	pconfig "config/permissions"
	"connectordb/authoperator/permissions"
	"connectordb/datastream"
	"connectordb/messenger"
	"connectordb/query"
	"connectordb/users"
	"errors"
)

var (
	// ErrTimestampOrder is thrown when the tiemstamps are not increasing
	ErrTimestampOrder = errors.New("Timestamps are not ordered!")
)

func (db *Database) getStreamPath(strm *users.Stream) (*users.User, *users.Device, string, error) {
	dev, err := db.ReadDeviceByID(strm.DeviceID)
	if err != nil {
		return nil, nil, "", err
	}
	usr, err := db.ReadUserByID(dev.UserID)
	if err != nil {
		return nil, nil, "", err
	}
	return usr, dev, usr.Name + "/" + dev.Name + "/" + strm.Name, nil
}

//LengthStreamByID returns the total number of datapoints in the stream by ID
func (db *Database) LengthStreamByID(streamID int64, substream string) (int64, error) {
	strm, err := db.ReadStreamByID(streamID)
	if err != nil {
		return 0, err
	}
	return db.DataStream.StreamLength(strm.DeviceID, strm.StreamID, substream)
}

//TimeToIndexStreamByID returns the index for the given timestamp
func (db *Database) TimeToIndexStreamByID(streamID int64, substream string, time float64) (int64, error) {
	strm, err := db.ReadStreamByID(streamID)
	if err != nil {
		return 0, err
	}

	return db.DataStream.GetTimeIndex(strm.DeviceID, streamID, substream, time)
}

//InsertStreamByID inserts into the stream given by the ID
func (db *Database) InsertStreamByID(streamID int64, substream string, data datastream.DatapointArray, restamp bool) error {
	strm, err := db.ReadStreamByID(streamID)
	if err != nil {
		return err
	}
	data.SetZeroTime()
	//Now check that everything is okay
	if !strm.Validate(data) {
		return datastream.ErrInvalidDatapoint
	}
	if !data.IsTimestampOrdered() {
		return ErrTimestampOrder
	}

	u, _, streampath, err := db.getStreamPath(strm)
	if substream != "" {
		streampath = streampath + "/" + substream
	}
	if err != nil {
		return err
	}

	if !strm.Ephemeral {

		r := permissions.GetUserRole(pconfig.Get(), u)
		_, err = db.DataStream.Insert(strm.DeviceID, strm.StreamID, substream, data, restamp, r.MaxDeviceSize, r.MaxStreamSize)
		if err != nil {
			return err
		}
	}

	return db.Messenger.Publish(streampath, messenger.Message{streampath, "", data})
}

//GetStreamTimeRangeByID reads time range by ID
func (db *Database) GetStreamTimeRangeByID(streamID int64, substream string, t1 float64, t2 float64, limit int64, transform string) (datastream.DataRange, error) {
	strm, err := db.ReadStreamByID(streamID)
	if err != nil {
		return nil, err
	}

	dr, err := db.DataStream.TRange(strm.DeviceID, strm.StreamID, substream, t1, t2)
	if limit > 0 {
		dr = datastream.NewNumRange(dr, limit)
	}
	//Add a transform to the resulting data range if one is wanted
	if transform != "" {
		tr, err := query.NewExtendedTransformRange(dr, transform)
		if err != nil {
			dr.Close()
			return nil, err
		}
		dr = tr
	}

	return dr, err
}

//GetShiftedStreamTimeRangeByID reads time range by ID with an index shift
func (db *Database) GetShiftedStreamTimeRangeByID(streamID int64, substream string, t1 float64, t2 float64, shift, limit int64, transform string) (datastream.DataRange, error) {
	strm, err := db.ReadStreamByID(streamID)
	if err != nil {
		return nil, err
	}

	dr, err := db.DataStream.TimePlusIndexRange(strm.DeviceID, strm.StreamID, substream, t1, t2, shift)
	if err != nil {
		return nil, err
	}

	if limit > 0 {
		dr = datastream.NewNumRange(dr, limit)
	}
	//Add a transform to the resulting data range if one is wanted
	if transform != "" {
		tr, err := query.NewExtendedTransformRange(dr, transform)
		if err != nil {
			dr.Close()
			return nil, err
		}
		dr = tr
	}

	return dr, err
}

//GetStreamIndexRangeByID reads index range by ID
func (db *Database) GetStreamIndexRangeByID(streamID int64, substream string, i1 int64, i2 int64, transform string) (datastream.DataRange, error) {
	strm, err := db.ReadStreamByID(streamID)
	if err != nil {
		return nil, err
	}

	dr, err := db.DataStream.IRange(strm.DeviceID, strm.StreamID, substream, i1, i2)
	if err != nil {
		return nil, err
	}

	//Add a transform to the resulting data range if one is wanted
	if transform != "" {
		tr, err := query.NewExtendedTransformRange(dr, transform)
		if err != nil {
			dr.Close()
			return nil, err
		}
		dr = tr
	}
	return dr, err
}
<commit_msg>Moved limit to after transform<commit_after>/**
Copyright (c) 2016 The ConnectorDB Contributors
Licensed under the MIT license.
**/
package connectordb

import (
	pconfig "config/permissions"
	"connectordb/authoperator/permissions"
	"connectordb/datastream"
	"connectordb/messenger"
	"connectordb/query"
	"connectordb/users"
	"errors"
)

var (
	// ErrTimestampOrder is thrown when the tiemstamps are not increasing
	ErrTimestampOrder = errors.New("Timestamps are not ordered!")
)

func (db *Database) getStreamPath(strm *users.Stream) (*users.User, *users.Device, string, error) {
	dev, err := db.ReadDeviceByID(strm.DeviceID)
	if err != nil {
		return nil, nil, "", err
	}
	usr, err := db.ReadUserByID(dev.UserID)
	if err != nil {
		return nil, nil, "", err
	}
	return usr, dev, usr.Name + "/" + dev.Name + "/" + strm.Name, nil
}

//LengthStreamByID returns the total number of datapoints in the stream by ID
func (db *Database) LengthStreamByID(streamID int64, substream string) (int64, error) {
	strm, err := db.ReadStreamByID(streamID)
	if err != nil {
		return 0, err
	}
	return db.DataStream.StreamLength(strm.DeviceID, strm.StreamID, substream)
}

//TimeToIndexStreamByID returns the index for the given timestamp
func (db *Database) TimeToIndexStreamByID(streamID int64, substream string, time float64) (int64, error) {
	strm, err := db.ReadStreamByID(streamID)
	if err != nil {
		return 0, err
	}

	return db.DataStream.GetTimeIndex(strm.DeviceID, streamID, substream, time)
}

//InsertStreamByID inserts into the stream given by the ID
func (db *Database) InsertStreamByID(streamID int64, substream string, data datastream.DatapointArray, restamp bool) error {
	strm, err := db.ReadStreamByID(streamID)
	if err != nil {
		return err
	}
	data.SetZeroTime()
	//Now check that everything is okay
	if !strm.Validate(data) {
		return datastream.ErrInvalidDatapoint
	}
	if !data.IsTimestampOrdered() {
		return ErrTimestampOrder
	}

	u, _, streampath, err := db.getStreamPath(strm)
	if substream != "" {
		streampath = streampath + "/" + substream
	}
	if err != nil {
		return err
	}

	if !strm.Ephemeral {

		r := permissions.GetUserRole(pconfig.Get(), u)
		_, err = db.DataStream.Insert(strm.DeviceID, strm.StreamID, substream, data, restamp, r.MaxDeviceSize, r.MaxStreamSize)
		if err != nil {
			return err
		}
	}

	return db.Messenger.Publish(streampath, messenger.Message{streampath, "", data})
}

//GetStreamTimeRangeByID reads time range by ID
func (db *Database) GetStreamTimeRangeByID(streamID int64, substream string, t1 float64, t2 float64, limit int64, transform string) (datastream.DataRange, error) {
	strm, err := db.ReadStreamByID(streamID)
	if err != nil {
		return nil, err
	}

	dr, err := db.DataStream.TRange(strm.DeviceID, strm.StreamID, substream, t1, t2)

	//Add a transform to the resulting data range if one is wanted
	if transform != "" {
		tr, err := query.NewExtendedTransformRange(dr, transform)
		if err != nil {
			dr.Close()
			return nil, err
		}
		dr = tr
	}

	if limit > 0 {
		dr = datastream.NewNumRange(dr, limit)
	}

	return dr, err
}

//GetShiftedStreamTimeRangeByID reads time range by ID with an index shift
func (db *Database) GetShiftedStreamTimeRangeByID(streamID int64, substream string, t1 float64, t2 float64, shift, limit int64, transform string) (datastream.DataRange, error) {
	strm, err := db.ReadStreamByID(streamID)
	if err != nil {
		return nil, err
	}

	dr, err := db.DataStream.TimePlusIndexRange(strm.DeviceID, strm.StreamID, substream, t1, t2, shift)
	if err != nil {
		return nil, err
	}

	//Add a transform to the resulting data range if one is wanted
	if transform != "" {
		tr, err := query.NewExtendedTransformRange(dr, transform)
		if err != nil {
			dr.Close()
			return nil, err
		}
		dr = tr
	}
	if limit > 0 {
		dr = datastream.NewNumRange(dr, limit)
	}

	return dr, err
}

//GetStreamIndexRangeByID reads index range by ID
func (db *Database) GetStreamIndexRangeByID(streamID int64, substream string, i1 int64, i2 int64, transform string) (datastream.DataRange, error) {
	strm, err := db.ReadStreamByID(streamID)
	if err != nil {
		return nil, err
	}

	dr, err := db.DataStream.IRange(strm.DeviceID, strm.StreamID, substream, i1, i2)
	if err != nil {
		return nil, err
	}

	//Add a transform to the resulting data range if one is wanted
	if transform != "" {
		tr, err := query.NewExtendedTransformRange(dr, transform)
		if err != nil {
			dr.Close()
			return nil, err
		}
		dr = tr
	}
	return dr, err
}
<|endoftext|>


<commit_before>/*
 *
 * k6 - a next-generation load testing tool
 * Copyright (C) 2019 Load Impact
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

package executor

import (
	"context"
	"fmt"
	"sync/atomic"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	null "gopkg.in/guregu/null.v3"

	"github.com/loadimpact/k6/lib"
	"github.com/loadimpact/k6/lib/types"
)

func TestVariableLoopingVUsRun(t *testing.T) {
	t.Parallel()

	config := VariableLoopingVUsConfig{
		BaseConfig:       BaseConfig{GracefulStop: types.NullDurationFrom(0)},
		GracefulRampDown: types.NullDurationFrom(0),
		StartVUs:         null.IntFrom(5),
		Stages: []Stage{
			{
				Duration: types.NullDurationFrom(1 * time.Second),
				Target:   null.IntFrom(5),
			},
			{
				Duration: types.NullDurationFrom(0),
				Target:   null.IntFrom(3),
			},
			{
				Duration: types.NullDurationFrom(1 * time.Second),
				Target:   null.IntFrom(3),
			},
		},
	}

	var iterCount int64
	es := lib.NewExecutionState(lib.Options{}, 10, 50)
	var ctx, cancel, executor, _ = setupExecutor(
		t, config, es,
		simpleRunner(func(ctx context.Context) error {
			// Sleeping for a weird duration somewhat offset from the
			// executor ticks to hopefully keep race conditions out of
			// our control from failing the test.
			time.Sleep(300 * time.Millisecond)
			atomic.AddInt64(&iterCount, 1)
			return nil
		}),
	)
	defer cancel()

	sampleTimes := []time.Duration{
		500 * time.Millisecond,
		1000 * time.Millisecond,
		700 * time.Millisecond,
	}

	errCh := make(chan error)
	go func() { errCh <- executor.Run(ctx, nil) }()

	var result = make([]int64, len(sampleTimes))
	for i, d := range sampleTimes {
		time.Sleep(d)
		result[i] = es.GetCurrentlyActiveVUsCount()
	}

	require.NoError(t, <-errCh)

	assert.Equal(t, []int64{5, 3, 0}, result)
	assert.Equal(t, int64(29), iterCount)
}

// Ensure there's no wobble of VUs during graceful ramp-down, without segments.
// See https://github.com/loadimpact/k6/issues/1296
func TestVariableLoopingVUsRampDownNoWobble(t *testing.T) {
	t.Parallel()

	config := VariableLoopingVUsConfig{
		BaseConfig:       BaseConfig{GracefulStop: types.NullDurationFrom(0)},
		GracefulRampDown: types.NullDurationFrom(1 * time.Second),
		StartVUs:         null.IntFrom(0),
		Stages: []Stage{
			{
				Duration: types.NullDurationFrom(3 * time.Second),
				Target:   null.IntFrom(10),
			},
			{
				Duration: types.NullDurationFrom(2 * time.Second),
				Target:   null.IntFrom(0),
			},
		},
	}

	es := lib.NewExecutionState(lib.Options{}, 10, 50)
	var ctx, cancel, executor, _ = setupExecutor(
		t, config, es,
		simpleRunner(func(ctx context.Context) error {
			time.Sleep(1 * time.Second)
			return nil
		}),
	)
	defer cancel()

	var (
		wg     sync.WaitGroup
		result []int64
		m      sync.Mutex
	)

	sampleActiveVUs := func(delay time.Duration) {
		time.Sleep(delay)
		m.Lock()
		result = append(result, es.GetCurrentlyActiveVUsCount())
		m.Unlock()
	}

	wg.Add(1)
	go func() {
		defer wg.Done()
		sampleActiveVUs(100 * time.Millisecond)
		sampleActiveVUs(3 * time.Second)
		time.AfterFunc(2*time.Second, func() {
			sampleActiveVUs(0)
		})
		time.Sleep(1 * time.Second)
		// Sample ramp-down at a higher frequency
		for i := 0; i < 15; i++ {
			sampleActiveVUs(100 * time.Millisecond)
		}
	}()

	err := executor.Run(ctx, nil)

	wg.Wait()
	require.NoError(t, err)
	assert.Equal(t, int64(0), result[0])
	assert.Equal(t, int64(10), result[1])
	assert.Equal(t, int64(0), result[len(result)-1])

	var curr int64
	last := result[2]
	// Check all ramp-down samples
	for i := 3; i < len(result[2:]); i++ {
		curr = result[i]
		// Detect ramp-ups, missteps (e.g. 7 -> 4), but ignore pauses
		if curr > last || (curr != last && curr != last-1) {
			assert.FailNow(t,
				fmt.Sprintf("ramping down wobble bug - "+
					"current: %d, previous: %d\nVU samples: %v", curr, last, result))
		}
		last = curr
	}
}
<commit_msg>Make TestVariableLoopingVUsRampDownNoWobble more deterministic<commit_after>/*
 *
 * k6 - a next-generation load testing tool
 * Copyright (C) 2019 Load Impact
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

package executor

import (
	"context"
	"fmt"
	"sync/atomic"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	null "gopkg.in/guregu/null.v3"

	"github.com/loadimpact/k6/lib"
	"github.com/loadimpact/k6/lib/types"
)

func TestVariableLoopingVUsRun(t *testing.T) {
	t.Parallel()

	config := VariableLoopingVUsConfig{
		BaseConfig:       BaseConfig{GracefulStop: types.NullDurationFrom(0)},
		GracefulRampDown: types.NullDurationFrom(0),
		StartVUs:         null.IntFrom(5),
		Stages: []Stage{
			{
				Duration: types.NullDurationFrom(1 * time.Second),
				Target:   null.IntFrom(5),
			},
			{
				Duration: types.NullDurationFrom(0),
				Target:   null.IntFrom(3),
			},
			{
				Duration: types.NullDurationFrom(1 * time.Second),
				Target:   null.IntFrom(3),
			},
		},
	}

	var iterCount int64
	es := lib.NewExecutionState(lib.Options{}, 10, 50)
	var ctx, cancel, executor, _ = setupExecutor(
		t, config, es,
		simpleRunner(func(ctx context.Context) error {
			// Sleeping for a weird duration somewhat offset from the
			// executor ticks to hopefully keep race conditions out of
			// our control from failing the test.
			time.Sleep(300 * time.Millisecond)
			atomic.AddInt64(&iterCount, 1)
			return nil
		}),
	)
	defer cancel()

	sampleTimes := []time.Duration{
		500 * time.Millisecond,
		1000 * time.Millisecond,
		700 * time.Millisecond,
	}

	errCh := make(chan error)
	go func() { errCh <- executor.Run(ctx, nil) }()

	var result = make([]int64, len(sampleTimes))
	for i, d := range sampleTimes {
		time.Sleep(d)
		result[i] = es.GetCurrentlyActiveVUsCount()
	}

	require.NoError(t, <-errCh)

	assert.Equal(t, []int64{5, 3, 0}, result)
	assert.Equal(t, int64(29), iterCount)
}

// Ensure there's no wobble of VUs during graceful ramp-down, without segments.
// See https://github.com/loadimpact/k6/issues/1296
func TestVariableLoopingVUsRampDownNoWobble(t *testing.T) {
	t.Parallel()

	config := VariableLoopingVUsConfig{
		BaseConfig:       BaseConfig{GracefulStop: types.NullDurationFrom(0)},
		GracefulRampDown: types.NullDurationFrom(1 * time.Second),
		StartVUs:         null.IntFrom(0),
		Stages: []Stage{
			{
				Duration: types.NullDurationFrom(3 * time.Second),
				Target:   null.IntFrom(10),
			},
			{
				Duration: types.NullDurationFrom(2 * time.Second),
				Target:   null.IntFrom(0),
			},
		},
	}

	es := lib.NewExecutionState(lib.Options{}, 10, 50)
	var ctx, cancel, executor, _ = setupExecutor(
		t, config, es,
		simpleRunner(func(ctx context.Context) error {
			time.Sleep(1 * time.Second)
			return nil
		}),
	)
	defer cancel()

	sampleTimes := []time.Duration{
		100 * time.Millisecond,
		3400 * time.Millisecond,
	}
	const rampDownSamples = 50

	errCh := make(chan error)
	go func() { errCh <- executor.Run(ctx, nil) }()

	var result = make([]int64, len(sampleTimes)+rampDownSamples)
	for i, d := range sampleTimes {
		time.Sleep(d)
		result[i] = es.GetCurrentlyActiveVUsCount()
	}

	// Sample ramp-down at a higher rate
	for i := len(sampleTimes); i < rampDownSamples; i++ {
		time.Sleep(50 * time.Millisecond)
		result[i] = es.GetCurrentlyActiveVUsCount()
	}

	require.NoError(t, <-errCh)

	// Some baseline checks
	assert.Equal(t, int64(0), result[0])
	assert.Equal(t, int64(10), result[1])
	assert.Equal(t, int64(0), result[len(result)-1])

	var curr int64
	last := result[2]
	// Check all ramp-down samples for wobble
	for i := 3; i < len(result[2:]); i++ {
		curr = result[i]
		// Detect ramp-ups, missteps (e.g. 7 -> 4), but ignore pauses (repeats)
		if curr > last || (curr != last && curr != last-1) {
			assert.FailNow(t,
				fmt.Sprintf("ramping down wobble bug - "+
					"current: %d, previous: %d\nVU samples: %v", curr, last, result))
		}
		last = curr
	}
}
<|endoftext|>


<commit_before>package uaa_client

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"

	"code.cloudfoundry.org/lager"
)

type BadUaaResponse struct {
	StatusCode      int
	UaaResponseBody string
}

func (r BadUaaResponse) Error() string {
	return fmt.Sprintf("bad uaa response: %d: %s", r.StatusCode, r.UaaResponseBody)
}

type Client struct {
	Host          string
	Name          string
	Secret        string
	HTTPClient    httpClient
	WarrantClient warrantClient
	Logger        lager.Logger
}

//go:generate counterfeiter -o ../fakes/warrant_client.go --fake-name WarrantClient . warrantClient
type warrantClient interface {
	GetToken(clientName, clientSecret string) (string, error)
}

//go:generate counterfeiter -o ../fakes/http_client.go --fake-name HTTPClient . httpClient
type httpClient interface {
	Do(*http.Request) (*http.Response, error)
}

type CheckTokenResponse struct {
	Scope    []string `json:"scope"`
	UserName string   `json:"user_name"`
}

func (c *Client) GetToken() (string, error) {
	token, err := c.WarrantClient.GetToken(c.Name, c.Secret)
	if err != nil {
		return "", fmt.Errorf("get token failed: %s", err)
	}
	return token, nil
}

func (c *Client) CheckToken(token string) (CheckTokenResponse, error) {
	reqURL := fmt.Sprintf("%s/check_token", c.Host)
	bodyString := "token=" + token
	request, err := http.NewRequest("POST", reqURL, strings.NewReader(bodyString))
	request.SetBasicAuth(c.Name, c.Secret)
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")

	c.Logger.Debug("check-token", lager.Data{
		"URL":    request.URL,
		"Header": request.Header,
		"Body":   bodyString,
	})

	resp, err := c.HTTPClient.Do(request)
	if err != nil {
		return CheckTokenResponse{}, fmt.Errorf("http client: %s", err)
	}
	defer resp.Body.Close()

	respBytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return CheckTokenResponse{}, fmt.Errorf("read body: %s", err)
	}

	if resp.StatusCode != 200 {
		err = BadUaaResponse{
			StatusCode:      resp.StatusCode,
			UaaResponseBody: string(respBytes),
		}
		return CheckTokenResponse{}, err
	}

	responseStruct := CheckTokenResponse{}
	err = json.Unmarshal(respBytes, &responseStruct)
	if err != nil {
		return CheckTokenResponse{}, fmt.Errorf("unmarshal json: %s", err)
	}
	return responseStruct, nil
}
<commit_msg>Remove token from debug log on policy server<commit_after>package uaa_client

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"

	"code.cloudfoundry.org/lager"
)

type BadUaaResponse struct {
	StatusCode      int
	UaaResponseBody string
}

func (r BadUaaResponse) Error() string {
	return fmt.Sprintf("bad uaa response: %d: %s", r.StatusCode, r.UaaResponseBody)
}

type Client struct {
	Host          string
	Name          string
	Secret        string
	HTTPClient    httpClient
	WarrantClient warrantClient
	Logger        lager.Logger
}

//go:generate counterfeiter -o ../fakes/warrant_client.go --fake-name WarrantClient . warrantClient
type warrantClient interface {
	GetToken(clientName, clientSecret string) (string, error)
}

//go:generate counterfeiter -o ../fakes/http_client.go --fake-name HTTPClient . httpClient
type httpClient interface {
	Do(*http.Request) (*http.Response, error)
}

type CheckTokenResponse struct {
	Scope    []string `json:"scope"`
	UserName string   `json:"user_name"`
}

func (c *Client) GetToken() (string, error) {
	token, err := c.WarrantClient.GetToken(c.Name, c.Secret)
	if err != nil {
		return "", fmt.Errorf("get token failed: %s", err)
	}
	return token, nil
}

func (c *Client) CheckToken(token string) (CheckTokenResponse, error) {
	reqURL := fmt.Sprintf("%s/check_token", c.Host)
	bodyString := "token=" + token
	request, err := http.NewRequest("POST", reqURL, strings.NewReader(bodyString))
	request.SetBasicAuth(c.Name, c.Secret)
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")

	c.Logger.Debug("check-token", lager.Data{
		"URL":    request.URL,
		"Header": request.Header,
	})

	resp, err := c.HTTPClient.Do(request)
	if err != nil {
		return CheckTokenResponse{}, fmt.Errorf("http client: %s", err)
	}
	defer resp.Body.Close()

	respBytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return CheckTokenResponse{}, fmt.Errorf("read body: %s", err)
	}

	if resp.StatusCode != 200 {
		err = BadUaaResponse{
			StatusCode:      resp.StatusCode,
			UaaResponseBody: string(respBytes),
		}
		return CheckTokenResponse{}, err
	}

	responseStruct := CheckTokenResponse{}
	err = json.Unmarshal(respBytes, &responseStruct)
	if err != nil {
		return CheckTokenResponse{}, fmt.Errorf("unmarshal json: %s", err)
	}
	return responseStruct, nil
}
<|endoftext|>


<commit_before>package softlayer

import (
	"errors"
	"os"
	"time"

	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/terraform"
	"github.com/softlayer/softlayer-go/session"
)

func Provider() terraform.ResourceProvider {
	defaultSoftLayerSession := session.New()
	return &schema.Provider{
		Schema: map[string]*schema.Schema{
			"username": {
				Type:     schema.TypeString,
				Required: true,
				DefaultFunc: func() (interface{}, error) {
					return defaultSoftLayerSession.UserName, nil
				},
				Description: "The user name for SoftLayer API operations.",
			},
			"api_key": {
				Type:     schema.TypeString,
				Required: true,
				DefaultFunc: func() (interface{}, error) {
					return defaultSoftLayerSession.APIKey, nil
				},
				Description: "The API key for SoftLayer API operations.",
			},
			"endpoint_url": {
				Type:     schema.TypeString,
				Required: true,
				DefaultFunc: func() (interface{}, error) {
					return defaultSoftLayerSession.Endpoint, nil
				},
				Description: "The endpoint url for the SoftLayer API.",
			},
			"timeout": {
				Type:        schema.TypeInt,
				Optional:    true,
				Description: "The timeout (in seconds) to set for any SoftLayer API calls made.",
			},
		},

		DataSourcesMap: map[string]*schema.Resource{
			"softlayer_ssh_key":        dataSourceSoftLayerSSHKey(),
			"softlayer_image_template": dataSourceSoftLayerImageTemplate(),
			"softlayer_vlan":           dataSourceSoftLayerVlan(),
			"softlayer_dns_domain":     dataSourceSoftLayerDnsDomain(),
		},

		ResourcesMap: map[string]*schema.Resource{
			"softlayer_virtual_guest":               resourceSoftLayerVirtualGuest(),
			"softlayer_bare_metal":                  resourceSoftLayerBareMetal(),
			"softlayer_ssh_key":                     resourceSoftLayerSSHKey(),
			"softlayer_dns_domain_record":           resourceSoftLayerDnsDomainRecord(),
			"softlayer_dns_domain":                  resourceSoftLayerDnsDomain(),
			"softlayer_lb_vpx":                      resourceSoftLayerLbVpx(),
			"softlayer_lb_vpx_vip":                  resourceSoftLayerLbVpxVip(),
			"softlayer_lb_vpx_service":              resourceSoftLayerLbVpxService(),
			"softlayer_lb_vpx_ha":                   resourceSoftLayerLbVpxHa(),
			"softlayer_lb_local":                    resourceSoftLayerLbLocal(),
			"softlayer_lb_local_service_group":      resourceSoftLayerLbLocalServiceGroup(),
			"softlayer_lb_local_service":            resourceSoftLayerLbLocalService(),
			"softlayer_security_certificate":        resourceSoftLayerSecurityCertificate(),
			"softlayer_user":                        resourceSoftLayerUser(),
			"softlayer_objectstorage_account":       resourceSoftLayerObjectStorageAccount(),
			"softlayer_provisioning_hook":           resourceSoftLayerProvisioningHook(),
			"softlayer_scale_policy":                resourceSoftLayerScalePolicy(),
			"softlayer_scale_group":                 resourceSoftLayerScaleGroup(),
			"softlayer_basic_monitor":               resourceSoftLayerBasicMonitor(),
			"softlayer_vlan":                        resourceSoftLayerVlan(),
			"softlayer_global_ip":                   resourceSoftLayerGlobalIp(),
			"softlayer_fw_hardware_dedicated":       resourceSoftLayerFwHardwareDedicated(),
			"softlayer_fw_hardware_dedicated_rules": resourceSoftLayerFwHardwareDedicatedRules(),
			"softlayer_file_storage":                resourceSoftLayerFileStorage(),
		},

		ConfigureFunc: providerConfigure,
	}
}

type ProviderConfig interface {
	SoftLayerSession() *session.Session
}

type providerConfig struct {
	Session *session.Session
}

func (config providerConfig) SoftLayerSession() *session.Session {
	return config.Session
}

func providerConfigure(d *schema.ResourceData) (interface{}, error) {
	sess := session.Session{
		UserName: d.Get("username").(string),
		APIKey:   d.Get("api_key").(string),
		Endpoint: d.Get("endpoint_url").(string),
	}

	if rawTimeout, ok := d.GetOk("timeout"); ok {
		timeout := rawTimeout.(int)
		sess.Timeout = time.Duration(timeout)
	}

	if sess.UserName == "" || sess.APIKey == "" {
		return nil, errors.New(
			"No SoftLayer credentials were found. Please ensure you have specified" +
				" them in the provider or in the environment (see the documentation).",
		)
	}

	if os.Getenv("TF_LOG") != "" {
		sess.Debug = true
	}

	return providerConfig{Session: &sess}, nil
}
<commit_msg>Adding block storage resource to provider<commit_after>package softlayer

import (
	"errors"
	"os"
	"time"

	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/terraform"
	"github.com/softlayer/softlayer-go/session"
)

func Provider() terraform.ResourceProvider {
	defaultSoftLayerSession := session.New()
	return &schema.Provider{
		Schema: map[string]*schema.Schema{
			"username": {
				Type:     schema.TypeString,
				Required: true,
				DefaultFunc: func() (interface{}, error) {
					return defaultSoftLayerSession.UserName, nil
				},
				Description: "The user name for SoftLayer API operations.",
			},
			"api_key": {
				Type:     schema.TypeString,
				Required: true,
				DefaultFunc: func() (interface{}, error) {
					return defaultSoftLayerSession.APIKey, nil
				},
				Description: "The API key for SoftLayer API operations.",
			},
			"endpoint_url": {
				Type:     schema.TypeString,
				Required: true,
				DefaultFunc: func() (interface{}, error) {
					return defaultSoftLayerSession.Endpoint, nil
				},
				Description: "The endpoint url for the SoftLayer API.",
			},
			"timeout": {
				Type:        schema.TypeInt,
				Optional:    true,
				Description: "The timeout (in seconds) to set for any SoftLayer API calls made.",
			},
		},

		DataSourcesMap: map[string]*schema.Resource{
			"softlayer_ssh_key":        dataSourceSoftLayerSSHKey(),
			"softlayer_image_template": dataSourceSoftLayerImageTemplate(),
			"softlayer_vlan":           dataSourceSoftLayerVlan(),
			"softlayer_dns_domain":     dataSourceSoftLayerDnsDomain(),
		},

		ResourcesMap: map[string]*schema.Resource{
			"softlayer_virtual_guest":               resourceSoftLayerVirtualGuest(),
			"softlayer_bare_metal":                  resourceSoftLayerBareMetal(),
			"softlayer_ssh_key":                     resourceSoftLayerSSHKey(),
			"softlayer_dns_domain_record":           resourceSoftLayerDnsDomainRecord(),
			"softlayer_dns_domain":                  resourceSoftLayerDnsDomain(),
			"softlayer_lb_vpx":                      resourceSoftLayerLbVpx(),
			"softlayer_lb_vpx_vip":                  resourceSoftLayerLbVpxVip(),
			"softlayer_lb_vpx_service":              resourceSoftLayerLbVpxService(),
			"softlayer_lb_vpx_ha":                   resourceSoftLayerLbVpxHa(),
			"softlayer_lb_local":                    resourceSoftLayerLbLocal(),
			"softlayer_lb_local_service_group":      resourceSoftLayerLbLocalServiceGroup(),
			"softlayer_lb_local_service":            resourceSoftLayerLbLocalService(),
			"softlayer_security_certificate":        resourceSoftLayerSecurityCertificate(),
			"softlayer_user":                        resourceSoftLayerUser(),
			"softlayer_objectstorage_account":       resourceSoftLayerObjectStorageAccount(),
			"softlayer_provisioning_hook":           resourceSoftLayerProvisioningHook(),
			"softlayer_scale_policy":                resourceSoftLayerScalePolicy(),
			"softlayer_scale_group":                 resourceSoftLayerScaleGroup(),
			"softlayer_basic_monitor":               resourceSoftLayerBasicMonitor(),
			"softlayer_vlan":                        resourceSoftLayerVlan(),
			"softlayer_global_ip":                   resourceSoftLayerGlobalIp(),
			"softlayer_fw_hardware_dedicated":       resourceSoftLayerFwHardwareDedicated(),
			"softlayer_fw_hardware_dedicated_rules": resourceSoftLayerFwHardwareDedicatedRules(),
			"softlayer_file_storage":                resourceSoftLayerFileStorage(),
			"softlayer_block_storage":               resourceSoftLayerBlockStorage(),
		},

		ConfigureFunc: providerConfigure,
	}
}

type ProviderConfig interface {
	SoftLayerSession() *session.Session
}

type providerConfig struct {
	Session *session.Session
}

func (config providerConfig) SoftLayerSession() *session.Session {
	return config.Session
}

func providerConfigure(d *schema.ResourceData) (interface{}, error) {
	sess := session.Session{
		UserName: d.Get("username").(string),
		APIKey:   d.Get("api_key").(string),
		Endpoint: d.Get("endpoint_url").(string),
	}

	if rawTimeout, ok := d.GetOk("timeout"); ok {
		timeout := rawTimeout.(int)
		sess.Timeout = time.Duration(timeout)
	}

	if sess.UserName == "" || sess.APIKey == "" {
		return nil, errors.New(
			"No SoftLayer credentials were found. Please ensure you have specified" +
				" them in the provider or in the environment (see the documentation).",
		)
	}

	if os.Getenv("TF_LOG") != "" {
		sess.Debug = true
	}

	return providerConfig{Session: &sess}, nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"io"
	"log"
	"net"
	"os"
	"os/signal"
	"sync"
	"syscall"
)

import "git.torproject.org/pluggable-transports/goptlib.git"

const ptMethodName = "meek"

var ptInfo pt.ClientInfo

// When a connection handler starts, +1 is written to this channel; when it
// ends, -1 is written.
var handlerChan = make(chan int)

func copyLoop(a, b net.Conn) {
	var wg sync.WaitGroup
	wg.Add(2)

	go func() {
		io.Copy(b, a)
		wg.Done()
	}()
	go func() {
		io.Copy(a, b)
		wg.Done()
	}()

	wg.Wait()
}

func handler(conn *pt.SocksConn) error {
	handlerChan <- 1
	defer func() {
		handlerChan <- -1
	}()

	defer conn.Close()
	remote, err := net.Dial("tcp", conn.Req.Target)
	if err != nil {
		conn.Reject()
		return err
	}
	defer remote.Close()
	err = conn.Grant(remote.RemoteAddr().(*net.TCPAddr))
	if err != nil {
		return err
	}

	copyLoop(conn, remote)

	return nil
}

func acceptLoop(ln *pt.SocksListener) error {
	defer ln.Close()
	for {
		conn, err := ln.AcceptSocks()
		if err != nil {
			log.Printf("error in AcceptSocks: %s", err)
			if e, ok := err.(net.Error); ok && !e.Temporary() {
				return err
			}
			continue
		}
		go func() {
			err := handler(conn)
			if err != nil {
				log.Printf("error in handling request: %s", err)
			}
		}()
	}
}

func main() {
	var logFilename string

	flag.StringVar(&logFilename, "log", "", "name of log file")
	flag.Parse()

	if logFilename != "" {
		f, err := os.OpenFile(logFilename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
		if err != nil {
			log.Fatalf("error opening log file: %s", err)
		}
		defer f.Close()
		log.SetOutput(f)
	}

	var err error
	ptInfo, err = pt.ClientSetup([]string{ptMethodName})
	if err != nil {
		log.Fatalf("error in ClientSetup: %s", err)
	}

	listeners := make([]net.Listener, 0)
	for _, methodName := range ptInfo.MethodNames {
		switch methodName {
		case ptMethodName:
			ln, err := pt.ListenSocks("tcp", "127.0.0.1:0")
			if err != nil {
				pt.CmethodError(methodName, err.Error())
				break
			}
			go acceptLoop(ln)
			pt.Cmethod(methodName, ln.Version(), ln.Addr())
			log.Printf("listening on %s", ln.Addr())
			listeners = append(listeners, ln)
		default:
			pt.CmethodError(methodName, "no such method")
		}
	}
	pt.CmethodsDone()

	var numHandlers int = 0
	var sig os.Signal
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)

	// wait for first signal
	sig = nil
	for sig == nil {
		select {
		case n := <-handlerChan:
			numHandlers += n
		case sig = <-sigChan:
		}
	}
	for _, ln := range listeners {
		ln.Close()
	}

	if sig == syscall.SIGTERM {
		return
	}

	// wait for second signal or no more handlers
	sig = nil
	for sig == nil && numHandlers != 0 {
		select {
		case n := <-handlerChan:
			numHandlers += n
		case sig = <-sigChan:
		}
	}

	log.Printf("done")
}
<commit_msg>Frame around request loop.<commit_after>package main

import (
	"crypto/rand"
	"encoding/base64"
	"flag"
	"log"
	"net"
	"net/url"
	"os"
	"os/signal"
	"syscall"
)

import "git.torproject.org/pluggable-transports/goptlib.git"

const ptMethodName = "meek"
const sessionIdLength = 32

var ptInfo pt.ClientInfo

// When a connection handler starts, +1 is written to this channel; when it
// ends, -1 is written.
var handlerChan = make(chan int)

func copyLoop(conn net.Conn, u, sessionId string) error {
	return nil
}

func genSessionId() string {
	buf := make([]byte, sessionIdLength)
	_, err := rand.Read(buf)
	if err != nil {
		panic(err.Error())
	}
	return base64.StdEncoding.EncodeToString(buf)
}

func handler(conn *pt.SocksConn) error {
	handlerChan <- 1
	defer func() {
		handlerChan <- -1
	}()

	defer conn.Close()
	err := conn.Grant(&net.TCPAddr{IP: net.ParseIP("0.0.0.0"), Port: 0})
	if err != nil {
		return err
	}

	sessionId := genSessionId()
	u := url.URL{
		Scheme: "http",
		Host:   conn.Req.Target,
		Path:   "/",
	}

	return copyLoop(conn, u.String(), sessionId)
}

func acceptLoop(ln *pt.SocksListener) error {
	defer ln.Close()
	for {
		conn, err := ln.AcceptSocks()
		if err != nil {
			log.Printf("error in AcceptSocks: %s", err)
			if e, ok := err.(net.Error); ok && !e.Temporary() {
				return err
			}
			continue
		}
		go func() {
			err := handler(conn)
			if err != nil {
				log.Printf("error in handling request: %s", err)
			}
		}()
	}
}

func main() {
	var logFilename string

	flag.StringVar(&logFilename, "log", "", "name of log file")
	flag.Parse()

	if logFilename != "" {
		f, err := os.OpenFile(logFilename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
		if err != nil {
			log.Fatalf("error opening log file: %s", err)
		}
		defer f.Close()
		log.SetOutput(f)
	}

	var err error
	ptInfo, err = pt.ClientSetup([]string{ptMethodName})
	if err != nil {
		log.Fatalf("error in ClientSetup: %s", err)
	}

	listeners := make([]net.Listener, 0)
	for _, methodName := range ptInfo.MethodNames {
		switch methodName {
		case ptMethodName:
			ln, err := pt.ListenSocks("tcp", "127.0.0.1:0")
			if err != nil {
				pt.CmethodError(methodName, err.Error())
				break
			}
			go acceptLoop(ln)
			pt.Cmethod(methodName, ln.Version(), ln.Addr())
			log.Printf("listening on %s", ln.Addr())
			listeners = append(listeners, ln)
		default:
			pt.CmethodError(methodName, "no such method")
		}
	}
	pt.CmethodsDone()

	var numHandlers int = 0
	var sig os.Signal
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)

	// wait for first signal
	sig = nil
	for sig == nil {
		select {
		case n := <-handlerChan:
			numHandlers += n
		case sig = <-sigChan:
		}
	}
	for _, ln := range listeners {
		ln.Close()
	}

	if sig == syscall.SIGTERM {
		return
	}

	// wait for second signal or no more handlers
	sig = nil
	for sig == nil && numHandlers != 0 {
		select {
		case n := <-handlerChan:
			numHandlers += n
		case sig = <-sigChan:
		}
	}

	log.Printf("done")
}
<|endoftext|>


<commit_before>package block

import (
	"sync"

	"golang.org/x/net/context"

	"github.com/barakmich/agro"
)

var _ agro.BlockStore = &tempBlockStore{}

func init() {
	agro.RegisterBlockStore("temp", openTempBlockStore)
}

type tempBlockStore struct {
	mut     sync.RWMutex
	store   map[agro.BlockID][]byte
	nBlocks uint64
}

func openTempBlockStore(cfg agro.Config, gmd agro.GlobalMetadata) (agro.BlockStore, error) {
	return &tempBlockStore{
		store: make(map[agro.BlockID][]byte),
		// Lie about the number of blocks.
		nBlocks: cfg.StorageSize / 1024,
	}, nil
}

func (t *tempBlockStore) Flush() error { return nil }

func (t *tempBlockStore) Close() error {
	t.mut.Lock()
	t.store = nil
	t.mut.Unlock()
	return nil
}

func (t *tempBlockStore) NumBlocks() uint64 {
	return t.nBlocks
}

func (t *tempBlockStore) GetBlock(_ context.Context, s agro.BlockID) ([]byte, error) {
	t.mut.RLock()
	defer t.mut.RUnlock()

	if t.store == nil {
		return nil, agro.ErrClosed
	}

	x, ok := t.store[s]
	if !ok {
		return nil, agro.ErrBlockNotExist
	}
	return x, nil
}

func (t *tempBlockStore) WriteBlock(_ context.Context, s agro.BlockID, data []byte) error {
	t.mut.Lock()
	defer t.mut.Unlock()

	if t.store == nil {
		return agro.ErrClosed
	}

	t.store[s] = data
	return nil
}

func (t *tempBlockStore) DeleteBlock(_ context.Context, s agro.BlockID) error {
	t.mut.Lock()
	defer t.mut.Unlock()

	if t.store == nil {
		return agro.ErrClosed
	}

	delete(t.store, s)
	return nil
}
<commit_msg>update TODO<commit_after>package block

import (
	"sync"

	"golang.org/x/net/context"

	"github.com/barakmich/agro"
)

var _ agro.BlockStore = &tempBlockStore{}

func init() {
	agro.RegisterBlockStore("temp", openTempBlockStore)
}

type tempBlockStore struct {
	mut     sync.RWMutex
	store   map[agro.BlockID][]byte
	nBlocks uint64
}

func openTempBlockStore(cfg agro.Config, gmd agro.GlobalMetadata) (agro.BlockStore, error) {
	return &tempBlockStore{
		store: make(map[agro.BlockID][]byte),
		// TODO(barakmich): Currently we lie about the number of blocks.
		// If we want to guess at a size, or make the map be a max size, or something, PRs accepted.
		nBlocks: cfg.StorageSize / 1024,
	}, nil
}

func (t *tempBlockStore) Flush() error { return nil }

func (t *tempBlockStore) Close() error {
	t.mut.Lock()
	t.store = nil
	t.mut.Unlock()
	return nil
}

func (t *tempBlockStore) NumBlocks() uint64 {
	return t.nBlocks
}

func (t *tempBlockStore) GetBlock(_ context.Context, s agro.BlockID) ([]byte, error) {
	t.mut.RLock()
	defer t.mut.RUnlock()

	if t.store == nil {
		return nil, agro.ErrClosed
	}

	x, ok := t.store[s]
	if !ok {
		return nil, agro.ErrBlockNotExist
	}
	return x, nil
}

func (t *tempBlockStore) WriteBlock(_ context.Context, s agro.BlockID, data []byte) error {
	t.mut.Lock()
	defer t.mut.Unlock()

	if t.store == nil {
		return agro.ErrClosed
	}

	t.store[s] = data
	return nil
}

func (t *tempBlockStore) DeleteBlock(_ context.Context, s agro.BlockID) error {
	t.mut.Lock()
	defer t.mut.Unlock()

	if t.store == nil {
		return agro.ErrClosed
	}

	delete(t.store, s)
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"flag"
	"fmt"
	"io"
	"os"

	"github.com/biogo/hts/bam"
	"github.com/biogo/hts/sam"
)

func check(e error) {
	if e != nil {
		panic(e)
	}
}

func stripTags(path string, tags []string) {
	f, err := os.Open(path)
	check(err)
	b, err := bam.NewReader(f, 3)
	check(err)

	out := os.Stdout
	check(err)

	w, err := bam.NewWriter(out, b.Header(), 2)
	check(err)

	btags := make([][]byte, len(tags))
	for i := range tags {
		btags[i] = []byte(tags[i])
	}

	for {
		rec, err := b.Read()
		if err != nil {
			if err == io.EOF {
				break
			}
			check(err)
		}
		newAux := make(sam.AuxFields, len(rec.AuxFields))
		copy(newAux, rec.AuxFields)
		for _, btag := range btags {
			for i, aux := range newAux {
				if bytes.Compare(aux[:2], btag) == 0 {
					copy(newAux[i:], newAux[i+1:])
					newAux[len(newAux)-1] = nil
					newAux = newAux[:len(newAux)-1]
					break
				}
			}

		}
		rec.AuxFields = newAux
		e := w.Write(rec)
		check(e)

	}
	w.Close()
}

func main() {

	bam := flag.String("bam", "", "path to bam to strip tags")
	flag.Parse()
	tags := flag.Args()
	if len(tags) == 0 || *bam == "" {
		fmt.Printf("send in names of tags to strip and path to bam file\n")
		fmt.Printf("e.g. strip-tags -bam some.bam XS AS MC")
		flag.PrintDefaults()
		return
	}
	stripTags(*bam, tags)
}
<commit_msg>fix flag check<commit_after>package main

import (
	"bytes"
	"flag"
	"fmt"
	"io"
	"os"

	"github.com/biogo/hts/bam"
	"github.com/biogo/hts/sam"
)

func check(e error) {
	if e != nil {
		panic(e)
	}
}

func stripTags(path string, tags []string) {
	f, err := os.Open(path)
	check(err)
	b, err := bam.NewReader(f, 3)
	check(err)

	out := os.Stdout
	check(err)

	w, err := bam.NewWriter(out, b.Header(), 2)
	check(err)

	btags := make([][]byte, len(tags))
	for i := range tags {
		btags[i] = []byte(tags[i])
	}

	for {
		rec, err := b.Read()
		if err != nil {
			if err == io.EOF {
				break
			}
			check(err)
		}
		newAux := make(sam.AuxFields, len(rec.AuxFields))
		copy(newAux, rec.AuxFields)
		for _, btag := range btags {
			for i, aux := range newAux {
				if bytes.Compare(aux[:2], btag) == 0 {
					copy(newAux[i:], newAux[i+1:])
					newAux[len(newAux)-1] = nil
					newAux = newAux[:len(newAux)-1]
					break
				}
			}

		}
		rec.AuxFields = newAux
		e := w.Write(rec)
		check(e)

	}
	w.Close()
}

func main() {

	bam := flag.String("bam", "", "path to bam to strip tags")
	flag.Parse()
	tags := flag.Args()
	if len(tags) == 0 && *bam == "" {
		fmt.Printf("send in names of tags to strip and path to bam file\n")
		fmt.Printf("e.g. strip-tags -bam some.bam XS AS MC")
		flag.PrintDefaults()
		return
	}
	stripTags(*bam, tags)
}
<|endoftext|>


<commit_before>package integration_test

import (
	"encoding/json"
	"flag"
	"fmt"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"time"

	"github.com/blang/semver"
	"github.com/cloudfoundry/libbuildpack"
	"github.com/cloudfoundry/libbuildpack/cutlass"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"testing"
)

var bpDir string
var buildpackVersion string
var packagedBuildpack cutlass.VersionedBuildpackPackage

func init() {
	flag.StringVar(&buildpackVersion, "version", "", "version to use (builds if empty)")
	flag.BoolVar(&cutlass.Cached, "cached", true, "cached buildpack")
	flag.StringVar(&cutlass.DefaultMemory, "memory", "256M", "default memory for pushed apps")
	flag.StringVar(&cutlass.DefaultDisk, "disk", "384M", "default disk for pushed apps")
	flag.Parse()
}

var _ = SynchronizedBeforeSuite(func() []byte {
	// Run once
	if buildpackVersion == "" {
		packagedBuildpack, err := cutlass.PackageUniquelyVersionedBuildpack()
		Expect(err).NotTo(HaveOccurred())

		data, err := json.Marshal(packagedBuildpack)
		Expect(err).NotTo(HaveOccurred())
		return data
	}

	return []byte{}
}, func(data []byte) {
	// Run on all nodes
	var err error
	if len(data) > 0 {
		err = json.Unmarshal(data, &packagedBuildpack)
		Expect(err).NotTo(HaveOccurred())
		buildpackVersion = packagedBuildpack.Version
	}

	bpDir, err = cutlass.FindRoot()
	Expect(err).NotTo(HaveOccurred())

	Expect(cutlass.CopyCfHome()).To(Succeed())

	cutlass.SeedRandom()
	cutlass.DefaultStdoutStderr = GinkgoWriter

	SetDefaultEventuallyTimeout(10 * time.Second)
})

var _ = SynchronizedAfterSuite(func() {
	// Run on all nodes
}, func() {
	// Run once
	cutlass.RemovePackagedBuildpack(packagedBuildpack)
	Expect(cutlass.DeleteOrphanedRoutes()).To(Succeed())
})

func TestIntegration(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "Integration Suite")
}

func ConfirmRunning(app *cutlass.App) {
	Eventually(func() ([]string, error) { return app.InstanceStates() }, 20*time.Second).Should(Equal([]string{"RUNNING"}))
}

func PushAppAndConfirm(app *cutlass.App) {
	Expect(app.Push()).To(Succeed())
	ConfirmRunning(app)
	Expect(app.ConfirmBuildpack(buildpackVersion)).To(Succeed())
}

func Restart(app *cutlass.App) {
	Expect(app.Restart()).To(Succeed())
	Eventually(func() ([]string, error) { return app.InstanceStates() }, 20*time.Second).Should(Equal([]string{"RUNNING"}))
}

func ApiGreaterThan(version string) bool {
	apiVersionString, err := cutlass.ApiVersion()
	Expect(err).To(BeNil())
	apiVersion, err := semver.Make(apiVersionString)
	Expect(err).To(BeNil())
	reqVersion, err := semver.ParseRange(">= " + version)
	Expect(err).To(BeNil())
	return reqVersion(apiVersion)
}

func ApiHasTask() bool {
	return ApiGreaterThan("2.75.0")
}
func ApiHasMultiBuildpack() bool {
	return ApiGreaterThan("3.27.0")
}

func SkipUnlessUncached() {
	if cutlass.Cached {
		Skip("Running cached tests")
	}
}

func SkipUnlessCached() {
	if !cutlass.Cached {
		Skip("Running uncached tests")
	}
}

func DestroyApp(app *cutlass.App) *cutlass.App {
	if app != nil {
		app.Destroy()
	}
	return nil
}

func DefaultVersion(name string) string {
	m := &libbuildpack.Manifest{}
	err := (&libbuildpack.YAML{}).Load(filepath.Join(bpDir, "manifest.yml"), m)
	Expect(err).ToNot(HaveOccurred())
	dep, err := m.DefaultVersion(name)
	Expect(err).ToNot(HaveOccurred())
	Expect(dep.Version).ToNot(Equal(""))
	return dep.Version
}

func AssertUsesProxyDuringStagingIfPresent(fixtureName string) {
	Context("with an uncached buildpack", func() {
		BeforeEach(SkipUnlessUncached)

		PIt("uses a proxy during staging if present", func() {
			proxy, err := cutlass.NewProxy()
			Expect(err).To(BeNil())
			defer proxy.Close()

			bpFile := filepath.Join(bpDir, buildpackVersion+"tmp")
			cmd := exec.Command("cp", packagedBuildpack.File, bpFile)
			err = cmd.Run()
			Expect(err).To(BeNil())
			defer os.Remove(bpFile)

			traffic, err := cutlass.InternetTraffic(
				bpDir,
				filepath.Join("fixtures", fixtureName),
				bpFile,
				[]string{"HTTP_PROXY=" + proxy.URL, "HTTPS_PROXY=" + proxy.URL},
			)
			Expect(err).To(BeNil())

			destUrl, err := url.Parse(proxy.URL)
			Expect(err).To(BeNil())

			Expect(cutlass.UniqueDestination(
				traffic, fmt.Sprintf("%s.%s", destUrl.Hostname(), destUrl.Port()),
			)).To(BeNil())
		})
	})
}

func AssertNoInternetTraffic(fixtureName string) {
	PIt("has no traffic", func() {
		SkipUnlessCached()

		bpFile := filepath.Join(bpDir, buildpackVersion+"tmp")
		cmd := exec.Command("cp", packagedBuildpack.File, bpFile)
		err := cmd.Run()
		Expect(err).To(BeNil())
		defer os.Remove(bpFile)

		traffic, err := cutlass.InternetTraffic(
			bpDir,
			filepath.Join("fixtures", fixtureName),
			bpFile,
			[]string{},
		)
		Expect(err).To(BeNil())
		Expect(traffic).To(BeEmpty())
	})
}
<commit_msg>Enforce ENV[COMPOSER_GITHUB_OAUTH_TOKEN]<commit_after>package integration_test

import (
	"encoding/json"
	"flag"
	"fmt"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"time"

	"github.com/blang/semver"
	"github.com/cloudfoundry/libbuildpack"
	"github.com/cloudfoundry/libbuildpack/cutlass"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"testing"
)

var bpDir string
var buildpackVersion string
var packagedBuildpack cutlass.VersionedBuildpackPackage

func init() {
	flag.StringVar(&buildpackVersion, "version", "", "version to use (builds if empty)")
	flag.BoolVar(&cutlass.Cached, "cached", true, "cached buildpack")
	flag.StringVar(&cutlass.DefaultMemory, "memory", "256M", "default memory for pushed apps")
	flag.StringVar(&cutlass.DefaultDisk, "disk", "384M", "default disk for pushed apps")
	flag.Parse()
}

var _ = SynchronizedBeforeSuite(func() []byte {
	// Run once
	Expect(os.Getenv("COMPOSER_GITHUB_OAUTH_TOKEN")).ToNot(BeEmpty()) // Required for some tests

	if buildpackVersion == "" {
		packagedBuildpack, err := cutlass.PackageUniquelyVersionedBuildpack()
		Expect(err).NotTo(HaveOccurred())

		data, err := json.Marshal(packagedBuildpack)
		Expect(err).NotTo(HaveOccurred())
		return data
	}

	return []byte{}
}, func(data []byte) {
	// Run on all nodes
	var err error
	if len(data) > 0 {
		err = json.Unmarshal(data, &packagedBuildpack)
		Expect(err).NotTo(HaveOccurred())
		buildpackVersion = packagedBuildpack.Version
	}

	bpDir, err = cutlass.FindRoot()
	Expect(err).NotTo(HaveOccurred())

	Expect(cutlass.CopyCfHome()).To(Succeed())

	cutlass.SeedRandom()
	cutlass.DefaultStdoutStderr = GinkgoWriter

	SetDefaultEventuallyTimeout(10 * time.Second)
})

var _ = SynchronizedAfterSuite(func() {
	// Run on all nodes
}, func() {
	// Run once
	cutlass.RemovePackagedBuildpack(packagedBuildpack)
	Expect(cutlass.DeleteOrphanedRoutes()).To(Succeed())
})

func TestIntegration(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "Integration Suite")
}

func ConfirmRunning(app *cutlass.App) {
	Eventually(func() ([]string, error) { return app.InstanceStates() }, 20*time.Second).Should(Equal([]string{"RUNNING"}))
}

func PushAppAndConfirm(app *cutlass.App) {
	Expect(app.Push()).To(Succeed())
	ConfirmRunning(app)
	Expect(app.ConfirmBuildpack(buildpackVersion)).To(Succeed())
}

func Restart(app *cutlass.App) {
	Expect(app.Restart()).To(Succeed())
	Eventually(func() ([]string, error) { return app.InstanceStates() }, 20*time.Second).Should(Equal([]string{"RUNNING"}))
}

func ApiGreaterThan(version string) bool {
	apiVersionString, err := cutlass.ApiVersion()
	Expect(err).To(BeNil())
	apiVersion, err := semver.Make(apiVersionString)
	Expect(err).To(BeNil())
	reqVersion, err := semver.ParseRange(">= " + version)
	Expect(err).To(BeNil())
	return reqVersion(apiVersion)
}

func ApiHasTask() bool {
	return ApiGreaterThan("2.75.0")
}
func ApiHasMultiBuildpack() bool {
	return ApiGreaterThan("3.27.0")
}

func SkipUnlessUncached() {
	if cutlass.Cached {
		Skip("Running cached tests")
	}
}

func SkipUnlessCached() {
	if !cutlass.Cached {
		Skip("Running uncached tests")
	}
}

func DestroyApp(app *cutlass.App) *cutlass.App {
	if app != nil {
		app.Destroy()
	}
	return nil
}

func DefaultVersion(name string) string {
	m := &libbuildpack.Manifest{}
	err := (&libbuildpack.YAML{}).Load(filepath.Join(bpDir, "manifest.yml"), m)
	Expect(err).ToNot(HaveOccurred())
	dep, err := m.DefaultVersion(name)
	Expect(err).ToNot(HaveOccurred())
	Expect(dep.Version).ToNot(Equal(""))
	return dep.Version
}

func AssertUsesProxyDuringStagingIfPresent(fixtureName string) {
	Context("with an uncached buildpack", func() {
		BeforeEach(SkipUnlessUncached)

		It("uses a proxy during staging if present", func() {
			proxy, err := cutlass.NewProxy()
			Expect(err).To(BeNil())
			defer proxy.Close()

			bpFile := filepath.Join(bpDir, buildpackVersion+"tmp")
			cmd := exec.Command("cp", packagedBuildpack.File, bpFile)
			err = cmd.Run()
			Expect(err).To(BeNil())
			defer os.Remove(bpFile)

			traffic, err := cutlass.InternetTraffic(
				bpDir,
				filepath.Join("fixtures", fixtureName),
				bpFile,
				[]string{"HTTP_PROXY=" + proxy.URL, "HTTPS_PROXY=" + proxy.URL},
			)
			Expect(err).To(BeNil())

			destUrl, err := url.Parse(proxy.URL)
			Expect(err).To(BeNil())

			Expect(cutlass.UniqueDestination(
				traffic, fmt.Sprintf("%s.%s", destUrl.Hostname(), destUrl.Port()),
			)).To(BeNil())
		})
	})
}

func AssertNoInternetTraffic(fixtureName string) {
	It("has no traffic", func() {
		SkipUnlessCached()

		bpFile := filepath.Join(bpDir, buildpackVersion+"tmp")
		cmd := exec.Command("cp", packagedBuildpack.File, bpFile)
		err := cmd.Run()
		Expect(err).To(BeNil())
		defer os.Remove(bpFile)

		traffic, err := cutlass.InternetTraffic(
			bpDir,
			filepath.Join("fixtures", fixtureName),
			bpFile,
			[]string{},
		)
		Expect(err).To(BeNil())
		Expect(traffic).To(BeEmpty())
	})
}
<|endoftext|>