<commit_before>package main

import (
	log "code.google.com/p/log4go"
	pbcodec "github.com/felixhao/goim/router/protobuf"
	"net"
	"net/rpc"
	"time"
)

var (
	DEAD_LINE = 5 * time.Minute
)

type RPCSubMsg struct {
	Ret    int
	State  int8
	Server int16
}

type RPCBatchSubMsg struct {
	Ret  int
	Subs []*Sub
}

func InitRPC() error {
	c := &RouterRPC{}
	rpc.Register(c)
	for _, bind := range Conf.RPCBind {
		log.Info("start listen rpc addr: \"%s\"", bind)
		go rpcListen(bind)
	}
	return nil
}

func rpcListen(bind string) {
	l, err := net.ListenTCP("tcp", bind)
	if err != nil {
		log.Error("net.Listen(\"tcp\", \"%s\") error(%v)", bind, err)
		panic(err)
	}
	// if process exit, then close the rpc bind
	defer func() {
		log.Info("rpc addr: \"%s\" close", bind)
		if err := l.Close(); err != nil {
			log.Error("listener.Close() error(%v)", err)
		}
	}()
	for {
		conn, err := l.AcceptTCP()
		if err != nil {
			continue
		}
		if err = conn.SetDeadline(time.Now().Add(DEAD_LINE)); err != nil {
			log.Error("conn.SetDeadline error(%v)", err)
			continue
		}
		go rpc.ServeCodec(pbcodec.NewPbServerCodec(conn))
	}
}

// Router RPC
type RouterRPC struct {
}

// Sub let client get sub info by sub key.
func (this *RouterRPC) Sub(key *string, ret *int64) (err error) {
	if key == nil {
		log.Error("RouterRPC.Push() key==nil")
		*ret = ParamterErr
		return
	}
	sb := DefaultBuckets.SubBucket(*key)
	if sb == nil {
		log.Error("DefaultBuckets get subbucket error key(%s)", *key)
		*ret = InternalErr
		return
	}
	n := sb.Get(*key)
	if n == nil {
		*ret = NoExistKey
		return
	}
	*ret |= (int64(n.server) << 48)
	*ret |= (int64(n.state) << 32)
	*ret |= OK
	return
}

// PbSub let client get sub info by sub key.
func (this *RouterRPC) PbSub(key *PbRPCSubKey, ret *PbRPCSubRet) (err error) {
	if key == nil {
		log.Error("RouterRPC.Push() key==nil")
		ret.Ret = ParamterErr
		return
	}
	log.Info("PbSub key(%s)", key.Key)
	sb := DefaultBuckets.SubBucket(key.Key)
	if sb == nil {
		log.Error("DefaultBuckets get subbucket error key(%s)", key.Key)
		ret.Ret = InternalErr
		return
	}
	n := sb.Get(key.Key)
	log.Info("PbSub node(%v)", n)
	if n == nil {
		ret.Ret = NoExistKey
		return
	}
	ret.Ret |= (int64(n.server) << 48)
	ret.Ret |= (int64(n.state) << 32)
	ret.Ret |= OK
	return
}

// BatchSub let client batch get sub info by sub keys.
func (this *RouterRPC) BatchSub(key *[]string, ret *RPCBatchSubMsg) (err error) {
	ret = new(RPCBatchSubMsg)
	if key == nil {
		log.Error("RouterRPC.Push() key==nil")
		ret.Ret = ParamterErr
		return
	}
	l := len(*key)
	if l == 0 {
		ret.Ret = OK
		return
	}
	ret.Subs = make([]*Sub, l)
	i := 0
	for _, v := range *key {
		sb := DefaultBuckets.SubBucket(v)
		if sb == nil {
			log.Error("DefaultBuckets batch get subbucket error key(%s)", v)
			continue
		}
		n := sb.Get(v)
		if n == nil {
			log.Error("DefaultBuckets batch get subbucket nil error key(%s)", v)
			continue
		}
		sub := &Sub{}
		sub.Key = v
		sub.State = n.state
		sub.Server = n.server
		ret.Subs[i] = sub
		i++
	}
	ret.Subs = ret.Subs[:i]
	ret.Ret = OK
	return
}

// Topic let client get all sub key in topic.
func (this *RouterRPC) Topic(key *string, ret *RPCBatchSubMsg) (err error) {
	ret = new(RPCBatchSubMsg)
	if key == nil {
		log.Error("RouterRPC.Topic() key==nil")
		ret.Ret = ParamterErr
		return
	}
	tb := DefaultBuckets.TopicBucket(*key)
	if tb == nil {
		log.Error("DefaultBuckets get topicbucket error key(%s)", *key)
		ret.Ret = InternalErr
		return
	}
	ret.Subs = tb.Get(*key)
	ret.Ret = OK
	return
}

type RPCTopicSubArg struct {
	Topic  string
	Subkey string
}

// SetTopic let client set topic.
func (this *RouterRPC) SetTopic(key *RPCTopicSubArg, ret *int) (err error) {
	if key == nil {
		log.Error("RouterRPC.SetTopic() key==nil")
		*ret = ParamterErr
		return
	}
	DefaultBuckets.PutToTopic(key.Topic, key.Subkey)
	*ret = OK
	return
}

type RPCSubArg struct {
	Subkey string
	State  int8
	Server int16
}

// SetSub let client set sub key.
func (this *RouterRPC) SetSub(key *RPCSubArg, ret *int) (err error) {
	if key == nil {
		log.Error("RouterRPC.SetSub() key==nil")
		*ret = ParamterErr
		return
	}
	log.Info("SetSub key(%s)", key)
	DefaultBuckets.SubBucket(key.Subkey).SetStateAndServer(key.Subkey, key.State, key.Server)
	*ret = OK
	return
}

// PbSetSub let client set sub key.
func (this *RouterRPC) PbSetSub(key *PbRPCSetSubArg, ret *PbRPCSubRet) (err error) {
	if key == nil {
		log.Error("RouterRPC.PbSetSub() key==nil")
		ret.Ret = ParamterErr
		return
	}
	log.Info("PbSetSub key(%v)", key)
	DefaultBuckets.SubBucket(key.Subkey).SetStateAndServer(key.Subkey, int8(key.State), int16(key.Server))
	ret.Ret = OK
	return
}
<commit_msg>fix build<commit_after>package main

import (
	log "code.google.com/p/log4go"
	pbcodec "github.com/felixhao/goim/router/protobuf"
	"net"
	"net/rpc"
)

type RPCSubMsg struct {
	Ret    int
	State  int8
	Server int16
}

type RPCBatchSubMsg struct {
	Ret  int
	Subs []*Sub
}

func InitRPC() error {
	c := &RouterRPC{}
	rpc.Register(c)
	for _, bind := range Conf.RPCBind {
		log.Info("start listen rpc addr: \"%s\"", bind)
		go rpcListen(bind)
	}
	return nil
}

func rpcListen(bind string) {
	l, err := net.Listen("tcp", bind)
	if err != nil {
		log.Error("net.Listen(\"tcp\", \"%s\") error(%v)", bind, err)
		panic(err)
	}
	// if process exit, then close the rpc bind
	defer func() {
		log.Info("rpc addr: \"%s\" close", bind)
		if err := l.Close(); err != nil {
			log.Error("listener.Close() error(%v)", err)
		}
	}()
	for {
		conn, err := l.Accept()
		if err != nil {
			continue
		}
		go rpc.ServeCodec(pbcodec.NewPbServerCodec(conn))
	}
}

// Router RPC
type RouterRPC struct {
}

// Sub let client get sub info by sub key.
func (this *RouterRPC) Sub(key *string, ret *int64) (err error) {
	if key == nil {
		log.Error("RouterRPC.Push() key==nil")
		*ret = ParamterErr
		return
	}
	sb := DefaultBuckets.SubBucket(*key)
	if sb == nil {
		log.Error("DefaultBuckets get subbucket error key(%s)", *key)
		*ret = InternalErr
		return
	}
	n := sb.Get(*key)
	if n == nil {
		*ret = NoExistKey
		return
	}
	*ret |= (int64(n.server) << 48)
	*ret |= (int64(n.state) << 32)
	*ret |= OK
	return
}

// PbSub let client get sub info by sub key.
func (this *RouterRPC) PbSub(key *PbRPCSubKey, ret *PbRPCSubRet) (err error) {
	if key == nil {
		log.Error("RouterRPC.Push() key==nil")
		ret.Ret = ParamterErr
		return
	}
	log.Info("PbSub key(%s)", key.Key)
	sb := DefaultBuckets.SubBucket(key.Key)
	if sb == nil {
		log.Error("DefaultBuckets get subbucket error key(%s)", key.Key)
		ret.Ret = InternalErr
		return
	}
	n := sb.Get(key.Key)
	log.Info("PbSub node(%v)", n)
	if n == nil {
		ret.Ret = NoExistKey
		return
	}
	ret.Ret |= (int64(n.server) << 48)
	ret.Ret |= (int64(n.state) << 32)
	ret.Ret |= OK
	return
}

// BatchSub let client batch get sub info by sub keys.
func (this *RouterRPC) BatchSub(key *[]string, ret *RPCBatchSubMsg) (err error) {
	ret = new(RPCBatchSubMsg)
	if key == nil {
		log.Error("RouterRPC.Push() key==nil")
		ret.Ret = ParamterErr
		return
	}
	l := len(*key)
	if l == 0 {
		ret.Ret = OK
		return
	}
	ret.Subs = make([]*Sub, l)
	i := 0
	for _, v := range *key {
		sb := DefaultBuckets.SubBucket(v)
		if sb == nil {
			log.Error("DefaultBuckets batch get subbucket error key(%s)", v)
			continue
		}
		n := sb.Get(v)
		if n == nil {
			log.Error("DefaultBuckets batch get subbucket nil error key(%s)", v)
			continue
		}
		sub := &Sub{}
		sub.Key = v
		sub.State = n.state
		sub.Server = n.server
		ret.Subs[i] = sub
		i++
	}
	ret.Subs = ret.Subs[:i]
	ret.Ret = OK
	return
}

// Topic let client get all sub key in topic.
func (this *RouterRPC) Topic(key *string, ret *RPCBatchSubMsg) (err error) {
	ret = new(RPCBatchSubMsg)
	if key == nil {
		log.Error("RouterRPC.Topic() key==nil")
		ret.Ret = ParamterErr
		return
	}
	tb := DefaultBuckets.TopicBucket(*key)
	if tb == nil {
		log.Error("DefaultBuckets get topicbucket error key(%s)", *key)
		ret.Ret = InternalErr
		return
	}
	ret.Subs = tb.Get(*key)
	ret.Ret = OK
	return
}

type RPCTopicSubArg struct {
	Topic  string
	Subkey string
}

// SetTopic let client set topic.
func (this *RouterRPC) SetTopic(key *RPCTopicSubArg, ret *int) (err error) {
	if key == nil {
		log.Error("RouterRPC.SetTopic() key==nil")
		*ret = ParamterErr
		return
	}
	DefaultBuckets.PutToTopic(key.Topic, key.Subkey)
	*ret = OK
	return
}

type RPCSubArg struct {
	Subkey string
	State  int8
	Server int16
}

// SetSub let client set sub key.
func (this *RouterRPC) SetSub(key *RPCSubArg, ret *int) (err error) {
	if key == nil {
		log.Error("RouterRPC.SetSub() key==nil")
		*ret = ParamterErr
		return
	}
	log.Info("SetSub key(%s)", key)
	DefaultBuckets.SubBucket(key.Subkey).SetStateAndServer(key.Subkey, key.State, key.Server)
	*ret = OK
	return
}

// PbSetSub let client set sub key.
func (this *RouterRPC) PbSetSub(key *PbRPCSetSubArg, ret *PbRPCSubRet) (err error) {
	if key == nil {
		log.Error("RouterRPC.PbSetSub() key==nil")
		ret.Ret = ParamterErr
		return
	}
	log.Info("PbSetSub key(%v)", key)
	DefaultBuckets.SubBucket(key.Subkey).SetStateAndServer(key.Subkey, int8(key.State), int16(key.Server))
	ret.Ret = OK
	return
}
<|endoftext|>


<commit_before>package acceptance_test

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"os"
	"os/exec"
	"strconv"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gbytes"
	"github.com/onsi/gomega/gexec"
	"github.com/onsi/say"
	"github.com/pivotal-cf-experimental/bletchley"
)

