<commit_before>package admin

import (
	"encoding/json"
	"fmt"
	"net/http"
	"path"
	"strings"

	"github.com/qor/qor/responder"
	"github.com/qor/qor/roles"
)

type controller struct {
	*Admin
}

const HTTPUnprocessableEntity = 422

func (context *Context) checkResourcePermission(permission roles.PermissionMode) bool {
	if context.Resource == nil || context.Resource.HasPermission(permission, context.Context) {
		return true
	}
	context.Writer.Write([]byte("Permission denied"))
	return false
}

func (ac *controller) Dashboard(context *Context) {
	context.Execute("dashboard", nil)
}

func (ac *controller) SearchCenter(context *Context) {
	type searchResult struct {
		Context  *Context
		Resource *Resource
		Results  interface{}
	}
	var searchResults []searchResult
	for _, res := range context.Admin.searchResources {
		resourceName := context.Request.URL.Query().Get("resource_name")
		if resourceName == "" || res.ToParam() == resourceName {
			ctx := context.clone().setResource(res)
			if results, err := ctx.FindMany(); err == nil {
				searchResults = append(searchResults, searchResult{
					Context:  ctx,
					Resource: res,
					Results:  results,
				})
			}
		}
	}
	context.Execute("search_center", searchResults)
}

func (ac *controller) Index(context *Context) {
	if context.checkResourcePermission(roles.Read) {
		// Singleton Resource
		if context.Resource.Config.Singleton {
			var result = context.Resource.NewStruct()
			if err := context.Resource.CallFindMany(result, context.Context); err == nil {
				context.Execute("show", result)
			} else {
				context.Execute("new", result)
			}
			return
		}

		result, err := context.FindMany()
		context.AddError(err)

		if context.HasError() {
			http.NotFound(context.Writer, context.Request)
		} else {
			responder.With("html", func() {
				context.Execute("index", result)
			}).With("json", func() {
				res := context.Resource
				js, _ := json.Marshal(res.convertObjectToMap(context, result, "index"))
				context.Writer.Write(js)
			}).Respond(context.Writer, context.Request)
		}
	}
}

func (ac *controller) Show(context *Context) {
	if context.checkResourcePermission(roles.Read) {
		result, err := context.FindOne()
		context.AddError(err)

		responder.With("html", func() {
			context.Execute("show", result)
		}).With("json", func() {
			res := context.Resource
			js, _ := json.Marshal(res.convertObjectToMap(context, result, "show"))
			context.Writer.Write(js)
		}).Respond(context.Writer, context.Request)
	}
}

func (ac *controller) New(context *Context) {
	if context.checkResourcePermission(roles.Create) {
		context.Execute("new", context.Resource.NewStruct())
	}
}

func (ac *controller) Create(context *Context) {
	if context.checkResourcePermission(roles.Create) {
		res := context.Resource
		result := res.NewStruct()
		if context.AddError(res.Decode(context.Context, result)); !context.HasError() {
			context.AddError(res.CallSave(result, context.Context))
		}

		if context.HasError() {
			responder.With("html", func() {
				context.Writer.WriteHeader(HTTPUnprocessableEntity)
				context.Execute("new", result)
			}).With("json", func() {
				context.Writer.WriteHeader(HTTPUnprocessableEntity)
				data, _ := json.Marshal(map[string]interface{}{"errors": context.GetErrors()})
				context.Writer.Write(data)
			}).Respond(context.Writer, context.Request)
		} else {
			responder.With("html", func() {
				context.Flash(context.dt("resource_successfully_created", "{{.Name}} was successfully created", res), "success")
				if res.Config.Singleton {
					http.Redirect(context.Writer, context.Request, path.Join(context.Request.URL.Path), http.StatusFound)
				} else {
					http.Redirect(context.Writer, context.Request, context.editResourcePath(result, res), http.StatusFound)
				}
			}).With("json", func() {
				js, _ := json.Marshal(context.Resource.convertObjectToMap(context, result, "show"))
				context.Writer.Write(js)
			}).Respond(context.Writer, context.Request)
		}
	}
}

func (ac *controller) Update(context *Context) {
	if context.checkResourcePermission(roles.Update) {
		res := context.Resource
		result, err := context.FindOne()
		context.AddError(err)
		if !context.HasError() {
			if context.AddError(res.Decode(context.Context, result)); !context.HasError() {
				context.AddError(res.CallSave(result, context.Context))
			}
		}

		if context.HasError() {
			context.Writer.WriteHeader(HTTPUnprocessableEntity)
			responder.With("html", func() {
				context.Execute("show", result)
			}).With("json", func() {
				data, _ := json.Marshal(map[string]interface{}{"errors": context.GetErrors()})
				context.Writer.Write(data)
			}).Respond(context.Writer, context.Request)
		} else {
			responder.With("html", func() {
				context.FlashNow(context.dt("resource_successfully_updated", "{{.Name}} was successfully updated", res), "success")
				if res.Config.Singleton {
					http.Redirect(context.Writer, context.Request, context.UrlFor(res), http.StatusFound)
				} else {
					context.Execute("show", result)
				}
			}).With("json", func() {
				js, _ := json.Marshal(context.Resource.convertObjectToMap(context, result, "show"))
				context.Writer.Write(js)
			}).Respond(context.Writer, context.Request)
		}
	}
}

func (ac *controller) Delete(context *Context) {
	if context.checkResourcePermission(roles.Delete) {
		res := context.Resource
		status := http.StatusOK
		if context.AddError(res.CallDelete(res.NewStruct(), context.Context)); context.HasError() {
			status = http.StatusNotFound
		}

		responder.With("html", func() {
			http.Redirect(context.Writer, context.Request, path.Join(ac.GetRouter().Prefix, res.ToParam()), status)
		}).With("json", func() {
			context.Writer.WriteHeader(status)
		}).Respond(context.Writer, context.Request)
	}
}

func (ac *controller) Action(context *Context) {
	var err error
	name := strings.Split(context.Request.URL.Path, "/")[4]

	for _, action := range context.Resource.actions {
		if action.Name == name {
			ids := context.Request.Form.Get("ids")
			scope := context.GetDB().Where(fmt.Sprintf("%v IN (?)", context.Resource.PrimaryField().DBName), ids)
			err = action.Handle(scope, context.Context)
		}
	}

	responder.With("html", func() {
		http.Redirect(context.Writer, context.Request, context.Request.Referer(), http.StatusFound)
	}).With("json", func() {
		if err == nil {
			context.Writer.Write([]byte("OK"))
		} else {
			context.Writer.Write([]byte(err.Error()))
		}
	}).Respond(context.Writer, context.Request)
}

func (ac *controller) Asset(context *Context) {
	file := strings.TrimPrefix(context.Request.URL.Path, ac.GetRouter().Prefix)
	if filename, err := context.findFile(file); err == nil {
		http.ServeFile(context.Writer, context.Request, filename)
	} else {
		http.NotFound(context.Writer, context.Request)
	}
}
<commit_msg>admin: handle action request errors<commit_after>package admin

import (
	"encoding/json"
	"fmt"
	"net/http"
	"path"
	"strings"

	"github.com/qor/qor/responder"
	"github.com/qor/qor/roles"
)

type controller struct {
	*Admin
}

const HTTPUnprocessableEntity = 422

func (context *Context) checkResourcePermission(permission roles.PermissionMode) bool {
	if context.Resource == nil || context.Resource.HasPermission(permission, context.Context) {
		return true
	}
	context.Writer.Write([]byte("Permission denied"))
	return false
}

func (ac *controller) Dashboard(context *Context) {
	context.Execute("dashboard", nil)
}

func (ac *controller) SearchCenter(context *Context) {
	type searchResult struct {
		Context  *Context
		Resource *Resource
		Results  interface{}
	}
	var searchResults []searchResult
	for _, res := range context.Admin.searchResources {
		resourceName := context.Request.URL.Query().Get("resource_name")
		if resourceName == "" || res.ToParam() == resourceName {
			ctx := context.clone().setResource(res)
			if results, err := ctx.FindMany(); err == nil {
				searchResults = append(searchResults, searchResult{
					Context:  ctx,
					Resource: res,
					Results:  results,
				})
			}
		}
	}
	context.Execute("search_center", searchResults)
}

func (ac *controller) Index(context *Context) {
	if context.checkResourcePermission(roles.Read) {
		// Singleton Resource
		if context.Resource.Config.Singleton {
			var result = context.Resource.NewStruct()
			if err := context.Resource.CallFindMany(result, context.Context); err == nil {
				context.Execute("show", result)
			} else {
				context.Execute("new", result)
			}
			return
		}

		result, err := context.FindMany()
		context.AddError(err)

		if context.HasError() {
			http.NotFound(context.Writer, context.Request)
		} else {
			responder.With("html", func() {
				context.Execute("index", result)
			}).With("json", func() {
				res := context.Resource
				js, _ := json.Marshal(res.convertObjectToMap(context, result, "index"))
				context.Writer.Write(js)
			}).Respond(context.Writer, context.Request)
		}
	}
}

func (ac *controller) Show(context *Context) {
	if context.checkResourcePermission(roles.Read) {
		result, err := context.FindOne()
		context.AddError(err)

		responder.With("html", func() {
			context.Execute("show", result)
		}).With("json", func() {
			res := context.Resource
			js, _ := json.Marshal(res.convertObjectToMap(context, result, "show"))
			context.Writer.Write(js)
		}).Respond(context.Writer, context.Request)
	}
}

func (ac *controller) New(context *Context) {
	if context.checkResourcePermission(roles.Create) {
		context.Execute("new", context.Resource.NewStruct())
	}
}

func (ac *controller) Create(context *Context) {
	if context.checkResourcePermission(roles.Create) {
		res := context.Resource
		result := res.NewStruct()
		if context.AddError(res.Decode(context.Context, result)); !context.HasError() {
			context.AddError(res.CallSave(result, context.Context))
		}

		if context.HasError() {
			responder.With("html", func() {
				context.Writer.WriteHeader(HTTPUnprocessableEntity)
				context.Execute("new", result)
			}).With("json", func() {
				context.Writer.WriteHeader(HTTPUnprocessableEntity)
				data, _ := json.Marshal(map[string]interface{}{"errors": context.GetErrors()})
				context.Writer.Write(data)
			}).Respond(context.Writer, context.Request)
		} else {
			responder.With("html", func() {
				context.Flash(context.dt("resource_successfully_created", "{{.Name}} was successfully created", res), "success")
				if res.Config.Singleton {
					http.Redirect(context.Writer, context.Request, path.Join(context.Request.URL.Path), http.StatusFound)
				} else {
					http.Redirect(context.Writer, context.Request, context.editResourcePath(result, res), http.StatusFound)
				}
			}).With("json", func() {
				js, _ := json.Marshal(context.Resource.convertObjectToMap(context, result, "show"))
				context.Writer.Write(js)
			}).Respond(context.Writer, context.Request)
		}
	}
}

func (ac *controller) Update(context *Context) {
	if context.checkResourcePermission(roles.Update) {
		res := context.Resource
		result, err := context.FindOne()
		context.AddError(err)
		if !context.HasError() {
			if context.AddError(res.Decode(context.Context, result)); !context.HasError() {
				context.AddError(res.CallSave(result, context.Context))
			}
		}

		if context.HasError() {
			context.Writer.WriteHeader(HTTPUnprocessableEntity)
			responder.With("html", func() {
				context.Execute("show", result)
			}).With("json", func() {
				data, _ := json.Marshal(map[string]interface{}{"errors": context.GetErrors()})
				context.Writer.Write(data)
			}).Respond(context.Writer, context.Request)
		} else {
			responder.With("html", func() {
				context.FlashNow(context.dt("resource_successfully_updated", "{{.Name}} was successfully updated", res), "success")
				if res.Config.Singleton {
					http.Redirect(context.Writer, context.Request, context.UrlFor(res), http.StatusFound)
				} else {
					context.Execute("show", result)
				}
			}).With("json", func() {
				js, _ := json.Marshal(context.Resource.convertObjectToMap(context, result, "show"))
				context.Writer.Write(js)
			}).Respond(context.Writer, context.Request)
		}
	}
}

func (ac *controller) Delete(context *Context) {
	if context.checkResourcePermission(roles.Delete) {
		res := context.Resource
		status := http.StatusOK
		if context.AddError(res.CallDelete(res.NewStruct(), context.Context)); context.HasError() {
			status = http.StatusNotFound
		}

		responder.With("html", func() {
			http.Redirect(context.Writer, context.Request, path.Join(ac.GetRouter().Prefix, res.ToParam()), status)
		}).With("json", func() {
			context.Writer.WriteHeader(status)
		}).Respond(context.Writer, context.Request)
	}
}

func (ac *controller) Action(context *Context) {
	var err error
	name := strings.Split(context.Request.URL.Path, "/")[4]

	for _, action := range context.Resource.actions {
		if action.Name == name {
			ids := context.Request.Form.Get("ids")
			scope := context.GetDB().Where(fmt.Sprintf("%v IN (?)", context.Resource.PrimaryField().DBName), ids)
			err = action.Handle(scope, context.Context)
		}
	}

	responder.With("html", func() {
		if err == nil {
			http.Redirect(context.Writer, context.Request, context.Request.Referer(), http.StatusFound)
		} else {
			context.Writer.WriteHeader(HTTPUnprocessableEntity)
			context.Writer.Write([]byte(err.Error()))
		}
	}).With("json", func() {
		if err == nil {
			context.Writer.Write([]byte("OK"))
		} else {
			context.Writer.WriteHeader(HTTPUnprocessableEntity)
			context.Writer.Write([]byte(err.Error()))
		}
	}).Respond(context.Writer, context.Request)
}

