<commit_before>package TriUI

import (
	"strconv"
	"strings"
	"trident.li/keyval"
	pf "trident.li/pitchfork/lib"
	pu "trident.li/pitchfork/ui"
	tr "trident.li/trident/src/lib"
)

func h_group_member(cui pu.PfUI) {
	path := cui.GetPath()

	if len(path) != 0 && path[0] != "" {
		pu.H_group_member_profile(cui)
		return
	}

	var err error

	tctx := tr.TriGetCtx(cui)
	total := 0
	offset := 0

	offset_v, err := cui.FormValue("offset")
	if err == nil && offset_v != "" {
		offset, _ = strconv.Atoi(offset_v)
	}

	search, err := cui.FormValue("search")
	if err != nil {
		search = ""
	}

	grp := tctx.TriSelectedGroup()

	total, err = grp.ListGroupMembersTot(search)
	if err != nil {
		cui.Err("error: " + err.Error())
		return
	}

	members, err := grp.ListGroupMembers(search, cui.TheUser().GetUserName(), offset, 10, false, cui.IAmGroupAdmin(), false)
	if err != nil {
		cui.Err(err.Error())
		return
	}

	/* Output the page */
	type Page struct {
		*pu.PfPage
		Group        pf.PfGroup
		GroupMembers []pf.PfGroupMember
		PagerOffset  int
		PagerTotal   int
		Search       string
		IsAdmin      bool
	}
	isadmin := cui.IAmGroupAdmin()

	p := Page{cui.Page_def(), grp, members, offset, total, search, isadmin}
	cui.Page_show("group/members.tmpl", p)
}

type NominateAdd struct {
	group        tr.TriGroup
	Action       string          `label:"Action" pftype:"hidden"`
	Vouchee      string          `label:"Username" pfset:"nobody" pfget:"none"`
	Comment      string          `label:"Vouch comment" pftype:"text" hint:"Vouch description for this user" pfreq:"yes"`
	Attestations map[string]bool `label:"Attestations (all required)" hint:"Attestations for this user" options:"GetAttestationOpts" pfcheckboxmode:"yes"`
	Button       string          `label:"Nominate" pftype:"submit"`
	Message      string          /* Used by pfform() */
	Error        string          /* Used by pfform() */
}

func (na *NominateAdd) GetAttestationOpts(obj interface{}) (kvs keyval.KeyVals, err error) {
	return na.group.GetAttestationsKVS()
}

func h_group_nominate_existing(cui pu.PfUI) {
	msg := ""
	errmsg := ""
	tctx := tr.TriGetCtx(cui)
	grp := tctx.TriSelectedGroup()

	vouchee_name, err := cui.FormValue("vouchee")
	if err != nil {
		pu.H_errtxt(cui, "No valid vouchee")
		return
	}

	err = tctx.SelectVouchee(vouchee_name, pu.PERM_USER_NOMINATE)
	if err != nil {
		pu.H_errtxt(cui, "Vouchee unselectable")
		return
	}

	if cui.IsPOST() {
		action, err := cui.FormValue("action")
		if err == nil && action == "nominate" {
			msg, err = vouch_nominate(cui)
			if err != nil {
				errmsg = err.Error()
			}
		}
	}

	vouchee := tctx.SelectedVouchee()

	type Page struct {
		*pu.PfPage
		Vouchee     string
		GroupName   string
		NominateAdd *NominateAdd
	}

	na := &NominateAdd{group: grp, Vouchee: vouchee.GetUserName(), Action: "nominate", Message: msg, Error: errmsg}

	p := Page{cui.Page_def(), vouchee.GetUserName(), grp.GetGroupName(), na}
	cui.Page_show("group/nominate_existing.tmpl", p)
}

type NominateNew struct {
	group        tr.TriGroup
	Action       string          `label:"Action" pftype:"hidden"`
	Search       string          `label:"Search" pftype:"hidden"`
	Email        string          `label:"Email address of nominee" pfset:"none"`
	FullName     string          `label:"Full Name" hint:"Full Name of this user" pfreq:"yes"`
	Affiliation  string          `label:"Affiliation" hint:"Who the user is affiliated to" pfreq:"yes"`
	Biography    string          `label:"Biography" pftype:"text" hint:"Biography for this user" pfreq:"yes"`
	Comment      string          `label:"Vouch Comment" pftype:"text" hint:"Vouch for this user" pfreq:"yes"`
	Attestations map[string]bool `label:"Attestations (all required)" hint:"Attestations for this user" options:"GetAttestationOpts" pfcheckboxmode:"yes"`
	Button       string          `label:"Nominate" pftype:"submit"`
	Message      string          /* Used by pfform() */
	Error        string          /* Used by pfform() */
}

func (na *NominateNew) GetAttestationOpts(obj interface{}) (kvs keyval.KeyVals, err error) {
	return na.group.GetAttestationsKVS()
}

func h_group_nominate(cui pu.PfUI) {
	var msg string
	var err error
	var errmsg string
	var list []pf.PfUser
	var search string

	tctx := tr.TriGetCtx(cui)
	user := tctx.TriSelectedUser()
	grp := tctx.TriSelectedGroup()
	added = false

	/* Something posted? */
	if cui.IsPOST() {
		/* An action to perform? */
		action, err := cui.FormValue("action")
		if err == nil && action == "nominate" {
			msg, err = vouch_nominate_new(cui)
			if err != nil {
				errmsg += err.Error()
			}
			added = true
		}

		/* Search field? */
		search, err = cui.FormValue("search")
		if err != nil {
			search = ""
		}

		/* Simple 'is there an @ sign, it must be an email address' check */
		if strings.Index(search, "@") == -1 {
			/* Not an email, do not allow searching */
			search = ""
		}
	}

	/* Need to search the list? */
	notfound := true
	if search != "" {
		/* Get list of users matching the given search query */
		list, err = user.GetList(cui, search, 0, 0, true)
		if err != nil {
			cui.Errf("Listing users failed: %s", err.Error())
			pu.H_error(cui, pu.StatusBadRequest)
			return
		}

		if len(list) != 0 {
			notfound = false
		}
	}

	type Page struct {
		*pu.PfPage
		Search    string
		GroupName string
		Users     []pf.PfUser
		NotFound  bool
		NewForm   *NominateNew
	}

	if added {
		notfound = true
	}

	/* Re-fill in the form (for people who do not enable the attestations) */
	descr, _ := cui.FormValue("fullname")
	affil, _ := cui.FormValue("affiliation")
	bio, _ := cui.FormValue("biography")
	comment, _ := cui.FormValue("comment")

	newform := &NominateNew{group: grp, Action: "nominate", Email: search, Message: msg, Error: errmsg, Search: search, FullName: descr, Affiliation: affil, Biography: bio, Comment: comment}

	p := Page{cui.Page_def(), search, grp.GetGroupName(), list, notfound, newform}
	cui.Page_show("group/nominate.tmpl", p)
}

func h_vouches_csv(cui pu.PfUI) {
	grp := cui.SelectedGroup()

	vouches, err := tr.Vouches_Get(cui, grp.GetGroupName())
	if err != nil {
		pu.H_errmsg(cui, err)
		return
	}

	csv := ""

	for _, v := range vouches {
		csv += v.Vouchor + "," + v.Vouchee + "," + v.Entered.Format(pf.Config.DateFormat) + "\n"
	}

	fname := grp.GetGroupName() + ".csv"

	cui.SetContentType("text/vcard")
	cui.SetFileName(fname)
	cui.SetExpires(60)
	cui.SetRaw([]byte(csv))
	return
}

func h_vouches(cui pu.PfUI) {
	fmt := cui.GetArg("format")

	if fmt == "csv" {
		h_vouches_csv(cui)
		return
	}

	grp := cui.SelectedGroup()
	vouches, err := tr.Vouches_Get(cui, grp.GetGroupName())
	if err != nil {
		pu.H_errmsg(cui, err)
		return
	}

	/* Output the page */
	type Page struct {
		*pu.PfPage
		Vouches []tr.Vouch
	}

	p := Page{cui.Page_def(), vouches}
	cui.Page_show("group/vouches.tmpl", p)
}

func h_group(cui pu.PfUI, menu *pu.PfUIMenu) {
	menu.Replace("member", h_group_member)

	m := []pu.PfUIMentry{
		{"nominate", "Nominate", pf.PERM_GROUP_MEMBER, h_group_nominate, nil},
		{"nominate_existing", "Nominate existing user", pf.PERM_GROUP_MEMBER | pf.PERM_HIDDEN, h_group_nominate_existing, nil},
		{"vouches", "Vouches", pf.PERM_GROUP_MEMBER, h_vouches, nil},
		{"vcp", "Vouching Control Panel", pf.PERM_GROUP_MEMBER, h_group_vcp, nil},
	}

	menu.Add(m...)
}
<commit_msg>Forgot a colon<commit_after>package TriUI

import (
	"strconv"
	"strings"
	"trident.li/keyval"
	pf "trident.li/pitchfork/lib"
	pu "trident.li/pitchfork/ui"
	tr "trident.li/trident/src/lib"
)

func h_group_member(cui pu.PfUI) {
	path := cui.GetPath()

	if len(path) != 0 && path[0] != "" {
		pu.H_group_member_profile(cui)
		return
	}

	var err error

	tctx := tr.TriGetCtx(cui)
	total := 0
	offset := 0

	offset_v, err := cui.FormValue("offset")
	if err == nil && offset_v != "" {
		offset, _ = strconv.Atoi(offset_v)
	}

	search, err := cui.FormValue("search")
	if err != nil {
		search = ""
	}

	grp := tctx.TriSelectedGroup()

	total, err = grp.ListGroupMembersTot(search)
	if err != nil {
		cui.Err("error: " + err.Error())
		return
	}

	members, err := grp.ListGroupMembers(search, cui.TheUser().GetUserName(), offset, 10, false, cui.IAmGroupAdmin(), false)
	if err != nil {
		cui.Err(err.Error())
		return
	}

	/* Output the page */
	type Page struct {
		*pu.PfPage
		Group        pf.PfGroup
		GroupMembers []pf.PfGroupMember
		PagerOffset  int
		PagerTotal   int
		Search       string
		IsAdmin      bool
	}
	isadmin := cui.IAmGroupAdmin()

	p := Page{cui.Page_def(), grp, members, offset, total, search, isadmin}
	cui.Page_show("group/members.tmpl", p)
}

type NominateAdd struct {
	group        tr.TriGroup
	Action       string          `label:"Action" pftype:"hidden"`
	Vouchee      string          `label:"Username" pfset:"nobody" pfget:"none"`
	Comment      string          `label:"Vouch comment" pftype:"text" hint:"Vouch description for this user" pfreq:"yes"`
	Attestations map[string]bool `label:"Attestations (all required)" hint:"Attestations for this user" options:"GetAttestationOpts" pfcheckboxmode:"yes"`
	Button       string          `label:"Nominate" pftype:"submit"`
	Message      string          /* Used by pfform() */
	Error        string          /* Used by pfform() */
}

func (na *NominateAdd) GetAttestationOpts(obj interface{}) (kvs keyval.KeyVals, err error) {
	return na.group.GetAttestationsKVS()
}

func h_group_nominate_existing(cui pu.PfUI) {
	msg := ""
	errmsg := ""
	tctx := tr.TriGetCtx(cui)
	grp := tctx.TriSelectedGroup()

	vouchee_name, err := cui.FormValue("vouchee")
	if err != nil {
		pu.H_errtxt(cui, "No valid vouchee")
		return
	}

	err = tctx.SelectVouchee(vouchee_name, pu.PERM_USER_NOMINATE)
	if err != nil {
		pu.H_errtxt(cui, "Vouchee unselectable")
		return
	}

	if cui.IsPOST() {
		action, err := cui.FormValue("action")
		if err == nil && action == "nominate" {
			msg, err = vouch_nominate(cui)
			if err != nil {
				errmsg = err.Error()
			}
		}
	}

	vouchee := tctx.SelectedVouchee()

	type Page struct {
		*pu.PfPage
		Vouchee     string
		GroupName   string
		NominateAdd *NominateAdd
	}

	na := &NominateAdd{group: grp, Vouchee: vouchee.GetUserName(), Action: "nominate", Message: msg, Error: errmsg}

	p := Page{cui.Page_def(), vouchee.GetUserName(), grp.GetGroupName(), na}
	cui.Page_show("group/nominate_existing.tmpl", p)
}

type NominateNew struct {
	group        tr.TriGroup
	Action       string          `label:"Action" pftype:"hidden"`
	Search       string          `label:"Search" pftype:"hidden"`
	Email        string          `label:"Email address of nominee" pfset:"none"`
	FullName     string          `label:"Full Name" hint:"Full Name of this user" pfreq:"yes"`
	Affiliation  string          `label:"Affiliation" hint:"Who the user is affiliated to" pfreq:"yes"`
	Biography    string          `label:"Biography" pftype:"text" hint:"Biography for this user" pfreq:"yes"`
	Comment      string          `label:"Vouch Comment" pftype:"text" hint:"Vouch for this user" pfreq:"yes"`
	Attestations map[string]bool `label:"Attestations (all required)" hint:"Attestations for this user" options:"GetAttestationOpts" pfcheckboxmode:"yes"`
	Button       string          `label:"Nominate" pftype:"submit"`
	Message      string          /* Used by pfform() */
	Error        string          /* Used by pfform() */
}