func run(args ...string) *gexec.Session {
	command := exec.Command(proctorCLIPath, args...)
	session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)
	Expect(err).NotTo(HaveOccurred())
	return session
}

var _ = Describe("Proctor CLI", func() {
	It("should print some help info", func() {
		session := run("help")
		Eventually(session).Should(gexec.Exit(1))
		Expect(session.Err.Contents()).To(ContainSubstring("Create a fresh classroom environment"))
		Expect(session.Err.Contents()).To(ContainSubstring("Destroy an existing classroom"))
	})

	XContext("when the command is not recognized", func() {
		It("should exit status 1", func() {
			session := run("nonsense")
			Eventually(session).Should(gexec.Exit(1))
			// this fails because of a bug in onsi/say
			// we should probably switch over to something else
		})
	})
})

var _ = Describe("Interactions with AWS", func() {
	if os.Getenv("SKIP_AWS_TESTS") == "true" {
		say.Println(0, say.Yellow("WARNING: Skipping acceptance tests that use AWS"))
		return
	}

	It("should create and delete classrooms", func() {
		classroomName := fmt.Sprintf("test-%d", rand.Int31())
		instanceCount := 3
		session := run("create", "-name", classroomName, "-number", strconv.Itoa(instanceCount))
		Eventually(session.Out, 10).Should(gbytes.Say("Looking up latest AMI for"))
		Eventually(session.Out, 10).Should(gbytes.Say("ami-[a-z,0-9]"))
		Eventually(session.Out, 10).Should(gbytes.Say("Creating SSH Keypair"))
		Eventually(session.Out, 10).Should(gbytes.Say("Uploading private key"))
		Eventually(session, 20).Should(gexec.Exit(0))

		session = run("list", "-format", "json")
		Eventually(session, 10).Should(gexec.Exit(0))
		var classrooms []string
		Expect(json.Unmarshal(session.Out.Contents(), &classrooms)).To(Succeed())
		Expect(classrooms).To(ContainElement(classroomName))

		var info struct {
			Status string
			SSHKey string `json:"ssh_key"`
			Number int
			Hosts  map[string]string
		}
		session = run("describe", "-name", classroomName, "-format", "json")
		Eventually(session, 10).Should(gexec.Exit(0))
		Expect(json.Unmarshal(session.Out.Contents(), &info)).To(Succeed())
		Expect(info.Status).To(Equal("CREATE_IN_PROGRESS"))
		Expect(info.Number).To(Equal(instanceCount))

		resp, err := http.Get(info.SSHKey)
		Expect(err).NotTo(HaveOccurred())
		Expect(resp.StatusCode).To(Equal(http.StatusOK))
		Expect(resp.Header["Content-Type"]).To(Equal([]string{"application/x-pem-file"}))
		keyPEM, err := ioutil.ReadAll(resp.Body)
		Expect(err).NotTo(HaveOccurred())
		sshPrivateKey, err := bletchley.PEMToPrivateKey(keyPEM)
		Expect(err).NotTo(HaveOccurred())
		Expect(sshPrivateKey).NotTo(BeNil())

		Eventually(func() []byte {
			session = run("describe", "-name", classroomName, "-format", "plain")
			Eventually(session, 10).Should(gexec.Exit(0))
			return session.Out.Contents()
		}, 600).Should(ContainSubstring("status: CREATE_COMPLETE"))

		session = run("describe", "-name", classroomName)
		Eventually(session, 10).Should(gexec.Exit(0))
		Expect(json.Unmarshal(session.Out.Contents(), &info)).To(Succeed())
		Expect(info.Status).To(Equal("CREATE_COMPLETE"))
		Expect(info.Hosts).To(HaveLen(instanceCount))
		for _, state := range info.Hosts {
			Expect(state).To(Equal("running"))
		}

		session = run("run", "-name", classroomName, "-c", "bosh status")
		Eventually(session, 20).Should(gexec.Exit(0))
		Expect(session.Out.Contents()).To(ContainSubstring("Bosh Lite Director"))

		session = run("destroy", "-name", classroomName)
		Eventually(session, 20).Should(gexec.Exit(0))
		Expect(session.ExitCode()).To(Equal(0))
	})
})
<commit_msg>Address acceptance test race condition<commit_after>package acceptance_test

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"os"
	"os/exec"
	"strconv"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gbytes"
	"github.com/onsi/gomega/gexec"
	"github.com/onsi/say"
	"github.com/pivotal-cf-experimental/bletchley"
)

func run(args ...string) *gexec.Session {
	command := exec.Command(proctorCLIPath, args...)
	session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)
	Expect(err).NotTo(HaveOccurred())
	return session
}

var _ = Describe("Proctor CLI", func() {
	It("should print some help info", func() {
		session := run("help")
		Eventually(session).Should(gexec.Exit(1))
		Expect(session.Err.Contents()).To(ContainSubstring("Create a fresh classroom environment"))
		Expect(session.Err.Contents()).To(ContainSubstring("Destroy an existing classroom"))
	})

	XContext("when the command is not recognized", func() {
		It("should exit status 1", func() {
			session := run("nonsense")
			Eventually(session).Should(gexec.Exit(1))
			// this fails because of a bug in onsi/say
			// we should probably switch over to something else
		})
	})
})

var _ = Describe("Interactions with AWS", func() {
	if os.Getenv("SKIP_AWS_TESTS") == "true" {
		say.Println(0, say.Yellow("WARNING: Skipping acceptance tests that use AWS"))
		return
	}

	It("should create and delete classrooms", func() {
		classroomName := fmt.Sprintf("test-%d", rand.Int31())
		instanceCount := 3
		session := run("create", "-name", classroomName, "-number", strconv.Itoa(instanceCount))
		Eventually(session.Out, 10).Should(gbytes.Say("Looking up latest AMI for"))
		Eventually(session.Out, 10).Should(gbytes.Say("ami-[a-z,0-9]"))
		Eventually(session.Out, 10).Should(gbytes.Say("Creating SSH Keypair"))
		Eventually(session.Out, 10).Should(gbytes.Say("Uploading private key"))
		Eventually(session, 20).Should(gexec.Exit(0))

		session = run("list", "-format", "json")
		Eventually(session, 10).Should(gexec.Exit(0))
		var classrooms []string
		Expect(json.Unmarshal(session.Out.Contents(), &classrooms)).To(Succeed())
		Expect(classrooms).To(ContainElement(classroomName))

		var info struct {
			Status string
			SSHKey string `json:"ssh_key"`
			Number int
			Hosts  map[string]string
		}
		session = run("describe", "-name", classroomName, "-format", "json")
		Eventually(session, 10).Should(gexec.Exit(0))
		Expect(json.Unmarshal(session.Out.Contents(), &info)).To(Succeed())
		Expect(info.Status).To(Equal("CREATE_IN_PROGRESS"))
		Expect(info.Number).To(Equal(instanceCount))

		resp, err := http.Get(info.SSHKey)
		Expect(err).NotTo(HaveOccurred())
		Expect(resp.StatusCode).To(Equal(http.StatusOK))
		Expect(resp.Header["Content-Type"]).To(Equal([]string{"application/x-pem-file"}))
		keyPEM, err := ioutil.ReadAll(resp.Body)
		Expect(err).NotTo(HaveOccurred())
		sshPrivateKey, err := bletchley.PEMToPrivateKey(keyPEM)
		Expect(err).NotTo(HaveOccurred())
		Expect(sshPrivateKey).NotTo(BeNil())

		Eventually(func() []byte {
			session = run("describe", "-name", classroomName, "-format", "plain")
			Eventually(session, 10).Should(gexec.Exit(0))
			return session.Out.Contents()
		}, 600).Should(ContainSubstring("status: CREATE_COMPLETE"))

		session = run("describe", "-name", classroomName)
		Eventually(session, 10).Should(gexec.Exit(0))
		Expect(json.Unmarshal(session.Out.Contents(), &info)).To(Succeed())
		Expect(info.Status).To(Equal("CREATE_COMPLETE"))
		Expect(info.Hosts).To(HaveLen(instanceCount))
		for _, state := range info.Hosts {
			Expect(state).To(Equal("running"))
		}

		session = run("run", "-name", classroomName, "-c", "bosh status")
		Eventually(session, 20).Should(gexec.Exit(0))
		Expect(session.Out.Contents()).To(ContainSubstring("/home/ubuntu/.bosh_config"))

		session = run("destroy", "-name", classroomName)
		Eventually(session, 20).Should(gexec.Exit(0))
		Expect(session.ExitCode()).To(Equal(0))
	})
})
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	//    "net/ipv4"
	"golang.org/x/net/ipv4"
	"net"
	"os"
)

func main() {
    manager, _ := NewUDP_Manager();
	c, err := NewUDP(20006, 20005, manager)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	fmt.Println(c.read(41))
	c.write([]byte{'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', 0})
	c.close()
}

type UDP_manager struct {
    pl net.PacketConn
    open bool
    conn *ipv4.RawConn
}

type UDP struct {
    conn *ipv4.RawConn
	src, dest uint16
}

func NewUDP_Manager() (*UDP_manager, error) {
	p, err := net.ListenPacket("ip4:17", "127.0.0.1")
	if err != nil {
		fmt.Println(err)
		return nil, err
	}

	r, err := ipv4.NewRawConn(p)
	if err != nil {
		fmt.Println(err)
		return nil, err
	}

	// TODO use r.JoinGroup at https://godoc.org/golang.org/x/net/ipv4#NewRawConn

	return &UDP_manager{open: true, conn: r, pl: p}, nil
}
func NewUDP(src, dest uint16, manager *UDP_manager) (*UDP, error) {
    return &UDP{src: src, dest: dest, conn: manager.conn}, nil
}

func (c *UDP) read(size int) ([]byte, error) {
	b := make([]byte, size)
	_, payload, _, err := c.conn.ReadFrom(b)
	if err != nil {
		return nil, err
	}
	return payload[8:], nil
}
func (c *UDP) write(x []byte) error {
	UDPHeader := []byte{
		(byte)(c.src >> 8), (byte)(c.src), // Source port in byte slice
		(byte)(c.dest >> 8), (byte)(c.dest), // Dest port in byte slice
		(byte)((8 + len(x)) >> 8), (byte)(8 + len(x)), // Length in bytes of UDP header + data
		0, 0, // Checksum
	}

	x = append(UDPHeader, x...)

	h := &ipv4.Header{
		Version:  ipv4.Version,      // protocol version
		Len:      20,                // header length
		TOS:      0,                 // type-of-service (0 is everything normal)
		TotalLen: len(x) + 20,       // packet total length (octets)
		ID:       0,                 // identification
		Flags:    ipv4.DontFragment, // flags
		FragOff:  0,                 // fragment offset
		TTL:      8,                 // time-to-live (maximum lifespan in seconds)
		Protocol: 17,                // next protocol (17 is UDP)
		Checksum: 0,                 // checksum (apparently autocomputed)
		//Src:    net.IPv4(127, 0, 0, 1), // source address, apparently done automatically
		Dst: net.IPv4(127, 0, 0, 1), // destination address
		//Options                         // options, extension headers
	}
	err := c.conn.WriteTo(h, x, nil)
	if err != nil {
		fmt.Println(err)
		return err
	}
	return nil
}
func (c *UDP) close() error {
	return c.conn.Close()
}
<commit_msg>UDP manager<commit_after>package main

import (
	"fmt"
	//    "net/ipv4"
	"golang.org/x/net/ipv4"
	"net"
	"os"
)

func main() {
	manager, _ := NewUDP_Manager()
	c, err := NewUDP(20006, 20005, manager)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	fmt.Println(c.read(41))
	c.write([]byte{'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', 0})
	c.close()
}

type UDP_manager struct {
	pl   net.PacketConn
	open bool
	conn *ipv4.RawConn
}

func NewUDP_Manager() (*UDP_manager, error) {
	p, err := net.ListenPacket("ip4:17", "127.0.0.1")
	if err != nil {
		fmt.Println(err)
		return nil, err
	}

	r, err := ipv4.NewRawConn(p)
	if err != nil {
		fmt.Println(err)
		return nil, err
	}

	// TODO use r.JoinGroup at https://godoc.org/golang.org/x/net/ipv4#NewRawConn

	return &UDP_manager{open: true, conn: r, pl: p}, nil
}

type UDP struct {
	conn      *ipv4.RawConn
	src, dest uint16
}