func (ac *controller) Asset(context *Context) {
	file := strings.TrimPrefix(context.Request.URL.Path, ac.GetRouter().Prefix)
	if filename, err := context.findFile(file); err == nil {
		http.ServeFile(context.Writer, context.Request, filename)
	} else {
		http.NotFound(context.Writer, context.Request)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/AutoRoute/l2"
	"github.com/AutoRoute/node"
	"github.com/AutoRoute/tuntap"

	"errors"
	"flag"
	"fmt"
	"log"
	"net"
	"runtime"
	"strings"
)

var listen = flag.String("listen", "127.0.0.1:34321",
	"The address to listen to incoming connections on")
var nolisten = flag.Bool("nolisten", false, "Disables listening")
var connect = flag.String("connect", "",
	"Comma separated list of addresses to connect to")
var autodiscover = flag.Bool("auto", false,
	"Whether we should try and find neighboring routers")
var dev_names = flag.String("interface", "",
	"Comma separated list of interfaces to discover on")
var tcptun = flag.String("tcptun", "",
	"Address to try and tcp tunnel to")
var keyfile = flag.String("keyfile", "",
	"The keyfile we should check for a key and write our current key to")

func GetLinkLocalAddr(dev net.Interface) (net.IP, error) {
	dev_addrs, err := dev.Addrs()
	if err != nil {
		return nil, err
	}

	for _, dev_addr := range dev_addrs {
		addr, _, err := net.ParseCIDR(dev_addr.String())
		if err != nil {
			return nil, err
		}

		if addr.IsLinkLocalUnicast() {
			return addr, nil
		}
	}
	return nil, errors.New("Unable to find link local address")
}

func FindNeighbors(dev net.Interface, ll_addr net.IP, key node.PublicKey) <-chan *node.FrameData {
	conn, err := l2.ConnectExistingDevice(dev.Name)
	if err != nil {
		log.Fatal(err)
	}
	nf := node.NewNeighborFinder(key, ll_addr)
	channel, err := nf.Find(dev.HardwareAddr, conn)
	if err != nil {
		log.Fatal(err)
	}
	return channel
}

func Probe(key node.PrivateKey, n *node.Server, dev net.Interface) {
	if dev.Name == "lo" {
		return
	}

	log.Printf("Probing %q", dev.Name)

	ll_addr, err := GetLinkLocalAddr(dev)
	if err != nil {
		log.Printf("Error probing %q: %v", dev.Name, err)
		return
	}

	neighbors := FindNeighbors(dev, ll_addr, key.PublicKey())
	for neighbor := range neighbors {
		log.Printf("Neighbour Found %x", neighbor.NodeAddr)
		err := n.Connect(fmt.Sprintf("[%s%%%s]:31337", neighbor.LLAddrStr, dev.Name))
		if err != nil {
			log.Printf("Error connecting: %v", err)
			return
		}
		log.Printf("Connection established to %x", neighbor.NodeAddr)
	}
}

func main() {

	runtime.GOMAXPROCS(runtime.NumCPU())

	log.Print("Starting")

	flag.Parse()
	quit := make(chan bool)

	var key node.PrivateKey
	var err error

	if len(*keyfile) > 0 {
		key, err = node.LoadKey(*keyfile)
	} else {
		log.Print("Generating key")
		key, err = node.NewECDSAKey()
		if err != nil {
			log.Fatal(err)
		}
	}
	log.Printf("Key is %x", key.PublicKey().Hash())

	n := node.NewServer(key)

	if *autodiscover {
		devs := make([]net.Interface, 0)

		if *dev_names == "" {
			devs, err = net.Interfaces()
			if err != nil {
				log.Fatal(err)
			}
		} else {
			for _, dev_name := range strings.Split(*dev_names, ",") {
				dev, err := net.InterfaceByName(dev_name)
				if err != nil {
					log.Fatal(err)
				}
				devs = append(devs, *dev)
			}
		}

		for _, dev := range devs {
			go Probe(key, n, dev)
		}
	}

	if !*nolisten {
		log.Print("Starting to listen")
		err := n.Listen(*listen)
		if err != nil {
			log.Printf("Error listening: %v", err)
		}
	}

	for _, ip := range strings.Split(*connect, ",") {
		if len(ip) == 0 {
			continue
		}
		err := n.Connect(ip)
		if err != nil {
			log.Printf("Error connecting to %s: %v", ip, err)
		}
	}

	if len(*tcptun) > 0 {
		log.Printf("Establishing tcp tunnel to %v", *tcptun)
		i, err := tuntap.Open("tun%d", tuntap.DevTun)
		if err != nil {
			log.Fatal(err)
		}
		dest := ""
		_, err = fmt.Sscanf(*tcptun, "%x", &dest)
		if err != nil {
			log.Fatal(err)
		}
		t := node.NewTCPTunnel(i, n.Node(), node.NodeAddress(dest), 1)
		t = t
		<-quit
	}

	<-quit
}
<commit_msg>More idiomatic flag name.<commit_after>package main

import (
	"github.com/AutoRoute/l2"
	"github.com/AutoRoute/node"
	"github.com/AutoRoute/tuntap"

	"errors"
	"flag"
	"fmt"
	"log"
	"net"
	"runtime"
	"strings"
)

var listen = flag.String("listen", "127.0.0.1:34321",
	"The address to listen to incoming connections on")
var nolisten = flag.Bool("nolisten", false, "Disables listening")
var connect = flag.String("connect", "",
	"Comma separated list of addresses to connect to")
var autodiscover = flag.Bool("auto", false,
	"Whether we should try and find neighboring routers")
var dev_names = flag.String("devs", "",
	"Comma separated list of interfaces to discover on")
var tcptun = flag.String("tcptun", "",
	"Address to try and tcp tunnel to")
var keyfile = flag.String("keyfile", "",
	"The keyfile we should check for a key and write our current key to")

func GetLinkLocalAddr(dev net.Interface) (net.IP, error) {
	dev_addrs, err := dev.Addrs()
	if err != nil {
		return nil, err
	}

	for _, dev_addr := range dev_addrs {
		addr, _, err := net.ParseCIDR(dev_addr.String())
		if err != nil {
			return nil, err
		}

		if addr.IsLinkLocalUnicast() {
			return addr, nil
		}
	}
	return nil, errors.New("Unable to find link local address")
}

func FindNeighbors(dev net.Interface, ll_addr net.IP, key node.PublicKey) <-chan *node.FrameData {
	conn, err := l2.ConnectExistingDevice(dev.Name)
	if err != nil {
		log.Fatal(err)
	}
	nf := node.NewNeighborFinder(key, ll_addr)
	channel, err := nf.Find(dev.HardwareAddr, conn)
	if err != nil {
		log.Fatal(err)
	}
	return channel
}

func Probe(key node.PrivateKey, n *node.Server, dev net.Interface) {
	if dev.Name == "lo" {
		return
	}

	log.Printf("Probing %q", dev.Name)

	ll_addr, err := GetLinkLocalAddr(dev)
	if err != nil {
		log.Printf("Error probing %q: %v", dev.Name, err)
		return
	}

	neighbors := FindNeighbors(dev, ll_addr, key.PublicKey())
	for neighbor := range neighbors {
		log.Printf("Neighbour Found %x", neighbor.NodeAddr)
		err := n.Connect(fmt.Sprintf("[%s%%%s]:31337", neighbor.LLAddrStr, dev.Name))
		if err != nil {
			log.Printf("Error connecting: %v", err)
			return
		}
		log.Printf("Connection established to %x", neighbor.NodeAddr)
	}
}

func main() {

	runtime.GOMAXPROCS(runtime.NumCPU())

	log.Print("Starting")

	flag.Parse()
	quit := make(chan bool)

	var key node.PrivateKey
	var err error

	if len(*keyfile) > 0 {
		key, err = node.LoadKey(*keyfile)
	} else {
		log.Print("Generating key")
		key, err = node.NewECDSAKey()
		if err != nil {
			log.Fatal(err)
		}
	}
	log.Printf("Key is %x", key.PublicKey().Hash())

	n := node.NewServer(key)

	if *autodiscover {
		devs := make([]net.Interface, 0)

		if *dev_names == "" {
			devs, err = net.Interfaces()
			if err != nil {
				log.Fatal(err)
			}
		} else {
			for _, dev_name := range strings.Split(*dev_names, ",") {
				dev, err := net.InterfaceByName(dev_name)
				if err != nil {
					log.Fatal(err)
				}
				devs = append(devs, *dev)
			}
		}

		for _, dev := range devs {
			go Probe(key, n, dev)
		}
	}

	if !*nolisten {
		log.Print("Starting to listen")
		err := n.Listen(*listen)
		if err != nil {
			log.Printf("Error listening: %v", err)
		}
	}

	for _, ip := range strings.Split(*connect, ",") {
		if len(ip) == 0 {
			continue
		}
		err := n.Connect(ip)
		if err != nil {
			log.Printf("Error connecting to %s: %v", ip, err)
		}
	}

	if len(*tcptun) > 0 {
		log.Printf("Establishing tcp tunnel to %v", *tcptun)
		i, err := tuntap.Open("tun%d", tuntap.DevTun)
		if err != nil {
			log.Fatal(err)
		}
		dest := ""
		_, err = fmt.Sscanf(*tcptun, "%x", &dest)
		if err != nil {
			log.Fatal(err)
		}
		t := node.NewTCPTunnel(i, n.Node(), node.NodeAddress(dest), 1)
		t = t
		<-quit
	}

	<-quit
}
<|endoftext|>


<commit_before>package buffer // import "github.com/tdewolff/parse/buffer"

import (
	"io"
	"io/ioutil"
)

var nullBuffer = []byte{0}

// Lexer is a buffered reader that allows peeking forward and shifting, taking an io.Reader.
// It keeps data in-memory until Free, taking a byte length, is called to move beyond the data.
type Lexer struct {
	buf   []byte
	pos   int // index in buf
	start int // index in buf
	err   error

	restore func()
}

// NewLexerBytes returns a new Lexer for a given io.Reader, and uses ioutil.ReadAll to read it into a byte slice.
// If the io.Reader implements Bytes, that is used instead.
// It will append a NULL at the end of the buffer.
func NewLexer(r io.Reader) *Lexer {
	var b []byte
	if r != nil {
		if buffer, ok := r.(interface {
			Bytes() []byte
		}); ok {
			b = buffer.Bytes()
		} else {
			var err error
			b, err = ioutil.ReadAll(r)
			if err != nil {
				return &Lexer{
					buf: []byte{0},
					err: err,
				}
			}
		}
	}
	return NewLexerBytes(b)
}

// NewLexerBytes returns a new Lexer for a given byte slice, and appends NULL at the end.
// To avoid reallocation, make sure the capacity has room for one more byte.
func NewLexerBytes(b []byte) *Lexer {
	z := &Lexer{
		buf: b,
	}

	n := len(b)
	if n == 0 {
		z.buf = nullBuffer
	} else if b[n-1] != 0 {
		// Append NULL to buffer, but try to avoid reallocation
		if cap(b) > n {
			// Overwrite next byte but restore when done
			b = b[:n+1]
			c := b[n]
			b[n] = 0

			z.buf = b
			z.restore = func() {
				b[n] = c
			}
		} else {
			z.buf = append(b, 0)
		}
	}
	return z
}

// Restore restores the replaced byte past the end of the buffer by NULL.
func (z *Lexer) Restore() {
	if z.restore != nil {
		z.restore()
		z.restore = nil
	}
}

// Err returns the error returned from io.Reader or io.EOF when the end has been reached.
func (z *Lexer) Err() error {
	return z.PeekErr(0)
}

// PeekErr returns the error at position pos. When pos is zero, this is the same as calling Err().
func (z *Lexer) PeekErr(pos int) error {
	if z.err != nil {
		return z.err
	} else if z.pos+pos >= len(z.buf)-1 {
		return io.EOF
	}
	return nil
}

// Peek returns the ith byte relative to the end position.
// Peek returns 0 when an error has occurred, Err returns the error.
func (z *Lexer) Peek(pos int) byte {
	pos += z.pos
	return z.buf[pos]
}

// PeekRune returns the rune and rune length of the ith byte relative to the end position.
func (z *Lexer) PeekRune(pos int) (rune, int) {
	// from unicode/utf8
	c := z.Peek(pos)
	if c < 0xC0 || z.Peek(pos+1) == 0 {
		return rune(c), 1
	} else if c < 0xE0 || z.Peek(pos+2) == 0 {
		return rune(c&0x1F)<<6 | rune(z.Peek(pos+1)&0x3F), 2
	} else if c < 0xF0 || z.Peek(pos+3) == 0 {
		return rune(c&0x0F)<<12 | rune(z.Peek(pos+1)&0x3F)<<6 | rune(z.Peek(pos+2)&0x3F), 3
	}
	return rune(c&0x07)<<18 | rune(z.Peek(pos+1)&0x3F)<<12 | rune(z.Peek(pos+2)&0x3F)<<6 | rune(z.Peek(pos+3)&0x3F), 4
}

// Move advances the position.
func (z *Lexer) Move(n int) {
	z.pos += n
}

// Pos returns a mark to which can be rewinded.
func (z *Lexer) Pos() int {
	return z.pos - z.start
}

// Rewind rewinds the position to the given position.
func (z *Lexer) Rewind(pos int) {
	z.pos = z.start + pos
}

// Lexeme returns the bytes of the current selection.
func (z *Lexer) Lexeme() []byte {
	return z.buf[z.start:z.pos]
}

// Skip collapses the position to the end of the selection.
func (z *Lexer) Skip() {
	z.start = z.pos
}

// Shift returns the bytes of the current selection and collapses the position to the end of the selection.
func (z *Lexer) Shift() []byte {
	b := z.buf[z.start:z.pos]
	z.start = z.pos
	return b
}

// Offset returns the character position in the buffer.
func (z *Lexer) Offset() int {
	return z.pos
}

// Bytes returns the underlying buffer.
func (z *Lexer) Bytes() []byte {
	return z.buf
}
<commit_msg>Bugfix: don't return terminating NULL on Bytes()<commit_after>package buffer // import "github.com/tdewolff/parse/buffer"

import (
	"io"
	"io/ioutil"
)

var nullBuffer = []byte{0}

// Lexer is a buffered reader that allows peeking forward and shifting, taking an io.Reader.
// It keeps data in-memory until Free, taking a byte length, is called to move beyond the data.
type Lexer struct {
	buf   []byte
	pos   int // index in buf
	start int // index in buf
	err   error

	restore func()
}

// NewLexerBytes returns a new Lexer for a given io.Reader, and uses ioutil.ReadAll to read it into a byte slice.
// If the io.Reader implements Bytes, that is used instead.
// It will append a NULL at the end of the buffer.
func NewLexer(r io.Reader) *Lexer {
	var b []byte
	if r != nil {
		if buffer, ok := r.(interface {
			Bytes() []byte
		}); ok {
			b = buffer.Bytes()
		} else {
			var err error
			b, err = ioutil.ReadAll(r)
			if err != nil {
				return &Lexer{
					buf: []byte{0},
					err: err,
				}
			}
		}
	}
	return NewLexerBytes(b)
}

// NewLexerBytes returns a new Lexer for a given byte slice, and appends NULL at the end.
// To avoid reallocation, make sure the capacity has room for one more byte.
func NewLexerBytes(b []byte) *Lexer {
	z := &Lexer{
		buf: b,
	}

	n := len(b)
	if n == 0 {
		z.buf = nullBuffer
	} else if b[n-1] != 0 {
		// Append NULL to buffer, but try to avoid reallocation
		if cap(b) > n {
			// Overwrite next byte but restore when done
			b = b[:n+1]
			c := b[n]
			b[n] = 0

			z.buf = b
			z.restore = func() {
				b[n] = c
			}
		} else {
			z.buf = append(b, 0)
		}
	}
	return z
}

// Restore restores the replaced byte past the end of the buffer by NULL.
func (z *Lexer) Restore() {
	if z.restore != nil {
		z.restore()
		z.restore = nil
	}
}

// Err returns the error returned from io.Reader or io.EOF when the end has been reached.
func (z *Lexer) Err() error {
	return z.PeekErr(0)
}

// PeekErr returns the error at position pos. When pos is zero, this is the same as calling Err().
func (z *Lexer) PeekErr(pos int) error {
	if z.err != nil {
		return z.err
	} else if z.pos+pos >= len(z.buf)-1 {
		return io.EOF
	}
	return nil
}

// Peek returns the ith byte relative to the end position.
// Peek returns 0 when an error has occurred, Err returns the error.
func (z *Lexer) Peek(pos int) byte {
	pos += z.pos
	return z.buf[pos]
}

// PeekRune returns the rune and rune length of the ith byte relative to the end position.
func (z *Lexer) PeekRune(pos int) (rune, int) {
	// from unicode/utf8
	c := z.Peek(pos)
	if c < 0xC0 || z.Peek(pos+1) == 0 {
		return rune(c), 1
	} else if c < 0xE0 || z.Peek(pos+2) == 0 {
		return rune(c&0x1F)<<6 | rune(z.Peek(pos+1)&0x3F), 2
	} else if c < 0xF0 || z.Peek(pos+3) == 0 {
		return rune(c&0x0F)<<12 | rune(z.Peek(pos+1)&0x3F)<<6 | rune(z.Peek(pos+2)&0x3F), 3
	}
	return rune(c&0x07)<<18 | rune(z.Peek(pos+1)&0x3F)<<12 | rune(z.Peek(pos+2)&0x3F)<<6 | rune(z.Peek(pos+3)&0x3F), 4
}

// Move advances the position.
func (z *Lexer) Move(n int) {
	z.pos += n
}

// Pos returns a mark to which can be rewinded.
func (z *Lexer) Pos() int {
	return z.pos - z.start
}

// Rewind rewinds the position to the given position.
func (z *Lexer) Rewind(pos int) {
	z.pos = z.start + pos
}

// Lexeme returns the bytes of the current selection.
func (z *Lexer) Lexeme() []byte {
	return z.buf[z.start:z.pos]
}

// Skip collapses the position to the end of the selection.
func (z *Lexer) Skip() {
	z.start = z.pos
}

// Shift returns the bytes of the current selection and collapses the position to the end of the selection.
func (z *Lexer) Shift() []byte {
	b := z.buf[z.start:z.pos]
	z.start = z.pos
	return b
}

// Offset returns the character position in the buffer.
func (z *Lexer) Offset() int {
	return z.pos
}

// Bytes returns the underlying buffer.
func (z *Lexer) Bytes() []byte {
    if len(z.buf) == 0 {
        return nil
    }
	return z.buf[:len(z.buf)-1]
}
<|endoftext|>


<commit_before>package rabbitsmpp

import (
	"encoding/json"

	"github.com/streadway/amqp"
)

type Publisher interface {
	Publish(Job) error
}

type publisher struct {
	*client
}

func NewPublisher(conf Config) (Publisher, error) {
	c := NewClient(conf).(*client)
	return &publisher{c}, nil
}

func (p *publisher) Publish(j Job) error {
	_, err := p.Bind()
	if err != nil {
		return err
	}

	ch, err := p.Channel()
	if err != nil {
		return err
	}
	defer ch.Close()

	q, err := ch.QueueDeclare(
		p.QueueName(), // name
		true,          // durable
		false,         // delete when unused
		false,         // exclusive
		false,         // no-wait
		nil,           // arguments
	)
	if err != nil {
		return err
	}

	bodyBytes, err := json.Marshal(j)
	if err != nil {
		return err
	}
	err = ch.Publish(
		"",     // exchange
		q.Name, // routing key
		false,  // mandatory
		false,  // immediate
		amqp.Publishing{
			ContentType: "application/json",
			Body:        bodyBytes,
		})
	if err != nil {
		return err
	}

	return nil
}
<commit_msg>Close conn after publish<commit_after>package rabbitsmpp

import (
	"encoding/json"

	"github.com/streadway/amqp"
)

type Publisher interface {
	Publish(Job) error
}

type publisher struct {
	*client
}

func NewPublisher(conf Config) (Publisher, error) {
	c := NewClient(conf).(*client)
	return &publisher{c}, nil
}

func (p *publisher) Publish(j Job) error {
	_, err := p.Bind()
	if err != nil {
		return err
	}
	defer p.conn.Close()

	ch, err := p.Channel()
	if err != nil {
		return err
	}
	defer ch.Close()

	q, err := ch.QueueDeclare(
		p.QueueName(), // name
		true,          // durable
		false,         // delete when unused
		false,         // exclusive
		false,         // no-wait
		nil,           // arguments
	)
	if err != nil {
		return err
	}

	bodyBytes, err := json.Marshal(j)
	if err != nil {
		return err
	}
	err = ch.Publish(
		"",     // exchange
		q.Name, // routing key
		false,  // mandatory
		false,  // immediate
		amqp.Publishing{
			ContentType: "application/json",
			Body:        bodyBytes,
		})
	if err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package webpack

import (
	"fmt"
	"os/exec"
	"path/filepath"

	"github.com/gobuffalo/buffalo/generators"
	"github.com/gobuffalo/buffalo/generators/assets"
	"github.com/gobuffalo/buffalo/generators/assets/standard"
	"github.com/gobuffalo/makr"
	"github.com/pkg/errors"
)

var logo = &makr.RemoteFile{
	File:       makr.NewFile("assets/images/logo.svg", ""),
	RemotePath: assets.LogoURL,
}

// BinPath is the path to the local install of webpack
var BinPath = filepath.Join("node_modules", ".bin", "webpack")

// Run webpack generator
func (w Generator) Run(root string, data makr.Data) error {
	g := makr.New()

	command := "yarn"

	if !w.WithYarn {
		command = "npm"
	} else {
		err := installYarn(data)
		if err != nil {
			return errors.WithStack(err)
		}
	}

	// if there's no npm, return!
	if _, err := exec.LookPath("npm"); err != nil {
		fmt.Println("Could not find npm. Skipping webpack generation.")

		return standard.Run(root, data)
	}

	g.Add(logo)

	files, err := generators.Find(filepath.Join(generators.TemplatesPath, "assets", "webpack"))
	if err != nil {
		return errors.WithStack(err)
	}

	for _, f := range files {
		g.Add(makr.NewFile(f.WritePath, f.Body))
	}

	args := []string{"install", "--no-progress", "--save"}
	g.Add(makr.NewCommand(exec.Command(command, args...)))
	data["opts"] = w
	return g.Run(root, data)
}

func installYarn(data makr.Data) error {
	// if there's no yarn, install it!
	_, err := exec.LookPath("yarn")
	// A new makr is necessary to have yarn available in path
	if err != nil {
		yg := makr.New()
		yargs := []string{"install", "-g", "yarn"}
		yg.Add(makr.NewCommand(exec.Command("npm", yargs...)))
		err = yg.Run(".", data)
		if err != nil {
			return err
		}
	}
	return nil
}
<commit_msg>check for npm earlier in new apps<commit_after>package webpack

import (
	"fmt"
	"os/exec"
	"path/filepath"

	"github.com/gobuffalo/buffalo/generators"
	"github.com/gobuffalo/buffalo/generators/assets"
	"github.com/gobuffalo/buffalo/generators/assets/standard"
	"github.com/gobuffalo/makr"
	"github.com/pkg/errors"
)

var logo = &makr.RemoteFile{
	File:       makr.NewFile("assets/images/logo.svg", ""),
	RemotePath: assets.LogoURL,
}

// BinPath is the path to the local install of webpack
var BinPath = filepath.Join("node_modules", ".bin", "webpack")

// Run webpack generator
func (w Generator) Run(root string, data makr.Data) error {
	g := makr.New()

	// if there's no npm, return!
	if _, err := exec.LookPath("npm"); err != nil {
		fmt.Println("Could not find npm. Skipping webpack generation.")

		return standard.Run(root, data)
	}

	command := "yarn"

	if !w.WithYarn {
		command = "npm"
	} else {
		err := installYarn(data)
		if err != nil {
			return errors.WithStack(err)
		}
	}

	g.Add(logo)

	files, err := generators.Find(filepath.Join(generators.TemplatesPath, "assets", "webpack"))
	if err != nil {
		return errors.WithStack(err)
	}

	for _, f := range files {
		g.Add(makr.NewFile(f.WritePath, f.Body))
	}

	args := []string{"install", "--no-progress", "--save"}
	g.Add(makr.NewCommand(exec.Command(command, args...)))
	data["opts"] = w
	return g.Run(root, data)
}

func installYarn(data makr.Data) error {
	// if there's no yarn, install it!
	_, err := exec.LookPath("yarn")
	// A new makr is necessary to have yarn available in path
	if err != nil {
		yg := makr.New()
		yargs := []string{"install", "-g", "yarn"}
		yg.Add(makr.NewCommand(exec.Command("npm", yargs...)))
		err = yg.Run(".", data)
		if err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package localbitcoins

import (
	"fmt"
	"net/http"
	"reflect"
	"testing"
)

func TestEscrowsService_List(t *testing.T) {
	setup()
	defer teardown()

	mux.HandleFunc("/api/escrows", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, "GET")
		fmt.Fprint(w, `{
      "data":{
        "escrow_list":[
        {
          "data":{"buyer_username":"foo"},
          "actions":{"release_url":"bar"}
        }
        ]
      }
    }`)
	})

	escrow, _, err := client.Escrows.List()
	if err != nil {
		t.Errorf("Escrows.List returned error: %v", err)
	}

	want := []*Escrow{
		&Escrow{BuyerUsername: String("foo"), releaseUrl: String("bar")},
	}
	if !reflect.DeepEqual(escrow, want) {
		t.Errorf("Escrows.List returned %+v, want %+v", escrow, want)
	}
}
<commit_msg>Add escrow.Release test.<commit_after>package localbitcoins

import (
	"fmt"
	"net/http"
	"reflect"
	"testing"
)

func TestEscrow_Release(t *testing.T) {
	setup()
	defer teardown()

	escrow := &Escrow{
		releaseUrl: String("https://localbitcoins.com/api/escrow_release/1"),
	}

	mux.HandleFunc("/api/escrow_release/1", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, "POST")
		fmt.Fprint(w, `Success!`)
	})

	_, err := escrow.Release()
	if err != nil {
		t.Errorf("Error releasing escrow: %v", err)
	}
}