func (na *NominateNew) GetAttestationOpts(obj interface{}) (kvs keyval.KeyVals, err error) {
	return na.group.GetAttestationsKVS()
}

func h_group_nominate(cui pu.PfUI) {
	var msg string
	var err error
	var errmsg string
	var list []pf.PfUser
	var search string

	tctx := tr.TriGetCtx(cui)
	user := tctx.TriSelectedUser()
	grp := tctx.TriSelectedGroup()
	added := false

	/* Something posted? */
	if cui.IsPOST() {
		/* An action to perform? */
		action, err := cui.FormValue("action")
		if err == nil && action == "nominate" {
			msg, err = vouch_nominate_new(cui)
			if err != nil {
				errmsg += err.Error()
			}
			added = true
		}

		/* Search field? */
		search, err = cui.FormValue("search")
		if err != nil {
			search = ""
		}

		/* Simple 'is there an @ sign, it must be an email address' check */
		if strings.Index(search, "@") == -1 {
			/* Not an email, do not allow searching */
			search = ""
		}
	}

	/* Need to search the list? */
	notfound := true
	if search != "" {
		/* Get list of users matching the given search query */
		list, err = user.GetList(cui, search, 0, 0, true)
		if err != nil {
			cui.Errf("Listing users failed: %s", err.Error())
			pu.H_error(cui, pu.StatusBadRequest)
			return
		}

		if len(list) != 0 {
			notfound = false
		}
	}

	type Page struct {
		*pu.PfPage
		Search    string
		GroupName string
		Users     []pf.PfUser
		NotFound  bool
		NewForm   *NominateNew
	}

	if added {
		notfound = true
	}

	/* Re-fill in the form (for people who do not enable the attestations) */
	descr, _ := cui.FormValue("fullname")
	affil, _ := cui.FormValue("affiliation")
	bio, _ := cui.FormValue("biography")
	comment, _ := cui.FormValue("comment")

	newform := &NominateNew{group: grp, Action: "nominate", Email: search, Message: msg, Error: errmsg, Search: search, FullName: descr, Affiliation: affil, Biography: bio, Comment: comment}

	p := Page{cui.Page_def(), search, grp.GetGroupName(), list, notfound, newform}
	cui.Page_show("group/nominate.tmpl", p)
}

func h_vouches_csv(cui pu.PfUI) {
	grp := cui.SelectedGroup()

	vouches, err := tr.Vouches_Get(cui, grp.GetGroupName())
	if err != nil {
		pu.H_errmsg(cui, err)
		return
	}

	csv := ""

	for _, v := range vouches {
		csv += v.Vouchor + "," + v.Vouchee + "," + v.Entered.Format(pf.Config.DateFormat) + "\n"
	}

	fname := grp.GetGroupName() + ".csv"

	cui.SetContentType("text/vcard")
	cui.SetFileName(fname)
	cui.SetExpires(60)
	cui.SetRaw([]byte(csv))
	return
}

func h_vouches(cui pu.PfUI) {
	fmt := cui.GetArg("format")

	if fmt == "csv" {
		h_vouches_csv(cui)
		return
	}

	grp := cui.SelectedGroup()
	vouches, err := tr.Vouches_Get(cui, grp.GetGroupName())
	if err != nil {
		pu.H_errmsg(cui, err)
		return
	}

	/* Output the page */
	type Page struct {
		*pu.PfPage
		Vouches []tr.Vouch
	}

	p := Page{cui.Page_def(), vouches}
	cui.Page_show("group/vouches.tmpl", p)
}

func h_group(cui pu.PfUI, menu *pu.PfUIMenu) {
	menu.Replace("member", h_group_member)

	m := []pu.PfUIMentry{
		{"nominate", "Nominate", pf.PERM_GROUP_MEMBER, h_group_nominate, nil},
		{"nominate_existing", "Nominate existing user", pf.PERM_GROUP_MEMBER | pf.PERM_HIDDEN, h_group_nominate_existing, nil},
		{"vouches", "Vouches", pf.PERM_GROUP_MEMBER, h_vouches, nil},
		{"vcp", "Vouching Control Panel", pf.PERM_GROUP_MEMBER, h_group_vcp, nil},
	}

	menu.Add(m...)
}
<|endoftext|>


<commit_before>package epictest

import (
	"bytes"
	"fmt"
	"io"
	"math"
	"os"
	"testing"
	"time"

	context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
	"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-random"
	blockservice "github.com/jbenet/go-ipfs/blockservice"
	bitswap "github.com/jbenet/go-ipfs/exchange/bitswap"
	tn "github.com/jbenet/go-ipfs/exchange/bitswap/testnet"
	importer "github.com/jbenet/go-ipfs/importer"
	chunk "github.com/jbenet/go-ipfs/importer/chunk"
	merkledag "github.com/jbenet/go-ipfs/merkledag"
	mocknet "github.com/jbenet/go-ipfs/net/mock"
	path "github.com/jbenet/go-ipfs/path"
	mockrouting "github.com/jbenet/go-ipfs/routing/mock"
	uio "github.com/jbenet/go-ipfs/unixfs/io"
	util "github.com/jbenet/go-ipfs/util"
	errors "github.com/jbenet/go-ipfs/util/debugerror"
)

const kSeed = 1

func Test1KBInstantaneous(t *testing.T) {
	conf := Config{
		NetworkLatency:    0,
		RoutingLatency:    0,
		BlockstoreLatency: 0,
	}

	if err := AddCatBytes(RandomBytes(1*KB), conf); err != nil {
		t.Fatal(err)
	}
}

func TestDegenerateSlowBlockstore(t *testing.T) {
	SkipUnlessEpic(t)
	conf := Config{BlockstoreLatency: 50 * time.Millisecond}
	if err := AddCatPowers(conf, 128); err != nil {
		t.Fatal(err)
	}
}

func TestDegenerateSlowNetwork(t *testing.T) {
	SkipUnlessEpic(t)
	conf := Config{NetworkLatency: 400 * time.Millisecond}
	if err := AddCatPowers(conf, 128); err != nil {
		t.Fatal(err)
	}
}

func TestDegenerateSlowRouting(t *testing.T) {
	SkipUnlessEpic(t)
	conf := Config{RoutingLatency: 400 * time.Millisecond}
	if err := AddCatPowers(conf, 128); err != nil {
		t.Fatal(err)
	}
}

func Test100MBMacbookCoastToCoast(t *testing.T) {
	SkipUnlessEpic(t)
	conf := Config{}.Network_NYtoSF().Blockstore_SlowSSD2014().Routing_Slow()
	if err := AddCatBytes(RandomBytes(100*1024*1024), conf); err != nil {
		t.Fatal(err)
	}
}

func AddCatPowers(conf Config, megabytesMax int64) error {
	var i int64
	for i = 1; i < megabytesMax; i = i * 2 {
		fmt.Printf("%d MB\n", i)
		if err := AddCatBytes(RandomBytes(i*1024*1024), conf); err != nil {
			return err
		}
	}
	return nil
}

func RandomBytes(n int64) []byte {
	var data bytes.Buffer
	random.WritePseudoRandomBytes(n, &data, kSeed)
	return data.Bytes()
}

func AddCatBytes(data []byte, conf Config) error {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	mn := mocknet.New(ctx)
	// defer mn.Close() FIXME does mocknet require clean-up
	mn.SetLinkDefaults(mocknet.LinkOptions{
		Latency:   conf.NetworkLatency,
		// TODO add to conf. This is tricky because we want 0 values to be functional.
		Bandwidth: math.MaxInt32,
	})
	dhtNetwork := mockrouting.NewDHTNetwork(mn)
	net, err := tn.StreamNet(ctx, mn, dhtNetwork)
	if err != nil {
		return errors.Wrap(err)
	}
	sessionGenerator := bitswap.NewSessionGenerator(net)
	defer sessionGenerator.Close()

	adder := sessionGenerator.Next()
	catter := sessionGenerator.Next()
	// catter.Routing.Update(context.TODO(), adder.Peer)

	peers := mn.Peers()
	if len(peers) != 2 {
		return errors.New("peers not in network")
	}

	for _, i := range peers {
		for _, j := range peers {
			if i == j {
				continue
			}
			if _, err := mn.LinkPeers(i, j); err != nil {
				return err
			}
			if err := mn.ConnectPeers(i, j); err != nil {
				return err
			}
		}
	}

	catter.SetBlockstoreLatency(conf.BlockstoreLatency)

	adder.SetBlockstoreLatency(0) // disable blockstore latency during add operation
	keyAdded, err := add(adder, bytes.NewReader(data))
	if err != nil {
		return err
	}
	adder.SetBlockstoreLatency(conf.BlockstoreLatency) // add some blockstore delay to make the catter wait

	readerCatted, err := cat(catter, keyAdded)
	if err != nil {
		return err
	}

	// verify
	var bufout bytes.Buffer
	io.Copy(&bufout, readerCatted)
	if 0 != bytes.Compare(bufout.Bytes(), data) {
		return errors.New("catted data does not match added data")
	}
	return nil
}

func cat(catter bitswap.Instance, k util.Key) (io.Reader, error) {
	catterdag := merkledag.NewDAGService(&blockservice.BlockService{catter.Blockstore(), catter.Exchange})
	nodeCatted, err := (&path.Resolver{catterdag}).ResolvePath(k.String())
	if err != nil {
		return nil, err
	}
	return uio.NewDagReader(nodeCatted, catterdag)
}

func add(adder bitswap.Instance, r io.Reader) (util.Key, error) {
	nodeAdded, err := importer.BuildDagFromReader(
		r,
		merkledag.NewDAGService(&blockservice.BlockService{adder.Blockstore(), adder.Exchange}),
		nil,
		chunk.DefaultSplitter,
	)
	if err != nil {
		return "", err
	}
	return nodeAdded.Key()
}

func SkipUnlessEpic(t *testing.T) {
	if os.Getenv("IPFS_EPIC_TEST") == "" {
		t.SkipNow()
	}
}
<commit_msg>use raw primitives<commit_after>package epictest

import (
	"bytes"
	"fmt"
	"io"
	"math"
	"os"
	"testing"
	"time"

	context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
	datastore "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore"
	sync "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore/sync"
	random "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-random"
	blockstore "github.com/jbenet/go-ipfs/blocks/blockstore"
	blockservice "github.com/jbenet/go-ipfs/blockservice"
	exchange "github.com/jbenet/go-ipfs/exchange"
	bitswap "github.com/jbenet/go-ipfs/exchange/bitswap"
	bsnet "github.com/jbenet/go-ipfs/exchange/bitswap/network"
	importer "github.com/jbenet/go-ipfs/importer"
	chunk "github.com/jbenet/go-ipfs/importer/chunk"
	merkledag "github.com/jbenet/go-ipfs/merkledag"
	net "github.com/jbenet/go-ipfs/net"
	mocknet "github.com/jbenet/go-ipfs/net/mock"
	path "github.com/jbenet/go-ipfs/path"
	peer "github.com/jbenet/go-ipfs/peer"
	dht "github.com/jbenet/go-ipfs/routing/dht"
	uio "github.com/jbenet/go-ipfs/unixfs/io"
	util "github.com/jbenet/go-ipfs/util"
	"github.com/jbenet/go-ipfs/util/datastore2"
	errors "github.com/jbenet/go-ipfs/util/debugerror"
	delay "github.com/jbenet/go-ipfs/util/delay"
)

const kSeed = 1

func Test1KBInstantaneous(t *testing.T) {
	conf := Config{
		NetworkLatency:    0,
		RoutingLatency:    0,
		BlockstoreLatency: 0,
	}

	if err := AddCatBytes(RandomBytes(100*MB), conf); err != nil {
		t.Fatal(err)
	}
}

func TestDegenerateSlowBlockstore(t *testing.T) {
	SkipUnlessEpic(t)
	conf := Config{BlockstoreLatency: 50 * time.Millisecond}
	if err := AddCatPowers(conf, 128); err != nil {
		t.Fatal(err)
	}
}

func TestDegenerateSlowNetwork(t *testing.T) {
	SkipUnlessEpic(t)
	conf := Config{NetworkLatency: 400 * time.Millisecond}
	if err := AddCatPowers(conf, 128); err != nil {
		t.Fatal(err)
	}
}

func TestDegenerateSlowRouting(t *testing.T) {
	SkipUnlessEpic(t)
	conf := Config{RoutingLatency: 400 * time.Millisecond}
	if err := AddCatPowers(conf, 128); err != nil {
		t.Fatal(err)
	}
}

func Test100MBMacbookCoastToCoast(t *testing.T) {
	SkipUnlessEpic(t)
	conf := Config{}.Network_NYtoSF().Blockstore_SlowSSD2014().Routing_Slow()
	if err := AddCatBytes(RandomBytes(100*1024*1024), conf); err != nil {
		t.Fatal(err)
	}
}

func AddCatPowers(conf Config, megabytesMax int64) error {
	var i int64
	for i = 1; i < megabytesMax; i = i * 2 {
		fmt.Printf("%d MB\n", i)
		if err := AddCatBytes(RandomBytes(i*1024*1024), conf); err != nil {
			return err
		}
	}
	return nil
}