func NewUDP(src, dest uint16, manager *UDP_manager) (*UDP, error) {
	return &UDP{src: src, dest: dest, conn: manager.conn}, nil
}

func (c *UDP) read(size int) ([]byte, error) {
	b := make([]byte, size)

	var payload []byte
	var err error

	for {
		_, payload, _, err = c.conn.ReadFrom(b)
		if err != nil {
			return nil, err
		}

		dest := (((uint16)(payload[2])) << 8) + ((uint16)(payload[3]))
		if dest == c.src {
			break
		}
	}
	return payload[8:], nil
}
func (c *UDP) write(x []byte) error {
	UDPHeader := []byte{
		(byte)(c.src >> 8), (byte)(c.src), // Source port in byte slice
		(byte)(c.dest >> 8), (byte)(c.dest), // Dest port in byte slice
		(byte)((8 + len(x)) >> 8), (byte)(8 + len(x)), // Length in bytes of UDP header + data
		0, 0, // Checksum
	}

	x = append(UDPHeader, x...)

	h := &ipv4.Header{
		Version:  ipv4.Version,      // protocol version
		Len:      20,                // header length
		TOS:      0,                 // type-of-service (0 is everything normal)
		TotalLen: len(x) + 20,       // packet total length (octets)
		ID:       0,                 // identification
		Flags:    ipv4.DontFragment, // flags
		FragOff:  0,                 // fragment offset
		TTL:      8,                 // time-to-live (maximum lifespan in seconds)
		Protocol: 17,                // next protocol (17 is UDP)
		Checksum: 0,                 // checksum (apparently autocomputed)
		//Src:    net.IPv4(127, 0, 0, 1), // source address, apparently done automatically
		Dst: net.IPv4(127, 0, 0, 1), // destination address
		//Options                         // options, extension headers
	}
	err := c.conn.WriteTo(h, x, nil)
	if err != nil {
		fmt.Println(err)
		return err
	}
	return nil
}
func (c *UDP) close() error {
	return c.conn.Close()
}
<|endoftext|>


<commit_before>package cmd

import (
	"fmt"
	"net/http"
	"regexp"
	"strconv"
	"sync"
	"time"

	"github.com/go-errors/errors"
	"github.com/privacybydesign/irmago"
	"github.com/privacybydesign/irmago/server"
	"github.com/privacybydesign/irmago/server/irmaserver"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
	prefixed "github.com/x-cray/logrus-prefixed-formatter"
)

const pollInterval = 1000 * time.Millisecond

var (
	httpServer *http.Server
	irmaServer *irmaserver.Server
	logger     *logrus.Logger
	defaulturl string
)

// sessionCmd represents the session command
var sessionCmd = &cobra.Command{
	Use:   "session",
	Short: "Perform an IRMA disclosure, issuance or signature session",
	Long: `Perform an IRMA disclosure, issuance or signature session on the command line

Using either the builtin IRMA server library, or an external IRMA server (specify its URL
with --server), an IRMA session is started; the QR is printed in the terminal; and the session
result is printed when the session completes or fails.

A session request can either be constructed using the --disclose, --issue, and --sign together
with --message flags, or it can be specified as JSON to the --request flag.`,
	Example: `irma session --disclose irma-demo.MijnOverheid.root.BSN
irma session --sign irma-demo.MijnOverheid.root.BSN --message message
irma session --issue irma-demo.MijnOverheid.ageLower=yes,yes,yes,no --disclose irma-demo.MijnOverheid.root.BSN
irma session --request '{"type":"disclosing","content":[{"label":"BSN","attributes":["irma-demo.MijnOverheid.root.BSN"]}]}'
irma session --server http://localhost:8088 --authmethod token --key mytoken --disclose irma-demo.MijnOverheid.root.BSN`,
	Run: func(cmd *cobra.Command, args []string) {
		request, irmaconfig, err := configureSession(cmd)
		if err != nil {
			die("", err)
		}

		// Make sure we always run with latest configuration
		if err = irmaconfig.UpdateSchemes(); err != nil {
			die("failed updating schemes", err)
		}

		var result *server.SessionResult
		url, _ := cmd.Flags().GetString("url")
		serverurl, _ := cmd.Flags().GetString("server")
		noqr, _ := cmd.Flags().GetBool("noqr")
		flags := cmd.Flags()

		if url != defaulturl && serverurl != "" {
			die("Failed to read configuration", errors.New("--url can't be combined with --server"))
		}

		if serverurl == "" {
			port, _ := flags.GetInt("port")
			privatekeysPath, _ := flags.GetString("privkeys")
			verbosity, _ := cmd.Flags().GetCount("verbose")
			result, err = libraryRequest(request, irmaconfig, url, port, privatekeysPath, noqr, verbosity)
		} else {
			authmethod, _ := flags.GetString("authmethod")
			key, _ := flags.GetString("key")
			name, _ := flags.GetString("name")
			result, err = serverRequest(request, serverurl, authmethod, key, name, noqr)
		}
		if err != nil {
			die("Session failed", err)
		}

		printSessionResult(result)

		// Done!
		if httpServer != nil {
			_ = httpServer.Close()
		}
	},
}

func libraryRequest(
	request irma.RequestorRequest,
	irmaconfig *irma.Configuration,
	url string,
	port int,
	privatekeysPath string,
	noqr bool,
	verbosity int,
) (*server.SessionResult, error) {
	if err := configureSessionServer(url, port, privatekeysPath, irmaconfig, verbosity); err != nil {
		return nil, err
	}
	startServer(port)

	// Start the session
	resultchan := make(chan *server.SessionResult)
	qr, _, err := irmaServer.StartSession(request, func(r *server.SessionResult) {
		resultchan <- r
	})
	if err != nil {
		return nil, errors.WrapPrefix(err, "IRMA session failed", 0)
	}

	// Print QR code
	if err := printQr(qr, noqr); err != nil {
		return nil, errors.WrapPrefix(err, "Failed to print QR", 0)
	}

	// Wait for session to finish and then return session result
	return <-resultchan, nil
}

func serverRequest(
	request irma.RequestorRequest,
	serverurl, authmethod, key, name string,
	noqr bool,
) (*server.SessionResult, error) {
	logger.Debug("Server URL: ", serverurl)

	// Start session at server
	qr, transport, err := postRequest(serverurl, request, name, authmethod, key)
	if err != nil {
		return nil, err
	}

	// Print session QR
	logger.Debug("QR: ", prettyprint(qr))
	if err := printQr(qr, noqr); err != nil {
		return nil, errors.WrapPrefix(err, "Failed to print QR", 0)
	}

	statuschan := make(chan server.Status)
	var wg sync.WaitGroup

	go wait(server.StatusInitialized, transport, statuschan)

	wg.Add(1)
	go func() {
		defer wg.Done()

		// Wait until client connects
		status := <-statuschan
		if status != server.StatusConnected {
			err = errors.Errorf("Unexpected status: %s", status)
			return
		}

		// Wait until client finishes
		status = <-statuschan
		if status != server.StatusCancelled && status != server.StatusDone {
			err = errors.Errorf("Unexpected status: %s", status)
			return
		}
	}()

	wg.Wait()
	if err != nil {
		return nil, err
	}

	// Retrieve session result
	result := &server.SessionResult{}
	if err := transport.Get("result", result); err != nil {
		return nil, errors.WrapPrefix(err, "Failed to get session result", 0)
	}
	return result, nil
}

func postRequest(serverurl string, request irma.RequestorRequest, name, authmethod, key string) (*irma.Qr, *irma.HTTPTransport, error) {
	var (
		err       error
		pkg       = &server.SessionPackage{}
		transport = irma.NewHTTPTransport(serverurl, false)
	)

	switch authmethod {
	case "none":
		err = transport.Post("session", pkg, request)
	case "token":
		transport.SetHeader("Authorization", key)
		err = transport.Post("session", pkg, request)
	case "hmac", "rsa":
		var jwtstr string
		jwtstr, err = signRequest(request, name, authmethod, key)
		if err != nil {
			return nil, nil, err
		}
		logger.Debug("Session request JWT: ", jwtstr)
		err = transport.Post("session", pkg, jwtstr)
	default:
		return nil, nil, errors.New("Invalid authentication method (must be none, token, hmac or rsa)")
	}

	token := pkg.Token
	transport.Server += fmt.Sprintf("session/%s/", token)
	return pkg.SessionPtr, transport, err
}

// Configuration functions

func configureSessionServer(url string, port int, privatekeysPath string, irmaconfig *irma.Configuration, verbosity int) error {
	// Replace "port" in url with actual port
	replace := "$1:" + strconv.Itoa(port)
	url = string(regexp.MustCompile("(https?://[^/]*):port").ReplaceAll([]byte(url), []byte(replace)))

	config := &server.Configuration{
		IrmaConfiguration:    irmaconfig,
		Logger:               logger,
		URL:                  url,
		DisableSchemesUpdate: true,
		Verbose:              verbosity,
	}
	if privatekeysPath != "" {
		config.IssuerPrivateKeysPath = privatekeysPath
	}

	var err error
	irmaServer, err = irmaserver.New(config)
	return err
}

func configureSession(cmd *cobra.Command) (irma.RequestorRequest, *irma.Configuration, error) {
	verbosity, _ := cmd.Flags().GetCount("verbose")
	logger.Level = server.Verbosity(verbosity)
	irma.SetLogger(logger)

	return configureRequest(cmd)
}

func init() {
	RootCmd.AddCommand(sessionCmd)

	logger = logrus.New()
	logger.Formatter = &prefixed.TextFormatter{FullTimestamp: true}

	var err error
	defaulturl, err = server.LocalIP()
	if err != nil {
		logger.Warn("Could not determine local IP address: ", err.Error())
	} else {
		defaulturl = "http://" + defaulturl + ":port"
	}

	flags := sessionCmd.Flags()
	flags.SortFlags = false
	flags.String("server", "", "External IRMA server to post request to (leave blank to use builtin library)")
	flags.StringP("url", "u", defaulturl, "external URL to which IRMA app connects (when not using --server), \":port\" being replaced by --port value")
	flags.IntP("port", "p", 48680, "port to listen at (when not using --server)")
	flags.Bool("noqr", false, "Print JSON instead of draw QR")
	flags.StringP("request", "r", "", "JSON session request")
	flags.StringP("privkeys", "k", "", "path to private keys")

	addRequestFlags(flags)

	flags.CountP("verbose", "v", "verbose (repeatable)")
}
<commit_msg>feat: support disabling scheme auto-updating in irma session<commit_after>package cmd

import (
	"fmt"
	"net/http"
	"regexp"
	"strconv"
	"sync"
	"time"

	"github.com/go-errors/errors"
	"github.com/privacybydesign/irmago"
	"github.com/privacybydesign/irmago/server"
	"github.com/privacybydesign/irmago/server/irmaserver"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
	prefixed "github.com/x-cray/logrus-prefixed-formatter"
)

const pollInterval = 1000 * time.Millisecond

var (
	httpServer *http.Server
	irmaServer *irmaserver.Server
	logger     *logrus.Logger
	defaulturl string
)

// sessionCmd represents the session command
var sessionCmd = &cobra.Command{
	Use:   "session",
	Short: "Perform an IRMA disclosure, issuance or signature session",
	Long: `Perform an IRMA disclosure, issuance or signature session on the command line

Using either the builtin IRMA server library, or an external IRMA server (specify its URL
with --server), an IRMA session is started; the QR is printed in the terminal; and the session
result is printed when the session completes or fails.

A session request can either be constructed using the --disclose, --issue, and --sign together
with --message flags, or it can be specified as JSON to the --request flag.`,
	Example: `irma session --disclose irma-demo.MijnOverheid.root.BSN
irma session --sign irma-demo.MijnOverheid.root.BSN --message message
irma session --issue irma-demo.MijnOverheid.ageLower=yes,yes,yes,no --disclose irma-demo.MijnOverheid.root.BSN
irma session --request '{"type":"disclosing","content":[{"label":"BSN","attributes":["irma-demo.MijnOverheid.root.BSN"]}]}'
irma session --server http://localhost:8088 --authmethod token --key mytoken --disclose irma-demo.MijnOverheid.root.BSN`,
	Run: func(cmd *cobra.Command, args []string) {
		request, irmaconfig, err := configureSession(cmd)
		if err != nil {
			die("", err)
		}

		// Make sure we always run with latest configuration
		flags := cmd.Flags()
		disableUpdate, _ := flags.GetBool("disable-schemes-update")
		if !disableUpdate {
			if err = irmaconfig.UpdateSchemes(); err != nil {
				die("failed updating schemes", err)
			}
		}

		var result *server.SessionResult
		url, _ := cmd.Flags().GetString("url")
		serverurl, _ := cmd.Flags().GetString("server")
		noqr, _ := cmd.Flags().GetBool("noqr")

		if url != defaulturl && serverurl != "" {
			die("Failed to read configuration", errors.New("--url can't be combined with --server"))
		}

		if serverurl == "" {
			port, _ := flags.GetInt("port")
			privatekeysPath, _ := flags.GetString("privkeys")
			verbosity, _ := cmd.Flags().GetCount("verbose")
			result, err = libraryRequest(request, irmaconfig, url, port, privatekeysPath, noqr, verbosity)
		} else {
			authmethod, _ := flags.GetString("authmethod")
			key, _ := flags.GetString("key")
			name, _ := flags.GetString("name")
			result, err = serverRequest(request, serverurl, authmethod, key, name, noqr)
		}
		if err != nil {
			die("Session failed", err)
		}

		printSessionResult(result)

		// Done!
		if httpServer != nil {
			_ = httpServer.Close()
		}
	},
}