func TestEscrowsService_List(t *testing.T) {
	setup()
	defer teardown()

	mux.HandleFunc("/api/escrows", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, "GET")
		fmt.Fprint(w, `{
      "data":{
        "escrow_list":[
        {
          "data":{"buyer_username":"foo"},
          "actions":{"release_url":"bar"}
        }
        ]
      }
    }`)
	})

	escrow, _, err := client.Escrows.List()
	if err != nil {
		t.Errorf("Escrows.List returned error: %v", err)
	}

	want := []*Escrow{
		&Escrow{BuyerUsername: String("foo"), releaseUrl: String("bar")},
	}
	if !reflect.DeepEqual(escrow, want) {
		t.Errorf("Escrows.List returned %+v, want %+v", escrow, want)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
)

//NewAlfredScriptFilterTranslator creates
//an instance of an Alfred script filtertransltor.
func NewAlfredScriptFilterTranslator() *AlfredScriptFilterTranslator {
	return new(AlfredScriptFilterTranslator)
}

//AlfredScriptFilterTranslator is a translator that
//allows for the output of lists/keys/value in the
//expected xml format for an Alfred Script Filter.
type AlfredScriptFilterTranslator struct {
}

//Initialize allows for a chance to do any
//initial actions to the io stream.
func (t *AlfredScriptFilterTranslator) Initialize(w io.Writer, s Storage) {
	fmt.Fprint(w, "<?xml version=\"1.0\"?>\n")
	fmt.Fprint(w, "<items>\n")
}