func RandomBytes(n int64) []byte {
	var data bytes.Buffer
	random.WritePseudoRandomBytes(n, &data, kSeed)
	return data.Bytes()
}

type instance struct {
	ID             peer.ID
	Network        net.Network
	Blockstore     blockstore.Blockstore
	Datastore      datastore.ThreadSafeDatastore
	DHT            *dht.IpfsDHT
	Exchange       exchange.Interface
	BitSwapNetwork bsnet.BitSwapNetwork

	datastoreDelay delay.D
}

func AddCatBytes(data []byte, conf Config) error {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	const numPeers = 2
	instances := make(map[peer.ID]*instance, numPeers)

	// create network
	mn, err := mocknet.FullMeshLinked(ctx, numPeers)
	if err != nil {
		return errors.Wrap(err)
	}
	mn.SetLinkDefaults(mocknet.LinkOptions{
		Latency: conf.NetworkLatency,
		// TODO add to conf. This is tricky because we want 0 values to be functional.
		Bandwidth: math.MaxInt32,
	})
	for _, p := range mn.Peers() {
		instances[p] = &instance{
			ID:      p,
			Network: mn.Net(p),
		}
	}

	// create dht network
	for _, p := range mn.Peers() {
		dsDelay := delay.Fixed(conf.BlockstoreLatency)
		instances[p].Datastore = sync.MutexWrap(datastore2.WithDelay(datastore.NewMapDatastore(), dsDelay))
		instances[p].datastoreDelay = dsDelay
	}
	for _, p := range mn.Peers() {
		instances[p].DHT = dht.NewDHT(ctx, p, instances[p].Network, instances[p].Datastore)
	}
	// create two bitswap network clients
	for _, p := range mn.Peers() {
		instances[p].BitSwapNetwork = bsnet.NewFromIpfsNetwork(instances[p].Network, instances[p].DHT)
	}
	for _, p := range mn.Peers() {
		const kWriteCacheElems = 100
		const alwaysSendToPeer = true
		adapter := instances[p].BitSwapNetwork
		dstore := instances[p].Datastore
		instances[p].Blockstore, err = blockstore.WriteCached(blockstore.NewBlockstore(dstore), kWriteCacheElems)
		if err != nil {
			return err
		}
		instances[p].Exchange = bitswap.New(ctx, p, adapter, instances[p].Blockstore, alwaysSendToPeer)
	}
	var peers []peer.ID
	for _, p := range mn.Peers() {
		peers = append(peers, p)
	}

	adder := instances[peers[0]]
	catter := instances[peers[1]]

	// bootstrap the DHTs
	adder.DHT.Connect(ctx, catter.ID)
	catter.DHT.Connect(ctx, adder.ID)

	adder.datastoreDelay.Set(0) // disable blockstore latency during add operation
	keyAdded, err := add(adder, bytes.NewReader(data))
	if err != nil {
		return err
	}
	adder.datastoreDelay.Set(conf.BlockstoreLatency) // add some blockstore delay to make the catter wait

	readerCatted, err := cat(catter, keyAdded)
	if err != nil {
		return err
	}

	// verify
	var bufout bytes.Buffer
	io.Copy(&bufout, readerCatted)
	if 0 != bytes.Compare(bufout.Bytes(), data) {
		return errors.New("catted data does not match added data")
	}
	return nil
}

func cat(catter *instance, k util.Key) (io.Reader, error) {
	catterdag := merkledag.NewDAGService(&blockservice.BlockService{catter.Blockstore, catter.Exchange})
	nodeCatted, err := (&path.Resolver{catterdag}).ResolvePath(k.String())
	if err != nil {
		return nil, err
	}
	return uio.NewDagReader(nodeCatted, catterdag)
}

func add(adder *instance, r io.Reader) (util.Key, error) {
	nodeAdded, err := importer.BuildDagFromReader(
		r,
		merkledag.NewDAGService(&blockservice.BlockService{adder.Blockstore, adder.Exchange}),
		nil,
		chunk.DefaultSplitter,
	)
	if err != nil {
		return "", err
	}
	return nodeAdded.Key()
}

func SkipUnlessEpic(t *testing.T) {
	if os.Getenv("IPFS_EPIC_TEST") == "" {
		t.SkipNow()
	}
}
<|endoftext|>


<commit_before>package module

import (
	"bytes"
	"reflect"
	"testing"
)

func TestModuleHCL(t *testing.T) {
	hclInput := `
import {
  module = [
    "base-module",
    "some-other-module",
  ]
}

resource "pacman" {
  name = "openssh"
}

resource "pacman" {
  name = "tmux"
  state = "present"
}
`
	hclModule, err := Load("main", bytes.NewBufferString(hclInput))
	if err != nil {
		t.Fatal(err)
	}

	wantName := "main"
	wantNumImports := 2
	wantImportNames := []string{"base-module", "some-other-module"}
	wantNumResources := 2

	if wantName != hclModule.Name {
		t.Errorf("want module name %q, got name %q", wantName, hclModule.Name)
	}

	if wantNumImports != len(hclModule.ModuleImport.Module) {
		t.Errorf("want %d imports, got %d imports", wantNumImports, len(hclModule.ModuleImport.Module))
	}

	if !reflect.DeepEqual(wantImportNames, hclModule.ModuleImport.Module) {
		t.Errorf("want %q import names, got %q names", wantImportNames, hclModule.ModuleImport.Module)
	}

	if wantNumResources != len(hclModule.Resources) {
		t.Errorf("want %d resources, got %d resources", wantNumResources, len(hclModule.Resources))
	}
}

func TestModuleJSON(t *testing.T) {
	jsonInput := `
{
  "import": {
    "module": [
      "base-module",
      "some-other-module"
    ],
  },
  "resource": [
    {
      "pacman": {
        "name": "openssh",
        "state": "present"
      }
    },
    {
      "pacman": {
        "name": "tmux",
        "state": "present",
      }
    }
  ]
}
`
	jsonModule, err := Load("main", bytes.NewBufferString(jsonInput))
	if err != nil {
		t.Fatal(err)
	}

	wantName := "main"
	wantNumImports := 2
	wantImportNames := []string{"base-module", "some-other-module"}
	wantNumResources := 2

	if wantName != jsonModule.Name {
		t.Errorf("want module name %q, got name %q", wantName, jsonModule.Name)
	}

	if wantNumImports != len(jsonModule.ModuleImport.Module) {
		t.Errorf("want %d imports, got %d imports", wantNumImports, len(jsonModule.ModuleImport.Module))
	}

	if !reflect.DeepEqual(wantImportNames, jsonModule.ModuleImport.Module) {
		t.Errorf("want %q import names, got %q names", wantImportNames, jsonModule.ModuleImport.Module)
	}

	if wantNumResources != len(jsonModule.Resources) {
		t.Errorf("want %d resources, got %d resources", wantNumResources, len(jsonModule.Resources))
	}
}
<commit_msg>tests: fix module tests<commit_after>package module

import (
	"bytes"
	"reflect"
	"testing"
)

func TestModuleHCL(t *testing.T) {
	hclInput := `
import {
  name = "base-module"
}

import {
  name = "some-other-module"
}

pacman "openssh" {
  state = "present"
}

pacman "tmux" {
  state = "present"
}
`
	hclModule, err := Load("main", bytes.NewBufferString(hclInput))
	if err != nil {
		t.Fatal(err)
	}

	wantName := "main"
	wantImports := []Import{
		Import{Name: "base-module"},
		Import{Name: "some-other-module"},
	}
	wantNumResources := 2

	if wantName != hclModule.Name {
		t.Errorf("want module name %q, got name %q", wantName, hclModule.Name)
	}

	if !reflect.DeepEqual(wantImports, hclModule.Imports) {
		t.Errorf("want %q imports, got %q imports", wantImports, hclModule.Imports)
	}

	if wantNumResources != len(hclModule.Resources) {
		t.Errorf("want %d resources, got %d resources", wantNumResources, len(hclModule.Resources))
	}
}

func TestModuleJSON(t *testing.T) {
	jsonInput := `
{
  "import": [
    {
      "name": "base-module"
    },
    {
      "name": "some-other-module"
    }
  ],
  "pacman": [
    {
      "openssh": {
        "name": "openssh",
        "state": "present"
      }
    },
    {
      "valgrind": {
        "name": "tmux",
        "state": "present",
      }
    }
  ]
}
`
	jsonModule, err := Load("main", bytes.NewBufferString(jsonInput))
	if err != nil {
		t.Fatal(err)
	}

	wantName := "main"
	wantImports := []Import{
		Import{Name: "base-module"},
		Import{Name: "some-other-module"},
	}
	wantNumResources := 2

	if wantName != jsonModule.Name {
		t.Errorf("want module name %q, got name %q", wantName, jsonModule.Name)
	}

	if !reflect.DeepEqual(wantImports, jsonModule.Imports) {
		t.Errorf("want %q imports, got %q imports", wantImports, jsonModule.Imports)
	}

	if wantNumResources != len(jsonModule.Resources) {
		t.Errorf("want %d resources, got %d resources", wantNumResources, len(jsonModule.Resources))
	}
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"fmt"
	"time"
	"sort"
	"bufio"
	"strconv"
	"strings"
	"text/template"
)

func main() {
	fmt.Println("Starting...")

	headers := []string{ "User", "Tildes", "Last Collection" }
	generate("tilde collectors", sortScore(readData("/home/krowbar/Code/irc/tildescores.txt", "&^%", headers)), "tildes")
}

type Table struct {
	Headers []string
	Rows []Row
}

type Row struct {
	Data []string
}

type By func(r1, r2 *Row) bool
func (by By) Sort(rows []Row) {
	rs := &rowSorter {
		rows: rows,
		by: by,
	}
	sort.Sort(rs)
}
type rowSorter struct {
	rows []Row
	by func(r1, r2 *Row) bool
}
func (r *rowSorter) Len() int {
	return len(r.rows)
}
func (r *rowSorter) Swap(i, j int) {
	r.rows[i], r.rows[j] = r.rows[j], r.rows[i]
}
func (r *rowSorter) Less(i, j int) bool {
	return r.by(&r.rows[i], &r.rows[j])
}

func sortScore(table *Table) *Table {
	score := func(r1, r2 *Row) bool {
		s1, _ := strconv.Atoi(r1.Data[1])
		s2, _ := strconv.Atoi(r2.Data[1])
		return s1 < s2
	}
	decScore := func(r1, r2 *Row) bool {
		return !score(r1, r2)
	}
	By(decScore).Sort(table.Rows)

	return table
}

func readData(path string, delimiter string, headers []string) *Table {
	f, _ := os.Open(path)

	defer f.Close()

	rows := []Row{}
	table := &Table{Headers: headers, Rows: nil}
	s := bufio.NewScanner(f)
	s.Split(bufio.ScanLines)

	for s.Scan() {
		data := strings.Split(s.Text(), delimiter)
		row := &Row{Data: data}
		rows = append(rows, *row)
	}
	table.Rows = rows

	return table
}

type Page struct {
	Title string
	Table Table
	Updated string
	UpdatedForHumans string
}

func generate(title string, table *Table, outputFile string) {
	fmt.Println("Generating page.")

	f, err := os.Create(os.Getenv("HOME") + "/public_html/" + outputFile + ".html")
	if err != nil {
		panic(err)
	}

	defer f.Close()

	w := bufio.NewWriter(f)
	template, err := template.ParseFiles("templates/table.html")
	if err != nil {
		panic(err)
	}

	// Extra page data
	curTime := time.Now().UTC()
	updatedReadable := curTime.Format(time.RFC1123)
	updated := curTime.Format(time.RFC3339)

	// Generate the page
	page := &Page{Title: title, Table: *table, UpdatedForHumans: updatedReadable, Updated: updated}
	template.ExecuteTemplate(w, "table", page)
	w.Flush()

	fmt.Println("DONE!")
}
<commit_msg>Accept -o (output) flag, extract src path into const<commit_after>package main

import (
	"os"
	"fmt"
	"time"
	"flag"
	"sort"
	"bufio"
	"strconv"
	"strings"
	"text/template"
)

const scores = "/home/krowbar/Code/irc/tildescores.txt"

func main() {
	fmt.Println("Starting...")

	// Get any arguments
	outPtr := flag.String("o", "tildescores", "Output file name")
	flag.Parse()

	headers := []string{ "User", "Tildes", "Last Collection" }
	generate("tilde collectors", sortScore(readData(scores, "&^%", headers)), *outPtr)
}

type Table struct {
	Headers []string
	Rows []Row
}

type Row struct {
	Data []string
}

type By func(r1, r2 *Row) bool
func (by By) Sort(rows []Row) {
	rs := &rowSorter {
		rows: rows,
		by: by,
	}
	sort.Sort(rs)
}
type rowSorter struct {
	rows []Row
	by func(r1, r2 *Row) bool
}
func (r *rowSorter) Len() int {
	return len(r.rows)
}
func (r *rowSorter) Swap(i, j int) {
	r.rows[i], r.rows[j] = r.rows[j], r.rows[i]
}
func (r *rowSorter) Less(i, j int) bool {
	return r.by(&r.rows[i], &r.rows[j])
}

