<commit_before>package server

import (
	"os"
	"net"

	"junta/util"
	"junta/paxos"
	"junta/proto"
	"junta/store"
	"strconv"
	"time"
)

type ReadFromWriteToer interface {
	ReadFrom([]byte) (int, net.Addr, os.Error)
	WriteTo([]byte, net.Addr) (int, os.Error)
	LocalAddr() net.Addr
}

const packetSize = 3000

type conn struct {
	net.Conn
	s *Server
}

type Manager interface {
	PutFrom(string, paxos.Msg)
	Propose(string) (uint64, string, os.Error)
	Alpha() int
}

type Server struct {
	Addr string
	St *store.Store
	Mg Manager
}

func (sv *Server) ListenAndServe() os.Error {
	logger := util.NewLogger("server %s", sv.Addr)

	logger.Log("binding")
	l, err := net.Listen("tcp", sv.Addr)
	if err != nil {
		logger.Log(err)
		return err
	}
	defer l.Close()
	logger.Log("listening")

	err = sv.Serve(l)
	if err != nil {
		logger.Logf("%s: %s", l, err)
}
	return err
}

func (sv *Server) ListenAndServeUdp(outs chan paxos.Packet) os.Error {
	logger := util.NewLogger("udp server %s", sv.Addr)

	logger.Log("binding")
	u, err := net.ListenPacket("udp", sv.Addr)
	if err != nil {
		logger.Log(err)
		return err
	}
	defer u.Close()
	logger.Log("listening")

	err = sv.ServeUdp(u, outs)
	if err != nil {
		logger.Logf("%s: %s", u, err)
	}
	return err
}

func (sv *Server) ServeUdp(u ReadFromWriteToer, outs chan paxos.Packet) os.Error {
	recvd := make(chan paxos.Packet)
	sent := make(chan paxos.Packet)

	logger := util.NewLogger("udp server %s", u.LocalAddr())
	go func() {
		logger.Log("reading messages...")
		for {
			msg, addr, err := paxos.ReadMsg(u, packetSize)
			if err != nil {
				logger.Log(err)
				continue
			}
			logger.Logf("read %v from %s", msg, addr)
			recvd <- paxos.Packet{msg, addr}
			sv.Mg.PutFrom(addr, msg)
		}
	}()

	go func() {
		logger.Log("sending messages...")
		for pk := range outs {
			logger.Logf("sending %v", pk)
			udpAddr, err := net.ResolveUDPAddr(pk.Addr)
			if err != nil {
				logger.Log(err)
				continue
			}

			_, err = u.WriteTo(pk.Msg.WireBytes(), udpAddr)
			if err != nil {
				logger.Log(err)
				continue
			}
			sent <- paxos.Packet{pk.Msg, pk.Addr}
		}
	}()

	needsAck := make(map[string]bool)
	resend := make(chan paxos.Packet)
	for {
		select {
		case pk := <-recvd:
			if pk.Msg.HasFlags(paxos.Ack) {
				logger.Logf("got ack %s %v", pk.Addr, pk.Msg)
				needsAck[pk.Id()] = false
			} else {
				logger.Logf("sending ack %s %v", pk.Addr, pk.Msg)
				udpAddr, err := net.ResolveUDPAddr(pk.Addr)
				if err != nil {
					break
				}
				ack := pk.Msg.Dup().SetFlags(paxos.Ack)
				u.WriteTo(ack.WireBytes(), udpAddr)
			}
		case pk := <-sent:
			needsAck[pk.Id()] = true
			logger.Logf("needs ack %s %v", pk.Addr, pk.Msg)
			go func() {
				time.Sleep(100000000) // ns == 0.1s
				resend <- pk
			}()
		case pk := <-resend:
			if needsAck[pk.Id()] {
				logger.Logf("resending %s %v", pk.Addr, pk.Msg)
				go func() {
					outs <- pk
				}()
			} else {
				needsAck[pk.Id()] = false, false
			}
		}
	}

	panic("not reached")
}

func (s *Server) Serve(l net.Listener) os.Error {
	for {
		rw, e := l.Accept()
		if e != nil {
			return e
		}
		c := &conn{rw, s}
		go c.serve()
	}

	panic("not reached")
}

func (sv *Server) setOnce(path, body, cas string) (uint64, os.Error) {
	mut, err := store.EncodeSet(path, body, cas)
	if err != nil {
		return 0, err
	}

	seqn, v, err := sv.Mg.Propose(mut)
	if err != nil {
		return 0, err
	}

	// We failed, but only because of a competing proposal. The client should
	// retry.
	if v != mut {
		return 0, os.EAGAIN
	}

	return seqn, nil
}

func (sv *Server) Set(path, body, cas string) (seqn uint64, err os.Error) {
	err = os.EAGAIN
	for err == os.EAGAIN {
		seqn, err = sv.setOnce(path, body, cas)
	}
	return
}

func (sv *Server) delOnce(path, cas string) (uint64, os.Error) {
	mut, err := store.EncodeDel(path, cas)
	if err != nil {
		return 0, err
	}

	seqn, v, err := sv.Mg.Propose(mut)
	if err != nil {
		return 0, err
	}

	// We failed, but only because of a competing proposal. The client should
	// retry.
	if v != mut {
		return 0, os.EAGAIN
	}

	return seqn, nil
}

func (sv *Server) Del(path, cas string) (seqn uint64, err os.Error) {
	err = os.EAGAIN
	for err == os.EAGAIN {
		seqn, err = sv.delOnce(path, cas)
	}
	return
}

func (sv *Server) WaitForPathSet(path string) (body string, err os.Error) {
	evs := make(chan store.Event)
	defer close(evs)
	sv.St.Watch(path, evs)

	parts, cas := sv.St.Lookup(path)
	if cas != store.Dir && cas != store.Missing {
		return parts[0], nil
	}

	for ev := range evs {
		if ev.IsSet() {
			return ev.Body, nil
		}
	}

	panic("not reached")
}

// Repeatedly propose nop values until a successful read from `done`.
func (sv *Server) AdvanceUntil(done chan int) {
	for _, ok := <-done; !ok; _, ok = <-done {
		sv.Mg.Propose(store.Nop)
	}
}

func (c *conn) serve() {
	pc := proto.NewConn(c)
	logger := util.NewLogger("%v", c.RemoteAddr())
	logger.Log("accepted connection")
	for {
		rid, parts, err := pc.ReadRequest()
		if err != nil {
			if err == os.EOF {
				logger.Log("connection closed by peer")
			} else {
				logger.Log(err)
			}
			return
		}

		rlogger := util.NewLogger("%v - req [%d]", c.RemoteAddr(), rid)
		rlogger.Logf("received <%v>", parts)

		if len(parts) == 0 {
			rlogger.Log("zero parts supplied")
			pc.SendError(rid, proto.InvalidCommand + ": no command")
			continue
		}

		switch parts[0] {
		default:
			rlogger.Logf("unknown command <%s>", parts[0])
			pc.SendError(rid, proto.InvalidCommand + " " + parts[0])
		case "set":
			if len(parts) != 4 {
				rlogger.Logf("invalid set command: %#v", parts)
				pc.SendError(rid, "wrong number of parts")
				break
			}
			rlogger.Logf("set %q=%q (cas %q)", parts[1], parts[2], parts[3])
			_, err := c.s.Set(parts[1], parts[2], parts[3])
			if err != nil {
				rlogger.Logf("bad: %s", err)
				pc.SendError(rid, err.String())
			} else {
				rlogger.Logf("good")
				pc.SendResponse(rid, "true")
			}
		case "del":
			if len(parts) != 3 {
				rlogger.Logf("invalid del command: %v", parts)
				pc.SendError(rid, "wrong number of parts")
				break
			}
			rlogger.Logf("del %q (cas %q)", parts[1], parts[2])
			_, err := c.s.Del(parts[1], parts[2])
			if err != nil {
				rlogger.Logf("bad: %s", err)
				pc.SendError(rid, err.String())
			} else {
				rlogger.Logf("good")
				pc.SendResponse(rid, "true")
			}
		case "wait-for-path-set": // TODO this is for demo purposes only
			if len(parts) != 2 {
				rlogger.Logf("invalid wait-for-path-set command: %v", parts)
				pc.SendError(rid, "wrong number of parts")
				break
			}
			rlogger.Logf("wait-for-path-set %q", parts[1])
			body, err := c.s.WaitForPathSet(parts[1])
			if err != nil {
				rlogger.Logf("bad: %s", err)
				pc.SendError(rid, err.String())
			} else {
				rlogger.Logf("good %q", body)
				pc.SendResponse(rid, body)
			}
		case "join":
			// join abc123 1.2.3.4:999
			if len(parts) != 3 {
				rlogger.Logf("invalid join command: %v", parts)
				pc.SendError(rid, "wrong number of parts")
				break
			}

			who, addr := parts[1], parts[2]
			rlogger.Logf("membership requested for %s at %s", who, addr)

			key := "/j/junta/members/" + who

			seqn, err := c.s.Set(key, addr, store.Missing)
			if err != nil {
				rlogger.Logf("bad: %s", err)
				pc.SendError(rid, err.String())
			} else {
				rlogger.Logf("good")
				done := make(chan int)
				go c.s.AdvanceUntil(done)
				c.s.St.Sync(seqn + uint64(c.s.Mg.Alpha()))
				close(done)
				seqn, snap := c.s.St.Snapshot()
				pc.SendResponse(rid, strconv.Uitoa64(seqn), snap)
			}
		}
	}
}
<commit_msg>return the seqn after a set command<commit_after>package server

import (
	"os"
	"net"

	"junta/util"
	"junta/paxos"
	"junta/proto"
	"junta/store"
	"strconv"
	"time"
)

type ReadFromWriteToer interface {
	ReadFrom([]byte) (int, net.Addr, os.Error)
	WriteTo([]byte, net.Addr) (int, os.Error)
	LocalAddr() net.Addr
}

const packetSize = 3000

type conn struct {
	net.Conn
	s *Server
}

type Manager interface {
	PutFrom(string, paxos.Msg)
	Propose(string) (uint64, string, os.Error)
	Alpha() int
}

type Server struct {
	Addr string
	St *store.Store
	Mg Manager
}

func (sv *Server) ListenAndServe() os.Error {
	logger := util.NewLogger("server %s", sv.Addr)

	logger.Log("binding")
	l, err := net.Listen("tcp", sv.Addr)
	if err != nil {
		logger.Log(err)
		return err
	}
	defer l.Close()
	logger.Log("listening")

	err = sv.Serve(l)
	if err != nil {
		logger.Logf("%s: %s", l, err)
}
	return err
}

func (sv *Server) ListenAndServeUdp(outs chan paxos.Packet) os.Error {
	logger := util.NewLogger("udp server %s", sv.Addr)

	logger.Log("binding")
	u, err := net.ListenPacket("udp", sv.Addr)
	if err != nil {
		logger.Log(err)
		return err
	}
	defer u.Close()
	logger.Log("listening")

	err = sv.ServeUdp(u, outs)
	if err != nil {
		logger.Logf("%s: %s", u, err)
	}
	return err
}