//Execute performs the requested translation.
func (t *AlfredScriptFilterTranslator) Execute(w io.Writer, s Storage, list string, key string, value string) {
	fmt.Fprintf(w, "<item uid=\"%s:%s:%s\" arg=\"%s %s\">\n", list, key, value, list, key)
	fmt.Fprintf(w, "<title>%s: \"%s\"</title>\n", key, value)
	fmt.Fprintf(w, "<subtitle>In list: %s</subtitle>\n", list)
	fmt.Fprintf(w, "<icon type=\"fileicon\">alfredhat.png</icon>\n")
	fmt.Fprint(w, "</item>\n")
}

//Finalize performs an final actions to the io stream.
func (t *AlfredScriptFilterTranslator) Finalize(w io.Writer, s Storage) {
	fmt.Fprint(w, "</items>\n")
}
<commit_msg>Changing format of messages.<commit_after>package main

import (
	"fmt"
	"io"
)

//NewAlfredScriptFilterTranslator creates
//an instance of an Alfred script filtertransltor.
func NewAlfredScriptFilterTranslator() *AlfredScriptFilterTranslator {
	return new(AlfredScriptFilterTranslator)
}

//AlfredScriptFilterTranslator is a translator that
//allows for the output of lists/keys/value in the
//expected xml format for an Alfred Script Filter.
type AlfredScriptFilterTranslator struct {
}

//Initialize allows for a chance to do any
//initial actions to the io stream.
func (t *AlfredScriptFilterTranslator) Initialize(w io.Writer, s Storage) {
	fmt.Fprint(w, "<?xml version=\"1.0\"?>\n")
	fmt.Fprint(w, "<items>\n")
}

//Execute performs the requested translation.
func (t *AlfredScriptFilterTranslator) Execute(w io.Writer, s Storage, list string, key string, value string) {
	fmt.Fprintf(w, "<item uid=\"%s:%s:%s\" arg=\"%s %s\">\n", list, key, value, list, key)
	fmt.Fprintf(w, "<title>%s</title>\n", key)
	fmt.Fprintf(w, "<subtitle>%s</subtitle>\n", value)
	fmt.Fprintf(w, "<icon type=\"fileicon\">alfredhat.png</icon>\n")
	fmt.Fprint(w, "</item>\n")
}

//Finalize performs an final actions to the io stream.
func (t *AlfredScriptFilterTranslator) Finalize(w io.Writer, s Storage) {
	fmt.Fprint(w, "</items>\n")
}
<|endoftext|>


<commit_before>// Copyright 2018 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.

package engine

import (
	"encoding/hex"
	"testing"

	"github.com/keybase/client/go/libkb"
	"github.com/stretchr/testify/require"
)

func persistState(m libkb.MetaContext, d libkb.DeviceCloneState) error {
	return libkb.SetDeviceCloneState(m, d)
}

func runAndGet(m libkb.MetaContext) (d libkb.DeviceCloneState, err error) {
	_, _, err = libkb.UpdateDeviceCloneState(m)
	d, _ = libkb.GetDeviceCloneState(m)
	return d, err
}

func assertIsValidToken(tc libkb.TestContext, token string) {
	_, err := hex.DecodeString(token)
	require.NoError(tc.T, err)
	require.Equal(tc.T, len(token), 32)
}

func assertSuccessfulRun(tc libkb.TestContext, d libkb.DeviceCloneState, err error) {
	require.NoError(tc.T, err)
	require.Equal(tc.T, d.Stage, "")
	assertIsValidToken(tc, d.Prior)
}

func TestDeviceCloneStateFirstRun(t *testing.T) {
	tc := SetupEngineTest(t, "DeviceCloneState")
	defer tc.Cleanup()
	_ = CreateAndSignupFakeUser(tc, "fu")
	m := NewMetaContextForTest(tc)

	d, err := runAndGet(m)

	assertSuccessfulRun(tc, d, err)
	require.Equal(tc.T, d.Clones, 1)
}

func TestDeviceCloneStateSuccessfulUpdate(t *testing.T) {
	tc := SetupEngineTest(t, "DeviceCloneState")
	defer tc.Cleanup()
	_ = CreateAndSignupFakeUser(tc, "fu")
	m := NewMetaContextForTest(tc)
	//setup: perform an initial run
	_, err := runAndGet(m)
	require.NoError(tc.T, err)

	d, err := runAndGet(m)

	assertSuccessfulRun(tc, d, err)
}

func TestDeviceCloneStateRecoveryFromFailureBeforeServer(t *testing.T) {
	tc := SetupEngineTest(t, "DeviceCloneState")
	defer tc.Cleanup()
	_ = CreateAndSignupFakeUser(tc, "fu")
	m := NewMetaContextForTest(tc)
	// setup: persist tokens as if the process failed
	// before the server received the update
	d0 := libkb.DeviceCloneState{
		Prior:  libkb.DefaultCloneTokenValue,
		Stage:  "22222222222222222222222222222222",
		Clones: 1,
	}
	persistState(m, d0)

	d, err := runAndGet(m)

	assertSuccessfulRun(tc, d, err)
}

func TestDeviceCloneStateRecoveryFromFailureAfterServer(t *testing.T) {
	tc := SetupEngineTest(t, "DeviceCloneState")
	defer tc.Cleanup()
	_ = CreateAndSignupFakeUser(tc, "fu")
	m := NewMetaContextForTest(tc)
	// setup: run twice. then reset the persistence to where it would have been
	// if the server got the second update but did not ack it successfully to the client.
	d0, err := runAndGet(m)
	d1, err := runAndGet(m)
	tmp := libkb.DeviceCloneState{Prior: d0.Prior, Stage: d1.Prior, Clones: 1}
	persistState(m, tmp)

	d, err := runAndGet(m)

	assertSuccessfulRun(tc, d, err)
}

func TestDeviceCloneStateCloneDetected(t *testing.T) {
	tc := SetupEngineTest(t, "DeviceCloneState")
	defer tc.Cleanup()
	_ = CreateAndSignupFakeUser(tc, "fu")
	m := NewMetaContextForTest(tc)
	// setup: perform two runs, and then manually persist the earlier
	// prior token to simulate a subsequent run by a cloned device
	d0, err := runAndGet(m)
	require.NoError(tc.T, err)
	_, err = runAndGet(m)
	require.NoError(tc.T, err)
	persistState(m, d0)

	_, _, err = libkb.UpdateDeviceCloneState(m)
	d, _ := libkb.GetDeviceCloneState(m)

	assertSuccessfulRun(tc, d, err)
}

func TestDeviceCloneStateBeforeAndAfterOnFirstRun(t *testing.T) {
	tc := SetupEngineTest(t, "DeviceCloneState")
	defer tc.Cleanup()
	_ = CreateAndSignupFakeUser(tc, "fu")
	m := NewMetaContextForTest(tc)

	before, after, err := libkb.UpdateDeviceCloneState(m)

	require.NoError(tc.T, err)
	require.Equal(tc.T, before, 1, "there was one clone before the test run")
	require.Equal(tc.T, after, 1, "there was one clone after the test run")
}
<commit_msg>Revert "remove device_clone test assertions until the server can support them" (#12995)<commit_after>// Copyright 2018 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.

package engine

import (
	"encoding/hex"
	"testing"

	"github.com/keybase/client/go/libkb"
	"github.com/stretchr/testify/require"
)

func persistState(m libkb.MetaContext, d libkb.DeviceCloneState) error {
	return libkb.SetDeviceCloneState(m, d)
}

func runAndGet(m libkb.MetaContext) (d libkb.DeviceCloneState, err error) {
	_, _, err = libkb.UpdateDeviceCloneState(m)
	d, _ = libkb.GetDeviceCloneState(m)
	return d, err
}

func assertIsValidToken(tc libkb.TestContext, token string) {
	_, err := hex.DecodeString(token)
	require.NoError(tc.T, err)
	require.Equal(tc.T, len(token), 32)
}

func assertSuccessfulRun(tc libkb.TestContext, d libkb.DeviceCloneState, err error) {
	require.NoError(tc.T, err)
	require.Equal(tc.T, d.Stage, "")
	assertIsValidToken(tc, d.Prior)
}

func TestDeviceCloneStateFirstRun(t *testing.T) {
	tc := SetupEngineTest(t, "DeviceCloneState")
	defer tc.Cleanup()
	_ = CreateAndSignupFakeUser(tc, "fu")
	m := NewMetaContextForTest(tc)

	d, err := runAndGet(m)

	assertSuccessfulRun(tc, d, err)
	require.Equal(tc.T, d.Clones, 1)
}

func TestDeviceCloneStateSuccessfulUpdate(t *testing.T) {
	tc := SetupEngineTest(t, "DeviceCloneState")
	defer tc.Cleanup()
	_ = CreateAndSignupFakeUser(tc, "fu")
	m := NewMetaContextForTest(tc)
	//setup: perform an initial run
	d0, err := runAndGet(m)
	require.NoError(tc.T, err)

	d, err := runAndGet(m)

	assertSuccessfulRun(tc, d, err)
	require.NotEqual(tc.T, d.Prior, d0.Prior)
	require.Equal(tc.T, d.Clones, 1)
}

func TestDeviceCloneStateRecoveryFromFailureBeforeServer(t *testing.T) {
	tc := SetupEngineTest(t, "DeviceCloneState")
	defer tc.Cleanup()
	_ = CreateAndSignupFakeUser(tc, "fu")
	m := NewMetaContextForTest(tc)
	// setup: persist tokens as if the process failed
	// before the server received the update
	d0 := libkb.DeviceCloneState{
		Prior:  libkb.DefaultCloneTokenValue,
		Stage:  "22222222222222222222222222222222",
		Clones: 1,
	}
	persistState(m, d0)

	d, err := runAndGet(m)

	assertSuccessfulRun(tc, d, err)
	require.Equal(tc.T, d.Prior, d0.Stage)
	require.Equal(tc.T, d.Clones, 1)
}

func TestDeviceCloneStateRecoveryFromFailureAfterServer(t *testing.T) {
	tc := SetupEngineTest(t, "DeviceCloneState")
	defer tc.Cleanup()
	_ = CreateAndSignupFakeUser(tc, "fu")
	m := NewMetaContextForTest(tc)
	// setup: run twice. then reset the persistence to where it would have been
	// if the server got the second update but did not ack it successfully to the client.
	d0, err := runAndGet(m)
	d1, err := runAndGet(m)
	tmp := libkb.DeviceCloneState{Prior: d0.Prior, Stage: d1.Prior, Clones: 1}
	persistState(m, tmp)

	d, err := runAndGet(m)

	assertSuccessfulRun(tc, d, err)
	require.Equal(tc.T, d.Prior, d1.Prior)
	require.Equal(tc.T, d.Clones, 1)
}

func TestDeviceCloneStateCloneDetected(t *testing.T) {
	tc := SetupEngineTest(t, "DeviceCloneState")
	defer tc.Cleanup()
	_ = CreateAndSignupFakeUser(tc, "fu")
	m := NewMetaContextForTest(tc)
	// setup: perform two runs, and then manually persist the earlier
	// prior token to simulate a subsequent run by a cloned device
	d0, err := runAndGet(m)
	require.NoError(tc.T, err)
	_, err = runAndGet(m)
	require.NoError(tc.T, err)
	persistState(m, d0)

	before, after, err := libkb.UpdateDeviceCloneState(m)
	d, _ := libkb.GetDeviceCloneState(m)

	assertSuccessfulRun(tc, d, err)
	require.NotEqual(tc.T, d.Prior, d0.Stage, "despite there being a clone, the prior still needs to change")
	require.Equal(tc.T, d.Clones, 2)
	require.Equal(tc.T, before, 1, "there was one clone before the test run")
	require.Equal(tc.T, after, 2, "there were two clones after the test run")
}

func TestDeviceCloneStateBeforeAndAfterOnFirstRun(t *testing.T) {
	tc := SetupEngineTest(t, "DeviceCloneState")
	defer tc.Cleanup()
	_ = CreateAndSignupFakeUser(tc, "fu")
	m := NewMetaContextForTest(tc)

	before, after, err := libkb.UpdateDeviceCloneState(m)

	require.NoError(tc.T, err)
	require.Equal(tc.T, before, 1, "there was one clone before the test run")
	require.Equal(tc.T, after, 1, "there was one clone after the test run")
}
<|endoftext|>


<commit_before>package config

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"net"
	"net/url"
	"path"
	"strconv"
	"strings"

	"github.com/koding/multiconfig"
)