func libraryRequest(
	request irma.RequestorRequest,
	irmaconfig *irma.Configuration,
	url string,
	port int,
	privatekeysPath string,
	noqr bool,
	verbosity int,
) (*server.SessionResult, error) {
	if err := configureSessionServer(url, port, privatekeysPath, irmaconfig, verbosity); err != nil {
		return nil, err
	}
	startServer(port)

	// Start the session
	resultchan := make(chan *server.SessionResult)
	qr, _, err := irmaServer.StartSession(request, func(r *server.SessionResult) {
		resultchan <- r
	})
	if err != nil {
		return nil, errors.WrapPrefix(err, "IRMA session failed", 0)
	}

	// Print QR code
	if err := printQr(qr, noqr); err != nil {
		return nil, errors.WrapPrefix(err, "Failed to print QR", 0)
	}

	// Wait for session to finish and then return session result
	return <-resultchan, nil
}

func serverRequest(
	request irma.RequestorRequest,
	serverurl, authmethod, key, name string,
	noqr bool,
) (*server.SessionResult, error) {
	logger.Debug("Server URL: ", serverurl)

	// Start session at server
	qr, transport, err := postRequest(serverurl, request, name, authmethod, key)
	if err != nil {
		return nil, err
	}

	// Print session QR
	logger.Debug("QR: ", prettyprint(qr))
	if err := printQr(qr, noqr); err != nil {
		return nil, errors.WrapPrefix(err, "Failed to print QR", 0)
	}

	statuschan := make(chan server.Status)
	var wg sync.WaitGroup

	go wait(server.StatusInitialized, transport, statuschan)

	wg.Add(1)
	go func() {
		defer wg.Done()

		// Wait until client connects
		status := <-statuschan
		if status != server.StatusConnected {
			err = errors.Errorf("Unexpected status: %s", status)
			return
		}

		// Wait until client finishes
		status = <-statuschan
		if status != server.StatusCancelled && status != server.StatusDone {
			err = errors.Errorf("Unexpected status: %s", status)
			return
		}
	}()

	wg.Wait()
	if err != nil {
		return nil, err
	}

	// Retrieve session result
	result := &server.SessionResult{}
	if err := transport.Get("result", result); err != nil {
		return nil, errors.WrapPrefix(err, "Failed to get session result", 0)
	}
	return result, nil
}

func postRequest(serverurl string, request irma.RequestorRequest, name, authmethod, key string) (*irma.Qr, *irma.HTTPTransport, error) {
	var (
		err       error
		pkg       = &server.SessionPackage{}
		transport = irma.NewHTTPTransport(serverurl, false)
	)

	switch authmethod {
	case "none":
		err = transport.Post("session", pkg, request)
	case "token":
		transport.SetHeader("Authorization", key)
		err = transport.Post("session", pkg, request)
	case "hmac", "rsa":
		var jwtstr string
		jwtstr, err = signRequest(request, name, authmethod, key)
		if err != nil {
			return nil, nil, err
		}
		logger.Debug("Session request JWT: ", jwtstr)
		err = transport.Post("session", pkg, jwtstr)
	default:
		return nil, nil, errors.New("Invalid authentication method (must be none, token, hmac or rsa)")
	}

	token := pkg.Token
	transport.Server += fmt.Sprintf("session/%s/", token)
	return pkg.SessionPtr, transport, err
}

// Configuration functions

func configureSessionServer(url string, port int, privatekeysPath string, irmaconfig *irma.Configuration, verbosity int) error {
	// Replace "port" in url with actual port
	replace := "$1:" + strconv.Itoa(port)
	url = string(regexp.MustCompile("(https?://[^/]*):port").ReplaceAll([]byte(url), []byte(replace)))

	config := &server.Configuration{
		IrmaConfiguration:    irmaconfig,
		Logger:               logger,
		URL:                  url,
		DisableSchemesUpdate: true,
		Verbose:              verbosity,
	}
	if privatekeysPath != "" {
		config.IssuerPrivateKeysPath = privatekeysPath
	}

	var err error
	irmaServer, err = irmaserver.New(config)
	return err
}

func configureSession(cmd *cobra.Command) (irma.RequestorRequest, *irma.Configuration, error) {
	verbosity, _ := cmd.Flags().GetCount("verbose")
	logger.Level = server.Verbosity(verbosity)
	irma.SetLogger(logger)

	return configureRequest(cmd)
}

func init() {
	RootCmd.AddCommand(sessionCmd)

	logger = logrus.New()
	logger.Formatter = &prefixed.TextFormatter{FullTimestamp: true}

	var err error
	defaulturl, err = server.LocalIP()
	if err != nil {
		logger.Warn("Could not determine local IP address: ", err.Error())
	} else {
		defaulturl = "http://" + defaulturl + ":port"
	}

	flags := sessionCmd.Flags()
	flags.SortFlags = false
	flags.String("server", "", "External IRMA server to post request to (leave blank to use builtin library)")
	flags.StringP("url", "u", defaulturl, "external URL to which IRMA app connects (when not using --server), \":port\" being replaced by --port value")
	flags.IntP("port", "p", 48680, "port to listen at (when not using --server)")
	flags.Bool("noqr", false, "Print JSON instead of draw QR")
	flags.StringP("request", "r", "", "JSON session request")
	flags.StringP("privkeys", "k", "", "path to private keys")
	flags.Bool("disable-schemes-update", false, "disable scheme updates")

	addRequestFlags(flags)

	flags.CountP("verbose", "v", "verbose (repeatable)")
}
<|endoftext|>


<commit_before>package configuration

import (
	"encoding/json"
	"io/ioutil"
	"os"
	"path"

	"github.com/kevintavog/findaphoto/common"

	"github.com/ian-kent/go-log/log"
	"github.com/spf13/viper"
)

type Configuration struct {
	ElasticSearchUrl string
	OpenMapUrl       string
	OpenMapKey       string
	Paths            []string
}

var Current Configuration

func ReadConfiguration() {

	common.InitDirectories("FindAPhoto")
	configDirectory := common.ConfigDirectory

	configFile := path.Join(configDirectory, "rangic.findaphotoService")
	_, err := os.Stat(configFile)
	if err != nil {
		defaultPaths := make([]string, 2)
		defaultPaths[0] = "first path"
		defaultPaths[1] = "second path"

		defaults := &Configuration{
			ElasticSearchUrl: "provideUrl",
			OpenMapUrl:       "provideUrl",
			OpenMapKey:       "key goes here",
			Paths:            defaultPaths,
		}
		json, jerr := json.Marshal(defaults)
		if jerr != nil {
			log.Fatal("Config file (%s) doesn't exist; attempt to write defaults failed: %s", configFile, jerr.Error())
		}

		werr := ioutil.WriteFile(configFile, json, os.ModePerm)
		if werr != nil {
			log.Fatal("Config file (%s) doesn't exist; attempt to write defaults failed: %s", configFile, werr.Error())
		} else {
			log.Fatal("Config file (%s) doesn't exist; one was written with defaults", configFile)
		}
	} else {
		viper.SetConfigFile(configFile)
		viper.SetConfigType("json")
		err := viper.ReadInConfig()
		if err != nil {
			log.Fatal("Error reading config file (%s): %s", configFile, err.Error())
		}
		err = viper.Unmarshal(&Current)
		if err != nil {
			log.Fatal("Failed converting configuration from (%s): %s", configFile, err.Error())
		}
	}
}
<commit_msg>Paths aren't currently used; get rid of to minimize confusion<commit_after>package configuration

import (
	"encoding/json"
	"io/ioutil"
	"os"
	"path"

	"github.com/kevintavog/findaphoto/common"

	"github.com/ian-kent/go-log/log"
	"github.com/spf13/viper"
)

type Configuration struct {
	ElasticSearchUrl string
	OpenMapUrl       string
	OpenMapKey       string
}

var Current Configuration

func ReadConfiguration() {

	common.InitDirectories("FindAPhoto")
	configDirectory := common.ConfigDirectory

	configFile := path.Join(configDirectory, "rangic.findaphotoService")
	_, err := os.Stat(configFile)
	if err != nil {
		defaultPaths := make([]string, 2)
		defaultPaths[0] = "first path"
		defaultPaths[1] = "second path"

		defaults := &Configuration{
			ElasticSearchUrl: "provideUrl",
			OpenMapUrl:       "provideUrl",
			OpenMapKey:       "key goes here",
		}
		json, jerr := json.Marshal(defaults)
		if jerr != nil {
			log.Fatal("Config file (%s) doesn't exist; attempt to write defaults failed: %s", configFile, jerr.Error())
		}

		werr := ioutil.WriteFile(configFile, json, os.ModePerm)
		if werr != nil {
			log.Fatal("Config file (%s) doesn't exist; attempt to write defaults failed: %s", configFile, werr.Error())
		} else {
			log.Fatal("Config file (%s) doesn't exist; one was written with defaults", configFile)
		}
	} else {
		viper.SetConfigFile(configFile)
		viper.SetConfigType("json")
		err := viper.ReadInConfig()
		if err != nil {
			log.Fatal("Error reading config file (%s): %s", configFile, err.Error())
		}
		err = viper.Unmarshal(&Current)
		if err != nil {
			log.Fatal("Failed converting configuration from (%s): %s", configFile, err.Error())
		}
	}
}
<|endoftext|>


<commit_before>package gin

import (
	"html/template"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"os"
	"path"
	"strings"
	"testing"
)

// TestRouterGroupGETRouteOK tests that GET route is correctly invoked.
func TestRouterGroupGETRouteOK(t *testing.T) {
	req, _ := http.NewRequest("GET", "/test", nil)
	w := httptest.NewRecorder()
	passed := false

	r := Default()
	r.GET("/test", func(c *Context) {
		passed = true
	})

	r.ServeHTTP(w, req)

	if passed == false {
		t.Errorf("GET route handler was not invoked.")
	}

	if w.Code != http.StatusOK {
		t.Errorf("Status code should be %v, was %d", http.StatusOK, w.Code)
	}
}

// TestRouterGroupGETNoRootExistsRouteOK tests that a GET requse to root is correctly
// handled (404) when no root route exists.
func TestRouterGroupGETNoRootExistsRouteOK(t *testing.T) {
	req, _ := http.NewRequest("GET", "/", nil)
	w := httptest.NewRecorder()

	r := Default()
	r.GET("/test", func(c *Context) {
	})

	r.ServeHTTP(w, req)

	if w.Code != http.StatusNotFound {
		// If this fails, it's because httprouter needs to be updated to at least f78f58a0db
		t.Errorf("Status code should be %v, was %d. Location: %s", http.StatusNotFound, w.Code, w.HeaderMap.Get("Location"))
	}
}

// TestRouterGroupPOSTRouteOK tests that POST route is correctly invoked.
func TestRouterGroupPOSTRouteOK(t *testing.T) {
	req, _ := http.NewRequest("POST", "/test", nil)
	w := httptest.NewRecorder()
	passed := false

	r := Default()
	r.POST("/test", func(c *Context) {
		passed = true
	})

	r.ServeHTTP(w, req)

	if passed == false {
		t.Errorf("POST route handler was not invoked.")
	}

	if w.Code != http.StatusOK {
		t.Errorf("Status code should be %v, was %d", http.StatusOK, w.Code)
	}
}