func sortScore(table *Table) *Table {
	score := func(r1, r2 *Row) bool {
		s1, _ := strconv.Atoi(r1.Data[1])
		s2, _ := strconv.Atoi(r2.Data[1])
		return s1 < s2
	}
	decScore := func(r1, r2 *Row) bool {
		return !score(r1, r2)
	}
	By(decScore).Sort(table.Rows)

	return table
}

func readData(path string, delimiter string, headers []string) *Table {
	f, _ := os.Open(path)

	defer f.Close()

	rows := []Row{}
	table := &Table{Headers: headers, Rows: nil}
	s := bufio.NewScanner(f)
	s.Split(bufio.ScanLines)

	for s.Scan() {
		data := strings.Split(s.Text(), delimiter)
		row := &Row{Data: data}
		rows = append(rows, *row)
	}
	table.Rows = rows

	return table
}

type Page struct {
	Title string
	Table Table
	Updated string
	UpdatedForHumans string
}

func generate(title string, table *Table, outputFile string) {
	fmt.Println("Generating page.")

	f, err := os.Create(os.Getenv("HOME") + "/public_html/" + outputFile + ".html")
	if err != nil {
		panic(err)
	}

	defer f.Close()

	w := bufio.NewWriter(f)
	template, err := template.ParseFiles("templates/table.html")
	if err != nil {
		panic(err)
	}

	// Extra page data
	curTime := time.Now().UTC()
	updatedReadable := curTime.Format(time.RFC1123)
	updated := curTime.Format(time.RFC3339)

	// Generate the page
	page := &Page{Title: title, Table: *table, UpdatedForHumans: updatedReadable, Updated: updated}
	template.ExecuteTemplate(w, "table", page)
	w.Flush()

	fmt.Println("DONE!")
}
<|endoftext|>


<commit_before>package tag

import (
	"bytes"
	"fmt"
	"image"
	"io"
	"io/ioutil"
	"log"
	"os"

	window "github.com/as/ms/win"

	"github.com/as/clip"
	"github.com/as/cursor"
)

func readfile(s string) (p []byte) {
	var err error
	if isdir(s) {
		fi, err := ioutil.ReadDir(s)
		if err != nil {
			log.Println(err)
			return nil
		}
		b := new(bytes.Buffer)
		for _, v := range fi {
			fmt.Fprintf(b, "%s\t", v.Name())
		}
		return b.Bytes()
	}
	p, err = ioutil.ReadFile(s)
	if err != nil {
		log.Println(err)
	}
	return p
}
func writefile(s string, p []byte) {
	fd, err := os.Create(s)
	if err != nil {
		log.Println(err)
	}
	n, err := io.Copy(fd, bytes.NewReader(p))
	if err != nil {
		log.Println(err)
	}
	println("wrote", n, "bytes")
}

func init() {
	var err error
	Clip, err = clip.New()
	if err != nil {
		panic(err)
	}
}
func moveMouse(pt image.Point) {
	cursor.MoveTo(window.ClientAbs().Min.Add(pt))
}
<commit_msg>fixes as/a#2<commit_after>package tag

import (
	"bytes"
	"fmt"
	"image"
	"io"
	"io/ioutil"
	"log"
	"os"
	"text/tabwriter"
	"sort"
	"strings"
	window "github.com/as/ms/win"

	"github.com/as/clip"
	"github.com/as/cursor"
)

func (t *Tag) readfile(s string) (p []byte) {
	var err error
	if isdir(s) {
		fi, err := ioutil.ReadDir(s)
		if err != nil {
			log.Println(err)
			return nil
		}
		sort.SliceStable(fi, func(i, j int) bool{
			if fi[i].IsDir() && !fi[j].IsDir(){
				return true
			}
			ni,nj := fi[i].Name(), fi[j].Name()
			return strings.Compare(ni, nj) < 0
		})
		x := t.Font.MeasureByte('e')
		n := t.Frame.Bounds().Dx()/x
		m := 0
		b := new(bytes.Buffer)
		w := tabwriter.NewWriter(b, 0, 0, 3, ' ', 0)
		for _, v := range fi {
			nm := v.Name()
			if v.IsDir(){
				nm += string(os.PathSeparator)
			}
			entry := fmt.Sprintf("%s\t", nm)
			dm := m+len(entry)
			if dm > n{
				fmt.Fprintf(w, "\n")
				m=-(dm+3)
			}
			fmt.Fprintf(w, entry)
			m+=dm+3
		}
		w.Flush()
		return b.Bytes()
	}
	p, err = ioutil.ReadFile(s)
	if err != nil {
		log.Println(err)
	}
	return p
}
func writefile(s string, p []byte) {
	fd, err := os.Create(s)
	if err != nil {
		log.Println(err)
	}
	n, err := io.Copy(fd, bytes.NewReader(p))
	if err != nil {
		log.Println(err)
	}
	println("wrote", n, "bytes")
}

func init() {
	var err error
	Clip, err = clip.New()
	if err != nil {
		panic(err)
	}
}
func moveMouse(pt image.Point) {
	cursor.MoveTo(window.ClientAbs().Min.Add(pt))
}
<|endoftext|>


<commit_before>package upload_test

import (
	"log"
	"strings"
	"testing"

	"github.com/Sirupsen/logrus"
	"github.com/arduino/arduino-create-agent/upload"
	homedir "github.com/mitchellh/go-homedir"
)

type mockTools struct{}

func (mockTools) GetLocation(el string) (string, error) {
	return "$loc" + el, nil
}

// TestSerialData requires a leonardo connected to the /dev/ttyACM0 port
var TestSerialData = []struct {
	Name        string
	Port        string
	Commandline string
	Extra       upload.Extra
}{
	{
		"leonardo", "/dev/ttyACM0",
		`"~/.arduino-create/avrdude/6.3.0-arduino6/bin/avrdude" "-C~/.arduino-create/avrdude/6.3.0-arduino6/etc/avrdude.conf" -v -patmega32u4 -cavr109 -P/dev/ttyACM0 -b57600 -D "-Uflash:w:./upload_test.hex:i"`, upload.Extra{Use1200bpsTouch: true, WaitForUploadPort: true}},
}

func TestSerial(t *testing.T) {
	logger := logrus.New()
	logger.Level = logrus.DebugLevel

	home, _ := homedir.Dir()

	for _, test := range TestSerialData {
		commandline := strings.Replace(test.Commandline, "~", home, -1)
		err := upload.Serial(test.Port, commandline, test.Extra, logger)
		log.Println(err)
	}
}

var TestNetworkData = []struct {
	Name        string
	Port        string
	Board       string
	File        string
	Commandline string
	Auth        upload.Auth
}{
	{
		"yun", "", "", "",
		``, upload.Auth{}},
}

func TestNetwork(t *testing.T) {
	logger := logrus.New()
	logger.Level = logrus.DebugLevel

	home, _ := homedir.Dir()

	for _, test := range TestNetworkData {
		commandline := strings.Replace(test.Commandline, "~", home, -1)
		err := upload.Network(test.Port, test.Board, test.File, commandline, test.Auth, logger)
		log.Println(err)
	}
}

var TestResolveData = []struct {
	Port        string
	Board       string
	File        string
	Commandline string
	Extra       upload.Extra
	Result      string
}{
	{"/dev/ttyACM0", "arduino:avr:leonardo", "./upload_test.hex",
		`"{runtime.tools.avrdude.path}/bin/avrdude" "-C{runtime.tools.avrdude.path}/etc/avrdude.conf" {upload.verbose} {upload.verify} -patmega32u4 -cavr109 -P{serial.port} -b57600 -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"`, upload.Extra{Use1200bpsTouch: true, WaitForUploadPort: true},
		`"$loc$loc{runtime.tools.avrdude.path}/bin/avrdude" "-C{runtime.tools.avrdude.path}/etc/avrdude.conf"  $loc{upload.verify} -patmega32u4 -cavr109 -P/dev/ttyACM0 -b57600 -D "-Uflash:w:./upload_test.hex:i"`},
}

func TestResolve(t *testing.T) {
	for _, test := range TestResolveData {
		result, _ := upload.Resolve(test.Port, test.Board, test.File, test.Commandline, test.Extra, mockTools{})
		if result != test.Result {
			t.Error("expected " + test.Result + ", got " + result)
			continue
		}
	}
}
<commit_msg>Avoid bashisms<commit_after>package upload_test

import (
	"log"
	"strings"
	"testing"

	"github.com/Sirupsen/logrus"
	"github.com/arduino/arduino-create-agent/upload"
	homedir "github.com/mitchellh/go-homedir"
)

type mockTools struct{}

func (mockTools) GetLocation(el string) (string, error) {
	return "$loc" + el, nil
}

// TestSerialData requires a leonardo connected to the /dev/ttyACM0 port
var TestSerialData = []struct {
	Name        string
	Port        string
	Commandline string
	Extra       upload.Extra
}{
	{
		"leonardo", "/dev/ttyACM0",
		`"$HOME/.arduino-create/avrdude/6.3.0-arduino6/bin/avrdude" "-C$HOME/.arduino-create/avrdude/6.3.0-arduino6/etc/avrdude.conf" -v -patmega32u4 -cavr109 -P/dev/ttyACM0 -b57600 -D "-Uflash:w:./upload_test.hex:i"`, upload.Extra{Use1200bpsTouch: true, WaitForUploadPort: true}},
}

func TestSerial(t *testing.T) {
	logger := logrus.New()
	logger.Level = logrus.DebugLevel

	home, _ := homedir.Dir()

	for _, test := range TestSerialData {
		commandline := strings.Replace(test.Commandline, "$HOME", home, -1)
		err := upload.Serial(test.Port, commandline, test.Extra, logger)
		log.Println(err)
	}
}

var TestNetworkData = []struct {
	Name        string
	Port        string
	Board       string
	File        string
	Commandline string
	Auth        upload.Auth
}{
	{
		"yun", "", "", "",
		``, upload.Auth{}},
}

func TestNetwork(t *testing.T) {
	logger := logrus.New()
	logger.Level = logrus.DebugLevel

	home, _ := homedir.Dir()

	for _, test := range TestNetworkData {
		commandline := strings.Replace(test.Commandline, "$HOME", home, -1)
		err := upload.Network(test.Port, test.Board, test.File, commandline, test.Auth, logger)
		log.Println(err)
	}
}

var TestResolveData = []struct {
	Port        string
	Board       string
	File        string
	Commandline string
	Extra       upload.Extra
	Result      string
}{
	{"/dev/ttyACM0", "arduino:avr:leonardo", "./upload_test.hex",
		`"{runtime.tools.avrdude.path}/bin/avrdude" "-C{runtime.tools.avrdude.path}/etc/avrdude.conf" {upload.verbose} {upload.verify} -patmega32u4 -cavr109 -P{serial.port} -b57600 -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"`, upload.Extra{Use1200bpsTouch: true, WaitForUploadPort: true},
		`"$loc$loc{runtime.tools.avrdude.path}/bin/avrdude" "-C{runtime.tools.avrdude.path}/etc/avrdude.conf"  $loc{upload.verify} -patmega32u4 -cavr109 -P/dev/ttyACM0 -b57600 -D "-Uflash:w:./upload_test.hex:i"`},
}