//go:generate go run genconfig.go -pkg config -i config.json -o config.json.go

// Builtin stores configuration that was generated at compile time.
var Builtin *Config

func init() {
	rawCfg := MustAsset("config.json")

	loaders := []multiconfig.Loader{
		&multiconfig.JSONLoader{Reader: bytes.NewReader(rawCfg)},
		&multiconfig.EnvironmentLoader{Prefix: "KONFIG_GOKODING"},
	}

	d := &multiconfig.DefaultLoader{
		Loader:    multiconfig.MultiLoader(loaders...),
		Validator: &multiconfig.RequiredValidator{},
	}

	Builtin = &Config{}

	d.MustLoad(Builtin)
	d.MustValidate(Builtin)

	// set global compile time environment.
	environment = Builtin.Environment

	// Check if routes values are correct.
	for route, host := range Builtin.Routes {
		if host == "" {
			panic("empty host for route: " + route)
		}
	}
}

// environment defines the environment on which configuration was generated.
var environment string

// URL is a wrapper for url.URL that implements the following interfaces:
//
//   - flag.Getter
//   - json.Marshaler
//   - json.Unmarshaler
//
type URL struct {
	*url.URL
}

var (
	_ flag.Getter      = (*URL)(nil)
	_ json.Marshaler   = (*URL)(nil)
	_ json.Unmarshaler = (*URL)(nil)
)

// Get implements the flag.Getter interface.
func (u URL) Get() interface{} {
	return u.URL
}

// Set implements the flag.Value interface.
func (u *URL) Set(s string) error {
	ur, err := url.Parse(s)
	if err != nil {
		return err
	}
	u.URL = ur
	return nil
}

// Unmarshal implements the json.Unmarshaler interface.
func (u *URL) UnmarshalJSON(p []byte) error {
	s, err := strconv.Unquote(string(p))
	if err != nil {
		return err
	}
	u.URL, err = url.Parse(s)
	return err
}

// MarshalJSON implements the json.Marshaler interface.
func (u *URL) MarshalJSON() ([]byte, error) {
	return []byte(strconv.Quote(u.String())), nil
}

// WithPath gives new URL with append paths to its Path field.
func (u *URL) WithPath(paths ...string) *URL {
	ur := *u.URL
	ur.Path = path.Join(ur.Path, path.Join(paths...))
	return &URL{URL: &ur}
}

// Copy returns a copy of the u.
func (u *URL) Copy() *URL {
	if u.IsNil() {
		return nil
	}

	uCopy := *u.URL
	if u.URL.User != nil {
		userCopy := *u.URL.User
		uCopy.User = &userCopy
	}

	return &URL{
		URL: &uCopy,
	}
}

// IsNil returns true if either u or the underlying url is nil.
func (u *URL) IsNil() bool {
	return u == nil || u.URL == nil
}

// Endpoint represents a single endpoint.
type Endpoint struct {
	Public  *URL `json:"public,omitempty"`
	Private *URL `json:"private,omitempty"`
}

// NewEndpoint gives new endpoint with public field set to u.
//
// The u is expected to parse as url.URL, otherwise the function
// panics.
//
// If u is empty, NewEndpoint returns zero value for an Endpoint
// type with all pointer fields initialized.
func NewEndpoint(u string) *Endpoint {
	e := &Endpoint{
		Public: &URL{URL: &url.URL{}},
	}

	if u != "" {
		var err error
		e.Public.URL, err = url.Parse(u)
		if err != nil {
			panic(fmt.Errorf("NewEndpoint(%q): %s", u, err))
		}
	}

	return e
}

// NewEndpointURL gives new endpoint with:
//
//   - public field set to u
//   - private field set to 127.0.0.1:<port>, where
//     port is port part of u.Hostname
//
// The u argument is expected to be non-nil.
func NewEndpointURL(u *url.URL) *Endpoint {
	uPriv := *u
	uPriv.Scheme = "http"
	uPriv.Host = "127.0.0.1"

	if _, port, err := net.SplitHostPort(u.Host); err == nil {
		uPriv.Host = net.JoinHostPort(uPriv.Host, port)
	}

	return &Endpoint{
		Public:  &URL{URL: u},
		Private: &URL{URL: &uPriv},
	}
}

// Equal gives true when e and rhs endpoints match.
func (e *Endpoint) Equal(rhs *Endpoint) bool {
	if (e.Public != nil) != (rhs.Public != nil) {
		return false
	}

	if e.Public != nil && e.Public.String() != rhs.Public.String() {
		return false
	}

	if (e.Private != nil) != (rhs.Private != nil) {
		return false
	}

	return e.Private == nil || e.Private.String() == rhs.Private.String()
}

// WithPath gives new Endpoint with path appended to both
// Public and Private URLs.
func (e *Endpoint) WithPath(path string) *Endpoint {
	ePath := &Endpoint{}

	if e.Public != nil {
		ePath.Public = e.Public.WithPath(path)
	}

	if e.Private != nil {
		ePath.Private = e.Private.WithPath(path)
	}

	return ePath
}

// Copy returns a copy of the e.
func (e *Endpoint) Copy() *Endpoint {
	if e.IsNil() {
		return nil
	}
	return &Endpoint{
		Public:  e.Public.Copy(),
		Private: e.Private.Copy(),
	}
}

// IsNil returns true if either e or both of the public and private urls are nil.
func (e *Endpoint) IsNil() bool {
	return e == nil || (e.Public.IsNil() && e.Private.IsNil())
}

// Config stores all static configuration data generated during ./configure phase.
type Config struct {
	Environment string `json:"environment" required:"true"`
	Buckets     struct {
		PublicLogs Bucket `json:"publicLogs" required:"true"`
	} `json:"buckets" required:"true"`
	Endpoints struct {
		IP           *Endpoint `json:"ip" required:"true"`
		IPCheck      *Endpoint `json:"ipCheck" required:"true"`
		KDLatest     *Endpoint `json:"kdLatest" required:"true"`
		KlientLatest *Endpoint `json:"klientLatest" required:"true"`
		KodingBase   *Endpoint `json:"kodingBase" required:"true"`
		TunnelServer *Endpoint `json:"tunnelServer" required:"true"`
	} `json:"endpoints"`
	Routes map[string]string `json:"routes"`
}

// KontrolPublic gives new public endpoint for the given URL.
func (c *Config) KontrolPublic() *url.URL {
	u := *c.Endpoints.KodingBase.Public.URL
	u.Path = "/kontrol/kite"
	return &u
}

// Bucket represents a S3 storage bucket. It stores bucket name and the physical
// region in which bucket was created.
type Bucket struct {
	Name   string `json:"name" required:"true"`
	Region string `json:"region" required:"true"`
}

func mustURL(s string) *URL {
	u, err := url.Parse(s)
	if err != nil {
		panic(`url.Parse("` + s + `"): ` + err.Error())
	}

	return &URL{URL: u}
}

// ReplaceEnv should be used in case when caller environment is different than
// the build in one. This function should be removed when service environments
// are unified/cleaned.
func ReplaceEnv(e *Endpoint, env string) *Endpoint {
	return ReplaceCustomEnv(e, environment, env)
}

// ReplaceCustomEnv should be used in case when provided environment is different than
// the build one.
//
// This function should be removed when service environments are unified/cleaned.
func ReplaceCustomEnv(e *Endpoint, env, newEnv string) *Endpoint {
	// This is a workaround when caller's env doesn't match build in one.
	eReplaced := &Endpoint{}

	if e.Public != nil {
		eReplaced.Public = mustURL(strings.Replace(e.Public.String(), env, RmAlias(newEnv), -1))
	}

	if e.Private != nil {
		eReplaced.Private = mustURL(strings.Replace(e.Private.String(), env, RmAlias(newEnv), -1))
	}

	return eReplaced
}

var defaultAliases = aliases{
	"production":  {},
	"managed":     {},
	"development": {"sandbox", "default", "dev"},
	"devmanaged":  {},
	"default":     {},
}

type aliases map[string][]string

// RmAlias removes aliased environments like sandbox which is in fact
// a development build. If provided environment is not found, this function
// returns build in environment.
func RmAlias(env string) string {
	return rmAlias(env, environment)
}

func rmAlias(env, defaultEnv string) string {
	for e := range defaultAliases {
		if e == env {
			return e
		}

		// Lookup for environment aliases.
		for _, alias := range defaultAliases[e] {
			if alias == env {
				return e
			}
		}
	}

	return defaultEnv
}

// RmManaged maps managed environments to their build in counterparts.
func RmManaged(env string) string {
	switch env {
	case "managed":
		return "production"
	case "devmanaged":
		return "development"
	default:
		return env
	}
}
<commit_msg>kites/config: don't alias default env<commit_after>package config

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"net"
	"net/url"
	"path"
	"strconv"
	"strings"

	"github.com/koding/multiconfig"
)

//go:generate go run genconfig.go -pkg config -i config.json -o config.json.go

// Builtin stores configuration that was generated at compile time.
var Builtin *Config

func init() {
	rawCfg := MustAsset("config.json")

	loaders := []multiconfig.Loader{
		&multiconfig.JSONLoader{Reader: bytes.NewReader(rawCfg)},
		&multiconfig.EnvironmentLoader{Prefix: "KONFIG_GOKODING"},
	}

	d := &multiconfig.DefaultLoader{
		Loader:    multiconfig.MultiLoader(loaders...),
		Validator: &multiconfig.RequiredValidator{},
	}

	Builtin = &Config{}

	d.MustLoad(Builtin)
	d.MustValidate(Builtin)

	// Check if routes values are correct.
	for route, host := range Builtin.Routes {
		if host == "" {
			panic("empty host for route: " + route)
		}
	}
}

// URL is a wrapper for url.URL that implements the following interfaces:
//
//   - flag.Getter
//   - json.Marshaler
//   - json.Unmarshaler
//
type URL struct {
	*url.URL
}

var (
	_ flag.Getter      = (*URL)(nil)
	_ json.Marshaler   = (*URL)(nil)
	_ json.Unmarshaler = (*URL)(nil)
)

// Get implements the flag.Getter interface.
func (u URL) Get() interface{} {
	return u.URL
}

// Set implements the flag.Value interface.
func (u *URL) Set(s string) error {
	ur, err := url.Parse(s)
	if err != nil {
		return err
	}
	u.URL = ur
	return nil
}

// Unmarshal implements the json.Unmarshaler interface.
func (u *URL) UnmarshalJSON(p []byte) error {
	s, err := strconv.Unquote(string(p))
	if err != nil {
		return err
	}
	u.URL, err = url.Parse(s)
	return err
}

// MarshalJSON implements the json.Marshaler interface.
func (u *URL) MarshalJSON() ([]byte, error) {
	return []byte(strconv.Quote(u.String())), nil
}

// WithPath gives new URL with append paths to its Path field.
func (u *URL) WithPath(paths ...string) *URL {
	ur := *u.URL
	ur.Path = path.Join(ur.Path, path.Join(paths...))
	return &URL{URL: &ur}
}

// Copy returns a copy of the u.
func (u *URL) Copy() *URL {
	if u.IsNil() {
		return nil
	}

	uCopy := *u.URL
	if u.URL.User != nil {
		userCopy := *u.URL.User
		uCopy.User = &userCopy
	}

	return &URL{
		URL: &uCopy,
	}
}

// IsNil returns true if either u or the underlying url is nil.
func (u *URL) IsNil() bool {
	return u == nil || u.URL == nil
}

// Endpoint represents a single endpoint.
type Endpoint struct {
	Public  *URL `json:"public,omitempty"`
	Private *URL `json:"private,omitempty"`
}

// NewEndpoint gives new endpoint with public field set to u.
//
// The u is expected to parse as url.URL, otherwise the function
// panics.
//
// If u is empty, NewEndpoint returns zero value for an Endpoint
// type with all pointer fields initialized.
func NewEndpoint(u string) *Endpoint {
	e := &Endpoint{
		Public: &URL{URL: &url.URL{}},
	}

	if u != "" {
		var err error
		e.Public.URL, err = url.Parse(u)
		if err != nil {
			panic(fmt.Errorf("NewEndpoint(%q): %s", u, err))
		}
	}

	return e
}

// NewEndpointURL gives new endpoint with:
//
//   - public field set to u
//   - private field set to 127.0.0.1:<port>, where
//     port is port part of u.Hostname
//
// The u argument is expected to be non-nil.
func NewEndpointURL(u *url.URL) *Endpoint {
	uPriv := *u
	uPriv.Scheme = "http"
	uPriv.Host = "127.0.0.1"

	if _, port, err := net.SplitHostPort(u.Host); err == nil {
		uPriv.Host = net.JoinHostPort(uPriv.Host, port)
	}

	return &Endpoint{
		Public:  &URL{URL: u},
		Private: &URL{URL: &uPriv},
	}
}