// TestRouterGroupDELETERouteOK tests that DELETE route is correctly invoked.
func TestRouterGroupDELETERouteOK(t *testing.T) {
	req, _ := http.NewRequest("DELETE", "/test", nil)
	w := httptest.NewRecorder()
	passed := false

	r := Default()
	r.DELETE("/test", func(c *Context) {
		passed = true
	})

	r.ServeHTTP(w, req)

	if passed == false {
		t.Errorf("DELETE route handler was not invoked.")
	}

	if w.Code != http.StatusOK {
		t.Errorf("Status code should be %v, was %d", http.StatusOK, w.Code)
	}
}

// TestRouterGroupPATCHRouteOK tests that PATCH route is correctly invoked.
func TestRouterGroupPATCHRouteOK(t *testing.T) {
	req, _ := http.NewRequest("PATCH", "/test", nil)
	w := httptest.NewRecorder()
	passed := false

	r := Default()
	r.PATCH("/test", func(c *Context) {
		passed = true
	})

	r.ServeHTTP(w, req)

	if passed == false {
		t.Errorf("PATCH route handler was not invoked.")
	}

	if w.Code != http.StatusOK {
		t.Errorf("Status code should be %v, was %d", http.StatusOK, w.Code)
	}
}

// TestRouterGroupPUTRouteOK tests that PUT route is correctly invoked.
func TestRouterGroupPUTRouteOK(t *testing.T) {
	req, _ := http.NewRequest("PUT", "/test", nil)
	w := httptest.NewRecorder()
	passed := false

	r := Default()
	r.PUT("/test", func(c *Context) {
		passed = true
	})

	r.ServeHTTP(w, req)

	if passed == false {
		t.Errorf("PUT route handler was not invoked.")
	}

	if w.Code != http.StatusOK {
		t.Errorf("Status code should be %v, was %d", http.StatusOK, w.Code)
	}
}

// TestRouterGroupOPTIONSRouteOK tests that OPTIONS route is correctly invoked.
func TestRouterGroupOPTIONSRouteOK(t *testing.T) {
	req, _ := http.NewRequest("OPTIONS", "/test", nil)
	w := httptest.NewRecorder()
	passed := false

	r := Default()
	r.OPTIONS("/test", func(c *Context) {
		passed = true
	})

	r.ServeHTTP(w, req)

	if passed == false {
		t.Errorf("OPTIONS route handler was not invoked.")
	}

	if w.Code != http.StatusOK {
		t.Errorf("Status code should be %v, was %d", http.StatusOK, w.Code)
	}
}

// TestRouterGroupHEADRouteOK tests that HEAD route is correctly invoked.
func TestRouterGroupHEADRouteOK(t *testing.T) {
	req, _ := http.NewRequest("HEAD", "/test", nil)
	w := httptest.NewRecorder()
	passed := false

	r := Default()
	r.HEAD("/test", func(c *Context) {
		passed = true
	})

	r.ServeHTTP(w, req)

	if passed == false {
		t.Errorf("HEAD route handler was not invoked.")
	}

	if w.Code != http.StatusOK {
		t.Errorf("Status code should be %v, was %d", http.StatusOK, w.Code)
	}
}

// TestRouterGroup404 tests that 404 is returned for a route that does not exist.
func TestEngine404(t *testing.T) {
	req, _ := http.NewRequest("GET", "/", nil)
	w := httptest.NewRecorder()

	r := Default()
	r.ServeHTTP(w, req)

	if w.Code != http.StatusNotFound {
		t.Errorf("Response code should be %v, was %d", http.StatusNotFound, w.Code)
	}
}

// TestContextParamsGet tests that a parameter can be parsed from the URL.
func TestContextParamsByName(t *testing.T) {
	req, _ := http.NewRequest("GET", "/test/alexandernyquist", nil)
	w := httptest.NewRecorder()
	name := ""

	r := Default()
	r.GET("/test/:name", func(c *Context) {
		name = c.Params.ByName("name")
	})

	r.ServeHTTP(w, req)

	if name != "alexandernyquist" {
		t.Errorf("Url parameter was not correctly parsed. Should be alexandernyquist, was %s.", name)
	}
}

// TestContextSetGet tests that a parameter is set correctly on the
// current context and can be retrieved using Get.
func TestContextSetGet(t *testing.T) {
	req, _ := http.NewRequest("GET", "/test", nil)
	w := httptest.NewRecorder()

	r := Default()
	r.GET("/test", func(c *Context) {
		// Key should be lazily created
		if c.Keys != nil {
			t.Error("Keys should be nil")
		}

		// Set
		c.Set("foo", "bar")

		v, err := c.Get("foo")
		if err != nil {
			t.Errorf("Error on exist key")
		}
		if v != "bar" {
			t.Errorf("Value should be bar, was %s", v)
		}
	})

	r.ServeHTTP(w, req)
}

// TestContextJSON tests that the response is serialized as JSON
// and Content-Type is set to application/json
func TestContextJSON(t *testing.T) {
	req, _ := http.NewRequest("GET", "/test", nil)
	w := httptest.NewRecorder()

	r := Default()
	r.GET("/test", func(c *Context) {
		c.JSON(200, H{"foo": "bar"})
	})

	r.ServeHTTP(w, req)

	if w.Body.String() != "{\"foo\":\"bar\"}\n" {
		t.Errorf("Response should be {\"foo\":\"bar\"}, was: %s", w.Body.String())
	}

	if w.HeaderMap.Get("Content-Type") != "application/json" {
		t.Errorf("Content-Type should be application/json, was %s", w.HeaderMap.Get("Content-Type"))
	}
}

// TestContextHTML tests that the response executes the templates
// and responds with Content-Type set to text/html
func TestContextHTML(t *testing.T) {
	req, _ := http.NewRequest("GET", "/test", nil)
	w := httptest.NewRecorder()

	r := Default()
	templ, _ := template.New("t").Parse(`Hello {{.Name}}`)
	r.SetHTMLTemplate(templ)

	type TestData struct{ Name string }

	r.GET("/test", func(c *Context) {
		c.HTML(200, "t", TestData{"alexandernyquist"})
	})

	r.ServeHTTP(w, req)

	if w.Body.String() != "Hello alexandernyquist" {
		t.Errorf("Response should be Hello alexandernyquist, was: %s", w.Body.String())
	}

	if w.HeaderMap.Get("Content-Type") != "text/html" {
		t.Errorf("Content-Type should be text/html, was %s", w.HeaderMap.Get("Content-Type"))
	}
}

// TestContextString tests that the response is returned
// with Content-Type set to text/plain
func TestContextString(t *testing.T) {
	req, _ := http.NewRequest("GET", "/test", nil)
	w := httptest.NewRecorder()

	r := Default()
	r.GET("/test", func(c *Context) {
		c.String(200, "test")
	})

	r.ServeHTTP(w, req)

	if w.Body.String() != "test" {
		t.Errorf("Response should be test, was: %s", w.Body.String())
	}

	if w.HeaderMap.Get("Content-Type") != "text/plain" {
		t.Errorf("Content-Type should be text/plain, was %s", w.HeaderMap.Get("Content-Type"))
	}
}

// TestHandleStaticFile - ensure the static file handles properly
func TestHandleStaticFile(t *testing.T) {

	testRoot, _ := os.Getwd()

	f, err := ioutil.TempFile(testRoot, "")
	defer os.Remove(f.Name())

	if err != nil {
		t.Error(err)
	}

	filePath := path.Join("/", path.Base(f.Name()))
	req, _ := http.NewRequest("GET", filePath, nil)

	f.WriteString("Gin Web Framework")
	f.Close()

	w := httptest.NewRecorder()

	r := Default()
	r.ServeFiles("/*filepath", http.Dir("./"))

	r.ServeHTTP(w, req)

	if w.Code != 200 {
		t.Errorf("Response code should be Ok, was: %s", w.Code)
	}

	if w.Body.String() != "Gin Web Framework" {
		t.Errorf("Response should be test, was: %s", w.Body.String())
	}

	if w.HeaderMap.Get("Content-Type") != "text/plain; charset=utf-8" {
		t.Errorf("Content-Type should be text/plain, was %s", w.HeaderMap.Get("Content-Type"))
	}
}

// TestHandleStaticDir - ensure the root/sub dir handles properly
func TestHandleStaticDir(t *testing.T) {

	req, _ := http.NewRequest("GET", "/", nil)

	w := httptest.NewRecorder()

	r := Default()
	r.ServeFiles("/*filepath", http.Dir("./"))

	r.ServeHTTP(w, req)

	if w.Code != 200 {
		t.Errorf("Response code should be Ok, was: %s", w.Code)
	}

	bodyAsString := w.Body.String()

	if len(bodyAsString) == 0 {
		t.Errorf("Got empty body instead of file tree")
	}

	if !strings.Contains(bodyAsString, "gin.go") {
		t.Errorf("Can't find:`gin.go` in file tree: %s", bodyAsString)
	}

	if w.HeaderMap.Get("Content-Type") != "text/html; charset=utf-8" {
		t.Errorf("Content-Type should be text/plain, was %s", w.HeaderMap.Get("Content-Type"))
	}
}
<commit_msg>Replaced deprecated ServeFiles<commit_after>package gin

import (
	"html/template"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"os"
	"path"
	"strings"
	"testing"
)

// TestRouterGroupGETRouteOK tests that GET route is correctly invoked.
func TestRouterGroupGETRouteOK(t *testing.T) {
	req, _ := http.NewRequest("GET", "/test", nil)
	w := httptest.NewRecorder()
	passed := false

	r := Default()
	r.GET("/test", func(c *Context) {
		passed = true
	})

	r.ServeHTTP(w, req)

	if passed == false {
		t.Errorf("GET route handler was not invoked.")
	}

	if w.Code != http.StatusOK {
		t.Errorf("Status code should be %v, was %d", http.StatusOK, w.Code)
	}
}

// TestRouterGroupGETNoRootExistsRouteOK tests that a GET requse to root is correctly
// handled (404) when no root route exists.
func TestRouterGroupGETNoRootExistsRouteOK(t *testing.T) {
	req, _ := http.NewRequest("GET", "/", nil)
	w := httptest.NewRecorder()

	r := Default()
	r.GET("/test", func(c *Context) {
	})

	r.ServeHTTP(w, req)

	if w.Code != http.StatusNotFound {
		// If this fails, it's because httprouter needs to be updated to at least f78f58a0db
		t.Errorf("Status code should be %v, was %d. Location: %s", http.StatusNotFound, w.Code, w.HeaderMap.Get("Location"))
	}
}

// TestRouterGroupPOSTRouteOK tests that POST route is correctly invoked.
func TestRouterGroupPOSTRouteOK(t *testing.T) {
	req, _ := http.NewRequest("POST", "/test", nil)
	w := httptest.NewRecorder()
	passed := false

	r := Default()
	r.POST("/test", func(c *Context) {
		passed = true
	})

	r.ServeHTTP(w, req)

	if passed == false {
		t.Errorf("POST route handler was not invoked.")
	}

	if w.Code != http.StatusOK {
		t.Errorf("Status code should be %v, was %d", http.StatusOK, w.Code)
	}
}

// TestRouterGroupDELETERouteOK tests that DELETE route is correctly invoked.
func TestRouterGroupDELETERouteOK(t *testing.T) {
	req, _ := http.NewRequest("DELETE", "/test", nil)
	w := httptest.NewRecorder()
	passed := false

	r := Default()
	r.DELETE("/test", func(c *Context) {
		passed = true
	})

	r.ServeHTTP(w, req)

	if passed == false {
		t.Errorf("DELETE route handler was not invoked.")
	}

	if w.Code != http.StatusOK {
		t.Errorf("Status code should be %v, was %d", http.StatusOK, w.Code)
	}
}

// TestRouterGroupPATCHRouteOK tests that PATCH route is correctly invoked.
func TestRouterGroupPATCHRouteOK(t *testing.T) {
	req, _ := http.NewRequest("PATCH", "/test", nil)
	w := httptest.NewRecorder()
	passed := false

	r := Default()
	r.PATCH("/test", func(c *Context) {
		passed = true
	})

	r.ServeHTTP(w, req)

	if passed == false {
		t.Errorf("PATCH route handler was not invoked.")
	}

	if w.Code != http.StatusOK {
		t.Errorf("Status code should be %v, was %d", http.StatusOK, w.Code)
	}
}