func TestResolve(t *testing.T) {
	for _, test := range TestResolveData {
		result, _ := upload.Resolve(test.Port, test.Board, test.File, test.Commandline, test.Extra, mockTools{})
		if result != test.Result {
			t.Error("expected " + test.Result + ", got " + result)
			continue
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net"
	"os"
	"strconv"
	"sync"
	"time"

	"github.com/MoZhonghua/mytools/upnp"
	"github.com/MoZhonghua/mytools/util"
	"github.com/codegangsta/cli"
)

var (
	devTypes = []string{
		"urn:schemas-upnp-org:device:InternetGatewayDevice:1",
		"urn:schemas-upnp-org:device:InternetGatewayDevice:2"}
)

func parseInt(s string) (int, error) {
	v, err := strconv.ParseInt(s, 10, 32)
	if err != nil {
		return 0, err
	}

	return int(v), nil
}

func marshalData(v interface{}) string {
	b, _ := json.MarshalIndent(v, "", "    ")
	return string(b)
}

var debug bool
var proxy string

func fail(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, format, args...)
	fmt.Fprintln(os.Stderr, "")
	os.Exit(-1)
}

func main() {
	app := cli.NewApp()
	app.Version = "1.0"
	app.Usage = "upnp client"
	app.Name = "upnp client"
	app.Author = "MoZhonghua"
	app.CommandNotFound = func(ctx *cli.Context, command string) {
		fail("unknown command: %v", command)
	}
	app.Writer = os.Stdout

	app.Flags = []cli.Flag{
		&cli.BoolFlag{
			Name:        "debug",
			Usage:       "debug",
			Destination: &debug,
		},
		&cli.StringFlag{
			Name:        "proxy",
			Usage:       "proxy",
			Destination: &proxy,
		},
	}

	app.Commands = []cli.Command{
		{
			Name:      "listinterface",
			Usage:     "list all network interfaces",
			ArgsUsage: "",
			Action:    cmdListInterface,
		},
		{
			Name:      "ssdpsearch",
			Usage:     "SSDP Search",
			ArgsUsage: "<interface>",
			Action:    cmdSSDPSearch,
		},
		{
			Name:      "addportmap",
			Usage:     "add port mapping",
			ArgsUsage: "<igdURL> <localPort> <externalPort>",
			Action:    cmdAddPortMapping,
		},
		{
			Name:      "deleteportmap",
			Usage:     "delete port mapping",
			ArgsUsage: "<igdURL> <externalPort>",
			Action:    cmdDelPortMapping,
		},
	}

	err := app.Run(os.Args)
	if err != nil {
		os.Exit(1)
	}
}

func discover(wg *sync.WaitGroup, intf *net.Interface, deviceType string,
	timeout time.Duration) error {
	defer wg.Done()
	results, err := upnp.SSDPSearch(intf, deviceType, timeout)
	if err != nil {
		fmt.Printf("failed to SSDP Search on %s: %v\n", intf.Name, err)
		return nil
	}
	for n := range results {
		b, _ := json.MarshalIndent(n, "", "    ")
		fmt.Println(string(b))
	}
	return nil
}

func createHttpClient() *util.HttpClient {
	cfg := &util.HttpClientConfig{}
	cfg.Proxy = proxy
	cfg.Debug = debug
	cfg.Logger = log.New(os.Stdout, "", log.LstdFlags|log.Lshortfile)

	c, err := util.NewHttpClient(cfg)
	if err != nil {
		fail("error: %v", err)
	}
	return c
}

func cmdListInterface(c *cli.Context) error {
	intfs, err := net.Interfaces()
	if err != nil {
		fail("error: %v", err)
	}

	for _, intf := range intfs {
		fmt.Printf("%s %s\n", intf.Name, intf.Flags.String())
	}
	return nil
}

func cmdSSDPSearch(c *cli.Context) error {
	if len(c.Args()) < 1 {
		cli.ShowSubcommandHelp(c)
		os.Exit(1)
	}

	intfName := c.Args()[0]

	intfs, err := net.Interfaces()
	if err != nil {
		fail("error: %v", err)
	}

	var wg sync.WaitGroup
	for _, intf := range intfs {
		if intfName != "all" && intfName != intf.Name {
			continue
		}
		fmt.Printf("intfName: %s %s\n", intf.Name, intf.Flags.String())
		if intf.Flags&net.FlagUp == 0 || intf.Flags&net.FlagMulticast == 0 {
			fmt.Printf("intfName down or multicast not support, skip\n")
			continue
		}

		for _, deviceType := range devTypes {
			wg.Add(1)
			discover(&wg, &intf, deviceType, 10*time.Second)
		}
	}
	wg.Wait()
	return nil
}

func cmdAddPortMapping(c *cli.Context) error {
	if len(c.Args()) < 3 {
		cli.ShowSubcommandHelp(c)
		os.Exit(1)
	}

	hc := createHttpClient()

	igdURL := c.Args()[0]

	root, err := upnp.GetUPnPData(igdURL)
	if err != nil {
		fail("error: %v", err)
	}

	igd, err := upnp.GetIGDDevice(root, igdURL)
	if err != nil {
		fail("error: %v", err)
	}

	localPort, err := parseInt(c.Args()[1])
	if err != nil {
		fail("error: %v", err)
	}
	externalPort, err := parseInt(c.Args()[2])
	if err != nil {
		fail("error: %v", err)
	}

	for _, s := range igd.Services {
		externalIP, err := s.GetExternalIPAddress(hc)
		if err != nil {
			fail("error: %v", err)
		}

		err = s.AddPortMapping(hc, igd.LocalIPAddress.String(),
			"TCP", localPort, externalPort, "", 0)
		if err != nil {
			fail("error: %v", err)
		}

		fmt.Printf("Port mapping %s:%d -> %s:%d OK!\n",
			externalIP.String(), externalPort,
			igd.LocalIPAddress.String(), localPort)

		return nil
	}
	return nil
}

func cmdDelPortMapping(c *cli.Context) error {
	if len(c.Args()) < 2 {
		cli.ShowSubcommandHelp(c)
		os.Exit(1)
	}

	igdURL := c.Args()[0]

	root, err := upnp.GetUPnPData(igdURL)
	if err != nil {
		fail("error: %v", err)
	}

	igd, err := upnp.GetIGDDevice(root, igdURL)
	if err != nil {
		fail("error: %v", err)
	}

	externalPort, err := parseInt(c.Args()[1])
	if err != nil {
		fail("error: %v", err)
	}

	hc := createHttpClient()
	for _, s := range igd.Services {
		err := s.DeletePortMapping(hc, "TCP", externalPort)
		if err != nil {
			fail("error: %v", err)
		}
	}
	fmt.Println("OK!")
	return nil
}
<commit_msg>update<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net"
	"os"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/MoZhonghua/mytools/upnp"
	"github.com/MoZhonghua/mytools/util"
	"github.com/codegangsta/cli"
)

var (
	devTypes = []string{
		"urn:schemas-upnp-org:device:InternetGatewayDevice:1",
		"urn:schemas-upnp-org:device:InternetGatewayDevice:2"}
)

func parseInt(s string) (int, error) {
	v, err := strconv.ParseInt(s, 10, 32)
	if err != nil {
		return 0, err
	}

	return int(v), nil
}

func marshalData(v interface{}) string {
	b, _ := json.MarshalIndent(v, "", "    ")
	return string(b)
}

var debug bool
var proxy string

func fail(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, format, args...)
	fmt.Fprintln(os.Stderr, "")
	os.Exit(-1)
}

func main() {
	app := cli.NewApp()
	app.Version = "1.0"
	app.Usage = "upnp client"
	app.Name = "upnp client"
	app.Author = "MoZhonghua"
	app.CommandNotFound = func(ctx *cli.Context, command string) {
		fail("unknown command: %v", command)
	}
	app.Writer = os.Stdout

	app.Flags = []cli.Flag{
		&cli.BoolFlag{
			Name:        "debug",
			Usage:       "debug",
			Destination: &debug,
		},
		&cli.StringFlag{
			Name:        "proxy",
			Usage:       "proxy",
			Destination: &proxy,
		},
	}

	app.Commands = []cli.Command{
		{
			Name:      "listinterface",
			Usage:     "list all network interfaces",
			ArgsUsage: "",
			Action:    cmdListInterface,
		},
		{
			Name:      "ssdpsearch",
			Usage:     "SSDP Search",
			ArgsUsage: "<interface>",
			Action:    cmdSSDPSearch,
		},
		{
			Name:      "addportmap",
			Usage:     "add port mapping",
			ArgsUsage: "<igdURL> <localIP:localPort> <externalPort>",
			Action:    cmdAddPortMapping,
		},
		{
			Name:      "deleteportmap",
			Usage:     "delete port mapping",
			ArgsUsage: "<igdURL> <externalPort>",
			Action:    cmdDelPortMapping,
		},
	}

	err := app.Run(os.Args)
	if err != nil {
		os.Exit(1)
	}
}

func discover(wg *sync.WaitGroup, intf *net.Interface, deviceType string,
	timeout time.Duration) error {
	defer wg.Done()
	results, err := upnp.SSDPSearch(intf, deviceType, timeout)
	if err != nil {
		fmt.Printf("failed to SSDP Search on %s: %v\n", intf.Name, err)
		return nil
	}
	for n := range results {
		b, _ := json.MarshalIndent(n, "", "    ")
		fmt.Println(string(b))
	}
	return nil
}

func createHttpClient() *util.HttpClient {
	cfg := &util.HttpClientConfig{}
	cfg.Proxy = proxy
	cfg.Debug = debug
	cfg.Logger = log.New(os.Stdout, "", log.LstdFlags|log.Lshortfile)

	c, err := util.NewHttpClient(cfg)
	if err != nil {
		fail("error: %v", err)
	}
	return c
}

func cmdListInterface(c *cli.Context) error {
	intfs, err := net.Interfaces()
	if err != nil {
		fail("error: %v", err)
	}

	for _, intf := range intfs {
		fmt.Printf("%s %s\n", intf.Name, intf.Flags.String())
	}
	return nil
}

func cmdSSDPSearch(c *cli.Context) error {
	if len(c.Args()) < 1 {
		cli.ShowSubcommandHelp(c)
		os.Exit(1)
	}

	intfName := c.Args()[0]

	intfs, err := net.Interfaces()
	if err != nil {
		fail("error: %v", err)
	}

	var wg sync.WaitGroup
	for _, intf := range intfs {
		if intfName != "all" && intfName != intf.Name {
			continue
		}
		fmt.Printf("intfName: %s %s\n", intf.Name, intf.Flags.String())
		if intf.Flags&net.FlagUp == 0 || intf.Flags&net.FlagMulticast == 0 {
			fmt.Printf("intfName down or multicast not support, skip\n")
			continue
		}

		for _, deviceType := range devTypes {
			wg.Add(1)
			discover(&wg, &intf, deviceType, 10*time.Second)
		}
	}
	wg.Wait()
	return nil
}

func parseIPPort(s string) (net.IP, int, error) {
	f := strings.Split(s, ":")
	if len(f) != 2 {
		return nil, 0, fmt.Errorf("invalid addr: %s", s)
	}

	ip := net.ParseIP(f[0])
	port, err := parseInt(f[1])
	if err != nil {
		return nil, 0, err
	}

	return ip, port, nil
}

func cmdAddPortMapping(c *cli.Context) error {
	if len(c.Args()) < 3 {
		cli.ShowSubcommandHelp(c)
		os.Exit(1)
	}

	hc := createHttpClient()

	igdURL := c.Args()[0]

	root, err := upnp.GetUPnPData(igdURL)
	if err != nil {
		fail("error: %v", err)
	}

	igd, err := upnp.GetIGDDevice(root, igdURL)
	if err != nil {
		fail("error: %v", err)
	}

	localIP, localPort, err := parseIPPort(c.Args()[1])
	if err != nil {
		fail("error: %v", err)
	}
	externalPort, err := parseInt(c.Args()[2])
	if err != nil {
		fail("error: %v", err)
	}

	for _, s := range igd.Services {
		externalIP, err := s.GetExternalIPAddress(hc)
		if err != nil {
			fail("error: %v", err)
		}

		err = s.AddPortMapping(hc, localIP.String(),
			"TCP", localPort, externalPort, "", 0)
		if err != nil {
			fail("error: %v", err)
		}

		fmt.Printf("Port mapping %s:%d -> %s:%d OK!\n",
			externalIP.String(), externalPort,
			localIP.String(), localPort)

		return nil
	}
	return nil
}

func cmdDelPortMapping(c *cli.Context) error {
	if len(c.Args()) < 2 {
		cli.ShowSubcommandHelp(c)
		os.Exit(1)
	}

	igdURL := c.Args()[0]

	root, err := upnp.GetUPnPData(igdURL)
	if err != nil {
		fail("error: %v", err)
	}

	igd, err := upnp.GetIGDDevice(root, igdURL)
	if err != nil {
		fail("error: %v", err)
	}

	externalPort, err := parseInt(c.Args()[1])
	if err != nil {
		fail("error: %v", err)
	}

	hc := createHttpClient()
	for _, s := range igd.Services {
		err := s.DeletePortMapping(hc, "TCP", externalPort)
		if err != nil {
			fail("error: %v", err)
		}
	}
	fmt.Println("OK!")
	return nil
}
<|endoftext|>


<commit_before>// Copyright © 2017 Sascha Andres <sascha.andres@outlook.com>
//
// 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 (
	"github.com/sascha-andres/go-logsink/client"
	"github.com/spf13/cobra"
)

// connectCmd represents the connect command
var connectCmd = &cobra.Command{
	Use:   "connect",
	Short: "Connect to a go-logsink server and forward stdin",
	Long: `This command is used to connect to a go-logsink server.
Call it to forward data piped ito this application to the server.`,
	Run: func(cmd *cobra.Command, args []string) {
		client.Connect(cmd.Flag("address").Value.String())
	},
}

func init() {
	RootCmd.AddCommand(connectCmd)
	connectCmd.Flags().StringP("address", "a", "localhost:50051", "Provide server address")
}
<commit_msg>Printing out address to connect<commit_after>// Copyright © 2017 Sascha Andres <sascha.andres@outlook.com>
//
// 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"

	"github.com/sascha-andres/go-logsink/client"
	"github.com/spf13/cobra"
)

// connectCmd represents the connect command
var connectCmd = &cobra.Command{
	Use:   "connect",
	Short: "Connect to a go-logsink server and forward stdin",
	Long: `This command is used to connect to a go-logsink server.
Call it to forward data piped ito this application to the server.`,
	Run: func(cmd *cobra.Command, args []string) {
		address := cmd.Flag("address").Value.String()
		fmt.Printf("Connecting to %s\n", address)
		client.Connect(address)
	},
}

func init() {
	RootCmd.AddCommand(connectCmd)
	connectCmd.Flags().StringP("address", "a", "localhost:50051", "Provide server address")
}
<|endoftext|>


<commit_before>// Copyright © 2017 NAME HERE <EMAIL ADDRESS>
//
// 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 (
	"github.com/sascha-andres/go-logsink/client"
	"github.com/spf13/cobra"
)