// Equal gives true when e and rhs endpoints match.
func (e *Endpoint) Equal(rhs *Endpoint) bool {
	if (e.Public != nil) != (rhs.Public != nil) {
		return false
	}

	if e.Public != nil && e.Public.String() != rhs.Public.String() {
		return false
	}

	if (e.Private != nil) != (rhs.Private != nil) {
		return false
	}

	return e.Private == nil || e.Private.String() == rhs.Private.String()
}

// WithPath gives new Endpoint with path appended to both
// Public and Private URLs.
func (e *Endpoint) WithPath(path string) *Endpoint {
	ePath := &Endpoint{}

	if e.Public != nil {
		ePath.Public = e.Public.WithPath(path)
	}

	if e.Private != nil {
		ePath.Private = e.Private.WithPath(path)
	}

	return ePath
}

// Copy returns a copy of the e.
func (e *Endpoint) Copy() *Endpoint {
	if e.IsNil() {
		return nil
	}
	return &Endpoint{
		Public:  e.Public.Copy(),
		Private: e.Private.Copy(),
	}
}

// IsNil returns true if either e or both of the public and private urls are nil.
func (e *Endpoint) IsNil() bool {
	return e == nil || (e.Public.IsNil() && e.Private.IsNil())
}

// Config stores all static configuration data generated during ./configure phase.
type Config struct {
	Environment string `json:"environment" required:"true"`
	Buckets     struct {
		PublicLogs Bucket `json:"publicLogs" required:"true"`
	} `json:"buckets" required:"true"`
	Endpoints struct {
		IP           *Endpoint `json:"ip" required:"true"`
		IPCheck      *Endpoint `json:"ipCheck" required:"true"`
		KDLatest     *Endpoint `json:"kdLatest" required:"true"`
		KlientLatest *Endpoint `json:"klientLatest" required:"true"`
		KodingBase   *Endpoint `json:"kodingBase" required:"true"`
		TunnelServer *Endpoint `json:"tunnelServer" required:"true"`
	} `json:"endpoints"`
	Routes map[string]string `json:"routes"`
}

// KontrolPublic gives new public endpoint for the given URL.
func (c *Config) KontrolPublic() *url.URL {
	u := *c.Endpoints.KodingBase.Public.URL
	u.Path = "/kontrol/kite"
	return &u
}

// Bucket represents a S3 storage bucket. It stores bucket name and the physical
// region in which bucket was created.
type Bucket struct {
	Name   string `json:"name" required:"true"`
	Region string `json:"region" required:"true"`
}

func mustURL(s string) *URL {
	u, err := url.Parse(s)
	if err != nil {
		panic(`url.Parse("` + s + `"): ` + err.Error())
	}

	return &URL{URL: u}
}

// ReplaceEnv should be used in case when caller environment is different than
// the build in one. This function should be removed when service environments
// are unified/cleaned.
func ReplaceEnv(e *Endpoint, env string) *Endpoint {
	return ReplaceCustomEnv(e, Builtin.Environment, env)
}

// ReplaceCustomEnv should be used in case when provided environment is different than
// the build one.
//
// This function should be removed when service environments are unified/cleaned.
func ReplaceCustomEnv(e *Endpoint, env, newEnv string) *Endpoint {
	// This is a workaround when caller's env doesn't match build in one.
	eReplaced := &Endpoint{}

	if e.Public != nil {
		eReplaced.Public = mustURL(strings.Replace(e.Public.String(), env, RmAlias(newEnv), -1))
	}

	if e.Private != nil {
		eReplaced.Private = mustURL(strings.Replace(e.Private.String(), env, RmAlias(newEnv), -1))
	}

	return eReplaced
}

var defaultAliases = aliases{
	"production":  {},
	"managed":     {},
	"development": {"sandbox", "dev"},
	"devmanaged":  {},
	"default":     {},
}

type aliases map[string][]string

// RmAlias removes aliased environments like sandbox which is in fact
// a development build. If provided environment is not found, this function
// returns build in environment.
func RmAlias(env string) string {
	return rmAlias(env, Builtin.Environment)
}

func rmAlias(env, defaultEnv string) string {
	for e := range defaultAliases {
		if e == env {
			return e
		}

		// Lookup for environment aliases.
		for _, alias := range defaultAliases[e] {
			if alias == env {
				return e
			}
		}
	}

	return defaultEnv
}

// RmManaged maps managed environments to their build in counterparts.
func RmManaged(env string) string {
	switch env {
	case "managed":
		return "production"
	case "devmanaged":
		return "development"
	default:
		return env
	}
}
<|endoftext|>


<commit_before>package socialapi

import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
)

const maxBodyLen = 2 << 20 // 2 MiB

// contextKey is a value for use with context.WithValue.
type contextKey struct {
	name string
}

// SessionContextKey is a context key. It can be used in
// HTTP handlers to attach a client session to a request.
//
// The session is then read by the Transport and used
// for authentication.
//
// The associated value will be of *Session type.
var SessionContextKey = &contextKey{"client-session"}

// Session represents
type Session struct {
	// ClientID
	ClientID string

	// Username
	Username string

	// Team
	Team string
}

// Valid implements the stack.Validator interface.
func (s *Session) Valid() error {
	if s == nil {
		return errors.New("session is missing")
	}
	if s.ClientID == "" {
		return errors.New("empty client ID")
	}
	return nil
}

type AuthFunc func(*AuthOptions) (*Session, error)

type cacheKey struct {
	Username string
	Team     string
}

type SessionCache struct {
	AuthFunc AuthFunc

	cache map[cacheKey]*Session
}

func NewSessionCache(fn AuthFunc) *SessionCache {
	return &SessionCache{
		AuthFunc: fn,
		cache:    make(map[cacheKey]*Session),
	}
}

// Auth
func (s *SessionCache) Auth(opts *AuthOptions) (*Session, error) {
	if s.AuthFunc == nil {
		panic("socialapi: AuthFunc is nil")
	}

	return nil, nil
}

// AuthOptions
type AuthOptions struct {
	// Session
	Session *Session

	// Refresh
	Refresh bool

	// Request
	Request *http.Request
}

// Transport is a signing transport that
// authorizes each request with jSession.clientId.
type Transport struct {
	http.RoundTripper

	// Host
	Host string

	// RetryNum
	RetryNum int

	// AuthFunc
	AuthFunc AuthFunc
}

type httpTransport interface {
	http.RoundTripper
	httpRequestCanceler
	httpIdleConnectionsCloser
}

type httpRequestCanceler interface {
	CancelRequest(*http.Request)
}

type httpIdleConnectionsCloser interface {
	CloseIdleConnections()
}

var _ httpTransport = (*Transport)(nil)

func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
	if t.AuthFunc == nil {
		panic("socialapi: AuthFunc is nil")
	}

	reqCopy := copyRequest(req) // per RoundTripper contract

	switch req.Body.(type) {
	case nil:
	case io.ReadSeeker:
	default:
		p, err := ioutil.ReadAll(io.LimitReader(reqCopy.Body, maxBodyLen))
		if err != nil {
			return nil, err // non-retryable
		}

		reqCopy.Body = ioutil.NopCloser(bytes.NewReader(p))
	}

	var refresh bool
	var lastErr error
	var session *Session

	if s, ok := reqCopy.Context().Value(SessionContextKey).(*Session); ok {
		session = s
	}

	for attempts := t.retryNum(); attempts > 0; attempts-- {
		if reqCopy.Body != nil {
			if _, err := reqCopy.Body.(io.ReadSeeker).Seek(0, io.SeekStart); err != nil {
				return nil, err // non-retryable
			}
		}

		if err := session.Valid(); err != nil || refresh {
			opts := &AuthOptions{
				Session: session,
				Refresh: refresh,
				Request: reqCopy,
			}

			s, err := t.AuthFunc(opts)
			if err != nil {
				return nil, err // non-retryable
			}

			if err := s.Valid(); err != nil {
				return nil, err // non-retryable
			}

			session = s
			refresh = false
		}

		reqCopy.Header.Set("Authorization", "Bearer "+session.ClientID)
		if t.Host != "" {
			reqCopy.Host = t.Host
		}

		resp, err := t.RoundTripper.RoundTrip(reqCopy)
		if e, ok := err.(net.Error); ok && (e.Temporary() || e.Timeout()) {
			lastErr = err
			continue // retry
		}

		if err != nil {
			return nil, err // non-retryable
		}

		if resp.StatusCode == http.StatusUnauthorized {
			lastErr = errors.New(http.StatusText(resp.StatusCode))
			refresh = true
			continue // retry and force new session
		}

		return resp, nil
	}

	return nil, fmt.Errorf("socialapi: error sending request: %v", lastErr)
}

func (t *Transport) CancelRequest(req *http.Request) {
	if rc, ok := t.RoundTripper.(httpRequestCanceler); ok {
		rc.CancelRequest(req)
	}
}

func (t *Transport) CloseIdleConnections() {
	if icl, ok := t.RoundTripper.(httpIdleConnectionsCloser); ok {
		icl.CloseIdleConnections()
	}
}

func (t *Transport) retryNum() int {
	if t.RetryNum > 0 {
		return t.RetryNum
	}
	return 3
}

func copyURL(u *url.URL) *url.URL {
	uCopy := *u
	if u.User != nil {
		userCopy := *u.User
		uCopy.User = &userCopy
	}

	return &uCopy
}

func copyRequest(req *http.Request) *http.Request {
	reqCopy := new(http.Request)
	*reqCopy = *req
	reqCopy.URL = copyURL(req.URL)
	reqCopy.Header = make(http.Header, len(req.Header))
	for k, s := range req.Header {
		reqCopy.Header[k] = append([]string(nil), s...)
	}
	return reqCopy
}
<commit_msg>socialapi: add SessionCache<commit_after>package socialapi

import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
	"sync"
)

const maxBodyLen = 2 << 20 // 2 MiB

// contextKey is a value for use with context.WithValue.
type contextKey struct {
	name string
}

// SessionContextKey is a context key. It can be used in
// HTTP handlers to attach a client session to a request.
//
// The session is then read by the Transport and used
// for authentication.
//
// The associated value will be of *Session type.
var SessionContextKey = &contextKey{"client-session"}

// Session represents
type Session struct {
	// ClientID
	ClientID string

	// Username
	Username string

	// Team
	Team string
}

// Valid implements the stack.Validator interface.
func (s *Session) Valid() error {
	if s == nil {
		return errors.New("session is missing")
	}
	if s.ClientID == "" {
		return errors.New("empty client ID")
	}
	return nil
}

// AuthFunc
type AuthFunc func(*AuthOptions) (*Session, error)

type cacheKey struct{ username, team string }

// SessionCache
type SessionCache struct {
	AuthFunc AuthFunc

	cacheMu sync.RWMutex
	cache   map[cacheKey]*Session
}

func NewSessionCache(fn AuthFunc) *SessionCache {
	return &SessionCache{
		AuthFunc: fn,
		cache:    make(map[cacheKey]*Session),
	}
}

// Auth
func (s *SessionCache) Auth(opts *AuthOptions) (*Session, error) {
	if s.AuthFunc == nil {
		panic("socialapi: AuthFunc is nil")
	}

	// Early return - return existing session if it's valid
	// and we were not ask to invalidate it.
	if err := opts.Session.Valid(); err == nil && !opts.Refresh {
		return opts.Session, nil
	}

	if opts.Session == nil {
		return nil, errors.New("cannot determine user session")
	}

	key := cacheKey{
		username: opts.Session.Username,
		team:     opts.Session.Team,
	}

	if !opts.Refresh {
		s.cacheMu.RLock()
		session, ok := s.cache[key]
		s.cacheMu.RUnlock()

		if ok {
			return session, nil
		}
	}

	session, err := s.Auth(opts)

	s.cacheMu.Lock()
	if opts.Refresh {
		delete(s.cache, key)
	}
	if err == nil {
		s.cache[key] = session
	}
	s.cacheMu.Unlock()

	return session, err
}

// AuthOptions
type AuthOptions struct {
	// Session
	Session *Session

	// Refresh
	Refresh bool

	// Request
	Request *http.Request
}

type httpTransport interface {
	http.RoundTripper
	httpRequestCanceler
	httpIdleConnectionsCloser
}

type httpRequestCanceler interface {
	CancelRequest(*http.Request)
}

type httpIdleConnectionsCloser interface {
	CloseIdleConnections()
}

// nopCloser is like ioutil.NopCloser, but wraps io.ReadSeeker.
type nopCloser struct{ io.ReadSeeker }

func (nopCloser) Close() (_ error) { return }

var _ io.ReadSeeker = nopCloser{bytes.NewReader(nil)}

// Transport is a signing transport that
// authorizes each request with jSession.clientId.
type Transport struct {
	http.RoundTripper

	// Host
	Host string

	// RetryNum
	RetryNum int

	// AuthFunc
	AuthFunc AuthFunc
}

var _ httpTransport = (*Transport)(nil)