// TestRouterGroupPUTRouteOK tests that PUT route is correctly invoked.
func TestRouterGroupPUTRouteOK(t *testing.T) {
	req, _ := http.NewRequest("PUT", "/test", nil)
	w := httptest.NewRecorder()
	passed := false

	r := Default()
	r.PUT("/test", func(c *Context) {
		passed = true
	})

	r.ServeHTTP(w, req)

	if passed == false {
		t.Errorf("PUT route handler was not invoked.")
	}

	if w.Code != http.StatusOK {
		t.Errorf("Status code should be %v, was %d", http.StatusOK, w.Code)
	}
}

// TestRouterGroupOPTIONSRouteOK tests that OPTIONS route is correctly invoked.
func TestRouterGroupOPTIONSRouteOK(t *testing.T) {
	req, _ := http.NewRequest("OPTIONS", "/test", nil)
	w := httptest.NewRecorder()
	passed := false

	r := Default()
	r.OPTIONS("/test", func(c *Context) {
		passed = true
	})

	r.ServeHTTP(w, req)

	if passed == false {
		t.Errorf("OPTIONS route handler was not invoked.")
	}

	if w.Code != http.StatusOK {
		t.Errorf("Status code should be %v, was %d", http.StatusOK, w.Code)
	}
}

// TestRouterGroupHEADRouteOK tests that HEAD route is correctly invoked.
func TestRouterGroupHEADRouteOK(t *testing.T) {
	req, _ := http.NewRequest("HEAD", "/test", nil)
	w := httptest.NewRecorder()
	passed := false

	r := Default()
	r.HEAD("/test", func(c *Context) {
		passed = true
	})

	r.ServeHTTP(w, req)

	if passed == false {
		t.Errorf("HEAD route handler was not invoked.")
	}

	if w.Code != http.StatusOK {
		t.Errorf("Status code should be %v, was %d", http.StatusOK, w.Code)
	}
}

// TestRouterGroup404 tests that 404 is returned for a route that does not exist.
func TestEngine404(t *testing.T) {
	req, _ := http.NewRequest("GET", "/", nil)
	w := httptest.NewRecorder()

	r := Default()
	r.ServeHTTP(w, req)

	if w.Code != http.StatusNotFound {
		t.Errorf("Response code should be %v, was %d", http.StatusNotFound, w.Code)
	}
}

// TestContextParamsGet tests that a parameter can be parsed from the URL.
func TestContextParamsByName(t *testing.T) {
	req, _ := http.NewRequest("GET", "/test/alexandernyquist", nil)
	w := httptest.NewRecorder()
	name := ""

	r := Default()
	r.GET("/test/:name", func(c *Context) {
		name = c.Params.ByName("name")
	})

	r.ServeHTTP(w, req)

	if name != "alexandernyquist" {
		t.Errorf("Url parameter was not correctly parsed. Should be alexandernyquist, was %s.", name)
	}
}

// TestContextSetGet tests that a parameter is set correctly on the
// current context and can be retrieved using Get.
func TestContextSetGet(t *testing.T) {
	req, _ := http.NewRequest("GET", "/test", nil)
	w := httptest.NewRecorder()

	r := Default()
	r.GET("/test", func(c *Context) {
		// Key should be lazily created
		if c.Keys != nil {
			t.Error("Keys should be nil")
		}

		// Set
		c.Set("foo", "bar")

		v, err := c.Get("foo")
		if err != nil {
			t.Errorf("Error on exist key")
		}
		if v != "bar" {
			t.Errorf("Value should be bar, was %s", v)
		}
	})

	r.ServeHTTP(w, req)
}

// TestContextJSON tests that the response is serialized as JSON
// and Content-Type is set to application/json
func TestContextJSON(t *testing.T) {
	req, _ := http.NewRequest("GET", "/test", nil)
	w := httptest.NewRecorder()

	r := Default()
	r.GET("/test", func(c *Context) {
		c.JSON(200, H{"foo": "bar"})
	})

	r.ServeHTTP(w, req)

	if w.Body.String() != "{\"foo\":\"bar\"}\n" {
		t.Errorf("Response should be {\"foo\":\"bar\"}, was: %s", w.Body.String())
	}

	if w.HeaderMap.Get("Content-Type") != "application/json" {
		t.Errorf("Content-Type should be application/json, was %s", w.HeaderMap.Get("Content-Type"))
	}
}

// TestContextHTML tests that the response executes the templates
// and responds with Content-Type set to text/html
func TestContextHTML(t *testing.T) {
	req, _ := http.NewRequest("GET", "/test", nil)
	w := httptest.NewRecorder()

	r := Default()
	templ, _ := template.New("t").Parse(`Hello {{.Name}}`)
	r.SetHTMLTemplate(templ)

	type TestData struct{ Name string }

	r.GET("/test", func(c *Context) {
		c.HTML(200, "t", TestData{"alexandernyquist"})
	})

	r.ServeHTTP(w, req)

	if w.Body.String() != "Hello alexandernyquist" {
		t.Errorf("Response should be Hello alexandernyquist, was: %s", w.Body.String())
	}

	if w.HeaderMap.Get("Content-Type") != "text/html" {
		t.Errorf("Content-Type should be text/html, was %s", w.HeaderMap.Get("Content-Type"))
	}
}

// TestContextString tests that the response is returned
// with Content-Type set to text/plain
func TestContextString(t *testing.T) {
	req, _ := http.NewRequest("GET", "/test", nil)
	w := httptest.NewRecorder()

	r := Default()
	r.GET("/test", func(c *Context) {
		c.String(200, "test")
	})

	r.ServeHTTP(w, req)

	if w.Body.String() != "test" {
		t.Errorf("Response should be test, was: %s", w.Body.String())
	}

	if w.HeaderMap.Get("Content-Type") != "text/plain" {
		t.Errorf("Content-Type should be text/plain, was %s", w.HeaderMap.Get("Content-Type"))
	}
}

// TestHandleStaticFile - ensure the static file handles properly
func TestHandleStaticFile(t *testing.T) {

	testRoot, _ := os.Getwd()

	f, err := ioutil.TempFile(testRoot, "")
	defer os.Remove(f.Name())

	if err != nil {
		t.Error(err)
	}

	filePath := path.Join("/", path.Base(f.Name()))
	req, _ := http.NewRequest("GET", filePath, nil)

	f.WriteString("Gin Web Framework")
	f.Close()

	w := httptest.NewRecorder()

	r := Default()
	r.Static("./", testRoot)

	r.ServeHTTP(w, req)

	if w.Code != 200 {
		t.Errorf("Response code should be Ok, was: %s", w.Code)
	}

	if w.Body.String() != "Gin Web Framework" {
		t.Errorf("Response should be test, was: %s", w.Body.String())
	}

	if w.HeaderMap.Get("Content-Type") != "text/plain; charset=utf-8" {
		t.Errorf("Content-Type should be text/plain, was %s", w.HeaderMap.Get("Content-Type"))
	}
}

// TestHandleStaticDir - ensure the root/sub dir handles properly
func TestHandleStaticDir(t *testing.T) {

	req, _ := http.NewRequest("GET", "/", nil)

	w := httptest.NewRecorder()

	r := Default()
	r.Static("/", "./")

	r.ServeHTTP(w, req)

	if w.Code != 200 {
		t.Errorf("Response code should be Ok, was: %s", w.Code)
	}

	bodyAsString := w.Body.String()

	if len(bodyAsString) == 0 {
		t.Errorf("Got empty body instead of file tree")
	}

	if !strings.Contains(bodyAsString, "gin.go") {
		t.Errorf("Can't find:`gin.go` in file tree: %s", bodyAsString)
	}

	if w.HeaderMap.Get("Content-Type") != "text/html; charset=utf-8" {
		t.Errorf("Content-Type should be text/plain, was %s", w.HeaderMap.Get("Content-Type"))
	}
}
<|endoftext|>


<commit_before>package virt

import (
	"errors"
	"os/exec"
	"strconv"
	"strings"
	"time"

	"labix.org/v2/mgo/bson"
)

func (vm *VM) Start() error {
	if out, err := exec.Command("/usr/bin/lxc-start", "--name", vm.String(), "--daemon").CombinedOutput(); err != nil {
		return commandError("lxc-start failed.", err, out)
	}
	return vm.WaitForState("RUNNING", time.Second)
}

func (vm *VM) Stop() error {
	if out, err := exec.Command("/usr/bin/lxc-stop", "--name", vm.String()).CombinedOutput(); err != nil {
		return commandError("lxc-stop failed.", err, out)
	}
	return vm.WaitForState("STOPPED", time.Second)
}

func (vm *VM) Shutdown() error {
	if out, err := exec.Command("/usr/bin/lxc-shutdown", "--name", vm.String()).CombinedOutput(); err != nil {
		if vm.GetState() != "STOPPED" {
			return commandError("lxc-shutdown failed.", err, out)
		}
	}
	vm.WaitForState("STOPPED", 5*time.Second) // may time out, then vm is force stopped
	return vm.Stop()
}

func (vm *VM) AttachCommand(uid int, tty string, command ...string) *exec.Cmd {
	args := []string{"--name", vm.String()}
	if tty != "" {
		args = append(args, "--tty", tty)
	}
	args = append(args, "--", "/usr/bin/sudo", "-i", "-u", "#"+strconv.Itoa(uid), "--")
	args = append(args, command...)
	cmd := exec.Command("/usr/bin/lxc-attach", args...)
	cmd.Env = []string{"TERM=xterm-256color"}
	return cmd
}

func GetVMState(vmId bson.ObjectId) string {
	out, err := exec.Command("/usr/bin/lxc-info", "--name", VMName(vmId), "--state").CombinedOutput()
	if err != nil {
		lastError = commandError("lxc-info failed ", err, out)
		return "UNKNOWN"
	}
	return strings.TrimSpace(string(out)[6:])
}

func (vm *VM) GetState() string {
	return GetVMState(vm.Id)
}

func (vm *VM) WaitForState(state string, timeout time.Duration) error {
	tryUntil := time.Now().Add(timeout)
	for vm.GetState() != state {
		if time.Now().After(tryUntil) {
			return errors.New("Timeout while waiting for VM state.")
		}
		time.Sleep(time.Second / 10)
	}
	return nil
}

func (vm *VM) SendMessageToVMUsers(message string) error {
	cmd := exec.Command("/usr/bin/lxc-attach", "--name", vm.String(), "--", "/usr/bin/wall", "--nobanner")
	cmd.Stdin = strings.NewReader(message)
	if out, err := cmd.CombinedOutput(); err != nil {
		return commandError("wall failed.", err, out)
	}
	return nil
}

func (vm *VM) WaitForNetwork() error {
	timeout := time.Second * 5
	isNetworkUp := func() bool {
		// neglect error because it's not important and we also going to timeout
		out, _ := exec.Command("/usr/bin/lxc-attach", "--name", vm.String(),
			"--", "/bin/cat", "/sys/class/net/eth0/operstate").CombinedOutput()

		if strings.TrimSpace(string(out)) == "up" {
			return true
		}

		return false
	}

	tryUntil := time.Now().Add(timeout)
	for {
		if up := isNetworkUp(); up {
			return nil
		}

		if time.Now().After(tryUntil) {
			return errors.New("Timeout while waiting for VM Network state.")
		}

		time.Sleep(time.Millisecond * 100)
	}
}
<commit_msg>Ensure screen is also available before declaring the VM up<commit_after>package virt

import (
	"errors"
	"os/exec"
	"strconv"
	"strings"
	"time"

	"labix.org/v2/mgo/bson"
)

func (vm *VM) Start() error {
	if out, err := exec.Command("/usr/bin/lxc-start", "--name", vm.String(), "--daemon").CombinedOutput(); err != nil {
		return commandError("lxc-start failed.", err, out)
	}
	return vm.WaitForState("RUNNING", time.Second)
}

func (vm *VM) Stop() error {
	if out, err := exec.Command("/usr/bin/lxc-stop", "--name", vm.String()).CombinedOutput(); err != nil {
		return commandError("lxc-stop failed.", err, out)
	}
	return vm.WaitForState("STOPPED", time.Second)
}

func (vm *VM) Shutdown() error {
	if out, err := exec.Command("/usr/bin/lxc-shutdown", "--name", vm.String()).CombinedOutput(); err != nil {
		if vm.GetState() != "STOPPED" {
			return commandError("lxc-shutdown failed.", err, out)
		}
	}
	vm.WaitForState("STOPPED", 5*time.Second) // may time out, then vm is force stopped
	return vm.Stop()
}