func (sv *Server) ServeUdp(u ReadFromWriteToer, outs chan paxos.Packet) os.Error {
	recvd := make(chan paxos.Packet)
	sent := make(chan paxos.Packet)

	logger := util.NewLogger("udp server %s", u.LocalAddr())
	go func() {
		logger.Log("reading messages...")
		for {
			msg, addr, err := paxos.ReadMsg(u, packetSize)
			if err != nil {
				logger.Log(err)
				continue
			}
			logger.Logf("read %v from %s", msg, addr)
			recvd <- paxos.Packet{msg, addr}
			sv.Mg.PutFrom(addr, msg)
		}
	}()

	go func() {
		logger.Log("sending messages...")
		for pk := range outs {
			logger.Logf("sending %v", pk)
			udpAddr, err := net.ResolveUDPAddr(pk.Addr)
			if err != nil {
				logger.Log(err)
				continue
			}

			_, err = u.WriteTo(pk.Msg.WireBytes(), udpAddr)
			if err != nil {
				logger.Log(err)
				continue
			}
			sent <- paxos.Packet{pk.Msg, pk.Addr}
		}
	}()

	needsAck := make(map[string]bool)
	resend := make(chan paxos.Packet)
	for {
		select {
		case pk := <-recvd:
			if pk.Msg.HasFlags(paxos.Ack) {
				logger.Logf("got ack %s %v", pk.Addr, pk.Msg)
				needsAck[pk.Id()] = false
			} else {
				logger.Logf("sending ack %s %v", pk.Addr, pk.Msg)
				udpAddr, err := net.ResolveUDPAddr(pk.Addr)
				if err != nil {
					break
				}
				ack := pk.Msg.Dup().SetFlags(paxos.Ack)
				u.WriteTo(ack.WireBytes(), udpAddr)
			}
		case pk := <-sent:
			needsAck[pk.Id()] = true
			logger.Logf("needs ack %s %v", pk.Addr, pk.Msg)
			go func() {
				time.Sleep(100000000) // ns == 0.1s
				resend <- pk
			}()
		case pk := <-resend:
			if needsAck[pk.Id()] {
				logger.Logf("resending %s %v", pk.Addr, pk.Msg)
				go func() {
					outs <- pk
				}()
			} else {
				needsAck[pk.Id()] = false, false
			}
		}
	}

	panic("not reached")
}

func (s *Server) Serve(l net.Listener) os.Error {
	for {
		rw, e := l.Accept()
		if e != nil {
			return e
		}
		c := &conn{rw, s}
		go c.serve()
	}

	panic("not reached")
}

func (sv *Server) setOnce(path, body, cas string) (uint64, os.Error) {
	mut, err := store.EncodeSet(path, body, cas)
	if err != nil {
		return 0, err
	}

	seqn, v, err := sv.Mg.Propose(mut)
	if err != nil {
		return 0, err
	}

	// We failed, but only because of a competing proposal. The client should
	// retry.
	if v != mut {
		return 0, os.EAGAIN
	}

	return seqn, nil
}

func (sv *Server) Set(path, body, cas string) (seqn uint64, err os.Error) {
	err = os.EAGAIN
	for err == os.EAGAIN {
		seqn, err = sv.setOnce(path, body, cas)
	}
	return
}

func (sv *Server) delOnce(path, cas string) (uint64, os.Error) {
	mut, err := store.EncodeDel(path, cas)
	if err != nil {
		return 0, err
	}

	seqn, v, err := sv.Mg.Propose(mut)
	if err != nil {
		return 0, err
	}

	// We failed, but only because of a competing proposal. The client should
	// retry.
	if v != mut {
		return 0, os.EAGAIN
	}

	return seqn, nil
}

func (sv *Server) Del(path, cas string) (seqn uint64, err os.Error) {
	err = os.EAGAIN
	for err == os.EAGAIN {
		seqn, err = sv.delOnce(path, cas)
	}
	return
}

func (sv *Server) WaitForPathSet(path string) (body string, err os.Error) {
	evs := make(chan store.Event)
	defer close(evs)
	sv.St.Watch(path, evs)

	parts, cas := sv.St.Lookup(path)
	if cas != store.Dir && cas != store.Missing {
		return parts[0], nil
	}

	for ev := range evs {
		if ev.IsSet() {
			return ev.Body, nil
		}
	}

	panic("not reached")
}

// Repeatedly propose nop values until a successful read from `done`.
func (sv *Server) AdvanceUntil(done chan int) {
	for _, ok := <-done; !ok; _, ok = <-done {
		sv.Mg.Propose(store.Nop)
	}
}