func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
	if t.AuthFunc == nil {
		panic("socialapi: AuthFunc is nil")
	}

	reqCopy := copyRequest(req) // per RoundTripper contract

	switch req.Body.(type) {
	case nil:
	case io.ReadSeeker:
	default:
		p, err := ioutil.ReadAll(io.LimitReader(reqCopy.Body, maxBodyLen))
		if err != nil {
			return nil, err // non-retryable
		}

		reqCopy.Body = nopCloser{bytes.NewReader(p)}
	}

	var refresh bool
	var lastErr error
	var session *Session

	if s, ok := reqCopy.Context().Value(SessionContextKey).(*Session); ok {
		session = s
	}

	for attempts := t.retryNum(); attempts > 0; attempts-- {
		if reqCopy.Body != nil {
			if _, err := reqCopy.Body.(io.ReadSeeker).Seek(0, io.SeekStart); err != nil {
				return nil, err // non-retryable
			}
		}

		opts := &AuthOptions{
			Session: session,
			Refresh: refresh,
			Request: reqCopy,
		}

		s, err := t.AuthFunc(opts)
		if err != nil {
			return nil, err // non-retryable
		}

		if err := s.Valid(); err != nil {
			return nil, err // non-retryable
		}

		session = s
		refresh = false

		reqCopy.Header.Set("Authorization", "Bearer "+session.ClientID)
		if t.Host != "" {
			reqCopy.Host = t.Host
		}

		resp, err := t.RoundTripper.RoundTrip(reqCopy)
		if e, ok := err.(net.Error); ok && (e.Temporary() || e.Timeout()) {
			lastErr = err
			continue // retry
		}

		if err != nil {
			return nil, err // non-retryable
		}

		if resp.StatusCode == http.StatusUnauthorized {
			lastErr = errors.New(http.StatusText(resp.StatusCode))
			refresh = true
			continue // retry and force new session
		}

		return resp, nil
	}

	return nil, fmt.Errorf("socialapi: error sending request: %v", lastErr)
}

func (t *Transport) CancelRequest(req *http.Request) {
	if rc, ok := t.RoundTripper.(httpRequestCanceler); ok {
		rc.CancelRequest(req)
	}
}

func (t *Transport) CloseIdleConnections() {
	if icl, ok := t.RoundTripper.(httpIdleConnectionsCloser); ok {
		icl.CloseIdleConnections()
	}
}

func (t *Transport) retryNum() int {
	if t.RetryNum > 0 {
		return t.RetryNum
	}
	return 3
}

func copyURL(u *url.URL) *url.URL {
	uCopy := *u
	if u.User != nil {
		userCopy := *u.User
		uCopy.User = &userCopy
	}

	return &uCopy
}

func copyRequest(req *http.Request) *http.Request {
	reqCopy := new(http.Request)
	*reqCopy = *req
	reqCopy.URL = copyURL(req.URL)
	reqCopy.Header = make(http.Header, len(req.Header))
	for k, s := range req.Header {
		reqCopy.Header[k] = append([]string(nil), s...)
	}
	return reqCopy
}
<|endoftext|>


<commit_before>package uploads

import (
	"time"

	"math"

	"fmt"

	r "github.com/dancannon/gorethink"
	"github.com/materials-commons/gohandy/file"
	"github.com/materials-commons/mcstore/pkg/app"
	"github.com/materials-commons/mcstore/pkg/db/dai"
	"github.com/materials-commons/mcstore/pkg/db/schema"
	"github.com/materials-commons/mcstore/pkg/domain"
	"github.com/willf/bitset"
)

var _ = fmt.Println

// A IDRequest requests a new upload id be created for
// the given parameters.
type IDRequest struct {
	User        string
	DirectoryID string
	ProjectID   string
	FileName    string
	FileSize    int64
	Checksum    string
	ChunkSize   int32
	FileMTime   time.Time
	Host        string
	Birthtime   time.Time
}

// IDService creates new upload requests
type IDService interface {
	ID(req IDRequest) (*schema.Upload, error)
	Delete(requestID, user string) error
	UploadsForProject(projectID string) ([]schema.Upload, error)
}

// idService implements the IDService interface using
// the dai services.
type idService struct {
	dirs        dai.Dirs
	projects    dai.Projects
	uploads     dai.Uploads
	files       dai.Files
	access      domain.Access
	fops        file.Operations
	tracker     *blockTracker
	requestPath requestPath
}

// NewIDService creates a new idService that connects to the database using
// the given session.
func NewIDService(session *r.Session) *idService {
	access := domain.NewAccess(dai.NewRProjects(session), dai.NewRFiles(session), dai.NewRUsers(session))
	return &idService{
		dirs:        dai.NewRDirs(session),
		projects:    dai.NewRProjects(session),
		uploads:     dai.NewRUploads(session),
		files:       dai.NewRFiles(session),
		access:      access,
		fops:        file.OS,
		tracker:     requestBlockTracker,
		requestPath: &mcdirRequestPath{},
	}
}

// ID will create a new Upload request or return an existing one.
func (s *idService) ID(req IDRequest, proj *schema.Project, dir *schema.Directory) (*schema.Upload, error) {
	upload, err := s.findExisting(req, proj, dir)
	switch {
	case err == app.ErrNotFound:
		upload := s.prepareUploadRequest(req, proj, dir)
		return s.finishUploadRequest(upload)
	case err != nil:
		return nil, err
	default:
		return upload, nil
	}
}

// findExisting checks if there is an outstanding upload request, or a file that already matches
// the upload request. If it finds a match it will return the corresponding upload request. In
// the case of an already uploaded file it will return an upload request with all blocks marked
// as uploaded.
func (s *idService) findExisting(req IDRequest, proj *schema.Project, dir *schema.Directory) (*schema.Upload, error) {
	if _, err := s.files.ByChecksum(req.Checksum); err == nil {
		return s.createFinishedUpload(req, proj, dir)
	}
	return s.findMatchingUploadRequest(req)
}

// createFinishedUpload will create an upload entry with all blocks marked as uploaded.
func (s *idService) createFinishedUpload(req IDRequest, proj *schema.Project, dir *schema.Directory) (*schema.Upload, error) {
	// Create a new upload request and then set all blocks as already uploaded.
	upload := s.prepareUploadRequest(req, proj, dir)
	upload.IsExisting = true
	s.tracker.markAllBlocks(upload.ID)
	s.tracker.setIsExistingFile(upload.ID, true)
	upload.SetFBlocks(s.tracker.getBlocks(upload.ID))
	return s.finishUploadRequest(upload)
}

// findMatchingUploadRequest will search the set of upload requests and see if there
// is already an outstanding upload request that matches this one.
func (s *idService) findMatchingUploadRequest(req IDRequest) (*schema.Upload, error) {
	searchParams := dai.UploadSearch{
		ProjectID:   req.ProjectID,
		DirectoryID: req.DirectoryID,
		FileName:    req.FileName,
		Checksum:    req.Checksum,
	}

	if existingUpload, err := s.uploads.Search(searchParams); err == nil {
		// Found existing
		if bset := s.tracker.getBlocks(existingUpload.ID); bset != nil {
			existingUpload.File.Blocks = bset
		}
		return existingUpload, nil
	}
	return nil, app.ErrNotFound
}

// prepareUploadRequest creates a new upload request.
func (s *idService) prepareUploadRequest(req IDRequest, proj *schema.Project, dir *schema.Directory) *schema.Upload {
	n := uint(numBlocks(req.FileSize, req.ChunkSize))
	upload := schema.CUpload().
		Owner(req.User).
		Project(req.ProjectID, proj.Name).
		ProjectOwner(proj.Owner).
		Directory(req.DirectoryID, dir.Name).
		Host(req.Host).
		FName(req.FileName).
		FSize(req.FileSize).
		FChunk(int(req.ChunkSize), int(n)).
		FChecksum(req.Checksum).
		FRemoteMTime(req.FileMTime).
		FBlocks(bitset.New(n)).
		Create()
	return &upload
}

// finishUploadRequest takes a prepared upload request, inserts it into the database and
// initializes the state associated with the upload. If the upload fails to initialize
// it will delete the upload request from the database.
func (s *idService) finishUploadRequest(upload *schema.Upload) (*schema.Upload, error) {
	u, err := s.uploads.Insert(upload)
	if err != nil {
		return nil, err
	}

	if err := s.initUpload(u.ID, u.File.Size, int32(u.File.ChunkSize)); err != nil {
		s.uploads.Delete(u.ID)
		return nil, err
	}
	return u, nil
}

// initUpload initializes the upload state. It creates the directory to write
// the upload blocks to and creates a tracker entry for the upload.
func (s *idService) initUpload(id string, fileSize int64, chunkSize int32) error {
	if err := s.requestPath.mkdirFromID(id); err != nil {
		return err
	}

	s.tracker.load(id, numBlocks(fileSize, chunkSize))
	return nil
}

// numBlocks
func numBlocks(fileSize int64, chunkSize int32) int {
	// round up to nearest number of blocks
	d := float64(fileSize) / float64(chunkSize)
	n := int(math.Ceil(d))
	return n
}

// Delete will delete the given requestID if the user has access
// to delete that request. Owners of requests can delete their
// own requests. Project owners can delete any request, even if
// they don't own the request.
func (s *idService) Delete(requestID, user string) error {
	upload, err := s.uploads.ByID(requestID)
	switch {
	case err != nil:
		return err
	case !s.access.AllowedByOwner(upload.ProjectID, user):
		return app.ErrNoAccess
	default:
		if err := s.uploads.Delete(requestID); err != nil {
			return err
		}
		// Delete the directory where chunks were being written
		s.fops.RemoveAll(app.MCDir.UploadDir(requestID))
		return nil
	}
}

// ListForProject will return all the uploads associated with a project.
func (s *idService) UploadsForProject(projectID string) ([]schema.Upload, error) {
	return s.uploads.ForProject(projectID)
}
<commit_msg>Add commented out code for handling already uploaded files. The rest of the system doesn't work with already uploaded files so this exists for future work.<commit_after>package uploads

import (
	"time"

	"math"

	"fmt"

	r "github.com/dancannon/gorethink"
	"github.com/materials-commons/gohandy/file"
	"github.com/materials-commons/mcstore/pkg/app"
	"github.com/materials-commons/mcstore/pkg/db/dai"
	"github.com/materials-commons/mcstore/pkg/db/schema"
	"github.com/materials-commons/mcstore/pkg/domain"
	"github.com/willf/bitset"
)

var _ = fmt.Println

// A IDRequest requests a new upload id be created for
// the given parameters.
type IDRequest struct {
	User        string
	DirectoryID string
	ProjectID   string
	FileName    string
	FileSize    int64
	Checksum    string
	ChunkSize   int32
	FileMTime   time.Time
	Host        string
	Birthtime   time.Time
}

// IDService creates new upload requests
type IDService interface {
	ID(req IDRequest) (*schema.Upload, error)
	Delete(requestID, user string) error
	UploadsForProject(projectID string) ([]schema.Upload, error)
}

// idService implements the IDService interface using
// the dai services.
type idService struct {
	dirs        dai.Dirs
	projects    dai.Projects
	uploads     dai.Uploads
	files       dai.Files
	access      domain.Access
	fops        file.Operations
	tracker     *blockTracker
	requestPath requestPath
}

// NewIDService creates a new idService that connects to the database using
// the given session.
func NewIDService(session *r.Session) *idService {
	access := domain.NewAccess(dai.NewRProjects(session), dai.NewRFiles(session), dai.NewRUsers(session))
	return &idService{
		dirs:        dai.NewRDirs(session),
		projects:    dai.NewRProjects(session),
		uploads:     dai.NewRUploads(session),
		files:       dai.NewRFiles(session),
		access:      access,
		fops:        file.OS,
		tracker:     requestBlockTracker,
		requestPath: &mcdirRequestPath{},
	}
}

// ID will create a new Upload request or return an existing one.
func (s *idService) ID(req IDRequest, proj *schema.Project, dir *schema.Directory) (*schema.Upload, error) {
	upload, err := s.findExisting(req, proj, dir)
	switch {
	case err == app.ErrNotFound:
		upload := s.prepareUploadRequest(req, proj, dir)
		return s.finishUploadRequest(upload)
	case err != nil:
		return nil, err
	default:
		return upload, nil
	}
}

// findExisting checks if there is an outstanding upload request, or a file that already matches
// the upload request. If it finds a match it will return the corresponding upload request. In
// the case of an already uploaded file it will return an upload request with all blocks marked
// as uploaded.
func (s *idService) findExisting(req IDRequest, proj *schema.Project, dir *schema.Directory) (*schema.Upload, error) {
	if _, err := s.files.ByChecksum(req.Checksum); err == nil {
		return s.createFinishedUpload(req, proj, dir)
	}
	return s.findMatchingUploadRequest(req)
}

// createFinishedUpload will create an upload entry with all blocks marked as uploaded.
func (s *idService) createFinishedUpload(req IDRequest, proj *schema.Project, dir *schema.Directory) (*schema.Upload, error) {
	// Create a new upload request and then set all blocks as already uploaded.
	upload := s.prepareUploadRequest(req, proj, dir)
	upload.IsExisting = true
	s.tracker.markAllBlocks(upload.ID)
	s.tracker.setIsExistingFile(upload.ID, true)
	upload.SetFBlocks(s.tracker.getBlocks(upload.ID))
	return s.finishUploadRequest(upload)

	// Commented out logic as it should be. However the rest of the system doesn't support files that
	// are already uploaded. So this code exists for when we have time to deal with this issue so
	// that already uploaded files don't need to be sent up again.
	//	upload := s.prepareUploadRequest(req, proj, dir)
	//	upload, err := s.finishUploadRequest(upload)
	//	if err != nil {
	//		return nil, err
	//	}
	//	upload.IsExisting = true
	//	fmt.Println("Created finished upload id", upload.ID)
	//	s.tracker.markAllBlocks(upload.ID)
	//	s.tracker.setIsExistingFile(upload.ID, true)
	//	upload.SetFBlocks(s.tracker.getBlocks(upload.ID))
	//	return upload, nil
}