func (vm *VM) AttachCommand(uid int, tty string, command ...string) *exec.Cmd {
	args := []string{"--name", vm.String()}
	if tty != "" {
		args = append(args, "--tty", tty)
	}
	args = append(args, "--", "/usr/bin/sudo", "-i", "-u", "#"+strconv.Itoa(uid), "--")
	args = append(args, command...)
	cmd := exec.Command("/usr/bin/lxc-attach", args...)
	cmd.Env = []string{"TERM=xterm-256color"}
	return cmd
}

func GetVMState(vmId bson.ObjectId) string {
	out, err := exec.Command("/usr/bin/lxc-info", "--name", VMName(vmId), "--state").CombinedOutput()
	if err != nil {
		lastError = commandError("lxc-info failed ", err, out)
		return "UNKNOWN"
	}
	return strings.TrimSpace(string(out)[6:])
}

func (vm *VM) GetState() string {
	return GetVMState(vm.Id)
}

func (vm *VM) WaitForState(state string, timeout time.Duration) error {
	tryUntil := time.Now().Add(timeout)
	for vm.GetState() != state {
		if time.Now().After(tryUntil) {
			return errors.New("Timeout while waiting for VM state.")
		}
		time.Sleep(time.Second / 10)
	}
	return nil
}

func (vm *VM) SendMessageToVMUsers(message string) error {
	cmd := exec.Command("/usr/bin/lxc-attach", "--name", vm.String(), "--", "/usr/bin/wall", "--nobanner")
	cmd.Stdin = strings.NewReader(message)
	if out, err := cmd.CombinedOutput(); err != nil {
		return commandError("wall failed.", err, out)
	}
	return nil
}

func (vm *VM) WaitForNetwork() error {
	timeout := time.Second * 5
	isNetworkUp := func() bool {
		// neglect error because it's not important and we also going to timeout
		out, _ := exec.Command("/usr/bin/lxc-attach", "--name", vm.String(),
			"--", "/bin/cat", "/sys/class/net/eth0/operstate").CombinedOutput()

		if strings.TrimSpace(string(out)) == "up" {
			if out, err := exec.Command("/usr/bin/lxc-attach", "--name", vm.String(),
				"--", "/bin/stat", "/usr/bin/screen").CombinedOutput(); err != nil {
				return true
			} else {
				return false
			}
			return false
		}
	}
	tryUntil := time.Now().Add(timeout)
	for {
		if up := isNetworkUp(); up {
			return nil
		}

		if time.Now().After(tryUntil) {
			return errors.New("Timeout while waiting for VM Network state.")
		}

		time.Sleep(time.Millisecond * 100)
	}
}
<|endoftext|>


<commit_before>package appui

import (
	"github.com/docker/docker/api/types"
	gtermui "github.com/gizak/termui"
	"github.com/moncho/dry/ui"
	"github.com/moncho/dry/ui/termui"
)

type ImageRunWidget struct {
	image *types.ImageSummary
	termui.TextInput
}

func NewImageRunWidget(image *types.ImageSummary) *ImageRunWidget {
	w := &ImageRunWidget{
		image:     image,
		TextInput: *termui.NewTextInput("", false),
	}
	w.Height = 3
	w.Width = ui.ActiveScreen.Dimensions.Width / 2
	w.X = (ui.ActiveScreen.Dimensions.Width - w.Width) / 2
	w.Y = ui.ActiveScreen.Dimensions.Height / 2
	w.Bg = gtermui.Attribute(DryTheme.Bg)
	w.TextBgColor = gtermui.Attribute(DryTheme.Bg)
	w.TextFgColor = gtermui.ColorWhite
	w.BorderLabel = " docker run " + image.RepoTags[0]
	w.BorderLabelFg = gtermui.ColorWhite

	return w
}

func (w *ImageRunWidget) Mount() error {
	return nil

}
func (w *ImageRunWidget) Unmount() error {

	return nil
}

func (w *ImageRunWidget) Name() string {

	return "ImageRunWidget." + w.image.ID
}
<commit_msg>Use the repo digest as title if there is no tag<commit_after>package appui

import (
	"github.com/docker/docker/api/types"
	gtermui "github.com/gizak/termui"
	"github.com/moncho/dry/ui"
	"github.com/moncho/dry/ui/termui"
)

//ImageRunWidget is an input widget to run images
type ImageRunWidget struct {
	image *types.ImageSummary
	termui.TextInput
}

//NewImageRunWidget creates a new ImageRunWidget for the given image
func NewImageRunWidget(image *types.ImageSummary) *ImageRunWidget {
	w := &ImageRunWidget{
		image:     image,
		TextInput: *termui.NewTextInput("", false),
	}
	w.Height = 3
	w.Width = ui.ActiveScreen.Dimensions.Width / 2
	w.X = (ui.ActiveScreen.Dimensions.Width - w.Width) / 2
	w.Y = ui.ActiveScreen.Dimensions.Height / 2
	w.Bg = gtermui.Attribute(DryTheme.Bg)
	w.TextBgColor = gtermui.Attribute(DryTheme.Bg)
	w.TextFgColor = gtermui.ColorWhite
	w.BorderLabel = widgetTitle(image)
	w.BorderLabelFg = gtermui.ColorWhite

	return w
}

//Mount callback
func (w *ImageRunWidget) Mount() error {
	return nil
}

//Unmount callback
func (w *ImageRunWidget) Unmount() error {
	return nil
}

//Name returns the widget name
func (w *ImageRunWidget) Name() string {
	return "ImageRunWidget." + w.image.ID
}

func widgetTitle(image *types.ImageSummary) string {
	if len(image.RepoTags) > 0 {
		return " docker run " + image.RepoTags[0]
	} else if len(image.RepoDigests) > 0 {
		return " docker run " + image.RepoDigests[0]
	}
	return " docker run <none>"
}
<|endoftext|>