func (c *conn) serve() {
	pc := proto.NewConn(c)
	logger := util.NewLogger("%v", c.RemoteAddr())
	logger.Log("accepted connection")
	for {
		rid, parts, err := pc.ReadRequest()
		if err != nil {
			if err == os.EOF {
				logger.Log("connection closed by peer")
			} else {
				logger.Log(err)
			}
			return
		}

		rlogger := util.NewLogger("%v - req [%d]", c.RemoteAddr(), rid)
		rlogger.Logf("received <%v>", parts)

		if len(parts) == 0 {
			rlogger.Log("zero parts supplied")
			pc.SendError(rid, proto.InvalidCommand + ": no command")
			continue
		}

		switch parts[0] {
		default:
			rlogger.Logf("unknown command <%s>", parts[0])
			pc.SendError(rid, proto.InvalidCommand + " " + parts[0])
		case "set":
			if len(parts) != 4 {
				rlogger.Logf("invalid set command: %#v", parts)
				pc.SendError(rid, "wrong number of parts")
				break
			}
			rlogger.Logf("set %q=%q (cas %q)", parts[1], parts[2], parts[3])
			seqn, err := c.s.Set(parts[1], parts[2], parts[3])
			if err != nil {
				rlogger.Logf("bad: %s", err)
				pc.SendError(rid, err.String())
			} else {
				rlogger.Logf("good")
				pc.SendResponse(rid, strconv.Uitoa64(seqn))
			}
		case "del":
			if len(parts) != 3 {
				rlogger.Logf("invalid del command: %v", parts)
				pc.SendError(rid, "wrong number of parts")
				break
			}
			rlogger.Logf("del %q (cas %q)", parts[1], parts[2])
			_, err := c.s.Del(parts[1], parts[2])
			if err != nil {
				rlogger.Logf("bad: %s", err)
				pc.SendError(rid, err.String())
			} else {
				rlogger.Logf("good")
				pc.SendResponse(rid, "true")
			}
		case "wait-for-path-set": // TODO this is for demo purposes only
			if len(parts) != 2 {
				rlogger.Logf("invalid wait-for-path-set command: %v", parts)
				pc.SendError(rid, "wrong number of parts")
				break
			}
			rlogger.Logf("wait-for-path-set %q", parts[1])
			body, err := c.s.WaitForPathSet(parts[1])
			if err != nil {
				rlogger.Logf("bad: %s", err)
				pc.SendError(rid, err.String())
			} else {
				rlogger.Logf("good %q", body)
				pc.SendResponse(rid, body)
			}
		case "join":
			// join abc123 1.2.3.4:999
			if len(parts) != 3 {
				rlogger.Logf("invalid join command: %v", parts)
				pc.SendError(rid, "wrong number of parts")
				break
			}

			who, addr := parts[1], parts[2]
			rlogger.Logf("membership requested for %s at %s", who, addr)

			key := "/j/junta/members/" + who

			seqn, err := c.s.Set(key, addr, store.Missing)
			if err != nil {
				rlogger.Logf("bad: %s", err)
				pc.SendError(rid, err.String())
			} else {
				rlogger.Logf("good")
				done := make(chan int)
				go c.s.AdvanceUntil(done)
				c.s.St.Sync(seqn + uint64(c.s.Mg.Alpha()))
				close(done)
				seqn, snap := c.s.St.Snapshot()
				pc.SendResponse(rid, strconv.Uitoa64(seqn), snap)
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"net/http"

	"github.com/go-chi/chi"
	"github.com/go-chi/render"
	"github.com/serbe/edc"
)

func listCertificates(w http.ResponseWriter, r *http.Request) {
	type context struct {
		Title        string                `json:"title"`
		Certificates []edc.CertificateList `json:"certificates"`
	}
	certificates, err := db.GetCertificateListAll()
	if err != nil {
		errmsg("listCertificates GetCertificateListAll", err)
		return
	}
	ctx := context{Title: "List", Certificates: certificates}
	render.DefaultResponder(w, r, ctx)
}

func getCertificate(w http.ResponseWriter, r *http.Request) {
	type context struct {
		Title       string          `json:"title"`
		Certificate edc.Certificate `json:"certificate"`
	}
	id := toInt(chi.URLParam(r, "id"))
	certificate, err := db.GetCertificate(id)
	if err != nil {
		errmsg("getCertificate GetCertificate", err)
		return
	}
	ctx := context{Title: "Create certificate", Certificate: certificate}
	render.DefaultResponder(w, r, ctx)
}

func createCertificate(w http.ResponseWriter, r *http.Request) {
	var certificate edc.Certificate
	decoder := json.NewDecoder(r.Body)
	errchkmsg("createCertificate Decode", decoder.Decode(&certificate))
	defer func() {
		errchkmsg("createCertificate defer Body.Close", r.Body.Close())
	}()
	_, err := db.CreateCertificate(certificate)
	errchkmsg("createCertificate CreateCertificate", err)
}

func updateCertificate(w http.ResponseWriter, r *http.Request) {
	var certificate edc.Certificate
	decoder := json.NewDecoder(r.Body)
	errchkmsg("updateCertificate Decode", decoder.Decode(&certificate))
	defer func() {
		errchkmsg("updateCertificate defer Body.Close", r.Body.Close())
	}()
	errchkmsg("updateCertificate UpdateCertificate", db.UpdateCertificate(certificate))
}

func deleteCertificate(w http.ResponseWriter, r *http.Request) {
	id := toInt(chi.URLParam(r, "id"))
	errchkmsg("deleteCertificate DeleteCertificate", db.DeleteCertificate(id))
}
<commit_msg>fix missing contacts<commit_after>package main

import (
	"encoding/json"
	"net/http"

	"github.com/go-chi/chi"
	"github.com/go-chi/render"
	"github.com/serbe/edc"
)

func listCertificates(w http.ResponseWriter, r *http.Request) {
	type context struct {
		Title        string                `json:"title"`
		Certificates []edc.CertificateList `json:"certificates"`
	}
	certificates, err := db.GetCertificateListAll()
	if err != nil {
		errmsg("listCertificates GetCertificateListAll", err)
		return
	}
	ctx := context{Title: "List", Certificates: certificates}
	render.DefaultResponder(w, r, ctx)
}

func getCertificate(w http.ResponseWriter, r *http.Request) {
	type context struct {
		Title       string           `json:"title"`
		Certificate edc.Certificate  `json:"certificate"`
		Contacts    []edc.SelectItem `json:"contacts"`
	}
	id := toInt(chi.URLParam(r, "id"))
	certificate, err := db.GetCertificate(id)
	if err != nil {
		errmsg("getCertificate GetCertificate", err)
		// return
	}
	contacts, err := db.GetContactSelectAll()
	if err != nil {
		errmsg("getCertificate GetContactSelectAll", err)
		// return
	}
	ctx := context{Title: "Create certificate", Certificate: certificate, Contacts: contacts}
	render.DefaultResponder(w, r, ctx)
}

func createCertificate(w http.ResponseWriter, r *http.Request) {
	var certificate edc.Certificate
	decoder := json.NewDecoder(r.Body)
	errchkmsg("createCertificate Decode", decoder.Decode(&certificate))
	defer func() {
		errchkmsg("createCertificate defer Body.Close", r.Body.Close())
	}()
	_, err := db.CreateCertificate(certificate)
	errchkmsg("createCertificate CreateCertificate", err)
}

func updateCertificate(w http.ResponseWriter, r *http.Request) {
	var certificate edc.Certificate
	decoder := json.NewDecoder(r.Body)
	errchkmsg("updateCertificate Decode", decoder.Decode(&certificate))
	defer func() {
		errchkmsg("updateCertificate defer Body.Close", r.Body.Close())
	}()
	errchkmsg("updateCertificate UpdateCertificate", db.UpdateCertificate(certificate))
}

func deleteCertificate(w http.ResponseWriter, r *http.Request) {
	id := toInt(chi.URLParam(r, "id"))
	errchkmsg("deleteCertificate DeleteCertificate", db.DeleteCertificate(id))
}
<|endoftext|>


<commit_before>//  Copyright 2016 The goscope Authors
//
//  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 triggers

import (
	"testing"

	"github.com/zagrodzki/goscope/scope"
)

var sin = make([]scope.Voltage, 10000)

type dataRec struct {
	tb     int
	i      scope.Duration
	sweeps [][]scope.Voltage
	err    error
	done   chan struct{}
}

func (r *dataRec) TimeBase() scope.Duration {
	return scope.Millisecond * scope.Duration(r.tb)
}

func (r *dataRec) Reset(i scope.Duration, ch <-chan []scope.ChannelData) {
	r.i = i
	r.done = make(chan struct{}, 1)
	tbCount := int(r.TimeBase() / r.i)
	var buf []scope.Voltage
	var l int
	go func() {
		for d := range ch {
			l += len(d[0].Samples)
			buf = append(buf, d[0].Samples...)
			if l >= tbCount {
				l = 0
				r.sweeps = append(r.sweeps, buf)
				buf = nil
			}
		}
		if len(buf) > 0 {
			r.sweeps = append(r.sweeps, buf)
		}
		r.done <- struct{}{}
	}()
}

func (r *dataRec) Error(err error) {
	r.err = err
}

const (
	goodSource    = scope.ChanID("signal")
	missingSource = scope.ChanID("nonexistent")
)

func TestTrigger(t *testing.T) {
	for _, tc := range []struct {
		tbLen   int
		samples [][]scope.Voltage
		level   scope.Voltage
		edge    RisingEdge
		source  scope.ChanID
		want    [][]scope.Voltage
	}{
		{
			tbLen: 10,
			samples: [][]scope.Voltage{
				{0, 0.2, 0.4, 0.8},
				{1.0, 0.8, 0.6, 0.4},
				{0.2, 0, -0.2, -0.4},
				{-0.6, -0.8, -1, -0.8},
				{-0.6, -0.4, -0.2, 0},
			},
			level:  0.3,
			edge:   Falling,
			source: goodSource,
			want: [][]scope.Voltage{
				{0.2, 0, -0.2, -0.4, -0.6, -0.8, -1, -0.8, -0.6, -0.4},
			},
		},
		{
			tbLen: 8,
			samples: [][]scope.Voltage{
				{0.5, 0.7, 0.9, 1.1},
				{-0.1, 0.1, 0.2, 0.3},
				{0.4, 0.5, 0.6, 0.7},
				{0.8, 0.9, 1.0, 1.1},
			},
			level:  0.25,
			edge:   Rising,
			source: goodSource,
			want: [][]scope.Voltage{
				{0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0},
			},
		},
		{
			tbLen: 8,
			samples: [][]scope.Voltage{
				{1, 1, 1, 1},
				{1, 1, 1, 1},
				{1, 1, 1, 1},
				{1, 1, 1, 1},
			},
			level:  99,
			edge:   Rising,
			source: missingSource,
			want: [][]scope.Voltage{
				{1, 1, 1, 1, 1, 1, 1, 1},
				{1, 1, 1, 1, 1, 1, 1, 1},
			},
		},
		{
			tbLen: 8,
			samples: [][]scope.Voltage{
				{1, 1, 1, 1, 1, 1, 1, 1},
				{1, 1, 1, 1, 1, 1, 1, 1},
				{1, 1, 1, 1, 1, 1, 1, 1},
			},
			level:  -1,
			edge:   Falling,
			source: goodSource,
			want:   nil,
		},
		{
			tbLen: 8,
			samples: [][]scope.Voltage{
				{1, 1, 1, 1, 1, 1, 1, 1},
				{1, 1, 1, 1, 1, 1, 1, 1},
				{1, 1, 1, 1, 1, 1, 1, 1},
			},
			level:  -1,
			edge:   Rising,
			source: goodSource,
			want:   nil,
		},
	} {
		in := make(chan []scope.ChannelData, 10)
		buf := &dataRec{tb: tc.tbLen}
		tr := New(buf)
		tr.Source(tc.source)
		tr.Level(tc.level)
		tr.Edge(tc.edge)

		tr.Reset(scope.Millisecond, in)
		for _, v := range tc.samples {
			in <- []scope.ChannelData{
				{
					ID:      goodSource,
					Samples: v,
				},
			}
		}
		close(in)
		<-buf.done

		if got, want := len(buf.sweeps), len(tc.want); got < want {
			t.Errorf("got %d sweeps, want %d", got, want)
			continue
		}
	compareSweeps:
		for i, got := range buf.sweeps {
			want := tc.want[i]
			if len(got) != len(want) {
				t.Errorf("sweep #%d: got %d samples, want %d. Full sweeps:\nGot %v\nWant: %v", len(got), len(want), got, want)
				break
			}
			for j := 0; j < len(got); j++ {
				t.Logf("Sweep %d, #%d, %v vs %v", i, j, got[j], want[j])
				if got[j] != want[j] {
					t.Errorf("sweep #%d[%d]: got %v, want %v. Full sweeps:\nGot: %v\nWant: %v", i, j, got[j], want[j], got, want)
					break compareSweeps
				}
			}
		}
	}
}
<commit_msg>Add test cases for constant sample values exactly at the threshold, to make sure it doesn't trigger. Add test descriptions for better debuggability.<commit_after>//  Copyright 2016 The goscope Authors
//
//  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 triggers

import (
	"testing"

	"github.com/zagrodzki/goscope/scope"
)

var sin = make([]scope.Voltage, 10000)

type dataRec struct {
	tb     int
	i      scope.Duration
	sweeps [][]scope.Voltage
	err    error
	done   chan struct{}
}

func (r *dataRec) TimeBase() scope.Duration {
	return scope.Millisecond * scope.Duration(r.tb)
}

func (r *dataRec) Reset(i scope.Duration, ch <-chan []scope.ChannelData) {
	r.i = i
	r.done = make(chan struct{})
	tbCount := int(r.TimeBase() / r.i)
	var buf []scope.Voltage
	var l int
	go func() {
		for d := range ch {
			l += len(d[0].Samples)
			buf = append(buf, d[0].Samples...)
			if l >= tbCount {
				l = 0
				r.sweeps = append(r.sweeps, buf)
				buf = nil
			}
		}
		if len(buf) > 0 {
			r.sweeps = append(r.sweeps, buf)
		}
		close(r.done)
	}()
}

func (r *dataRec) Error(err error) {
	r.err = err
}

const (
	goodSource    = scope.ChanID("signal")
	missingSource = scope.ChanID("nonexistent")
)

func TestTrigger(t *testing.T) {
	for _, tc := range []struct {
		desc    string
		tbLen   int
		samples [][]scope.Voltage
		level   scope.Voltage
		edge    RisingEdge
		source  scope.ChanID
		want    [][]scope.Voltage
	}{
		{
			desc:  "triangle wave, simple trigger on falling edge",
			tbLen: 10,
			samples: [][]scope.Voltage{
				{0, 0.2, 0.4, 0.8},
				{1.0, 0.8, 0.6, 0.4},
				{0.2, 0, -0.2, -0.4},
				{-0.6, -0.8, -1, -0.8},
				{-0.6, -0.4, -0.2, 0},
			},
			level:  0.3,
			edge:   Falling,
			source: goodSource,
			want: [][]scope.Voltage{
				{0.2, 0, -0.2, -0.4, -0.6, -0.8, -1, -0.8, -0.6, -0.4},
			},
		},
		{
			desc:  "first sample above threshold, triggers only on actual crossing",
			tbLen: 8,
			samples: [][]scope.Voltage{
				{0.5, 0.7, 0.9, 1.1},
				{-0.1, 0.1, 0.2, 0.3},
				{0.4, 0.5, 0.6, 0.7},
				{0.8, 0.9, 1.0, 1.1},
			},
			level:  0.25,
			edge:   Rising,
			source: goodSource,
			want: [][]scope.Voltage{
				{0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0},
			},
		},
		{
			desc:  "never reaches the threshold, falling edge",
			tbLen: 8,
			samples: [][]scope.Voltage{
				{1, 1, 1, 1, 1, 1, 1, 1},
				{1, 1, 1, 1, 1, 1, 1, 1},
				{1, 1, 1, 1, 1, 1, 1, 1},
			},
			level:  -1,
			edge:   Falling,
			source: goodSource,
			want:   nil,
		},
		{
			desc:  "never reaches the threshold, rising edge",
			tbLen: 8,
			samples: [][]scope.Voltage{
				{1, 1, 1, 1, 1, 1, 1, 1},
				{1, 1, 1, 1, 1, 1, 1, 1},
				{1, 1, 1, 1, 1, 1, 1, 1},
			},
			level:  -1,
			edge:   Rising,
			source: goodSource,
			want:   nil,
		},
		{
			desc:  "constant samples at the threshold, rising edge",
			tbLen: 4,
			samples: [][]scope.Voltage{
				{1, 1, 1, 1, 1, 1, 1},
				{1, 1, 1, 1, 1},
				{1, 1, 1, 1, 1, 1, 1, 1},
			},
			level:  1,
			edge:   Rising,
			source: goodSource,
			want:   nil,
		},
		{
			desc:  "constant samples at the threshold, falling edge",
			tbLen: 4,
			samples: [][]scope.Voltage{
				{1, 1, 1, 1, 1, 1, 1},
				{1, 1, 1, 1, 1},
				{1, 1, 1, 1, 1, 1, 1, 1},
			},
			level:  1,
			edge:   Falling,
			source: goodSource,
			want:   nil,
		},
	} {
		buf := &dataRec{tb: tc.tbLen}
		tr := New(buf)
		tr.Source(tc.source)
		tr.Level(tc.level)
		tr.Edge(tc.edge)

		in := make(chan []scope.ChannelData, 10)
		tr.Reset(scope.Millisecond, in)

		for _, v := range tc.samples {
			in <- []scope.ChannelData{
				{
					ID:      goodSource,
					Samples: v,
				},
			}
		}
		close(in)
		<-buf.done

		if got, want := len(buf.sweeps), len(tc.want); got != want {
			t.Errorf("%s: got %d sweeps, want %d", tc.desc, got, want)
			continue
		}
	compareSweeps:
		for i, got := range buf.sweeps {
			want := tc.want[i]
			if len(got) != len(want) {
				t.Errorf("%s: sweep #%d: got %d samples, want %d. Full sweeps:\nGot %v\nWant: %v", tc.desc, len(got), len(want), got, want)
				break
			}
			for j := 0; j < len(got); j++ {
				t.Logf("Sweep %d, #%d, %v vs %v", i, j, got[j], want[j])
				if got[j] != want[j] {
					t.Errorf("%s: sweep #%d[%d]: got %v, want %v. Full sweeps:\nGot: %v\nWant: %v", tc.desc, i, j, got[j], want[j], got, want)
					break compareSweeps
				}
			}
		}
	}
}
<|endoftext|>


<commit_before>// Copyright 2010 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.

// General environment variables.

package os

// Expand replaces ${var} or $var in the string based on the mapping function.
// Invocations of undefined variables are replaced with the empty string.
func Expand(s string, mapping func(string) string) string {
	buf := make([]byte, 0, 2*len(s))
	// ${} is all ASCII, so bytes are fine for this operation.
	for i := 0; i < len(s); {
		if s[i] != '$' || i == len(s)-1 {
			buf = append(buf, s[i])
			i++
			continue
		}
		name, w := getShellName(s[i+1:])
		buf = append(buf, []byte(mapping(name))...)
		i += 1 + w
	}
	return string(buf)
}

// ShellExpand replaces ${var} or $var in the string according to the values
// of the operating system's environment variables.  References to undefined
// variables are replaced by the empty string.
func ShellExpand(s string) string {
	return Expand(s, Getenv)
}

// isSpellSpecialVar reports whether the character identifies a special
// shell variable such as $*.
func isShellSpecialVar(c uint8) bool {
	switch c {
	case '*', '#', '$', '@', '!', '?', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
		return true
	}
	return false
}

// isAlphaNum reports whether the byte is an ASCII letter, number, or underscore
func isAlphaNum(c uint8) bool {
	return c == '_' || '0' <= c && c <= '9' || 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z'
}

// getName returns the name that begins the string and the number of bytes
// consumed to extract it.  If the name is enclosed in {}, it's part of a ${}
// expansion and two more bytes are needed than the length of the name.
func getShellName(s string) (string, int) {
	switch {
	case s[0] == '{':
		if len(s) > 2 && isShellSpecialVar(s[1]) && s[2] == '}' {
			return s[1:2], 3
		}
		// Scan to closing brace
		for i := 1; i < len(s); i++ {
			if s[i] == '}' {
				return s[1:i], i + 1
			}
		}
		return "", 1 // Bad syntax; just eat the brace.
	case isShellSpecialVar(s[0]):
		return s[0:1], 1
	}
	// Scan alphanumerics.
	var i int
	for i = 0; i < len(s) && isAlphaNum(s[i]); i++ {
	}
	return s[:i], i
}
<commit_msg>os.Expand: don't call append for each non-variable char<commit_after>// Copyright 2010 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.

// General environment variables.

package os

// Expand replaces ${var} or $var in the string based on the mapping function.
// Invocations of undefined variables are replaced with the empty string.
func Expand(s string, mapping func(string) string) string {
	buf := make([]byte, 0, 2*len(s))
	// ${} is all ASCII, so bytes are fine for this operation.
	i := 0
	for j := 0; j < len(s); j++ {
		if s[j] == '$' && j+1 < len(s) {
			buf = append(buf, []byte(s[i:j])...)
			name, w := getShellName(s[j+1:])
			buf = append(buf, []byte(mapping(name))...)
			j += w
			i = j + 1
		}
	}
	return string(buf) + s[i:]
}

// ShellExpand replaces ${var} or $var in the string according to the values
// of the operating system's environment variables.  References to undefined
// variables are replaced by the empty string.
func ShellExpand(s string) string {
	return Expand(s, Getenv)
}

// isSpellSpecialVar reports whether the character identifies a special
// shell variable such as $*.
func isShellSpecialVar(c uint8) bool {
	switch c {
	case '*', '#', '$', '@', '!', '?', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
		return true
	}
	return false
}

// isAlphaNum reports whether the byte is an ASCII letter, number, or underscore
func isAlphaNum(c uint8) bool {
	return c == '_' || '0' <= c && c <= '9' || 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z'
}

// getName returns the name that begins the string and the number of bytes
// consumed to extract it.  If the name is enclosed in {}, it's part of a ${}
// expansion and two more bytes are needed than the length of the name.
func getShellName(s string) (string, int) {
	switch {
	case s[0] == '{':
		if len(s) > 2 && isShellSpecialVar(s[1]) && s[2] == '}' {
			return s[1:2], 3
		}
		// Scan to closing brace
		for i := 1; i < len(s); i++ {
			if s[i] == '}' {
				return s[1:i], i + 1
			}
		}
		return "", 1 // Bad syntax; just eat the brace.
	case isShellSpecialVar(s[0]):
		return s[0:1], 1
	}
	// Scan alphanumerics.
	var i int
	for i = 0; i < len(s) && isAlphaNum(s[i]); i++ {
	}
	return s[:i], i
}
<|endoftext|>


<commit_before>package admin

import (
	"context"
	"fmt"
	"sort"
	"strconv"
	"strings"

	"github.com/tsuru/gnuflag"
	"github.com/tsuru/go-tsuruclient/pkg/client"
	"github.com/tsuru/go-tsuruclient/pkg/tsuru"
	"github.com/tsuru/tablecli"
	"github.com/tsuru/tsuru/cmd"
)

type BrokerAdd struct {
	broker tsuru.ServiceBroker
	fs     *gnuflag.FlagSet
}

func (c *BrokerAdd) Info() *cmd.Info {
	return &cmd.Info{
		Name:    "service-broker-add",
		Usage:   "service-broker-add <name> <url> [-i/--insecure] [-c/--context key=value] [-t/--token token] [-u/--user username] [-p/--password password]",
		Desc:    `Adds a new Service Broker.`,
		MinArgs: 2,
	}
}

func (c *BrokerAdd) Flags() *gnuflag.FlagSet {
	if c.fs == nil {
		c.fs = flagsForServiceBroker(&c.broker)
	}
	return c.fs
}

func (c *BrokerAdd) Run(ctx *cmd.Context, cli *cmd.Client) error {
	apiClient, err := client.ClientFromEnvironment(&tsuru.Configuration{
		HTTPClient: cli.HTTPClient,
	})
	if err != nil {
		return err
	}
	c.broker.Name, c.broker.URL = ctx.Args[0], ctx.Args[1]
	_, err = apiClient.ServiceApi.ServiceBrokerCreate(context.TODO(), c.broker)
	if err != nil {
		return err
	}
	fmt.Fprintln(ctx.Stdout, "Service broker successfully added.")
	return nil
}

type BrokerUpdate struct {
	broker tsuru.ServiceBroker
	fs     *gnuflag.FlagSet
}

func (c *BrokerUpdate) Info() *cmd.Info {
	return &cmd.Info{
		Name:    "service-broker-update",
		Usage:   "service-broker-updates <name> <url> [-i/--insecure] [-c/--context key=value] [-t/--token token] [-u/--user username] [-p/--password password]",
		Desc:    `Updates a service broker.`,
		MinArgs: 2,
	}
}

func (c *BrokerUpdate) Flags() *gnuflag.FlagSet {
	if c.fs == nil {
		c.fs = flagsForServiceBroker(&c.broker)
	}
	return c.fs
}

func (c *BrokerUpdate) Run(ctx *cmd.Context, cli *cmd.Client) error {
	apiClient, err := client.ClientFromEnvironment(&tsuru.Configuration{
		HTTPClient: cli.HTTPClient,
	})
	if err != nil {
		return err
	}
	c.broker.Name, c.broker.URL = ctx.Args[0], ctx.Args[1]
	_, err = apiClient.ServiceApi.ServiceBrokerUpdate(context.TODO(), c.broker.Name, c.broker)
	if err != nil {
		return err
	}
	fmt.Fprintln(ctx.Stdout, "Service broker successfully updated.")
	return nil
}

type BrokerDelete struct{}

func (c *BrokerDelete) Info() *cmd.Info {
	return &cmd.Info{
		Name:    "service-broker-delete",
		Usage:   "service-broker-delete <name>",
		Desc:    `Removes a service broker.`,
		MinArgs: 1,
	}
}

func (c *BrokerDelete) Run(ctx *cmd.Context, cli *cmd.Client) error {
	apiClient, err := client.ClientFromEnvironment(&tsuru.Configuration{
		HTTPClient: cli.HTTPClient,
	})
	if err != nil {
		return err
	}
	_, err = apiClient.ServiceApi.ServiceBrokerDelete(context.TODO(), ctx.Args[0])
	if err != nil {
		return err
	}
	fmt.Fprintln(ctx.Stdout, "Service broker successfully deleted.")
	return nil
}

type BrokerList struct{}

func (c *BrokerList) Info() *cmd.Info {
	return &cmd.Info{
		Name:  "service-broker-list",
		Usage: "service-broker-list",
		Desc:  `List service brokers.`,
	}
}

func (c *BrokerList) Run(ctx *cmd.Context, cli *cmd.Client) error {
	apiClient, err := client.ClientFromEnvironment(&tsuru.Configuration{
		HTTPClient: cli.HTTPClient,
	})
	if err != nil {
		return err
	}
	brokerList, _, err := apiClient.ServiceApi.ServiceBrokerList(context.TODO())
	if err != nil {
		return err
	}
	tbl := tablecli.Table{
		Headers:       tablecli.Row{"Name", "URL", "Insecure", "Auth", "Context"},
		LineSeparator: true,
	}
	for _, b := range brokerList.Brokers {
		authMethod := "None"
		if b.Config.AuthConfig != nil {
			if b.Config.AuthConfig.BasicAuthConfig != nil {
				authMethod = "Basic\n"
			} else if b.Config.AuthConfig.BearerConfig != nil {
				authMethod = "Bearer\n"
			}
		}
		var contexts []string
		for k, v := range b.Config.Context {
			contexts = append(contexts, fmt.Sprintf("%v: %v", k, v))
		}
		sort.Strings(contexts)
		tbl.AddRow(tablecli.Row{
			b.Name,
			b.URL,
			strconv.FormatBool(b.Config.Insecure),
			authMethod,
			strings.Join(contexts, "\n"),
		})
	}
	fmt.Fprint(ctx.Stdout, tbl.String())
	return nil
}

func flagsForServiceBroker(broker *tsuru.ServiceBroker) *gnuflag.FlagSet {
	fs := gnuflag.NewFlagSet("", gnuflag.ExitOnError)

	if broker.Config == nil {
		broker.Config = &tsuru.ServiceBrokerConfig{
			AuthConfig: &tsuru.ServiceBrokerConfigAuthConfig{
				BasicAuthConfig: &tsuru.ServiceBrokerConfigAuthConfigBasicAuthConfig{},
				BearerConfig:    &tsuru.ServiceBrokerConfigAuthConfigBearerConfig{},
			},
		}
	}

	insecure := "Ignore TLS errors in the broker request."
	fs.BoolVar(&broker.Config.Insecure, "insecure", false, insecure)
	fs.BoolVar(&broker.Config.Insecure, "i", false, insecure)

	context := "Context values to be sent on every broker request."
	fs.Var(cmd.MapFlagWrapper{Dst: &broker.Config.Context}, "context", context)
	fs.Var(cmd.MapFlagWrapper{Dst: &broker.Config.Context}, "c", context)

	pass := "Service broker authentication password."
	fs.StringVar(&broker.Config.AuthConfig.BasicAuthConfig.Password, "password", "", pass)
	fs.StringVar(&broker.Config.AuthConfig.BasicAuthConfig.Password, "p", "", pass)

	user := "Service broker authentication username."
	fs.StringVar(&broker.Config.AuthConfig.BasicAuthConfig.Username, "user", "", user)
	fs.StringVar(&broker.Config.AuthConfig.BasicAuthConfig.Username, "u", "", user)

	token := "Service broker authentication token."
	fs.StringVar(&broker.Config.AuthConfig.BearerConfig.Token, "token", "", token)
	fs.StringVar(&broker.Config.AuthConfig.BearerConfig.Token, "t", "", token)

	return fs
}
<commit_msg>admin: fix service broker update doc<commit_after>package admin

import (
	"context"
	"fmt"
	"sort"
	"strconv"
	"strings"

	"github.com/tsuru/gnuflag"
	"github.com/tsuru/go-tsuruclient/pkg/client"
	"github.com/tsuru/go-tsuruclient/pkg/tsuru"
	"github.com/tsuru/tablecli"
	"github.com/tsuru/tsuru/cmd"
)

type BrokerAdd struct {
	broker tsuru.ServiceBroker
	fs     *gnuflag.FlagSet
}

func (c *BrokerAdd) Info() *cmd.Info {
	return &cmd.Info{
		Name:    "service-broker-add",
		Usage:   "service-broker-add <name> <url> [-i/--insecure] [-c/--context key=value] [-t/--token token] [-u/--user username] [-p/--password password]",
		Desc:    `Adds a new Service Broker.`,
		MinArgs: 2,
	}
}

func (c *BrokerAdd) Flags() *gnuflag.FlagSet {
	if c.fs == nil {
		c.fs = flagsForServiceBroker(&c.broker)
	}
	return c.fs
}

func (c *BrokerAdd) Run(ctx *cmd.Context, cli *cmd.Client) error {
	apiClient, err := client.ClientFromEnvironment(&tsuru.Configuration{
		HTTPClient: cli.HTTPClient,
	})
	if err != nil {
		return err
	}
	c.broker.Name, c.broker.URL = ctx.Args[0], ctx.Args[1]
	_, err = apiClient.ServiceApi.ServiceBrokerCreate(context.TODO(), c.broker)
	if err != nil {
		return err
	}
	fmt.Fprintln(ctx.Stdout, "Service broker successfully added.")
	return nil
}

type BrokerUpdate struct {
	broker tsuru.ServiceBroker
	fs     *gnuflag.FlagSet
}

func (c *BrokerUpdate) Info() *cmd.Info {
	return &cmd.Info{
		Name:    "service-broker-update",
		Usage:   "service-broker-update <name> <url> [-i/--insecure] [-c/--context key=value] [-t/--token token] [-u/--user username] [-p/--password password]",
		Desc:    `Updates a service broker.`,
		MinArgs: 2,
	}
}

func (c *BrokerUpdate) Flags() *gnuflag.FlagSet {
	if c.fs == nil {
		c.fs = flagsForServiceBroker(&c.broker)
	}
	return c.fs
}

func (c *BrokerUpdate) Run(ctx *cmd.Context, cli *cmd.Client) error {
	apiClient, err := client.ClientFromEnvironment(&tsuru.Configuration{
		HTTPClient: cli.HTTPClient,
	})
	if err != nil {
		return err
	}
	c.broker.Name, c.broker.URL = ctx.Args[0], ctx.Args[1]
	_, err = apiClient.ServiceApi.ServiceBrokerUpdate(context.TODO(), c.broker.Name, c.broker)
	if err != nil {
		return err
	}
	fmt.Fprintln(ctx.Stdout, "Service broker successfully updated.")
	return nil
}

type BrokerDelete struct{}

func (c *BrokerDelete) Info() *cmd.Info {
	return &cmd.Info{
		Name:    "service-broker-delete",
		Usage:   "service-broker-delete <name>",
		Desc:    `Removes a service broker.`,
		MinArgs: 1,
	}
}

func (c *BrokerDelete) Run(ctx *cmd.Context, cli *cmd.Client) error {
	apiClient, err := client.ClientFromEnvironment(&tsuru.Configuration{
		HTTPClient: cli.HTTPClient,
	})
	if err != nil {
		return err
	}
	_, err = apiClient.ServiceApi.ServiceBrokerDelete(context.TODO(), ctx.Args[0])
	if err != nil {
		return err
	}
	fmt.Fprintln(ctx.Stdout, "Service broker successfully deleted.")
	return nil
}

type BrokerList struct{}

func (c *BrokerList) Info() *cmd.Info {
	return &cmd.Info{
		Name:  "service-broker-list",
		Usage: "service-broker-list",
		Desc:  `List service brokers.`,
	}
}

func (c *BrokerList) Run(ctx *cmd.Context, cli *cmd.Client) error {
	apiClient, err := client.ClientFromEnvironment(&tsuru.Configuration{
		HTTPClient: cli.HTTPClient,
	})
	if err != nil {
		return err
	}
	brokerList, _, err := apiClient.ServiceApi.ServiceBrokerList(context.TODO())
	if err != nil {
		return err
	}
	tbl := tablecli.Table{
		Headers:       tablecli.Row{"Name", "URL", "Insecure", "Auth", "Context"},
		LineSeparator: true,
	}
	for _, b := range brokerList.Brokers {
		authMethod := "None"
		if b.Config.AuthConfig != nil {
			if b.Config.AuthConfig.BasicAuthConfig != nil {
				authMethod = "Basic\n"
			} else if b.Config.AuthConfig.BearerConfig != nil {
				authMethod = "Bearer\n"
			}
		}
		var contexts []string
		for k, v := range b.Config.Context {
			contexts = append(contexts, fmt.Sprintf("%v: %v", k, v))
		}
		sort.Strings(contexts)
		tbl.AddRow(tablecli.Row{
			b.Name,
			b.URL,
			strconv.FormatBool(b.Config.Insecure),
			authMethod,
			strings.Join(contexts, "\n"),
		})
	}
	fmt.Fprint(ctx.Stdout, tbl.String())
	return nil
}

func flagsForServiceBroker(broker *tsuru.ServiceBroker) *gnuflag.FlagSet {
	fs := gnuflag.NewFlagSet("", gnuflag.ExitOnError)

	if broker.Config == nil {
		broker.Config = &tsuru.ServiceBrokerConfig{
			AuthConfig: &tsuru.ServiceBrokerConfigAuthConfig{
				BasicAuthConfig: &tsuru.ServiceBrokerConfigAuthConfigBasicAuthConfig{},
				BearerConfig:    &tsuru.ServiceBrokerConfigAuthConfigBearerConfig{},
			},
		}
	}

	insecure := "Ignore TLS errors in the broker request."
	fs.BoolVar(&broker.Config.Insecure, "insecure", false, insecure)
	fs.BoolVar(&broker.Config.Insecure, "i", false, insecure)

	context := "Context values to be sent on every broker request."
	fs.Var(cmd.MapFlagWrapper{Dst: &broker.Config.Context}, "context", context)
	fs.Var(cmd.MapFlagWrapper{Dst: &broker.Config.Context}, "c", context)

	pass := "Service broker authentication password."
	fs.StringVar(&broker.Config.AuthConfig.BasicAuthConfig.Password, "password", "", pass)
	fs.StringVar(&broker.Config.AuthConfig.BasicAuthConfig.Password, "p", "", pass)

	user := "Service broker authentication username."
	fs.StringVar(&broker.Config.AuthConfig.BasicAuthConfig.Username, "user", "", user)
	fs.StringVar(&broker.Config.AuthConfig.BasicAuthConfig.Username, "u", "", user)

	token := "Service broker authentication token."
	fs.StringVar(&broker.Config.AuthConfig.BearerConfig.Token, "token", "", token)
	fs.StringVar(&broker.Config.AuthConfig.BearerConfig.Token, "t", "", token)

	return fs
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"log"
	"net"

	"telnet"
)

const (
	QUIT = iota
	MOTD = iota
	USER = iota
	PASS = iota
	EXEC = iota
	ENAB = iota
	CONF = iota
)

type TelnetClient struct {
	rd      *bufio.Reader
	wr      *bufio.Writer
	userOut chan string // outputLoop: read from userOut and write into wr
	quit    chan int
	status  int
}

type Command struct {
	client *TelnetClient
	line   string
}

var cmdInput = make(chan Command)

func inputLoop(client *TelnetClient) {
	//loop:
	//	- read from rd and feed into cli interpreter
	//	- watch idle timeout
	//	- watch quitInput channel

	scanner := bufio.NewScanner(client.rd)
	for scanner.Scan() {
		line := scanner.Text()
		log.Printf("inputLoop: [%v]", line)
		cmdInput <- Command{client, line}
	}

	if err := scanner.Err(); err != nil {
		log.Printf("inputLoop: %v", err)
	}

	log.Printf("inputLoop: exiting")
}

func outputLoop(client *TelnetClient) {
	//loop:
	//	- read from userOut channel and write into wr
	//	- watch quitOutput channel

LOOP:
	for {
		select {
		case msg := <-client.userOut:
			if n, err := client.wr.WriteString(msg); err != nil {
				log.Printf("outputLoop: written=%d from=%d: %v", n, len(msg), err)
			}
			if err := client.wr.Flush(); err != nil {
				log.Printf("outputLoop: flush: %v", err)
			}
		case _, ok := <-client.quit:
			if !ok {
				break LOOP
			}
		}
	}

	log.Printf("outputLoop: exiting")
}

func handleTelnet(conn net.Conn) {
	defer conn.Close()

	log.Printf("new telnet connection from: %s", conn.RemoteAddr())

	rd, wr := bufio.NewReader(conn), bufio.NewWriter(conn)

	client := TelnetClient{rd, wr, make(chan string), make(chan int), MOTD}

	defer close(client.userOut)

	cmdInput <- Command{&client, ""} // mock user input

	go inputLoop(&client)

	outputLoop(&client)
}

func listenTelnet(addr string) {
	telnetServer := telnet.Server{Addr: addr, Handler: handleTelnet}

	log.Printf("serving telnet on TCP %s", addr)

	if err := telnetServer.ListenAndServe(); err != nil {
		log.Fatalf("telnet server on address %s: error: %s", addr, err)
	}
}
<commit_msg>Skeleton for telnet commands.<commit_after>package main

import (
	"bufio"
	"log"
	"net"

	"telnet"
)

const (
	cmdWill = 251
	cmdWont = 252
	cmdDo   = 253
	cmdDont = 254
	cmdIAC  = 255
)

const (
	optEcho           = 1
	optSupressGoAhead = 3
	optLinemode       = 34
)

const (
	QUIT = iota
	MOTD = iota
	USER = iota
	PASS = iota
	EXEC = iota
	ENAB = iota
	CONF = iota
)

type TelnetClient struct {
	//rd      *bufio.Reader
	conn       net.Conn
	wr         *bufio.Writer
	userOut    chan string // outputLoop: read from userOut and write into wr
	quit       chan int
	status     int
	serverEcho bool
}

type Command struct {
	client *TelnetClient
	line   string
}

var cmdInput = make(chan Command)

func inputLoop(client *TelnetClient) {
	//loop:
	//	- read from rd and feed into cli interpreter
	//	- watch idle timeout
	//	- watch quitInput channel

	/*
		scanner := bufio.NewScanner(client.rd)
		for scanner.Scan() {
			line := scanner.Text()
			log.Printf("inputLoop: [%v]", line)
			cmdInput <- Command{client, line}
		}

		if err := scanner.Err(); err != nil {
			log.Printf("inputLoop: %v", err)
		}
	*/

	iac := false
	opt := false
	buf := [30]byte{} // underlying buffer
	line := buf[:0] // position at underlying buffer
	input := make([]byte, 10) // last input

	for {
		rd, err := client.conn.Read(input)
		if err != nil {
			log.Printf("inputLoop: net.Read: %v", err)
			break
		}
		curr := input[:rd]
		log.Printf("inputLoop: read len=%d [%s]", rd, curr)

		for _, b := range curr {
			if iac {
				// consume telnet commands
				if opt {
					opt = false
				} else {
					switch b {
					case cmdWill, cmdWont, cmdDo, cmdDont:
						opt = true
					}
				}
			} else {
				if b == cmdIAC {
					iac = true
				} else {
					// push non-commands bytes into line buffer
					line = append(buf[:len(line)], b)
				}
			}
		}

		log.Printf("inputLoop: buf len=%d [%s]", len(line), line)
	}

	log.Printf("inputLoop: exiting")
}

func outputLoop(client *TelnetClient) {
	//loop:
	//	- read from userOut channel and write into wr
	//	- watch quitOutput channel

LOOP:
	for {
		select {
		case msg := <-client.userOut:
			if n, err := client.wr.WriteString(msg); err != nil {
				log.Printf("outputLoop: written=%d from=%d: %v", n, len(msg), err)
			}
			if err := client.wr.Flush(); err != nil {
				log.Printf("outputLoop: flush: %v", err)
			}
		case _, ok := <-client.quit:
			if !ok {
				break LOOP
			}
		}
	}

	log.Printf("outputLoop: exiting")
}

func charMode(conn net.Conn) {
	cmd := []byte{cmdIAC, cmdWill, optEcho, cmdIAC, cmdWill, optSupressGoAhead, cmdIAC, cmdDont, optLinemode}

	wr, err := conn.Write(cmd)

	log.Printf("charMode: len=%d err=%v", wr, err)
}

func handleTelnet(conn net.Conn) {
	defer conn.Close()

	log.Printf("new telnet connection from: %s", conn.RemoteAddr())

	//rd, wr := bufio.NewReader(conn), bufio.NewWriter(conn)

	charMode(conn)

	client := TelnetClient{conn, bufio.NewWriter(conn), make(chan string), make(chan int), MOTD, true}

	defer close(client.userOut)

	cmdInput <- Command{&client, ""} // mock user input

	go inputLoop(&client)

	outputLoop(&client)
}

func listenTelnet(addr string) {
	telnetServer := telnet.Server{Addr: addr, Handler: handleTelnet}

	log.Printf("serving telnet on TCP %s", addr)

	if err := telnetServer.ListenAndServe(); err != nil {
		log.Fatalf("telnet server on address %s: error: %s", addr, err)
	}
}
<|endoftext|>


<commit_before>package gamedayapi

import (
	"reflect"
	"testing"
	//	"log"
)

func GameForTest() *Game {
	game, _ := GameFor("sea", "2014-06-22")
	return game
}

func assertEquals(t *testing.T, a interface{}, b interface{}) {
	if !reflect.DeepEqual(a, b) {
		t.Errorf("'%+v' != '%+v'", a, b)
	}
}

func TestFetchableDataDirectory(t *testing.T) {
	game := GameForTest()
	assertEquals(t, game.FetchableDataDirectory(), "/components/game/mlb/year_2014/month_06/day_22/gid_2014_06_22_seamlb_kcamlb_1")
}

func TestAtBatsOnInning(t *testing.T) {
	game := GameForTest()
	inning := game.AllInnings().Innings[0]
	atBatTotal := len(inning.Top.AtBats) + len(inning.Bottom.AtBats)
	assertEquals(t, len(inning.AtBats()), atBatTotal)
}

func TestDoubleheaders(t *testing.T) {
	games, _ := GamesFor("sea", "2014-05-07")
	assertEquals(t, len(games), 2)
	assertEquals(t, games[0].Gameday, "2014_05_07_seamlb_oakmlb_1")
	assertEquals(t, games[1].Gameday, "2014_05_07_seamlb_oakmlb_2")
}
<commit_msg>Test fixes for date changes.<commit_after>package gamedayapi

import (
	"reflect"
	"testing"
	"time"
)

func GameForTest() *Game {
	date, _ := time.Parse("2006-01-02", "2014-06-22")
	game, _ := GameFor("sea", date)
	return game
}

func assertEquals(t *testing.T, a interface{}, b interface{}) {
	if !reflect.DeepEqual(a, b) {
		t.Errorf("'%+v' != '%+v'", a, b)
	}
}

func TestFetchableDataDirectory(t *testing.T) {
	game := GameForTest()
	assertEquals(t, game.FetchableDataDirectory(), "/components/game/mlb/year_2014/month_06/day_22/gid_2014_06_22_seamlb_kcamlb_1")
}

func TestAtBatsOnInning(t *testing.T) {
	game := GameForTest()
	inning := game.AllInnings().Innings[0]
	atBatTotal := len(inning.Top.AtBats) + len(inning.Bottom.AtBats)
	assertEquals(t, len(inning.AtBats()), atBatTotal)
}

func TestDoubleheaders(t *testing.T) {
	date, _ := time.Parse("2006-01-02", "2014-05-07")
	games, _ := GamesFor("sea", date)
	assertEquals(t, len(games), 2)
	assertEquals(t, games[0].Gameday, "2014_05_07_seamlb_oakmlb_1")
	assertEquals(t, games[1].Gameday, "2014_05_07_seamlb_oakmlb_2")
}
<|endoftext|>


<commit_before>package gateway

import (
	"encoding/json"
	"log"
	"net/http"

	"github.com/ant0ine/go-json-rest/rest"
	"github.com/boltdb/bolt"
	"github.com/docker/libcontainer/netlink"
)

const (
	routesBucket = "routes"
	defaultKey   = "default"
)

var db *bolt.DB

type Gateway struct {
	IP   string `json:"ip"`
	Link string `json:"link"`
}

func PostGateway(w rest.ResponseWriter, req *rest.Request) {
	gateway := Gateway{}
	if err := req.DecodeJsonPayload(&gateway); err != nil {
		log.Printf(err.Error())
		rest.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	db.Update(func(tx *bolt.Tx) (err error) {
		b := tx.Bucket([]byte(routesBucket))
		data, err := json.Marshal(gateway)
		if err != nil {
			return
		}
		err = b.Put([]byte(defaultKey), []byte(data))
		return
	})

	if err := netlink.AddDefaultGw(gateway.IP, gateway.Link); err != nil {
		log.Printf(err.Error())
		rest.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.WriteJson(gateway)
}

func DBinit(d *bolt.DB) (err error) {
	db = d
	err = db.Update(func(tx *bolt.Tx) (err error) {
		_, err = tx.CreateBucketIfNotExists([]byte(routesBucket))
		return
	})
	if err != nil {
		return err
	}

	log.Printf("Reinstall previous gateway from DB")
	err = db.View(func(tx *bolt.Tx) (err error) {
		b := tx.Bucket([]byte(routesBucket))
		gateway := Gateway{}
		v := b.Get([]byte(defaultKey))
		if v != nil {
			if err := json.Unmarshal(v, &gateway); err != nil {
				log.Printf(err.Error())
			}
			if err := netlink.AddDefaultGw(gateway.IP, gateway.Link); err != nil {
				log.Printf(err.Error())
			}
		}
		return
	})
	return
}
<commit_msg>Adding default gw by invoking /sbin/route<commit_after>package gateway

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os/exec"
	"strings"

	"github.com/ant0ine/go-json-rest/rest"
	"github.com/boltdb/bolt"
)

const (
	routesBucket = "routes"
	defaultKey   = "default"
)

var db *bolt.DB

type Gateway struct {
	IP   string `json:"ip"`
	Link string `json:"link"`
}

func PostGateway(w rest.ResponseWriter, req *rest.Request) {
	gateway := Gateway{}
	if err := req.DecodeJsonPayload(&gateway); err != nil {
		log.Printf(err.Error())
		rest.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	db.Update(func(tx *bolt.Tx) (err error) {
		b := tx.Bucket([]byte(routesBucket))
		data, err := json.Marshal(gateway)
		if err != nil {
			return
		}
		err = b.Put([]byte(defaultKey), []byte(data))
		return
	})

	if err := addDefaultGw(gateway.IP, gateway.Link); err != nil {
		log.Printf(err.Error())
		rest.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.WriteJson(gateway)
}

func DBinit(d *bolt.DB) (err error) {
	db = d
	err = db.Update(func(tx *bolt.Tx) (err error) {
		_, err = tx.CreateBucketIfNotExists([]byte(routesBucket))
		return
	})
	if err != nil {
		return err
	}

	log.Printf("Reinstall previous gateway from DB")
	err = db.View(func(tx *bolt.Tx) (err error) {
		b := tx.Bucket([]byte(routesBucket))
		gateway := Gateway{}
		v := b.Get([]byte(defaultKey))
		if v != nil {
			if err := json.Unmarshal(v, &gateway); err != nil {
				log.Printf(err.Error())
			}
			if err := addDefaultGw(gateway.IP, gateway.Link); err != nil {
				log.Printf(err.Error())
			}
		}
		return
	})
	return
}

func addDefaultGw(ip string, linkName string) (err error) {
	err = exec.Command("sh", "-c", fmt.Sprintf("/sbin/route add default gw %s %s", ip, linkName)).Run()
	if err != nil && !strings.Contains(err.Error(), "exit status 7") {
		log.Printf(err.Error())
		return err
	}
	return nil
}
<|endoftext|>


<commit_before>package gateways

import (
	"fmt"

	"github.com/stripe/stripe-go"
	"github.com/stripe/stripe-go/client"

	"github.com/ghmeier/bloodlines/config"
	"github.com/ghmeier/coinage/models"
	tmodels "github.com/jakelong95/TownCenter/models"
	item "github.com/lcollin/warehouse/models"
)

/*Stripe wraps the stripe-go api for coinage use*/
type Stripe interface {
	NewCustomer(token string, userID string) (string, error)
	GetCustomer(id string) (*stripe.Customer, error)
	DeleteCustomer(id string) error
	AddSource(id string, token string) (*stripe.Customer, error)
	NewAccount(user *tmodels.User, roaster *tmodels.Roaster) (*stripe.Account, error)
	NewPlan(secret string, item *item.Item, freq models.Frequency) (*stripe.Plan, error)
	GetPlan(secret string, pid string) (*stripe.Plan, error)
	Subscribe(id string, planID string) (*stripe.Sub, error)
}

type stripeS struct {
	config config.Stripe
	c      *client.API
}

/*NewStripe initializes and returns a new Stripe implementation configured
  by the provided config*/
func NewStripe(config config.Stripe) Stripe {
	s := &stripeS{
		config: config,
		c:      client.New(config.Secret, nil),
	}

	return s
}

func (s *stripeS) NewCustomer(token string, userID string) (string, error) {
	params := &stripe.CustomerParams{
		Desc: fmt.Sprintf("Customer for user: %s", userID),
	}

	params.SetSource(token)
	c, err := s.c.Customers.New(params)
	if err != nil {
		return "", err
	}
	return c.ID, err
}

/*GetCustomer returns a stripe customer by their cutsomerID*/
func (s *stripeS) GetCustomer(id string) (*stripe.Customer, error) {
	c, err := s.c.Customers.Get(id, nil)
	if err != nil {
		return nil, err
	}

	return c, nil
}

/*DeleteCustomer removes customer from stripe by customer id*/
func (s *stripeS) DeleteCustomer(id string) error {
	_, err := s.c.Customers.Del(id)
	return err
}

/*AddSource creates and adds a new Default Source for the customer*/
func (s *stripeS) AddSource(id string, token string) (*stripe.Customer, error) {
	params := &stripe.CustomerParams{
		Source: &stripe.SourceParams{Token: token},
	}

	c, err := s.c.Customers.Update(id, params)
	if err != nil {
		return nil, err
	}

	return c, nil
}

func (s *stripeS) NewAccount(user *tmodels.User, roaster *tmodels.Roaster) (*stripe.Account, error) {
	params := &stripe.AccountParams{
		Managed:      true,
		Country:      "US",
		Email:        roaster.Email,
		BusinessName: roaster.Name,
		LegalEntity: &stripe.LegalEntity{
			BusinessName: roaster.Name,
			Address: stripe.Address{
				City:    roaster.AddressCity,
				Country: "US",
				Line1:   roaster.AddressLine1,
				Line2:   roaster.AddressLine2,
				Zip:     roaster.AddressZip,
				State:   roaster.AddressState,
			},
			PersonalAddress: stripe.Address{
				City:    user.AddressCity,
				Country: "US",
				Line1:   user.AddressLine1,
				Line2:   user.AddressLine2,
				Zip:     user.AddressZip,
				State:   user.AddressState,
			},
			First:       user.FirstName,
			Last:        user.LastName,
			PhoneNumber: roaster.Phone,
			Type:        "company",
		},
	}

	account, err := s.c.Account.New(params)
	if err != nil {
		return nil, err
	}

	return account, nil
}

func (s *stripeS) NewPlan(secret string, item *item.Item, freq models.Frequency) (*stripe.Plan, error) {
	interval, ok := models.ToFrequency(freq)
	if !ok {
		return nil, fmt.Errorf("ERROR: no frequency for interval %s", freq)
	}

	client := client.New(secret, nil)
	params := &stripe.PlanParams{
		ID:            fmt.Sprintf("%s-%s", item.ID.String(), string(freq)),
		Amount:        uint64(item.ConsumerPrice * 100),
		Currency:      "usd",
		Interval:      "week",
		IntervalCount: uint64(interval),
		Name:          fmt.Sprintf("%s %s", item.Name, string(freq)),
		Statement:     fmt.Sprintf("Expresso %s", item.Name),
	}
	params.AddMeta("itemId", item.ID.String())
	plan, err := client.Plans.New(params)

	if err != nil {
		return nil, err
	}

	return plan, nil
}

func (s *stripeS) GetPlan(secret string, pid string) (*stripe.Plan, error) {
	client := client.New(secret, nil)
	plan, err := client.Plans.Get(pid, nil)
	if err != nil {
		return nil, err
	}

	return plan, nil
}

func (s *stripeS) Subscribe(id string, planID string) (*stripe.Sub, error) {
	sub, err := s.c.Subs.New(&stripe.SubParams{Customer: id, Plan: planID})
	if err != nil {
		return nil, err
	}

	return sub, nil
}
<commit_msg>Set max length for plan names<commit_after>package gateways

import (
	"fmt"
	"strings"

	"github.com/stripe/stripe-go"
	"github.com/stripe/stripe-go/client"

	"github.com/ghmeier/bloodlines/config"
	"github.com/ghmeier/coinage/models"
	tmodels "github.com/jakelong95/TownCenter/models"
	item "github.com/lcollin/warehouse/models"
)

/*Stripe wraps the stripe-go api for coinage use*/
type Stripe interface {
	NewCustomer(token string, userID string) (string, error)
	GetCustomer(id string) (*stripe.Customer, error)
	DeleteCustomer(id string) error
	AddSource(id string, token string) (*stripe.Customer, error)
	NewAccount(user *tmodels.User, roaster *tmodels.Roaster) (*stripe.Account, error)
	NewPlan(secret string, item *item.Item, freq models.Frequency) (*stripe.Plan, error)
	GetPlan(secret string, pid string) (*stripe.Plan, error)
	Subscribe(id string, planID string) (*stripe.Sub, error)
}

type stripeS struct {
	config config.Stripe
	c      *client.API
}

/*NewStripe initializes and returns a new Stripe implementation configured
  by the provided config*/
func NewStripe(config config.Stripe) Stripe {
	s := &stripeS{
		config: config,
		c:      client.New(config.Secret, nil),
	}

	return s
}

func (s *stripeS) NewCustomer(token string, userID string) (string, error) {
	params := &stripe.CustomerParams{
		Desc: fmt.Sprintf("Customer for user: %s", userID),
	}

	params.SetSource(token)
	c, err := s.c.Customers.New(params)
	if err != nil {
		return "", err
	}
	return c.ID, err
}

/*GetCustomer returns a stripe customer by their cutsomerID*/
func (s *stripeS) GetCustomer(id string) (*stripe.Customer, error) {
	c, err := s.c.Customers.Get(id, nil)
	if err != nil {
		return nil, err
	}

	return c, nil
}

/*DeleteCustomer removes customer from stripe by customer id*/
func (s *stripeS) DeleteCustomer(id string) error {
	_, err := s.c.Customers.Del(id)
	return err
}

/*AddSource creates and adds a new Default Source for the customer*/
func (s *stripeS) AddSource(id string, token string) (*stripe.Customer, error) {
	params := &stripe.CustomerParams{
		Source: &stripe.SourceParams{Token: token},
	}

	c, err := s.c.Customers.Update(id, params)
	if err != nil {
		return nil, err
	}

	return c, nil
}

func (s *stripeS) NewAccount(user *tmodels.User, roaster *tmodels.Roaster) (*stripe.Account, error) {
	params := &stripe.AccountParams{
		Managed:      true,
		Country:      "US",
		Email:        roaster.Email,
		BusinessName: roaster.Name,
		LegalEntity: &stripe.LegalEntity{
			BusinessName: roaster.Name,
			Address: stripe.Address{
				City:    roaster.AddressCity,
				Country: "US",
				Line1:   roaster.AddressLine1,
				Line2:   roaster.AddressLine2,
				Zip:     roaster.AddressZip,
				State:   roaster.AddressState,
			},
			PersonalAddress: stripe.Address{
				City:    user.AddressCity,
				Country: "US",
				Line1:   user.AddressLine1,
				Line2:   user.AddressLine2,
				Zip:     user.AddressZip,
				State:   user.AddressState,
			},
			First:       user.FirstName,
			Last:        user.LastName,
			PhoneNumber: roaster.Phone,
			Type:        "company",
		},
	}

	account, err := s.c.Account.New(params)
	if err != nil {
		return nil, err
	}

	return account, nil
}

func (s *stripeS) NewPlan(secret string, item *item.Item, freq models.Frequency) (*stripe.Plan, error) {
	interval, ok := models.ToFrequency(freq)
	if !ok {
		return nil, fmt.Errorf("ERROR: no frequency for interval %s", freq)
	}

	client := client.New(secret, nil)
	params := &stripe.PlanParams{
		ID:            fmt.Sprintf("%s-%s", item.ID.String(), string(freq)),
		Amount:        uint64(item.ConsumerPrice * 100),
		Currency:      "usd",
		Interval:      "week",
		IntervalCount: uint64(interval),
		Name:          fmt.Sprintf("%s %s", item.Name, string(freq)),
		Statement:     strings.fmt.Sprintf("exp-%18s", item.Name),
	}
	params.AddMeta("itemId", item.ID.String())
	plan, err := client.Plans.New(params)

	if err != nil {
		return nil, err
	}

	return plan, nil
}

func (s *stripeS) GetPlan(secret string, pid string) (*stripe.Plan, error) {
	client := client.New(secret, nil)
	plan, err := client.Plans.Get(pid, nil)
	if err != nil {
		return nil, err
	}

	return plan, nil
}

func (s *stripeS) Subscribe(id string, planID string) (*stripe.Sub, error) {
	sub, err := s.c.Subs.New(&stripe.SubParams{Customer: id, Plan: planID})
	if err != nil {
		return nil, err
	}

	return sub, nil
}
<|endoftext|>


<commit_before>// Copyright 2015 PLUMgrid
//
// 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 gbp

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"os/exec"
	"strings"
	"syscall"
	"testing"
	"time"

	"github.com/iovisor/iomodules/hive"
	"github.com/vishvananda/netlink"
)

var testPolicy string = `
{
  "resolved-policies": {
    "resolved-policy": [
      {
        "consumer-tenant-id": "pepsi",
        "consumer-epg-id": "client",
        "provider-tenant-id": "pepsi",
        "provider-epg-id": "web",
        "policy-rule-group-with-endpoint-constraints": [
          {
            "policy-rule-group": [
              {
                "tenant-id": "pepsi",
                "contract-id": "web-client",
                "subject-name": "icmp-subject",
                "resolved-rule": [
                  {
                    "name": "allow-icmp-rule",
                    "classifier": [
                      {
                        "name": "icmp",
                        "parameter-value": [
                          {
                            "name": "proto",
                            "int-value": 1
                          }
                        ],
                        "classifier-definition-id": "ip-proto"
                      }
                    ],
                    "order": 0,
                    "action": [
                      {
                        "name": "allow1",
                        "order": 0,
                        "action-definition-id": "allow"
                      }
                    ]
                  }
                ]
              },
              {
                "tenant-id": "pepsi",
                "contract-id": "web-client",
                "subject-name": "http-subject",
                "resolved-rule": [
                  {
                    "name": "http-chain-rule-in",
                    "classifier": [
                      {
                        "name": "http-dest",
                        "parameter-value": [
                          {
                            "name": "destport",
                            "int-value": 80
                          },
                          {
                            "name": "proto",
                            "int-value": 6
                          }
                        ],
                        "direction": "in",
                        "classifier-definition-id": "4250ab32-e8b8-445a-aebb-e1bd2cdd291f"
                      }
                    ],
                    "order": 0,
                    "action": [
                      {
                        "name": "chain1",
                        "parameter-value": [
                          {
                            "name": "sfc-chain-name",
                            "string-value": "SFCGBP"
                          }
                        ],
                        "order": 0,
                        "action-definition-id": "3d886be7-059f-4c4f-bbef-0356bea40933"
                      }
                    ]
                  },
                  {
                    "name": "http-chain-rule-out",
                    "classifier": [
                      {
                        "name": "http-src",
                        "parameter-value": [
                          {
                            "name": "proto",
                            "int-value": 6
                          },
                          {
                            "name": "sourceport",
                            "int-value": 80
                          }
                        ],
                        "direction": "out",
                        "classifier-definition-id": "4250ab32-e8b8-445a-aebb-e1bd2cdd291f"
                      }
                    ],
                    "order": 1,
                    "action": [
                      {
                        "name": "chain1",
                        "parameter-value": [
                          {
                            "name": "sfc-chain-name",
                            "string-value": "SFCGBP"
                          }
                        ],
                        "order": 0,
                        "action-definition-id": "3d886be7-059f-4c4f-bbef-0356bea40933"
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
}
`

type testCase struct {
	url  string    // url of the request
	body io.Reader // body of the request
	code int       // expected pass criteria
}

func TestBasicPolicy(t *testing.T) {
	srv := httptest.NewServer(NewServer())
	defer srv.Close()
	testValues := []testCase{
		{
			url:  srv.URL + "/policies/",
			body: strings.NewReader(testPolicy),
			code: http.StatusOK,
		},
	}
	for _, test := range testValues {
		testOne(t, test, nil)
	}
}

var dockerSetup string = `
images=(gliderlabs/alpine moutten/iperf)
for i in ${images[@]}; do
  [[ $(docker images -q $i) != "" ]] || docker pull $i
done
`

func runCommand(cmd string, input io.Reader) (out string, err error) {
	cmds := strings.Split(cmd, " ")
	c := exec.Command(cmds[0], cmds[1:]...)
	if input != nil {
		c.Stdin = input
	}
	var outbuf, errbuf bytes.Buffer
	c.Stdout, c.Stderr = &outbuf, &errbuf
	err = c.Run()
	if err != nil {
		Error.Print(errbuf.String())
		return
	}
	out = strings.TrimSpace(outbuf.String())
	return
}

func runTestCommand(t *testing.T, cmd string, input io.Reader) string {
	out, err := runCommand(cmd, input)
	if err != nil {
		t.Error(err)
	}
	return out
}

// gatherLinks listens for netlink notifications and collects the list of links
// created during the subscription window.
func gatherLinks(ch <-chan netlink.LinkUpdate) ([]netlink.Link, error) {
	linkSet := make(map[int32]bool)
	timeout := time.After(500 * time.Millisecond)
	Debug.Printf("Waiting for link updates\n")
outer:
	for {
		select {
		case update := <-ch:
			if update.Header.Type == syscall.RTM_NEWLINK {
				if _, ok := update.Link.(*netlink.Veth); ok {
					Debug.Printf("NEWLINK %d\n", update.Index)
					linkSet[update.Index] = true
				}
			} else if update.Header.Type == syscall.RTM_DELLINK {
				Debug.Printf("DELLINK %d\n", update.Index)
				delete(linkSet, update.Index)
			}
		case <-timeout:
			break outer
		}
	}
	links := []netlink.Link{}
	for index, _ := range linkSet {
		l, err := netlink.LinkByIndex(int(index))
		if err == nil {
			links = append(links, l)
		}

	}
	return links, nil
}

func gatherOneLink(t *testing.T, ch <-chan netlink.LinkUpdate) netlink.Link {
	links, err := gatherLinks(ch)
	if err != nil {
		t.Fatal(err)
	}
	if len(links) != 1 {
		t.Fatalf("could not determine veth belonging to container (len == %d)", len(links))
	}
	return links[0]
}

func TestInterfaces(t *testing.T) {
	hive := httptest.NewServer(hive.NewServer())
	defer hive.Close()
	if err := dataplane.Init(hive.URL); err != nil {
		t.Fatal(err)
	}
	srv := httptest.NewServer(NewServer())
	defer srv.Close()

	// launch one policy dataplane
	testOne(t, testCase{
		url:  srv.URL + "/policies/",
		body: strings.NewReader(testPolicy),
		code: http.StatusOK,
	}, nil)

	// set up docker prereqs
	runTestCommand(t, "bash -ex", strings.NewReader(dockerSetup))

	// monitor for netlink updates to find docker veth
	ch, done := make(chan netlink.LinkUpdate), make(chan struct{})
	defer close(done)
	if err := netlink.LinkSubscribe(ch, done); err != nil {
		t.Error(err)
	}

	id1, id2 := "TestInterfaces-1", "TestInterfaces-2"
	// spawn one test server process
	runTestCommand(t, "docker run --name="+id1+" -d moutten/iperf", nil)
	defer runCommand("docker rm -f "+id1, nil)

	link1 := gatherOneLink(t, ch)
	testOne(t, testCase{
		url: hive.URL + "/links/",
		body: strings.NewReader(fmt.Sprintf(
			`{"modules": ["host", "%s"], "interfaces": ["%s", ""]}`,
			dataplane.Id(), link1.Attrs().Name)),
		code: http.StatusOK,
	}, nil)

	// find the ip of the test server
	ip1 := runTestCommand(t, "docker inspect -f {{.NetworkSettings.IPAddress}} "+id1, nil)

	// start a test client
	c := exec.Command("docker", "run", "-i", "--name="+id2, "--entrypoint", "/bin/sh", "moutten/iperf", "-ex")
	var inPipe *io.PipeWriter
	var out bytes.Buffer
	c.Stdin, inPipe = io.Pipe()
	c.Stdout, c.Stderr = &out, &out
	if err := c.Start(); err != nil {
		t.Fatal(err)
	}
	defer runCommand("docker rm -f "+id2, nil)

	link2 := gatherOneLink(t, ch)
	testOne(t, testCase{
		url: hive.URL + "/links/",
		body: strings.NewReader(fmt.Sprintf(
			`{"modules": ["host", "%s"], "interfaces": ["%s", ""]}`,
			dataplane.Id(), link2.Attrs().Name)),
		code: http.StatusOK,
	}, nil)

	inPipe.Write([]byte("iperf -t 2 -c " + ip1 + "\n"))
	inPipe.Close()
	Debug.Println("waiting for command to exit")
	err := c.Wait()
	Debug.Println("done waiting for command to exit")
	if err != nil {
		Error.Print(out.String())
		t.Fatal(err)
	}
	Debug.Print(out.String())
}

func testOne(t *testing.T, test testCase, rsp interface{}) {
	client := &http.Client{}

	resp, err := client.Post(test.url, "application/json", test.body)
	if err != nil {
		panic(err)
	}
	body, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()
	if err != nil {
		t.Error(err)
	}
	if resp.StatusCode != test.code {
		t.Errorf("Expected %d, got %d", test.code, resp.StatusCode)
	}
	if rsp != nil {
		if err := json.Unmarshal(body, rsp); err != nil {
			t.Error(err)
		}
	}
}
<commit_msg>Clean up command syntax in gbp test<commit_after>// Copyright 2015 PLUMgrid
//
// 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 gbp

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"os/exec"
	"strings"
	"syscall"
	"testing"
	"time"

	"github.com/iovisor/iomodules/hive"
	"github.com/vishvananda/netlink"
)

var testPolicy string = `
{
  "resolved-policies": {
    "resolved-policy": [
      {
        "consumer-tenant-id": "pepsi",
        "consumer-epg-id": "client",
        "provider-tenant-id": "pepsi",
        "provider-epg-id": "web",
        "policy-rule-group-with-endpoint-constraints": [
          {
            "policy-rule-group": [
              {
                "tenant-id": "pepsi",
                "contract-id": "web-client",
                "subject-name": "icmp-subject",
                "resolved-rule": [
                  {
                    "name": "allow-icmp-rule",
                    "classifier": [
                      {
                        "name": "icmp",
                        "parameter-value": [
                          {
                            "name": "proto",
                            "int-value": 1
                          }
                        ],
                        "classifier-definition-id": "ip-proto"
                      }
                    ],
                    "order": 0,
                    "action": [
                      {
                        "name": "allow1",
                        "order": 0,
                        "action-definition-id": "allow"
                      }
                    ]
                  }
                ]
              },
              {
                "tenant-id": "pepsi",
                "contract-id": "web-client",
                "subject-name": "http-subject",
                "resolved-rule": [
                  {
                    "name": "http-chain-rule-in",
                    "classifier": [
                      {
                        "name": "http-dest",
                        "parameter-value": [
                          {
                            "name": "destport",
                            "int-value": 80
                          },
                          {
                            "name": "proto",
                            "int-value": 6
                          }
                        ],
                        "direction": "in",
                        "classifier-definition-id": "4250ab32-e8b8-445a-aebb-e1bd2cdd291f"
                      }
                    ],
                    "order": 0,
                    "action": [
                      {
                        "name": "chain1",
                        "parameter-value": [
                          {
                            "name": "sfc-chain-name",
                            "string-value": "SFCGBP"
                          }
                        ],
                        "order": 0,
                        "action-definition-id": "3d886be7-059f-4c4f-bbef-0356bea40933"
                      }
                    ]
                  },
                  {
                    "name": "http-chain-rule-out",
                    "classifier": [
                      {
                        "name": "http-src",
                        "parameter-value": [
                          {
                            "name": "proto",
                            "int-value": 6
                          },
                          {
                            "name": "sourceport",
                            "int-value": 80
                          }
                        ],
                        "direction": "out",
                        "classifier-definition-id": "4250ab32-e8b8-445a-aebb-e1bd2cdd291f"
                      }
                    ],
                    "order": 1,
                    "action": [
                      {
                        "name": "chain1",
                        "parameter-value": [
                          {
                            "name": "sfc-chain-name",
                            "string-value": "SFCGBP"
                          }
                        ],
                        "order": 0,
                        "action-definition-id": "3d886be7-059f-4c4f-bbef-0356bea40933"
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
}
`

type testCase struct {
	url  string    // url of the request
	body io.Reader // body of the request
	code int       // expected pass criteria
}

func TestBasicPolicy(t *testing.T) {
	srv := httptest.NewServer(NewServer())
	defer srv.Close()
	testValues := []testCase{
		{
			url:  srv.URL + "/policies/",
			body: strings.NewReader(testPolicy),
			code: http.StatusOK,
		},
	}
	for _, test := range testValues {
		testOne(t, test, nil)
	}
}

var dockerSetup string = `
images=(gliderlabs/alpine moutten/iperf)
for i in ${images[@]}; do
  [[ $(docker images -q $i) != "" ]] || docker pull $i
done
`

func runCommand(cmd string, input io.Reader) (out string, err error) {
	cmds := strings.Split(cmd, " ")
	c := exec.Command(cmds[0], cmds[1:]...)
	if input != nil {
		c.Stdin = input
	}
	var outbuf, errbuf bytes.Buffer
	c.Stdout, c.Stderr = &outbuf, &errbuf
	err = c.Run()
	if err != nil {
		Error.Print(errbuf.String())
		return
	}
	out = strings.TrimSpace(outbuf.String())
	return
}

func startCommand(t *testing.T, cmd string) (*exec.Cmd, *io.PipeWriter, *bytes.Buffer) {
	out := &bytes.Buffer{}
	rpipe, wpipe := io.Pipe()
	cmds := strings.Split(cmd, " ")
	c := exec.Command(cmds[0], cmds[1:]...)
	c.Stdin, c.Stdout, c.Stderr = rpipe, out, out
	err := c.Start()
	if err != nil {
		t.Fatal(err)
	}
	return c, wpipe, out
}

func runTestCommand(t *testing.T, cmd string, input io.Reader) string {
	out, err := runCommand(cmd, input)
	if err != nil {
		t.Fatal(err)
	}
	return out
}

// gatherLinks listens for netlink notifications and collects the list of links
// created during the subscription window.
func gatherLinks(ch <-chan netlink.LinkUpdate) ([]netlink.Link, error) {
	linkSet := make(map[int32]bool)
	timeout := time.After(500 * time.Millisecond)
	Debug.Printf("Waiting for link updates\n")
outer:
	for {
		select {
		case update := <-ch:
			if update.Header.Type == syscall.RTM_NEWLINK {
				if _, ok := update.Link.(*netlink.Veth); ok {
					linkSet[update.Index] = true
				}
			} else if update.Header.Type == syscall.RTM_DELLINK {
				delete(linkSet, update.Index)
			}
		case <-timeout:
			break outer
		}
	}
	links := []netlink.Link{}
	for index, _ := range linkSet {
		l, err := netlink.LinkByIndex(int(index))
		if err == nil {
			links = append(links, l)
		}

	}
	return links, nil
}

func gatherOneLink(t *testing.T, ch <-chan netlink.LinkUpdate) netlink.Link {
	links, err := gatherLinks(ch)
	if err != nil {
		t.Fatal(err)
	}
	if len(links) != 1 {
		t.Fatalf("could not determine veth belonging to container (len == %d)", len(links))
	}
	return links[0]
}

func TestInterfaces(t *testing.T) {
	hive := httptest.NewServer(hive.NewServer())
	defer hive.Close()
	if err := dataplane.Init(hive.URL); err != nil {
		t.Fatal(err)
	}
	srv := httptest.NewServer(NewServer())
	defer srv.Close()

	// launch one policy dataplane
	testOne(t, testCase{
		url:  srv.URL + "/policies/",
		body: strings.NewReader(testPolicy),
		code: http.StatusOK,
	}, nil)

	// set up docker prereqs
	runTestCommand(t, "bash -ex", strings.NewReader(dockerSetup))

	// monitor for netlink updates to find docker veth
	ch, done := make(chan netlink.LinkUpdate), make(chan struct{})
	defer close(done)
	if err := netlink.LinkSubscribe(ch, done); err != nil {
		t.Error(err)
	}

	id1, id2 := "TestInterfaces-1", "TestInterfaces-2"
	// spawn one test server process
	runTestCommand(t, "docker run --name="+id1+" -d moutten/iperf", nil)
	defer runCommand("docker rm -f "+id1, nil)

	link1 := gatherOneLink(t, ch)
	testOne(t, testCase{
		url: hive.URL + "/links/",
		body: strings.NewReader(fmt.Sprintf(
			`{"modules": ["host", "%s"], "interfaces": ["%s", ""]}`,
			dataplane.Id(), link1.Attrs().Name)),
		code: http.StatusOK,
	}, nil)

	// find the ip of the test server
	ip1 := runTestCommand(t, "docker inspect -f {{.NetworkSettings.IPAddress}} "+id1, nil)

	// start a test client
	clientCmd, clientStdin, clientOutput := startCommand(t, "docker run -i --name="+id2+" --entrypoint /bin/sh moutten/iperf -ex")
	defer runCommand("docker rm -f "+id2, nil)

	link2 := gatherOneLink(t, ch)

	ip2 := runTestCommand(t, "docker inspect -f {{.NetworkSettings.IPAddress}} "+id2, nil)
	Debug.Printf("ip2=%s\n", ip2)

	testOne(t, testCase{
		url: hive.URL + "/links/",
		body: strings.NewReader(fmt.Sprintf(
			`{"modules": ["host", "%s"], "interfaces": ["%s", ""]}`,
			dataplane.Id(), link2.Attrs().Name)),
		code: http.StatusOK,
	}, nil)

	clientStdin.Write([]byte("iperf -t 2 -c " + ip1 + "\n"))
	clientStdin.Close()
	if err := clientCmd.Wait(); err != nil {
		Error.Print(clientOutput.String())
		t.Fatal(err)
	}
	Debug.Print(clientOutput.String())
}

func testOne(t *testing.T, test testCase, rsp interface{}) {
	client := &http.Client{}

	resp, err := client.Post(test.url, "application/json", test.body)
	if err != nil {
		panic(err)
	}
	body, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()
	if err != nil {
		t.Error(err)
	}
	if resp.StatusCode != test.code {
		t.Errorf("Expected %d, got %d", test.code, resp.StatusCode)
	}
	if rsp != nil {
		if err := json.Unmarshal(body, rsp); err != nil {
			t.Error(err)
		}
	}
}
<|endoftext|>