// findMatchingUploadRequest will search the set of upload requests and see if there
// is already an outstanding upload request that matches this one.
func (s *idService) findMatchingUploadRequest(req IDRequest) (*schema.Upload, error) {
	searchParams := dai.UploadSearch{
		ProjectID:   req.ProjectID,
		DirectoryID: req.DirectoryID,
		FileName:    req.FileName,
		Checksum:    req.Checksum,
	}

	if existingUpload, err := s.uploads.Search(searchParams); err == nil {
		// Found existing
		if bset := s.tracker.getBlocks(existingUpload.ID); bset != nil {
			existingUpload.File.Blocks = bset
		}
		return existingUpload, nil
	}
	return nil, app.ErrNotFound
}

// prepareUploadRequest creates a new upload request.
func (s *idService) prepareUploadRequest(req IDRequest, proj *schema.Project, dir *schema.Directory) *schema.Upload {
	n := uint(numBlocks(req.FileSize, req.ChunkSize))
	upload := schema.CUpload().
		Owner(req.User).
		Project(req.ProjectID, proj.Name).
		ProjectOwner(proj.Owner).
		Directory(req.DirectoryID, dir.Name).
		Host(req.Host).
		FName(req.FileName).
		FSize(req.FileSize).
		FChunk(int(req.ChunkSize), int(n)).
		FChecksum(req.Checksum).
		FRemoteMTime(req.FileMTime).
		FBlocks(bitset.New(n)).
		Create()
	return &upload
}

// finishUploadRequest takes a prepared upload request, inserts it into the database and
// initializes the state associated with the upload. If the upload fails to initialize
// it will delete the upload request from the database.
func (s *idService) finishUploadRequest(upload *schema.Upload) (*schema.Upload, error) {
	u, err := s.uploads.Insert(upload)
	if err != nil {
		return nil, err
	}

	if err := s.initUpload(u.ID, u.File.Size, int32(u.File.ChunkSize)); err != nil {
		s.uploads.Delete(u.ID)
		return nil, err
	}
	return u, nil
}

// initUpload initializes the upload state. It creates the directory to write
// the upload blocks to and creates a tracker entry for the upload.
func (s *idService) initUpload(id string, fileSize int64, chunkSize int32) error {
	if err := s.requestPath.mkdirFromID(id); err != nil {
		return err
	}

	s.tracker.load(id, numBlocks(fileSize, chunkSize))
	return nil
}

// numBlocks
func numBlocks(fileSize int64, chunkSize int32) int {
	// round up to nearest number of blocks
	d := float64(fileSize) / float64(chunkSize)
	n := int(math.Ceil(d))
	return n
}

// Delete will delete the given requestID if the user has access
// to delete that request. Owners of requests can delete their
// own requests. Project owners can delete any request, even if
// they don't own the request.
func (s *idService) Delete(requestID, user string) error {
	upload, err := s.uploads.ByID(requestID)
	switch {
	case err != nil:
		return err
	case !s.access.AllowedByOwner(upload.ProjectID, user):
		return app.ErrNoAccess
	default:
		if err := s.uploads.Delete(requestID); err != nil {
			return err
		}
		// Delete the directory where chunks were being written
		s.fops.RemoveAll(app.MCDir.UploadDir(requestID))
		return nil
	}
}

// ListForProject will return all the uploads associated with a project.
func (s *idService) UploadsForProject(projectID string) ([]schema.Upload, error) {
	return s.uploads.ForProject(projectID)
}
<|endoftext|>


<commit_before>// Copyright 2013 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 gccgoimporter

import (
	"go/types"
	"runtime"
	"testing"
)

var importablePackages = [...]string{
	"archive/tar",
	"archive/zip",
	"bufio",
	"bytes",
	"compress/bzip2",
	"compress/flate",
	"compress/gzip",
	"compress/lzw",
	"compress/zlib",
	"container/heap",
	"container/list",
	"container/ring",
	"crypto/aes",
	"crypto/cipher",
	"crypto/des",
	"crypto/dsa",
	"crypto/ecdsa",
	"crypto/elliptic",
	"crypto",
	"crypto/hmac",
	"crypto/md5",
	"crypto/rand",
	"crypto/rc4",
	"crypto/rsa",
	"crypto/sha1",
	"crypto/sha256",
	"crypto/sha512",
	"crypto/subtle",
	"crypto/tls",
	"crypto/x509",
	"crypto/x509/pkix",
	"database/sql/driver",
	"database/sql",
	"debug/dwarf",
	"debug/elf",
	"debug/gosym",
	"debug/macho",
	"debug/pe",
	"encoding/ascii85",
	"encoding/asn1",
	"encoding/base32",
	"encoding/base64",
	"encoding/binary",
	"encoding/csv",
	"encoding/gob",
	"encoding",
	"encoding/hex",
	"encoding/json",
	"encoding/pem",
	"encoding/xml",
	"errors",
	"exp/proxy",
	"exp/terminal",
	"expvar",
	"flag",
	"fmt",
	"go/ast",
	"go/build",
	"go/doc",
	"go/format",
	"go/parser",
	"go/printer",
	"go/scanner",
	"go/token",
	"hash/adler32",
	"hash/crc32",
	"hash/crc64",
	"hash/fnv",
	"hash",
	"html",
	"html/template",
	"image/color",
	"image/color/palette",
	"image/draw",
	"image/gif",
	"image",
	"image/jpeg",
	"image/png",
	"index/suffixarray",
	"io",
	"io/ioutil",
	"log",
	"log/syslog",
	"math/big",
	"math/cmplx",
	"math",
	"math/rand",
	"mime",
	"mime/multipart",
	"net",
	"net/http/cgi",
	"net/http/cookiejar",
	"net/http/fcgi",
	"net/http",
	"net/http/httptest",
	"net/http/httputil",
	"net/http/pprof",
	"net/mail",
	"net/rpc",
	"net/rpc/jsonrpc",
	"net/smtp",
	"net/textproto",
	"net/url",
	"old/regexp",
	"old/template",
	"os/exec",
	"os",
	"os/signal",
	"os/user",
	"path/filepath",
	"path",
	"reflect",
	"regexp",
	"regexp/syntax",
	"runtime/debug",
	"runtime",
	"runtime/pprof",
	"sort",
	"strconv",
	"strings",
	"sync/atomic",
	"sync",
	"syscall",
	"testing",
	"testing/iotest",
	"testing/quick",
	"text/scanner",
	"text/tabwriter",
	"text/template",
	"text/template/parse",
	"time",
	"unicode",
	"unicode/utf16",
	"unicode/utf8",
}

func TestInstallationImporter(t *testing.T) {
	// This test relies on gccgo being around, which it most likely will be if we
	// were compiled with gccgo.
	if runtime.Compiler != "gccgo" {
		t.Skip("This test needs gccgo")
	}

	var inst GccgoInstallation
	err := inst.InitFromDriver("gccgo")
	if err != nil {
		t.Fatal(err)
	}
	imp := inst.GetImporter(nil, nil)

	// Ensure we don't regress the number of packages we can parse. First import
	// all packages into the same map and then each individually.
	pkgMap := make(map[string]*types.Package)
	for _, pkg := range importablePackages {
		_, err = imp(pkgMap, pkg, ".", nil)
		if err != nil {
			t.Error(err)
		}
	}

	for _, pkg := range importablePackages {
		_, err = imp(make(map[string]*types.Package), pkg, ".", nil)
		if err != nil {
			t.Error(err)
		}
	}

	// Test for certain specific entities in the imported data.
	for _, test := range [...]importerTest{
		{pkgpath: "io", name: "Reader", want: "type Reader interface{Read(p []uint8) (n int, err error)}"},
		{pkgpath: "io", name: "ReadWriter", want: "type ReadWriter interface{Reader; Writer}"},
		{pkgpath: "math", name: "Pi", want: "const Pi untyped float"},
		{pkgpath: "math", name: "Sin", want: "func Sin(x float64) float64"},
		{pkgpath: "sort", name: "Ints", want: "func Ints(a []int)"},
		{pkgpath: "unsafe", name: "Pointer", want: "type Pointer unsafe.Pointer"},
	} {
		runImporterTest(t, imp, nil, &test)
	}
}
<commit_msg>go/internal/gccgoimporter: remove old and exp gccgo packages in test<commit_after>// Copyright 2013 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 gccgoimporter

import (
	"go/types"
	"runtime"
	"testing"
)

var importablePackages = [...]string{
	"archive/tar",
	"archive/zip",
	"bufio",
	"bytes",
	"compress/bzip2",
	"compress/flate",
	"compress/gzip",
	"compress/lzw",
	"compress/zlib",
	"container/heap",
	"container/list",
	"container/ring",
	"crypto/aes",
	"crypto/cipher",
	"crypto/des",
	"crypto/dsa",
	"crypto/ecdsa",
	"crypto/elliptic",
	"crypto",
	"crypto/hmac",
	"crypto/md5",
	"crypto/rand",
	"crypto/rc4",
	"crypto/rsa",
	"crypto/sha1",
	"crypto/sha256",
	"crypto/sha512",
	"crypto/subtle",
	"crypto/tls",
	"crypto/x509",
	"crypto/x509/pkix",
	"database/sql/driver",
	"database/sql",
	"debug/dwarf",
	"debug/elf",
	"debug/gosym",
	"debug/macho",
	"debug/pe",
	"encoding/ascii85",
	"encoding/asn1",
	"encoding/base32",
	"encoding/base64",
	"encoding/binary",
	"encoding/csv",
	"encoding/gob",
	"encoding",
	"encoding/hex",
	"encoding/json",
	"encoding/pem",
	"encoding/xml",
	"errors",
	"expvar",
	"flag",
	"fmt",
	"go/ast",
	"go/build",
	"go/doc",
	"go/format",
	"go/parser",
	"go/printer",
	"go/scanner",
	"go/token",
	"hash/adler32",
	"hash/crc32",
	"hash/crc64",
	"hash/fnv",
	"hash",
	"html",
	"html/template",
	"image/color",
	"image/color/palette",
	"image/draw",
	"image/gif",
	"image",
	"image/jpeg",
	"image/png",
	"index/suffixarray",
	"io",
	"io/ioutil",
	"log",
	"log/syslog",
	"math/big",
	"math/cmplx",
	"math",
	"math/rand",
	"mime",
	"mime/multipart",
	"net",
	"net/http/cgi",
	"net/http/cookiejar",
	"net/http/fcgi",
	"net/http",
	"net/http/httptest",
	"net/http/httputil",
	"net/http/pprof",
	"net/mail",
	"net/rpc",
	"net/rpc/jsonrpc",
	"net/smtp",
	"net/textproto",
	"net/url",
	"os/exec",
	"os",
	"os/signal",
	"os/user",
	"path/filepath",
	"path",
	"reflect",
	"regexp",
	"regexp/syntax",
	"runtime/debug",
	"runtime",
	"runtime/pprof",
	"sort",
	"strconv",
	"strings",
	"sync/atomic",
	"sync",
	"syscall",
	"testing",
	"testing/iotest",
	"testing/quick",
	"text/scanner",
	"text/tabwriter",
	"text/template",
	"text/template/parse",
	"time",
	"unicode",
	"unicode/utf16",
	"unicode/utf8",
}

func TestInstallationImporter(t *testing.T) {
	// This test relies on gccgo being around, which it most likely will be if we
	// were compiled with gccgo.
	if runtime.Compiler != "gccgo" {
		t.Skip("This test needs gccgo")
	}

	var inst GccgoInstallation
	err := inst.InitFromDriver("gccgo")
	if err != nil {
		t.Fatal(err)
	}
	imp := inst.GetImporter(nil, nil)

	// Ensure we don't regress the number of packages we can parse. First import
	// all packages into the same map and then each individually.
	pkgMap := make(map[string]*types.Package)
	for _, pkg := range importablePackages {
		_, err = imp(pkgMap, pkg, ".", nil)
		if err != nil {
			t.Error(err)
		}
	}

	for _, pkg := range importablePackages {
		_, err = imp(make(map[string]*types.Package), pkg, ".", nil)
		if err != nil {
			t.Error(err)
		}
	}

	// Test for certain specific entities in the imported data.
	for _, test := range [...]importerTest{
		{pkgpath: "io", name: "Reader", want: "type Reader interface{Read(p []uint8) (n int, err error)}"},
		{pkgpath: "io", name: "ReadWriter", want: "type ReadWriter interface{Reader; Writer}"},
		{pkgpath: "math", name: "Pi", want: "const Pi untyped float"},
		{pkgpath: "math", name: "Sin", want: "func Sin(x float64) float64"},
		{pkgpath: "sort", name: "Ints", want: "func Ints(a []int)"},
		{pkgpath: "unsafe", name: "Pointer", want: "type Pointer unsafe.Pointer"},
	} {
		runImporterTest(t, imp, nil, &test)
	}
}
<|endoftext|>