// connectCmd represents the connect command
var connectCmd = &cobra.Command{
	Use:   "connect",
	Short: "Connect to a go-logsink server and forward stdin",
	Long: `This command is used to connect to a go-logsink server.
Call it to forward data piped ito this application to the server.`,
	Run: func(cmd *cobra.Command, args []string) {
		client.Connect("localhost:50051")
	},
}

func init() {
	RootCmd.AddCommand(connectCmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// connectCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// connectCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")

}
<commit_msg>Made server address configurable<commit_after>// Copyright © 2017 Sascha Andres <sascha.andres@outlook.com>
//
// 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 (
	"github.com/sascha-andres/go-logsink/client"
	"github.com/spf13/cobra"
)

// connectCmd represents the connect command
var connectCmd = &cobra.Command{
	Use:   "connect",
	Short: "Connect to a go-logsink server and forward stdin",
	Long: `This command is used to connect to a go-logsink server.
Call it to forward data piped ito this application to the server.`,
	Run: func(cmd *cobra.Command, args []string) {
		client.Connect(cmd.Flag("address").Value.String())
	},
}

func init() {
	RootCmd.AddCommand(connectCmd)
	connectCmd.Flags().StringP("address", "a", "localhost:50051", "Provide server address")
}
<|endoftext|>


<commit_before>package cmd

import (
	"fmt"
	"github.com/smira/aptly/aptly"
	"github.com/smira/aptly/console"
	"github.com/smira/aptly/database"
	"github.com/smira/aptly/deb"
	"github.com/smira/aptly/files"
	"github.com/smira/aptly/http"
	"github.com/smira/aptly/utils"
	"github.com/smira/flag"
	"os"
	"path/filepath"
	"runtime"
	"runtime/pprof"
	"strings"
	"time"
)

// Common context shared by all commands
type AptlyContext struct {
	flags        *flag.FlagSet
	configLoaded bool

	progress          aptly.Progress
	downloader        aptly.Downloader
	database          database.Storage
	packagePool       aptly.PackagePool
	publishedStorage  aptly.PublishedStorage
	collectionFactory *deb.CollectionFactory
	dependencyOptions int
	architecturesList []string
	// Debug features
	fileCPUProfile *os.File
	fileMemProfile *os.File
	fileMemStats   *os.File
}

var context *AptlyContext

type FatalError struct {
	ReturnCode int
	Message    string
}

func Fatal(err error) {
	panic(&FatalError{ReturnCode: 1, Message: err.Error()})
}

func (context *AptlyContext) Config() *utils.ConfigStructure {
	if !context.configLoaded {
		var err error

		configLocation := context.flags.Lookup("config").Value.String()
		if configLocation != "" {
			err = utils.LoadConfig(configLocation, &utils.Config)

			if err != nil {
				Fatal(err)
			}
		} else {
			configLocations := []string{
				filepath.Join(os.Getenv("HOME"), ".aptly.conf"),
				"/etc/aptly.conf",
			}

			for _, configLocation := range configLocations {
				err = utils.LoadConfig(configLocation, &utils.Config)
				if err == nil {
					break
				}
				if !os.IsNotExist(err) {
					Fatal(fmt.Errorf("error loading config file %s: %s", configLocation, err))
				}
			}

			if err != nil {
				fmt.Printf("Config file not found, creating default config at %s\n\n", configLocations[0])
				utils.SaveConfig(configLocations[0], &utils.Config)
			}
		}

		context.configLoaded = true

	}
	return &utils.Config
}

func (context *AptlyContext) DependencyOptions() int {
	if context.dependencyOptions == -1 {
		context.dependencyOptions = 0
		if context.Config().DepFollowSuggests || context.flags.Lookup("dep-follow-suggests").Value.Get().(bool) {
			context.dependencyOptions |= deb.DepFollowSuggests
		}
		if context.Config().DepFollowRecommends || context.flags.Lookup("dep-follow-recommends").Value.Get().(bool) {
			context.dependencyOptions |= deb.DepFollowRecommends
		}
		if context.Config().DepFollowAllVariants || context.flags.Lookup("dep-follow-all-variants").Value.Get().(bool) {
			context.dependencyOptions |= deb.DepFollowAllVariants
		}
		if context.Config().DepFollowSource || context.flags.Lookup("dep-follow-source").Value.Get().(bool) {
			context.dependencyOptions |= deb.DepFollowSource
		}
	}

	return context.dependencyOptions
}

func (context *AptlyContext) ArchitecturesList() []string {
	if context.architecturesList == nil {
		context.architecturesList = context.Config().Architectures
		optionArchitectures := context.flags.Lookup("architectures").Value.String()
		if optionArchitectures != "" {
			context.architecturesList = strings.Split(optionArchitectures, ",")
		}
	}

	return context.architecturesList
}

func (context *AptlyContext) Progress() aptly.Progress {
	if context.progress == nil {
		context.progress = console.NewProgress()
		context.progress.Start()
	}

	return context.progress
}

func (context *AptlyContext) Downloader() aptly.Downloader {
	if context.downloader == nil {
		context.downloader = http.NewDownloader(context.Config().DownloadConcurrency, context.Progress())
	}

	return context.downloader
}

func (context *AptlyContext) DBPath() string {
	return filepath.Join(context.Config().RootDir, "db")
}

func (context *AptlyContext) Database() (database.Storage, error) {
	if context.database == nil {
		var err error

		context.database, err = database.OpenDB(context.DBPath())
		if err != nil {
			return nil, fmt.Errorf("can't open database: %s", err)
		}
	}

	return context.database, nil
}

func (context *AptlyContext) CollectionFactory() *deb.CollectionFactory {
	if context.collectionFactory == nil {
		db, err := context.Database()
		if err != nil {
			Fatal(err)
		}
		context.collectionFactory = deb.NewCollectionFactory(db)
	}

	return context.collectionFactory
}

func (context *AptlyContext) PackagePool() aptly.PackagePool {
	if context.packagePool == nil {
		context.packagePool = files.NewPackagePool(context.Config().RootDir)
	}

	return context.packagePool
}

func (context *AptlyContext) PublishedStorage() aptly.PublishedStorage {
	if context.publishedStorage == nil {
		context.publishedStorage = files.NewPublishedStorage(context.Config().RootDir)
	}

	return context.publishedStorage
}

// ShutdownContext shuts context down
func ShutdownContext() {
	if aptly.EnableDebug {
		if context.fileMemProfile != nil {
			pprof.WriteHeapProfile(context.fileMemProfile)
			context.fileMemProfile.Close()
			context.fileMemProfile = nil
		}
		if context.fileCPUProfile != nil {
			pprof.StopCPUProfile()
			context.fileCPUProfile.Close()
			context.fileCPUProfile = nil
		}
		if context.fileMemProfile != nil {
			context.fileMemProfile.Close()
			context.fileMemProfile = nil
		}
	}
	if context.database != nil {
		context.database.Close()
	}
	if context.downloader != nil {
		context.downloader.Shutdown()
	}
	if context.progress != nil {
		context.progress.Shutdown()
	}
}

// InitContext initializes context with default settings
func InitContext(flags *flag.FlagSet) error {
	var err error

	context = &AptlyContext{flags: flags, dependencyOptions: -1}

	if aptly.EnableDebug {
		cpuprofile := flags.Lookup("cpuprofile").Value.String()
		if cpuprofile != "" {
			context.fileCPUProfile, err = os.Create(cpuprofile)
			if err != nil {
				return err
			}
			pprof.StartCPUProfile(context.fileCPUProfile)
		}

		memprofile := flags.Lookup("memprofile").Value.String()
		if memprofile != "" {
			context.fileMemProfile, err = os.Create(memprofile)
			if err != nil {
				return err
			}
		}

		memstats := flags.Lookup("memstats").Value.String()
		if memstats != "" {
			interval := flags.Lookup("meminterval").Value.Get().(time.Duration)

			context.fileMemStats, err = os.Create(memstats)
			if err != nil {
				return err
			}

			context.fileMemStats.WriteString("# Time\tHeapSys\tHeapAlloc\tHeapIdle\tHeapReleased\n")

			go func() {
				var stats runtime.MemStats

				start := time.Now().UnixNano()

				for {
					runtime.ReadMemStats(&stats)
					if context.fileMemStats != nil {
						context.fileMemStats.WriteString(fmt.Sprintf("%d\t%d\t%d\t%d\t%d\n",
							(time.Now().UnixNano()-start)/1000000, stats.HeapSys, stats.HeapAlloc, stats.HeapIdle, stats.HeapReleased))
						time.Sleep(interval)
					} else {
						break
					}
				}
			}()
		}
	}

	return nil
}
<commit_msg>Style fixes.<commit_after>package cmd

import (
	"fmt"
	"github.com/smira/aptly/aptly"
	"github.com/smira/aptly/console"
	"github.com/smira/aptly/database"
	"github.com/smira/aptly/deb"
	"github.com/smira/aptly/files"
	"github.com/smira/aptly/http"
	"github.com/smira/aptly/utils"
	"github.com/smira/flag"
	"os"
	"path/filepath"
	"runtime"
	"runtime/pprof"
	"strings"
	"time"
)

// AptlyContext is a common context shared by all commands
type AptlyContext struct {
	flags        *flag.FlagSet
	configLoaded bool

	progress          aptly.Progress
	downloader        aptly.Downloader
	database          database.Storage
	packagePool       aptly.PackagePool
	publishedStorage  aptly.PublishedStorage
	collectionFactory *deb.CollectionFactory
	dependencyOptions int
	architecturesList []string
	// Debug features
	fileCPUProfile *os.File
	fileMemProfile *os.File
	fileMemStats   *os.File
}

var context *AptlyContext

// FatalError is type for panicking to abort execution with non-zero
// exit code and print meaningful explanation
type FatalError struct {
	ReturnCode int
	Message    string
}

// Fatal panics and aborts execution with exit code 1
func Fatal(err error) {
	panic(&FatalError{ReturnCode: 1, Message: err.Error()})
}

// Config loads and returns current configuration
func (context *AptlyContext) Config() *utils.ConfigStructure {
	if !context.configLoaded {
		var err error

		configLocation := context.flags.Lookup("config").Value.String()
		if configLocation != "" {
			err = utils.LoadConfig(configLocation, &utils.Config)

			if err != nil {
				Fatal(err)
			}
		} else {
			configLocations := []string{
				filepath.Join(os.Getenv("HOME"), ".aptly.conf"),
				"/etc/aptly.conf",
			}

			for _, configLocation := range configLocations {
				err = utils.LoadConfig(configLocation, &utils.Config)
				if err == nil {
					break
				}
				if !os.IsNotExist(err) {
					Fatal(fmt.Errorf("error loading config file %s: %s", configLocation, err))
				}
			}

			if err != nil {
				fmt.Printf("Config file not found, creating default config at %s\n\n", configLocations[0])
				utils.SaveConfig(configLocations[0], &utils.Config)
			}
		}

		context.configLoaded = true

	}
	return &utils.Config
}

// DependencyOptions calculates options related to dependecy handling
func (context *AptlyContext) DependencyOptions() int {
	if context.dependencyOptions == -1 {
		context.dependencyOptions = 0
		if context.Config().DepFollowSuggests || context.flags.Lookup("dep-follow-suggests").Value.Get().(bool) {
			context.dependencyOptions |= deb.DepFollowSuggests
		}
		if context.Config().DepFollowRecommends || context.flags.Lookup("dep-follow-recommends").Value.Get().(bool) {
			context.dependencyOptions |= deb.DepFollowRecommends
		}
		if context.Config().DepFollowAllVariants || context.flags.Lookup("dep-follow-all-variants").Value.Get().(bool) {
			context.dependencyOptions |= deb.DepFollowAllVariants
		}
		if context.Config().DepFollowSource || context.flags.Lookup("dep-follow-source").Value.Get().(bool) {
			context.dependencyOptions |= deb.DepFollowSource
		}
	}

	return context.dependencyOptions
}

// ArchitecturesList returns list of architectures fixed via command line or config
func (context *AptlyContext) ArchitecturesList() []string {
	if context.architecturesList == nil {
		context.architecturesList = context.Config().Architectures
		optionArchitectures := context.flags.Lookup("architectures").Value.String()
		if optionArchitectures != "" {
			context.architecturesList = strings.Split(optionArchitectures, ",")
		}
	}

	return context.architecturesList
}

// Progress creates or returns Progress object
func (context *AptlyContext) Progress() aptly.Progress {
	if context.progress == nil {
		context.progress = console.NewProgress()
		context.progress.Start()
	}

	return context.progress
}

// Downloader returns instance of current downloader
func (context *AptlyContext) Downloader() aptly.Downloader {
	if context.downloader == nil {
		context.downloader = http.NewDownloader(context.Config().DownloadConcurrency, context.Progress())
	}

	return context.downloader
}

// DBPath builds path to database
func (context *AptlyContext) DBPath() string {
	return filepath.Join(context.Config().RootDir, "db")
}

// Database opens and returns current instance of database
func (context *AptlyContext) Database() (database.Storage, error) {
	if context.database == nil {
		var err error

		context.database, err = database.OpenDB(context.DBPath())
		if err != nil {
			return nil, fmt.Errorf("can't open database: %s", err)
		}
	}

	return context.database, nil
}