<commit_before>/*
   Copyright (c) 2016 VMware, Inc. All Rights Reserved.
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
package controllers

import (
	"net/url"
	"os"

	"github.com/vmware/harbor/dao"
	"github.com/vmware/harbor/models"

	"github.com/astaxie/beego"
)

type ItemDetailController struct {
	BaseController
}

var SYS_ADMIN int = 1
var PROJECT_ADMIN int = 2
var DEVELOPER int = 3
var GUEST int = 4

func CheckProjectRole(userId int, projectId int64) bool {
	if projectId == 0 {
		return false
	}
	userQuery := models.User{UserId: int(userId)}
	if userId == SYS_ADMIN {
		return true
	}
	roleList, err := dao.GetUserProjectRoles(userQuery, projectId)
	if err != nil {
		beego.Error("Error occurred in GetUserProjectRoles:", err)
		return false
	}
	return len(roleList) > 0
}

func CheckPublicProject(projectId int64) bool {
	projectQuery := models.Project{ProjectId: projectId}
	project, err := dao.GetProjectById(projectQuery)
	if err != nil {
		beego.Error("Error occurred in GetProjectById:", err)
		return false
	}
	if project != nil && project.Public == 1 {
		return true
	}
	return false
}

func (idc *ItemDetailController) Get() {

	sessionUserId := idc.GetSession("userId")
	projectId, _ := idc.GetInt64("project_id")

	if CheckPublicProject(projectId) == false && (sessionUserId == nil || !CheckProjectRole(sessionUserId.(int), projectId)) {
		idc.Redirect("/signIn?uri="+url.QueryEscape(idc.Ctx.Input.URI()), 302)
	}

	projectQuery := models.Project{ProjectId: projectId}
	project, err := dao.GetProjectById(projectQuery)

	if err != nil {
		beego.Error("Error occurred in GetProjectById:", err)
		idc.CustomAbort(500, "Internal error.")
	}

	if project == nil {
		idc.Redirect("/signIn", 302)
	}

	idc.Data["ProjectId"] = project.ProjectId
	idc.Data["ProjectName"] = project.Name
	idc.Data["OwnerName"] = project.OwnerName
	idc.Data["OwnerId"] = project.OwnerId

	if sessionUserId != nil {
		idc.Data["Username"] = idc.GetSession("username")
		idc.Data["UserId"] = sessionUserId.(int)
		roleList, err := dao.GetUserProjectRoles(models.User{UserId: sessionUserId.(int)}, projectId)
		if err != nil {
			beego.Error("Error occurred in GetUserProjectRoles:", err)
			idc.CustomAbort(500, "Internal error.")
		}
		if len(roleList) > 0 {
			idc.Data["RoleId"] = roleList[0].RoleId
		}
	}

	idc.Data["HarborRegUrl"] = os.Getenv("HARBOR_REG_URL")
	idc.Data["RepoName"] = idc.GetString("repo_name")

	idc.ForwardTo("page_title_item_details", "item-detail")

}
<commit_msg>refactored codes in item_detail controller<commit_after>/*
   Copyright (c) 2016 VMware, Inc. All Rights Reserved.
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
package controllers

import (
	"net/url"
	"os"

	"github.com/vmware/harbor/dao"
	"github.com/vmware/harbor/models"

	"github.com/astaxie/beego"
)

type ItemDetailController struct {
	BaseController
}

func (idc *ItemDetailController) Get() {

	projectId, _ := idc.GetInt64("project_id")
	if projectId <= 0 {
		beego.Error("Invalid project id:", projectId)
		idc.Redirect("/signIn", 302)
	}

	projectQuery := models.Project{ProjectId: projectId}
	project, err := dao.GetProjectById(projectQuery)

	if err != nil {
		beego.Error("Error occurred in GetProjectById:", err)
		idc.CustomAbort(500, "Internal error.")
	}

	if project == nil {
		idc.Redirect("/signIn", 302)
	}

	sessionUserId := idc.GetSession("userId")

	if project.Public != 1 && sessionUserId == nil {
		idc.Redirect("/signIn?uri="+url.QueryEscape(idc.Ctx.Input.URI()), 302)
	}

	if sessionUserId != nil {

		idc.Data["Username"] = idc.GetSession("username")
		idc.Data["UserId"] = sessionUserId.(int)

		roleList, err := dao.GetUserProjectRoles(models.User{UserId: sessionUserId.(int)}, projectId)
		if err != nil {
			beego.Error("Error occurred in GetUserProjectRoles:", err)
			idc.CustomAbort(500, "Internal error.")
		}

		if project.Public == 0 && len(roleList) == 0 {
			idc.Redirect("/signIn?uri="+url.QueryEscape(idc.Ctx.Input.URI()), 302)
		} else if len(roleList) > 0 {
			idc.Data["RoleId"] = roleList[0].RoleId
		}
	}

	idc.Data["ProjectId"] = project.ProjectId
	idc.Data["ProjectName"] = project.Name
	idc.Data["OwnerName"] = project.OwnerName
	idc.Data["OwnerId"] = project.OwnerId

	idc.Data["HarborRegUrl"] = os.Getenv("HARBOR_REG_URL")
	idc.Data["RepoName"] = idc.GetString("repo_name")

	idc.ForwardTo("page_title_item_details", "item-detail")

}
<|endoftext|>


<commit_before>// Copyright 2018 Authors of Cilium
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
	"fmt"
	"os"
	"text/tabwriter"

	daemonAPI "github.com/cilium/cilium/api/v1/client/daemon"
	"github.com/cilium/cilium/api/v1/models"
	"github.com/cilium/cilium/pkg/api"
	"github.com/cilium/cilium/pkg/command"

	"github.com/spf13/cobra"
)

// mapGetCmd represents the map_get command
var mapGetCmd = &cobra.Command{
	Use:     "get <name>",
	Short:   "Display BPF map information",
	Example: "cilium map get cilium_ipcache",
	Run: func(cmd *cobra.Command, args []string) {
		if len(args) < 0 {
			Fatalf("map name must be specified")
		}

		params := daemonAPI.NewGetMapNameParams().WithName(args[0]).WithTimeout(api.ClientTimeout)

		resp, err := client.Daemon.GetMapName(params)
		if err != nil {
			Fatalf("%s", err)
		}

		m := resp.Payload
		if m == nil {
			return
		}

		if command.OutputJSON() {
			if err := command.PrintOutput(m); err != nil {
				os.Exit(1)
			}
		} else {
			printMapEntries(m)
		}
	},
}

func printMapEntries(m *models.BPFMap) {
	if m.Cache == nil {
		fmt.Printf("Cache is disabled\n\n")
		return
	}

	if len(m.Cache) == 0 {
		fmt.Printf("Cache is empty\n\n")
		return
	}

	w := tabwriter.NewWriter(os.Stdout, 5, 0, 3, ' ', 0)
	fmt.Fprintf(w, "Key\tValue\tState\tError\n")
	for _, e := range m.Cache {
		if e != nil {
			fmt.Fprintf(w, "%s\t%s\t%s\t%s\n",
				e.Key, e.Value, e.DesiredAction, e.LastError)
		}
	}
	w.Flush()
}

func init() {
	mapCmd.AddCommand(mapGetCmd)
	command.AddJSONOutput(mapGetCmd)
}
<commit_msg>bpf: fix empty map check condition<commit_after>// Copyright 2018 Authors of Cilium
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
	"fmt"
	"os"
	"text/tabwriter"

	daemonAPI "github.com/cilium/cilium/api/v1/client/daemon"
	"github.com/cilium/cilium/api/v1/models"
	"github.com/cilium/cilium/pkg/api"
	"github.com/cilium/cilium/pkg/command"

	"github.com/spf13/cobra"
)

// mapGetCmd represents the map_get command
var mapGetCmd = &cobra.Command{
	Use:     "get <name>",
	Short:   "Display BPF map information",
	Example: "cilium map get cilium_ipcache",
	Run: func(cmd *cobra.Command, args []string) {
		if len(args) == 0 {
			Fatalf("map name must be specified")
		}

		params := daemonAPI.NewGetMapNameParams().WithName(args[0]).WithTimeout(api.ClientTimeout)

		resp, err := client.Daemon.GetMapName(params)
		if err != nil {
			Fatalf("%s", err)
		}

		m := resp.Payload
		if m == nil {
			return
		}

		if command.OutputJSON() {
			if err := command.PrintOutput(m); err != nil {
				os.Exit(1)
			}
		} else {
			printMapEntries(m)
		}
	},
}

func printMapEntries(m *models.BPFMap) {
	if m.Cache == nil {
		fmt.Printf("Cache is disabled\n\n")
		return
	}

	if len(m.Cache) == 0 {
		fmt.Printf("Cache is empty\n\n")
		return
	}

	w := tabwriter.NewWriter(os.Stdout, 5, 0, 3, ' ', 0)
	fmt.Fprintf(w, "Key\tValue\tState\tError\n")
	for _, e := range m.Cache {
		if e != nil {
			fmt.Fprintf(w, "%s\t%s\t%s\t%s\n",
				e.Key, e.Value, e.DesiredAction, e.LastError)
		}
	}
	w.Flush()
}

func init() {
	mapCmd.AddCommand(mapGetCmd)
	command.AddJSONOutput(mapGetCmd)
}
<|endoftext|>


<commit_before>package output

import (
	"encoding/csv"
	"fmt"
	"strings"
	"text/tabwriter"

	"github.com/codegangsta/cli"
)

// ListTable writes a table listing from an array of map[string]interface{}
func ListTable(c *cli.Context, f *func() []map[string]interface{}, keys []string) {
	many := (*f)()
	if c.IsSet("csv") {
		w := csv.NewWriter(c.App.Writer)
		w.Write(keys)
		for _, m := range many {
			f := []string{}
			for _, key := range keys {
				f = append(f, fmt.Sprint(m[key]))
			}
			w.Write(f)
		}
		w.Flush()
	} else {
		w := tabwriter.NewWriter(c.App.Writer, 0, 8, 1, '\t', 0)
		// Write the header
		fmt.Fprintln(w, strings.Join(keys, "\t"))
		for _, m := range many {
			f := []string{}
			for _, key := range keys {
				f = append(f, fmt.Sprint(m[key]))
			}
			fmt.Fprintln(w, strings.Join(f, "\t"))
		}
		w.Flush()
	}
}

// MetadataTable writes standardized metadata out
func MetadataTable(c *cli.Context, f *func() map[string]interface{}, keys []string) {
	m := (*f)()
	if c.IsSet("csv") {
		w := csv.NewWriter(c.App.Writer)
		w.Write([]string{"PROPERTY", "VALUE"})
		for _, key := range keys {
			val := fmt.Sprint(m[key])
			w.Write([]string{key, val})
		}
		w.Flush()
	} else {
		w := tabwriter.NewWriter(c.App.Writer, 0, 8, 0, '\t', 0)
		fmt.Fprintln(w, "PROPERTY\tVALUE")
		for _, key := range keys {
			val := fmt.Sprint(m[key])
			fmt.Fprintf(w, "%s\t%s\n", key, strings.Replace(val, "\n", "\n\t", -1))
		}
		w.Flush()
	}
}
<commit_msg>break out table and csv into their own functions<commit_after>package output

import (
	"encoding/csv"
	"fmt"
	"strings"
	"text/tabwriter"

	"github.com/codegangsta/cli"
)

// ListTable writes a table listing from an array of map[string]interface{}
func ListTable(c *cli.Context, f *func() []map[string]interface{}, keys []string) {
	many := (*f)()
	if c.IsSet("csv") {
		w := csv.NewWriter(c.App.Writer)
		w.Write(keys)
		for _, m := range many {
			f := []string{}
			for _, key := range keys {
				f = append(f, fmt.Sprint(m[key]))
			}
			w.Write(f)
		}
		w.Flush()
	} else {
		w := tabwriter.NewWriter(c.App.Writer, 0, 8, 1, '\t', 0)
		// Write the header
		fmt.Fprintln(w, strings.Join(keys, "\t"))
		for _, m := range many {
			f := []string{}
			for _, key := range keys {
				f = append(f, fmt.Sprint(m[key]))
			}
			fmt.Fprintln(w, strings.Join(f, "\t"))
		}
		w.Flush()
	}
}

// MetadataTable writes standardized metadata out
func MetadataTable(c *cli.Context, f *func() map[string]interface{}, keys []string) {
	if c.IsSet("csv") {
		csvOut(c, f, keys)
	} else {
		tableOut(c, f, keys)
	}
}

func csvOut(c *cli.Context, f *func() map[string]interface{}, keys []string) {
	m := (*f)()
	w := csv.NewWriter(c.App.Writer)
	w.Write([]string{"PROPERTY", "VALUE"})
	for _, key := range keys {
		val := fmt.Sprint(m[key])
		w.Write([]string{key, val})
	}
	w.Flush()
}

func tableOut(c *cli.Context, f *func() map[string]interface{}, keys []string) {
	m := (*f)()
	w := tabwriter.NewWriter(c.App.Writer, 0, 8, 0, '\t', 0)
	fmt.Fprintln(w, "PROPERTY\tVALUE")
	for _, key := range keys {
		val := fmt.Sprint(m[key])
		fmt.Fprintf(w, "%s\t%s\n", key, strings.Replace(val, "\n", "\n\t", -1))
	}
	w.Flush()
}
<|endoftext|>


<commit_before>package main

import (
  "encoding/csv"
  "os"
  "fmt"
  "io"
  "github.com/bdon/jklmnt/linref"
  "strconv"
)

func main() {
  // Find the first trip for a shape
  tripsFile, _ := os.Open("muni_gtfs/trips.txt")
  defer tripsFile.Close()
  reader := csv.NewReader(tripsFile)
  reader.TrailingComma = true
  var tripId string
  for {
    record, err := reader.Read()
    if err == io.EOF {
      fmt.Println("No Record Found")
      break
    }
    if record[6] == "102909" {
      tripId = record[2]
      break
    }
  }
  fmt.Printf("trip id: %s\n", tripId)

  // Create a map of stop ids for that trip
  stopTimesFile, _ := os.Open("muni_gtfs/stop_times.txt")
  defer stopTimesFile.Close()
  stopTimesReader := csv.NewReader(stopTimesFile)
  stopTimesReader.TrailingComma = true
  stopMap := make(map[string]bool)
  for {
    record, err := stopTimesReader.Read()
    if err == io.EOF {
      break
    }
    if record[0] == tripId {
      stopMap[record[3]] = true
    }
  }
  fmt.Printf("stop ids: %s\n", stopMap)

  // create a linear referencer
  nReferencer := linref.NewReferencer("102909")

  // print all stops given a list of stop IDs
  stopsFile, _ := os.Open("muni_gtfs/stops.txt")
  defer stopsFile.Close()
  stopsReader := csv.NewReader(stopsFile)
  stopsReader.TrailingComma = true
  for {
    record, err := stopsReader.Read()
    if err == io.EOF {
      break
    }
    if stopMap[record[0]] {
     fmt.Println(record[1])
     stop_lat, _ := strconv.ParseFloat(record[3],64)
     stop_lon, _ := strconv.ParseFloat(record[4],64)
     fmt.Println(nReferencer.Reference(stop_lat, stop_lon))
    }
  }
}
<commit_msg>output stops json<commit_after>package main

import (
	"encoding/csv"
	"encoding/json"
	"fmt"
	"github.com/bdon/jklmnt/linref"
	"io"
	"os"
	"strconv"
	"strings"
)

type StopRepr struct {
	Index float64 `json:"index"`
	Name  string  `json:"name"`
	Lat   float64 `json:"lat"`
	Lon   float64 `json:"lon"`
}

func main() {
	// Find the first trip for a shape
	tripsFile, _ := os.Open("muni_gtfs/trips.txt")
	defer tripsFile.Close()
	reader := csv.NewReader(tripsFile)
	reader.TrailingComma = true
	var tripId string
	for {
		record, err := reader.Read()
		if err == io.EOF {
			fmt.Println("No Record Found")
			break
		}
		if record[6] == "102909" {
			tripId = record[2]
			break
		}
	}
	//fmt.Printf("trip id: %s\n", tripId)

	// Create a map of stop ids for that trip
	stopTimesFile, _ := os.Open("muni_gtfs/stop_times.txt")
	defer stopTimesFile.Close()
	stopTimesReader := csv.NewReader(stopTimesFile)
	stopTimesReader.TrailingComma = true
	stopMap := make(map[string]bool)
	for {
		record, err := stopTimesReader.Read()
		if err == io.EOF {
			break
		}
		if record[0] == tripId {
			stopMap[record[3]] = true
		}
	}
	//fmt.Printf("stop ids: %s\n", stopMap)

	// create a linear referencer
	nReferencer := linref.NewReferencer("102909")

	// create an output data structure
	output := []StopRepr{}

	// print all stops given a list of stop IDs
	stopsFile, _ := os.Open("muni_gtfs/stops.txt")
	defer stopsFile.Close()
	stopsReader := csv.NewReader(stopsFile)
	stopsReader.TrailingComma = true
	for {
		record, err := stopsReader.Read()
		if err == io.EOF {
			break
		}
		if stopMap[record[0]] {
			newStop := StopRepr{}
			stop_lat, _ := strconv.ParseFloat(record[3], 64)
			stop_lon, _ := strconv.ParseFloat(record[4], 64)
			index := nReferencer.Reference(stop_lat, stop_lon)
			newStop.Lat = stop_lat
			newStop.Lon = stop_lon
			newStop.Index = index
			newStop.Name = strings.TrimSpace(record[1])
			output = append(output, newStop)
		}
	}

	marshalled, _ := json.Marshal(output)
	fmt.Printf(string(marshalled))
}
<|endoftext|>


<commit_before>package multi

func NewRecentlyExisted(size int) *RecentlyExisted {
	return &RecentlyExisted{
		list: make([]string, size),
	}
}

type RecentlyExisted struct {
	list    []string
	current int
}

func (r *RecentlyExisted) CheckAndAdd(t string) bool {
	for _, c := range r.list {
		if c == t {
			u := current - 1
			if u < 0 {
				u = 0
			}
			list[u] = t
			return true
		}
	}

	list[current] = t
	current++
	if current == len(list) {
		current = 0
	}
	return false
}
<commit_msg>update<commit_after>package multi

func NewRecentlyExisted(size int) *RecentlyExisted {
	return &RecentlyExisted{
		list: make([]string, size),
	}
}

type RecentlyExisted struct {
	list    []string
	current int
}

func (r *RecentlyExisted) CheckAndAdd(t string) bool {
	for _, c := range r.list {
		if c == t {
			u := r.current - 1
			if u < 0 {
				u = 0
			}
			r.list[u] = t
			return true
		}
	}

	r.list[r.current] = t
	r.current++
	if r.current == len(r.list) {
		r.current = 0
	}
	return false
}
<|endoftext|>