// CollectionFactory builds factory producing all kinds of collections
func (context *AptlyContext) CollectionFactory() *deb.CollectionFactory {
	if context.collectionFactory == nil {
		db, err := context.Database()
		if err != nil {
			Fatal(err)
		}
		context.collectionFactory = deb.NewCollectionFactory(db)
	}

	return context.collectionFactory
}

// PackagePool returns instance of PackagePool
func (context *AptlyContext) PackagePool() aptly.PackagePool {
	if context.packagePool == nil {
		context.packagePool = files.NewPackagePool(context.Config().RootDir)
	}

	return context.packagePool
}

// PublishedStorage returns instance of PublishedStorage
func (context *AptlyContext) PublishedStorage() aptly.PublishedStorage {
	if context.publishedStorage == nil {
		context.publishedStorage = files.NewPublishedStorage(context.Config().RootDir)
	}

	return context.publishedStorage
}

// ShutdownContext shuts context down
func ShutdownContext() {
	if aptly.EnableDebug {
		if context.fileMemProfile != nil {
			pprof.WriteHeapProfile(context.fileMemProfile)
			context.fileMemProfile.Close()
			context.fileMemProfile = nil
		}
		if context.fileCPUProfile != nil {
			pprof.StopCPUProfile()
			context.fileCPUProfile.Close()
			context.fileCPUProfile = nil
		}
		if context.fileMemProfile != nil {
			context.fileMemProfile.Close()
			context.fileMemProfile = nil
		}
	}
	if context.database != nil {
		context.database.Close()
	}
	if context.downloader != nil {
		context.downloader.Shutdown()
	}
	if context.progress != nil {
		context.progress.Shutdown()
	}
}

// InitContext initializes context with default settings
func InitContext(flags *flag.FlagSet) error {
	var err error

	context = &AptlyContext{flags: flags, dependencyOptions: -1}

	if aptly.EnableDebug {
		cpuprofile := flags.Lookup("cpuprofile").Value.String()
		if cpuprofile != "" {
			context.fileCPUProfile, err = os.Create(cpuprofile)
			if err != nil {
				return err
			}
			pprof.StartCPUProfile(context.fileCPUProfile)
		}

		memprofile := flags.Lookup("memprofile").Value.String()
		if memprofile != "" {
			context.fileMemProfile, err = os.Create(memprofile)
			if err != nil {
				return err
			}
		}

		memstats := flags.Lookup("memstats").Value.String()
		if memstats != "" {
			interval := flags.Lookup("meminterval").Value.Get().(time.Duration)

			context.fileMemStats, err = os.Create(memstats)
			if err != nil {
				return err
			}

			context.fileMemStats.WriteString("# Time\tHeapSys\tHeapAlloc\tHeapIdle\tHeapReleased\n")

			go func() {
				var stats runtime.MemStats

				start := time.Now().UnixNano()

				for {
					runtime.ReadMemStats(&stats)
					if context.fileMemStats != nil {
						context.fileMemStats.WriteString(fmt.Sprintf("%d\t%d\t%d\t%d\t%d\n",
							(time.Now().UnixNano()-start)/1000000, stats.HeapSys, stats.HeapAlloc, stats.HeapIdle, stats.HeapReleased))
						time.Sleep(interval)
					} else {
						break
					}
				}
			}()
		}
	}

	return nil
}
<|endoftext|>


<commit_before>// Copyright 2019 Google LLC
//
// 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 (
	"context"
	"encoding/json"
	"os"

	"github.com/GoogleCloudPlatform/terraform-validator/tfgcv"
	"github.com/pkg/errors"
	"github.com/spf13/cobra"
)

var convertCmd = &cobra.Command{
	Use:   "convert <tfplan>",
	Short: "Convert resources in a Terraform plan to their Google CAI representation.",
	Long: `Convert (terraform-validator convert) will convert a Terraform plan file
into CAI (Cloud Asset Inventory) resources and output them as a JSON array.

Note:
  Only supported resources will be converted. Non supported resources are
  omitted from results.
  Run "terraform-validator list-supported-resources" to see all supported
  resources.

Example:
  terraform-validator convert ./example/terraform.tfplan --project my-project \
    --ancestry organization/my-org/folder/my-folder
`,
	PreRunE: func(c *cobra.Command, args []string) error {
		if len(args) != 1 {
			return errors.New("missing required argument <tfplan>")
		}
		if flags.validate.offline && flags.validate.ancestry == "" {
			return errors.New("please set ancestry via --ancestry in offline mode")
		}
		return nil
	},
	RunE: func(c *cobra.Command, args []string) error {
		ctx := context.Background()
		assets, err := tfgcv.ReadPlannedAssets(ctx, args[0], flags.convert.project, flags.convert.ancestry, flags.convert.offline)
		if err != nil {
			if errors.Cause(err) == tfgcv.ErrParsingProviderProject {
				return errors.New("unable to parse provider project, please use --project flag")
			}
			return errors.Wrap(err, "converting tfplan to CAI assets")
		}

		if err := json.NewEncoder(os.Stdout).Encode(assets); err != nil {
			return errors.Wrap(err, "encoding json")
		}

		return nil
	},
}
<commit_msg>Corrected flags checked in convert pre-run (#204)<commit_after>// Copyright 2019 Google LLC
//
// 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 (
	"context"
	"encoding/json"
	"os"

	"github.com/GoogleCloudPlatform/terraform-validator/tfgcv"
	"github.com/pkg/errors"
	"github.com/spf13/cobra"
)

var convertCmd = &cobra.Command{
	Use:   "convert <tfplan>",
	Short: "Convert resources in a Terraform plan to their Google CAI representation.",
	Long: `Convert (terraform-validator convert) will convert a Terraform plan file
into CAI (Cloud Asset Inventory) resources and output them as a JSON array.

Note:
  Only supported resources will be converted. Non supported resources are
  omitted from results.
  Run "terraform-validator list-supported-resources" to see all supported
  resources.

Example:
  terraform-validator convert ./example/terraform.tfplan --project my-project \
    --ancestry organization/my-org/folder/my-folder
`,
	PreRunE: func(c *cobra.Command, args []string) error {
		if len(args) != 1 {
			return errors.New("missing required argument <tfplan>")
		}
		if flags.convert.offline && flags.convert.ancestry == "" {
			return errors.New("please set ancestry via --ancestry in offline mode")
		}
		return nil
	},
	RunE: func(c *cobra.Command, args []string) error {
		ctx := context.Background()
		assets, err := tfgcv.ReadPlannedAssets(ctx, args[0], flags.convert.project, flags.convert.ancestry, flags.convert.offline)
		if err != nil {
			if errors.Cause(err) == tfgcv.ErrParsingProviderProject {
				return errors.New("unable to parse provider project, please use --project flag")
			}
			return errors.Wrap(err, "converting tfplan to CAI assets")
		}

		if err := json.NewEncoder(os.Stdout).Encode(assets); err != nil {
			return errors.Wrap(err, "encoding json")
		}

		return nil
	},
}
<|endoftext|>


<commit_before>/*
Copyright 2014 Google 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 main

import (
	"flag"
	"io/ioutil"
	"os"
	"runtime"
	"strconv"
	"time"

	"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/clientauth"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
	"github.com/golang/glog"
)

var (
	authConfig = flag.String("auth_config", os.Getenv("HOME")+"/.kubernetes_auth", "Path to the auth info file.")
	host       = flag.String("host", "", "The host to connect to")
)

func waitForPodRunning(c *client.Client, id string) {
	for {
		time.Sleep(5 * time.Second)
		pod, err := c.Pods(api.NamespaceDefault).Get(id)
		if err != nil {
			glog.Warningf("Get pod failed: %v", err)
			continue
		}
		if pod.CurrentState.Status == api.PodRunning {
			break
		}
		glog.Infof("Waiting for pod status to be running (%s)", pod.CurrentState.Status)
	}
}

func loadObjectOrDie(filePath string) interface{} {
	data, err := ioutil.ReadFile(filePath)
	if err != nil {
		glog.Fatalf("Failed to read pod: %v", err)
	}
	obj, err := latest.Codec.Decode(data)
	if err != nil {
		glog.Fatalf("Failed to decode pod: %v", err)
	}
	return obj
}

func loadPodOrDie(filePath string) *api.Pod {
	obj := loadObjectOrDie(filePath)
	pod, ok := obj.(*api.Pod)
	if !ok {
		glog.Fatalf("Failed to load pod: %v", obj)
	}
	return pod
}

func loadClientOrDie() *client.Client {
	config := client.Config{
		Host: *host,
	}
	auth, err := clientauth.LoadFromFile(*authConfig)
	if err != nil {
		glog.Fatalf("Error loading auth: %v", err)
	}
	config, err = auth.MergeWithConfig(config)
	if err != nil {
		glog.Fatalf("Error creating client")
	}
	c, err := client.New(&config)
	if err != nil {
		glog.Fatalf("Error creating client")
	}
	return c
}

func TestKubernetesROService(c *client.Client) bool {
	svc := api.ServiceList{}
	err := c.Get().
		Namespace("default").
		AbsPath("/api/v1beta1/proxy/services/kubernetes-ro/api/v1beta1/services").
		Do().
		Into(&svc)
	if err != nil {
		glog.Errorf("unexpected error listing services using ro service: %v", err)
		return false
	}
	var foundRW, foundRO bool
	for i := range svc.Items {
		if svc.Items[i].Name == "kubernetes" {
			foundRW = true
		}
		if svc.Items[i].Name == "kubernetes-ro" {
			foundRO = true
		}
	}
	if !foundRW {
		glog.Error("no RW service found")
	}
	if !foundRO {
		glog.Error("no RO service found")
	}
	if !foundRW || !foundRO {
		return false
	}
	return true
}

func TestPodUpdate(c *client.Client) bool {
	podClient := c.Pods(api.NamespaceDefault)

	pod := loadPodOrDie("./api/examples/pod.json")
	value := strconv.Itoa(time.Now().Nanosecond())
	pod.Labels["time"] = value

	_, err := podClient.Create(pod)
	if err != nil {
		glog.Errorf("Failed to create pod: %v", err)
		return false
	}
	defer podClient.Delete(pod.Name)
	waitForPodRunning(c, pod.Name)
	pods, err := podClient.List(labels.SelectorFromSet(labels.Set(map[string]string{"time": value})))
	if len(pods.Items) != 1 {
		glog.Errorf("Failed to find the correct pod")
		return false
	}

	podOut, err := podClient.Get(pod.Name)
	if err != nil {
		glog.Errorf("Failed to get pod: %v", err)
		return false
	}
	value = "time" + value
	pod.Labels["time"] = value
	pod.ResourceVersion = podOut.ResourceVersion
	pod.DesiredState.Manifest.UUID = podOut.DesiredState.Manifest.UUID
	pod, err = podClient.Update(pod)
	if err != nil {
		glog.Errorf("Failed to update pod: %v", err)
		return false
	}
	waitForPodRunning(c, pod.Name)
	pods, err = podClient.List(labels.SelectorFromSet(labels.Set(map[string]string{"time": value})))
	if len(pods.Items) != 1 {
		glog.Errorf("Failed to find the correct pod after update.")
		return false
	}
	glog.Infof("pod update OK")
	return true
}

// TestKubeletSendsEvent checks that kubelets and scheduler send events about pods scheduling and running.
func TestKubeletSendsEvent(c *client.Client) bool {
	podClient := c.Pods(api.NamespaceDefault)

	pod := loadPodOrDie("./api/examples/pod.json")
	value := strconv.Itoa(time.Now().Nanosecond())
	pod.Labels["time"] = value

	_, err := podClient.Create(pod)
	if err != nil {
		glog.Errorf("Failed to create pod: %v", err)
		return false
	}
	defer podClient.Delete(pod.Name)
	waitForPodRunning(c, pod.Name)
	pods, err := podClient.List(labels.SelectorFromSet(labels.Set(map[string]string{"time": value})))
	if len(pods.Items) != 1 {
		glog.Errorf("Failed to find the correct pod")
		return false
	}

	_, err = podClient.Get(pod.Name)
	if err != nil {
		glog.Errorf("Failed to get pod: %v", err)
		return false
	}

	// Check for scheduler event about the pod.
	events, err := c.Events(api.NamespaceDefault).List(
		labels.Everything(),
		labels.Set{
			"involvedObject.name":      pod.Name,
			"involvedObject.kind":      "Pod",
			"involvedObject.namespace": api.NamespaceDefault,
			"source":                   "scheduler",
		}.AsSelector(),
	)
	if err != nil {
		glog.Error("Error while listing events:", err)
		return false
	}
	if len(events.Items) == 0 {
		glog.Error("Didn't see any scheduler events even though pod was running.")
		return false
	}
	glog.Info("Saw scheduler event for our pod.")

	// Check for kubelet event about the pod.
	events, err = c.Events(api.NamespaceDefault).List(
		labels.Everything(),
		labels.Set{
			"involvedObject.name":      pod.Name,
			"involvedObject.kind":      "BoundPod",
			"involvedObject.namespace": api.NamespaceDefault,
			"source":                   "kubelet",
		}.AsSelector(),
	)
	if err != nil {
		glog.Error("Error while listing events:", err)
		return false
	}
	if len(events.Items) == 0 {
		glog.Error("Didn't see any kubelet events even though pod was running.")
		return false
	}
	glog.Info("Saw kubelet event for our pod.")
	return true
}

func main() {
	flag.Parse()
	runtime.GOMAXPROCS(runtime.NumCPU())
	util.ReallyCrash = true
	util.InitLogs()
	defer util.FlushLogs()

	go func() {
		defer util.FlushLogs()
		time.Sleep(3 * time.Minute)
		glog.Fatalf("This test has timed out.")
	}()

	c := loadClientOrDie()

	tests := []func(c *client.Client) bool{
		TestKubernetesROService,
		TestKubeletSendsEvent,
		// TODO(brendandburns): fix this test and re-add it: TestPodUpdate,
	}

	passed := true
	for _, test := range tests {
		testPassed := test(c)
		if !testPassed {
			passed = false
		}
	}
	if !passed {
		glog.Fatalf("Tests failed")
	}
}
<commit_msg>Only test events on GCE.<commit_after>/*
Copyright 2014 Google 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 main

import (
	"flag"
	"io/ioutil"
	"os"
	"runtime"
	"strconv"
	"time"

	"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/clientauth"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
	"github.com/golang/glog"
)

var (
	authConfig = flag.String("auth_config", os.Getenv("HOME")+"/.kubernetes_auth", "Path to the auth info file.")
	host       = flag.String("host", "", "The host to connect to")
)

func waitForPodRunning(c *client.Client, id string) {
	for {
		time.Sleep(5 * time.Second)
		pod, err := c.Pods(api.NamespaceDefault).Get(id)
		if err != nil {
			glog.Warningf("Get pod failed: %v", err)
			continue
		}
		if pod.CurrentState.Status == api.PodRunning {
			break
		}
		glog.Infof("Waiting for pod status to be running (%s)", pod.CurrentState.Status)
	}
}

func loadObjectOrDie(filePath string) interface{} {
	data, err := ioutil.ReadFile(filePath)
	if err != nil {
		glog.Fatalf("Failed to read pod: %v", err)
	}
	obj, err := latest.Codec.Decode(data)
	if err != nil {
		glog.Fatalf("Failed to decode pod: %v", err)
	}
	return obj
}

func loadPodOrDie(filePath string) *api.Pod {
	obj := loadObjectOrDie(filePath)
	pod, ok := obj.(*api.Pod)
	if !ok {
		glog.Fatalf("Failed to load pod: %v", obj)
	}
	return pod
}

func loadClientOrDie() *client.Client {
	config := client.Config{
		Host: *host,
	}
	auth, err := clientauth.LoadFromFile(*authConfig)
	if err != nil {
		glog.Fatalf("Error loading auth: %v", err)
	}
	config, err = auth.MergeWithConfig(config)
	if err != nil {
		glog.Fatalf("Error creating client")
	}
	c, err := client.New(&config)
	if err != nil {
		glog.Fatalf("Error creating client")
	}
	return c
}

func TestKubernetesROService(c *client.Client) bool {
	svc := api.ServiceList{}
	err := c.Get().
		Namespace("default").
		AbsPath("/api/v1beta1/proxy/services/kubernetes-ro/api/v1beta1/services").
		Do().
		Into(&svc)
	if err != nil {
		glog.Errorf("unexpected error listing services using ro service: %v", err)
		return false
	}
	var foundRW, foundRO bool
	for i := range svc.Items {
		if svc.Items[i].Name == "kubernetes" {
			foundRW = true
		}
		if svc.Items[i].Name == "kubernetes-ro" {
			foundRO = true
		}
	}
	if !foundRW {
		glog.Error("no RW service found")
	}
	if !foundRO {
		glog.Error("no RO service found")
	}
	if !foundRW || !foundRO {
		return false
	}
	return true
}

func TestPodUpdate(c *client.Client) bool {
	podClient := c.Pods(api.NamespaceDefault)

	pod := loadPodOrDie("./api/examples/pod.json")
	value := strconv.Itoa(time.Now().Nanosecond())
	pod.Labels["time"] = value

	_, err := podClient.Create(pod)
	if err != nil {
		glog.Errorf("Failed to create pod: %v", err)
		return false
	}
	defer podClient.Delete(pod.Name)
	waitForPodRunning(c, pod.Name)
	pods, err := podClient.List(labels.SelectorFromSet(labels.Set(map[string]string{"time": value})))
	if len(pods.Items) != 1 {
		glog.Errorf("Failed to find the correct pod")
		return false
	}

	podOut, err := podClient.Get(pod.Name)
	if err != nil {
		glog.Errorf("Failed to get pod: %v", err)
		return false
	}
	value = "time" + value
	pod.Labels["time"] = value
	pod.ResourceVersion = podOut.ResourceVersion
	pod.DesiredState.Manifest.UUID = podOut.DesiredState.Manifest.UUID
	pod, err = podClient.Update(pod)
	if err != nil {
		glog.Errorf("Failed to update pod: %v", err)
		return false
	}
	waitForPodRunning(c, pod.Name)
	pods, err = podClient.List(labels.SelectorFromSet(labels.Set(map[string]string{"time": value})))
	if len(pods.Items) != 1 {
		glog.Errorf("Failed to find the correct pod after update.")
		return false
	}
	glog.Infof("pod update OK")
	return true
}

// TestKubeletSendsEvent checks that kubelets and scheduler send events about pods scheduling and running.
func TestKubeletSendsEvent(c *client.Client) bool {
	provider := os.Getenv("KUBERNETES_PROVIDER")
	if provider == "" {
		glog.Errorf("unable to detect cloud type.")
		return false
	}
	if provider != "gce" {
		glog.Infof("skipping TestKubeletSendsEvent on cloud provider %s", provider)
		return true
	}

	podClient := c.Pods(api.NamespaceDefault)

	pod := loadPodOrDie("./api/examples/pod.json")
	value := strconv.Itoa(time.Now().Nanosecond())
	pod.Labels["time"] = value

	_, err := podClient.Create(pod)
	if err != nil {
		glog.Errorf("Failed to create pod: %v", err)
		return false
	}
	defer podClient.Delete(pod.Name)
	waitForPodRunning(c, pod.Name)
	pods, err := podClient.List(labels.SelectorFromSet(labels.Set(map[string]string{"time": value})))
	if len(pods.Items) != 1 {
		glog.Errorf("Failed to find the correct pod")
		return false
	}

	_, err = podClient.Get(pod.Name)
	if err != nil {
		glog.Errorf("Failed to get pod: %v", err)
		return false
	}

	// Check for scheduler event about the pod.
	events, err := c.Events(api.NamespaceDefault).List(
		labels.Everything(),
		labels.Set{
			"involvedObject.name":      pod.Name,
			"involvedObject.kind":      "Pod",
			"involvedObject.namespace": api.NamespaceDefault,
			"source":                   "scheduler",
			"time":                     value,
		}.AsSelector(),
	)
	if err != nil {
		glog.Error("Error while listing events:", err)
		return false
	}
	if len(events.Items) == 0 {
		glog.Error("Didn't see any scheduler events even though pod was running.")
		return false
	}
	glog.Info("Saw scheduler event for our pod.")

	// Check for kubelet event about the pod.
	events, err = c.Events(api.NamespaceDefault).List(
		labels.Everything(),
		labels.Set{
			"involvedObject.name":      pod.Name,
			"involvedObject.kind":      "BoundPod",
			"involvedObject.namespace": api.NamespaceDefault,
			"source":                   "kubelet",
		}.AsSelector(),
	)
	if err != nil {
		glog.Error("Error while listing events:", err)
		return false
	}
	if len(events.Items) == 0 {
		glog.Error("Didn't see any kubelet events even though pod was running.")
		return false
	}
	glog.Info("Saw kubelet event for our pod.")
	return true
}

func main() {
	flag.Parse()
	runtime.GOMAXPROCS(runtime.NumCPU())
	util.ReallyCrash = true
	util.InitLogs()
	defer util.FlushLogs()

	go func() {
		defer util.FlushLogs()
		time.Sleep(3 * time.Minute)
		glog.Fatalf("This test has timed out.")
	}()

	c := loadClientOrDie()

	tests := []func(c *client.Client) bool{
		TestKubernetesROService,
		TestKubeletSendsEvent,
		// TODO(brendandburns): fix this test and re-add it: TestPodUpdate,
	}

	passed := true
	for _, test := range tests {
		testPassed := test(c)
		if !testPassed {
			passed = false
		}
		// TODO: clean up objects created during a test after the test, so cases
		// are independent.
	}
	if !passed {
		glog.Fatalf("Tests failed")
	}
}
<|endoftext|>


<commit_before>// Copyright © 2016 Wei-Ting Kuo <waitingkuo0527@gmail.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package cmd

import (
	"fmt"
	"github.com/mitchellh/go-homedir"
	"os"
	"path/filepath"
	"runtime"
	"strings"

	"github.com/spf13/cobra"
	"github.com/waitingkuo/belt/utils"
)

// installCmd represents the install command
var installCmd = &cobra.Command{
	Use:   "install",
	Short: "A brief description of your command",
	Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
	Run: func(cmd *cobra.Command, args []string) {

		homeDir, err := homedir.Dir()
		if err != nil {
			panic(err)
		}

		rootPath := filepath.Join(homeDir, ".belt")

		// FIXME
		// move the store relative codes to store.go
		binPath := filepath.Join(rootPath, "bin")
		if err = os.MkdirAll(binPath, 0755); err != nil {
			panic(err)
		}

		if len(args) == 0 {
			os.Exit(0) // should define a better code
		}

		packageName := args[0]
		// FIXME
		// should build a better way to download packages
		// check how congo or brew work
		// missing verson control
		// move to another dir (pkg?)

		// consider GOARCH
		var rawurl string
		switch runtime.GOOS {
		case "linux":
			rawurl = "https://github.com/coreos/etcd/releases/download/v3.0.6/etcd-v3.0.6-linux-amd64.zip"
		case "darwin":
			rawurl = "https://github.com/coreos/etcd/releases/download/v3.0.6/etcd-v3.0.6-darwin-amd64.zip"
		default:
			fmt.Println(runtime.GOOS, "isn't supported")
		}
		if packageName == "etcd" {
			fmt.Println("Downloading ...")
			destPath, err := utils.Download(rawurl, "/tmp")
			if err != nil {
				panic(err)
			}
			fmt.Println("unziping", destPath)
			//fmt.Println("unzip ok")
			if err := utils.Unzip(destPath, "/tmp"); err != nil {
				panic(err)
			}
			dir := strings.TrimSuffix(destPath, filepath.Ext(destPath))
			os.Rename(filepath.Join(dir, "etcd"), filepath.Join(binPath, "etcd"))
			os.Rename(filepath.Join(dir, "etcdctl"), filepath.Join(binPath, "etcdctl"))

		}
	},
}

func init() {
	RootCmd.AddCommand(installCmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// installCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// installCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")

}
<commit_msg>add comment<commit_after>// Copyright © 2016 Wei-Ting Kuo <waitingkuo0527@gmail.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package cmd

import (
	"fmt"
	"github.com/mitchellh/go-homedir"
	"os"
	"path/filepath"
	"runtime"
	"strings"

	"github.com/spf13/cobra"
	"github.com/waitingkuo/belt/utils"
)

// installCmd represents the install command
var installCmd = &cobra.Command{
	Use:   "install",
	Short: "A brief description of your command",
	Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
	Run: func(cmd *cobra.Command, args []string) {

		homeDir, err := homedir.Dir()
		if err != nil {
			panic(err)
		}

		rootPath := filepath.Join(homeDir, ".belt")

		// FIXME
		// move the store relative codes to store.go
		binPath := filepath.Join(rootPath, "bin")
		if err = os.MkdirAll(binPath, 0755); err != nil {
			panic(err)
		}

		if len(args) == 0 {
			os.Exit(0) // should define a better code
		}

		packageName := args[0]
		// FIXME
		// should build a better way to download packages
		// check how congo or brew work
		// missing verson control
		// move to another dir (pkg?)
		// consider using outer bash instead

		// consider GOARCH
		var rawurl string
		switch runtime.GOOS {
		case "linux":
			rawurl = "https://github.com/coreos/etcd/releases/download/v3.0.6/etcd-v3.0.6-linux-amd64.zip"
		case "darwin":
			rawurl = "https://github.com/coreos/etcd/releases/download/v3.0.6/etcd-v3.0.6-darwin-amd64.zip"
		default:
			fmt.Println(runtime.GOOS, "isn't supported")
		}
		if packageName == "etcd" {
			fmt.Println("Downloading ...")
			destPath, err := utils.Download(rawurl, "/tmp")
			if err != nil {
				panic(err)
			}
			fmt.Println("unziping", destPath)
			//fmt.Println("unzip ok")
			if err := utils.Unzip(destPath, "/tmp"); err != nil {
				panic(err)
			}
			dir := strings.TrimSuffix(destPath, filepath.Ext(destPath))
			os.Rename(filepath.Join(dir, "etcd"), filepath.Join(binPath, "etcd"))
			os.Rename(filepath.Join(dir, "etcdctl"), filepath.Join(binPath, "etcdctl"))

		}
	},
}

func init() {
	RootCmd.AddCommand(installCmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// installCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// installCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")

}
<|endoftext|>