<commit_before>package aws

import (
	"fmt"
	"log"
	"time"

	"github.com/hashicorp/terraform/helper/resource"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/ec2"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/helper/validation"
)

func resourceAwsEc2TransitGatewayRoute() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsEc2TransitGatewayRouteCreate,
		Read:   resourceAwsEc2TransitGatewayRouteRead,
		Delete: resourceAwsEc2TransitGatewayRouteDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"destination_cidr_block": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"transit_gateway_attachment_id": {
				Type:         schema.TypeString,
				Required:     true,
				ForceNew:     true,
				ValidateFunc: validation.NoZeroValues,
			},
			"transit_gateway_route_table_id": {
				Type:         schema.TypeString,
				Required:     true,
				ForceNew:     true,
				ValidateFunc: validation.NoZeroValues,
			},
		},
	}
}

func resourceAwsEc2TransitGatewayRouteCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn

	destination := d.Get("destination_cidr_block").(string)
	transitGatewayRouteTableID := d.Get("transit_gateway_route_table_id").(string)

	input := &ec2.CreateTransitGatewayRouteInput{
		DestinationCidrBlock:       aws.String(destination),
		TransitGatewayAttachmentId: aws.String(d.Get("transit_gateway_attachment_id").(string)),
		TransitGatewayRouteTableId: aws.String(transitGatewayRouteTableID),
	}

	log.Printf("[DEBUG] Creating EC2 Transit Gateway Route: %s", input)
	_, err := conn.CreateTransitGatewayRoute(input)
	if err != nil {
		return fmt.Errorf("error creating EC2 Transit Gateway Route: %s", err)
	}

	d.SetId(fmt.Sprintf("%s_%s", transitGatewayRouteTableID, destination))

	return resourceAwsEc2TransitGatewayRouteRead(d, meta)
}

func resourceAwsEc2TransitGatewayRouteRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn

	transitGatewayRouteTableID, destination, err := decodeEc2TransitGatewayRouteID(d.Id())
	if err != nil {
		return err
	}

	// Handle EC2 eventual consistency
	var transitGatewayRoute *ec2.TransitGatewayRoute
	err = resource.Retry(1*time.Minute, func() *resource.RetryError {
		var err error
		transitGatewayRoute, err = ec2DescribeTransitGatewayRoute(conn, transitGatewayRouteTableID, destination)

		if err != nil {
			return resource.NonRetryableError(err)
		}

		if d.IsNewResource() && transitGatewayRoute == nil {
			return resource.RetryableError(&resource.NotFoundError{})
		}

		return nil
	})

	if isResourceTimeoutError(err) {
		transitGatewayRoute, err = ec2DescribeTransitGatewayRoute(conn, transitGatewayRouteTableID, destination)
	}

	if isAWSErr(err, "InvalidRouteTableID.NotFound", "") {
		log.Printf("[WARN] EC2 Transit Gateway Route Table (%s) not found, removing from state", transitGatewayRouteTableID)
		d.SetId("")
		return nil
	}

	if isResourceNotFoundError(err) {
		log.Printf("[WARN] EC2 Transit Gateway Route (%s) not found, removing from state", d.Id())
		d.SetId("")
		return nil
	}

	if err != nil {
		return fmt.Errorf("error reading EC2 Transit Gateway Route: %s", err)
	}

	if transitGatewayRoute == nil {
		log.Printf("[WARN] EC2 Transit Gateway Route (%s) not found, removing from state", d.Id())
		d.SetId("")
		return nil
	}

	state := aws.StringValue(transitGatewayRoute.State)
	if state == ec2.TransitGatewayRouteStateDeleted || state == ec2.TransitGatewayRouteStateDeleting {
		log.Printf("[WARN] EC2 Transit Gateway Route (%s) deleted, removing from state", d.Id())
		d.SetId("")
		return nil
	}

	d.Set("destination_cidr_block", transitGatewayRoute.DestinationCidrBlock)

	d.Set("transit_gateway_attachment_id", "")
	if len(transitGatewayRoute.TransitGatewayAttachments) > 0 && transitGatewayRoute.TransitGatewayAttachments[0] != nil {
		d.Set("transit_gateway_attachment_id", transitGatewayRoute.TransitGatewayAttachments[0].TransitGatewayAttachmentId)
	}

	d.Set("transit_gateway_route_table_id", transitGatewayRouteTableID)

	return nil
}

func resourceAwsEc2TransitGatewayRouteDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn

	transitGatewayRouteTableID, destination, err := decodeEc2TransitGatewayRouteID(d.Id())
	if err != nil {
		return err
	}

	input := &ec2.DeleteTransitGatewayRouteInput{
		DestinationCidrBlock:       aws.String(destination),
		TransitGatewayRouteTableId: aws.String(transitGatewayRouteTableID),
	}

	log.Printf("[DEBUG] Deleting EC2 Transit Gateway Route (%s): %s", d.Id(), input)
	_, err = conn.DeleteTransitGatewayRoute(input)

	if isAWSErr(err, "InvalidRoute.NotFound", "") || isAWSErr(err, "InvalidRouteTableID.NotFound", "") {
		return nil
	}

	if err != nil {
		return fmt.Errorf("error deleting EC2 Transit Gateway Route: %s", err)
	}

	return nil
}
<commit_msg>Add the blackhole parameter for a Transit Gateway route<commit_after>package aws

import (
	"fmt"
	"log"
	"time"

	"github.com/hashicorp/terraform/helper/resource"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/ec2"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/helper/validation"
)

func resourceAwsEc2TransitGatewayRoute() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsEc2TransitGatewayRouteCreate,
		Read:   resourceAwsEc2TransitGatewayRouteRead,
		Delete: resourceAwsEc2TransitGatewayRouteDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"destination_cidr_block": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"blackhole": {
				Type:     schema.TypeBool,
				Optional: true,
				ForceNew: true,
				Default:  false,
			},
			"transit_gateway_attachment_id": {
				Type:         schema.TypeString,
				Optional:     true,
				ForceNew:     true,
				ValidateFunc: validation.NoZeroValues,
			},
			"transit_gateway_route_table_id": {
				Type:         schema.TypeString,
				Required:     true,
				ForceNew:     true,
				ValidateFunc: validation.NoZeroValues,
			},
		},
	}
}

func resourceAwsEc2TransitGatewayRouteCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn

	destination := d.Get("destination_cidr_block").(string)
	transitGatewayRouteTableID := d.Get("transit_gateway_route_table_id").(string)

	input := &ec2.CreateTransitGatewayRouteInput{
		DestinationCidrBlock:       aws.String(destination),
		Blackhole:                  aws.Bool(d.Get("blackhole").(bool)),
		TransitGatewayAttachmentId: aws.String(d.Get("transit_gateway_attachment_id").(string)),
		TransitGatewayRouteTableId: aws.String(transitGatewayRouteTableID),
	}

	log.Printf("[DEBUG] Creating EC2 Transit Gateway Route: %s", input)
	_, err := conn.CreateTransitGatewayRoute(input)
	if err != nil {
		return fmt.Errorf("error creating EC2 Transit Gateway Route: %s", err)
	}

	d.SetId(fmt.Sprintf("%s_%s", transitGatewayRouteTableID, destination))

	return resourceAwsEc2TransitGatewayRouteRead(d, meta)
}

func resourceAwsEc2TransitGatewayRouteRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn

	transitGatewayRouteTableID, destination, err := decodeEc2TransitGatewayRouteID(d.Id())
	if err != nil {
		return err
	}

	// Handle EC2 eventual consistency
	var transitGatewayRoute *ec2.TransitGatewayRoute
	err = resource.Retry(1*time.Minute, func() *resource.RetryError {
		var err error
		transitGatewayRoute, err = ec2DescribeTransitGatewayRoute(conn, transitGatewayRouteTableID, destination)

		if err != nil {
			return resource.NonRetryableError(err)
		}

		if d.IsNewResource() && transitGatewayRoute == nil {
			return resource.RetryableError(&resource.NotFoundError{})
		}

		return nil
	})

	if isResourceTimeoutError(err) {
		transitGatewayRoute, err = ec2DescribeTransitGatewayRoute(conn, transitGatewayRouteTableID, destination)
	}

	if isAWSErr(err, "InvalidRouteTableID.NotFound", "") {
		log.Printf("[WARN] EC2 Transit Gateway Route Table (%s) not found, removing from state", transitGatewayRouteTableID)
		d.SetId("")
		return nil
	}

	if isResourceNotFoundError(err) {
		log.Printf("[WARN] EC2 Transit Gateway Route (%s) not found, removing from state", d.Id())
		d.SetId("")
		return nil
	}

	if err != nil {
		return fmt.Errorf("error reading EC2 Transit Gateway Route: %s", err)
	}

	if transitGatewayRoute == nil {
		log.Printf("[WARN] EC2 Transit Gateway Route (%s) not found, removing from state", d.Id())
		d.SetId("")
		return nil
	}

	state := aws.StringValue(transitGatewayRoute.State)
	if state == ec2.TransitGatewayRouteStateDeleted || state == ec2.TransitGatewayRouteStateDeleting {
		log.Printf("[WARN] EC2 Transit Gateway Route (%s) deleted, removing from state", d.Id())
		d.SetId("")
		return nil
	}

	d.Set("destination_cidr_block", transitGatewayRoute.DestinationCidrBlock)

	d.Set("transit_gateway_attachment_id", "")
	if len(transitGatewayRoute.TransitGatewayAttachments) > 0 && transitGatewayRoute.TransitGatewayAttachments[0] != nil {
		d.Set("transit_gateway_attachment_id", transitGatewayRoute.TransitGatewayAttachments[0].TransitGatewayAttachmentId)
		d.Set("blackhole", false)
	} else {
		d.Set("blackhole", true)
	}
	d.Set("transit_gateway_route_table_id", transitGatewayRouteTableID)

	return nil
}

func resourceAwsEc2TransitGatewayRouteDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn

	transitGatewayRouteTableID, destination, err := decodeEc2TransitGatewayRouteID(d.Id())
	if err != nil {
		return err
	}

	input := &ec2.DeleteTransitGatewayRouteInput{
		DestinationCidrBlock:       aws.String(destination),
		TransitGatewayRouteTableId: aws.String(transitGatewayRouteTableID),
	}

	log.Printf("[DEBUG] Deleting EC2 Transit Gateway Route (%s): %s", d.Id(), input)
	_, err = conn.DeleteTransitGatewayRoute(input)

	if isAWSErr(err, "InvalidRoute.NotFound", "") || isAWSErr(err, "InvalidRouteTableID.NotFound", "") {
		return nil
	}

	if err != nil {
		return fmt.Errorf("error deleting EC2 Transit Gateway Route: %s", err)
	}

	return nil
}
<|endoftext|>


<commit_before>package network

import (
	"sync"

	"github.com/micro/go-micro/config/options"
	"github.com/micro/go-micro/network/router"
	"github.com/micro/go-micro/network/proxy"
)

type network struct {
	options.Options

	// router
	r router.Router

	// proxy
	p proxy.Proxy

	// id of this network
	id string

	// links maintained for this network
	mtx sync.RWMutex
	links []Link
}

type node struct {
	*network

	// address of this node
	address string
}

type link struct {
	// the embedded node
	*node

	// length and weight of the link
	mtx sync.RWMutex
	length, weight int
}

// network methods

func (n *network) Id() string {
	return n.id
}

func (n *network) Connect() (Node, error) {
	return nil, nil
}

func (n *network) Peer(Network) (Link, error) {
	return nil, nil
}

func (n *network) Links() ([]Link, error) {
	n.mtx.RLock()
	defer n.mtx.RUnlock()
	return n.links, nil
}

// node methods

func (n *node) Address() string {
	return n.address
}

func (n *node) Close() error {
	return nil
}

func (n *node) Accept() (*Message, error) {
	return nil, nil
}

func (n *node) Send(*Message) error {
	return nil
}

// link methods

func (l *link) Length() int {
	l.mtx.RLock()
	defer l.mtx.RUnlock()
	return l.length
}

func (l *link) Weight() int {
	l.mtx.RLock()
	defer l.mtx.RUnlock()
	return l.weight
}
<commit_msg>go fmt<commit_after>package network

import (
	"sync"

	"github.com/micro/go-micro/config/options"
	"github.com/micro/go-micro/network/proxy"
	"github.com/micro/go-micro/network/router"
)

type network struct {
	options.Options

	// router
	r router.Router

	// proxy
	p proxy.Proxy

	// id of this network
	id string

	// links maintained for this network
	mtx   sync.RWMutex
	links []Link
}

type node struct {
	*network

	// address of this node
	address string
}

type link struct {
	// the embedded node
	*node

	// length and weight of the link
	mtx    sync.RWMutex
	length int
	weight int
}

// network methods

func (n *network) Id() string {
	return n.id
}

func (n *network) Connect() (Node, error) {
	return nil, nil
}

func (n *network) Peer(Network) (Link, error) {
	return nil, nil
}

func (n *network) Links() ([]Link, error) {
	n.mtx.RLock()
	defer n.mtx.RUnlock()
	return n.links, nil
}

// node methods

func (n *node) Address() string {
	return n.address
}

func (n *node) Close() error {
	return nil
}

func (n *node) Accept() (*Message, error) {
	return nil, nil
}

func (n *node) Send(*Message) error {
	return nil
}

// link methods

func (l *link) Length() int {
	l.mtx.RLock()
	defer l.mtx.RUnlock()
	return l.length
}

func (l *link) Weight() int {
	l.mtx.RLock()
	defer l.mtx.RUnlock()
	return l.weight
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/grpc-ecosystem/go-grpc-middleware"
	"github.com/grpc-ecosystem/go-grpc-middleware/recovery"
	"github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
	"github.com/grpc-ecosystem/go-grpc-prometheus"
	"google.golang.org/grpc"
)

func init() {
	// TODO: Set global gRPC logger
	// grpclog.SetLogger()
}

func createGrpcServer(appCtx *application) *grpc.Server {
	server := grpc.NewServer(
		grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(
			grpc_opentracing.StreamServerInterceptor(grpc_opentracing.WithTracer(appCtx.tracer)),
			grpc_prometheus.StreamServerInterceptor,
			grpc_recovery.StreamServerInterceptor(),
		)),
		grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
			grpc_opentracing.UnaryServerInterceptor(grpc_opentracing.WithTracer(appCtx.tracer)),
			grpc_prometheus.UnaryServerInterceptor,
			grpc_recovery.UnaryServerInterceptor(),
		)),
	)

	return server
}
<commit_msg>Improve grpc logging<commit_after>package main

import (
	"github.com/go-kit/kit/log"
	"github.com/go-kit/kit/log/level"
	"github.com/grpc-ecosystem/go-grpc-middleware"
	"github.com/grpc-ecosystem/go-grpc-middleware/recovery"
	"github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
	"github.com/grpc-ecosystem/go-grpc-prometheus"
	"google.golang.org/grpc"
	"google.golang.org/grpc/grpclog"
)

func createGrpcServer(appCtx *application) *grpc.Server {
	// TODO: separate log levels
	grpclog.SetLoggerV2(grpclog.NewLoggerV2(
		log.NewStdlibAdapter(level.Info(appCtx.logger)),
		log.NewStdlibAdapter(level.Warn(appCtx.logger)),
		log.NewStdlibAdapter(level.Error(appCtx.logger)),
	))

	server := grpc.NewServer(
		grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(
			grpc_opentracing.StreamServerInterceptor(grpc_opentracing.WithTracer(appCtx.tracer)),
			grpc_prometheus.StreamServerInterceptor,
			grpc_recovery.StreamServerInterceptor(),
		)),
		grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
			grpc_opentracing.UnaryServerInterceptor(grpc_opentracing.WithTracer(appCtx.tracer)),
			grpc_prometheus.UnaryServerInterceptor,
			grpc_recovery.UnaryServerInterceptor(),
		)),
	)

	return server
}
<|endoftext|>


<commit_before>package controllers

import (
	"fmt"
	"strings"

	"github.com/kataras/iris"
	"gopkg.in/redis.v4"
)

//IndexController for URL shorten handling
type IndexController struct {
	redis *redis.Client
}

//Response struct for http response
type Response struct {
	Result  bool   `json:"result"`
	Short   string `json:"short"`
	Message string `json:"message"`
}

func init() {
	client := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password set
		DB:       0,  // use default DB
	})

	pong, err := client.Ping().Result()
	fmt.Println(pong, err)
}

//IndexHandler for rendering the index page
func (c *IndexController) IndexHandler(ctx *iris.Context) {
	if err := ctx.Render("index.html", nil); err != nil {
		fmt.Println(err.Error())
		panic(err)
	}
}

//GetShortHandler for getting shorten URL querying result
func (c *IndexController) GetShortHandler(ctx *iris.Context) {
}

//ShortURLHandler for shorten long URL
func (c *IndexController) ShortURLHandler(ctx *iris.Context) {
	url := ctx.FormValue("url")
	resp := new(Response)
	inputURL := string(url)

	if inputURL == "" {
		resp.Result = false
		resp.Message = "Please input URL first..."

		ctx.JSON(iris.StatusOK, resp)
		return
	}

	if strings.Contains(inputURL, "biturl.top") {
		resp.Result = false
		resp.Message = "Cannot shorten it again..."

		ctx.JSON(iris.StatusOK, resp)
		return
	}

	fmt.Println("Input URL is:" + string(url))
	resp.Result = true
	resp.Short = "http://biturl.top/A4zhC32"
	ctx.JSON(iris.StatusOK, resp)
}
<commit_msg>update redis client version<commit_after>package controllers

import (
	"fmt"
	"strings"

	"github.com/kataras/iris"
	"gopkg.in/redis.v5"
)

//IndexController for URL shorten handling
type IndexController struct {
	redis *redis.Client
}

//Response struct for http response
type Response struct {
	Result  bool   `json:"result"`
	Short   string `json:"short"`
	Message string `json:"message"`
}

func init() {
	client := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password set
		DB:       0,  // use default DB
	})

	pong, err := client.Ping().Result()
	fmt.Println(pong, err)
}

//IndexHandler for rendering the index page
func (c *IndexController) IndexHandler(ctx *iris.Context) {
	if err := ctx.Render("index.html", nil); err != nil {
		fmt.Println(err.Error())
		panic(err)
	}
}

//GetShortHandler for getting shorten URL querying result
func (c *IndexController) GetShortHandler(ctx *iris.Context) {
}

//ShortURLHandler for shorten long URL
func (c *IndexController) ShortURLHandler(ctx *iris.Context) {
	url := ctx.FormValue("url")
	resp := new(Response)
	inputURL := string(url)

	if inputURL == "" {
		resp.Result = false
		resp.Message = "Please input URL first..."

		ctx.JSON(iris.StatusOK, resp)
		return
	}

	if strings.Contains(inputURL, "biturl.top") {
		resp.Result = false
		resp.Message = "Cannot shorten it again..."

		ctx.JSON(iris.StatusOK, resp)
		return
	}

	fmt.Println("Input URL is:" + string(url))
	resp.Result = true
	resp.Short = "http://biturl.top/A4zhC32"
	ctx.JSON(iris.StatusOK, resp)
}
<|endoftext|>


<commit_before>package scheduler

import (
	"fmt"
	"strconv"

	"os"

	"github.com/ellcrys/crypto"
	"github.com/ellcrys/util"
	"github.com/franela/goreq"
	"github.com/ncodes/cocoon/core/common"
	logging "github.com/op/go-logging"
)

var log = logging.MustGetLogger("nomad")

// SupportedCocoonCodeLang defines the supported chaincode language
var SupportedCocoonCodeLang = []string{"go"}

// SupportedMemory represents the allowed cocoon memory choices
var SupportedMemory = map[string]int{
	"512m": 512,
	"1g":   1024,
	"2g":   2048,
}

// SupportedCPUShare represents the allowed cocoon cpu share choices
var SupportedCPUShare = map[string]int{
	"1x": 100,
	"2x": 200,
}

// SupportedDiskSpace represents the allowed cocoon disk space
var SupportedDiskSpace = map[string]int{
	"1x": 300,
	"2x": 500,
}

// Nomad defines a nomad scheduler that implements
// scheduler.Scheduler interface. Every interaction with
// the scheduler is handled here.
type Nomad struct {
	schedulerAddr    string
	API              string
	ServiceDiscovery ServiceDiscovery
}

// NewNomad creates a nomad scheduler object
func NewNomad() *Nomad {
	return &Nomad{
		ServiceDiscovery: &NomadServiceDiscovery{
			ConsulAddr: util.Env("CONSUL_ADDR", "127.0.0.7:8500"),
			Protocol:   "http",
		},
	}
}

// GetName returns the scheduler name
func (sc *Nomad) GetName() string {
	return "nomad"
}

// SetAddr sets the nomad's API endpoint
func (sc *Nomad) SetAddr(addr string, https bool) {
	scheme := "http://"
	if https {
		scheme = "https://"
	}
	sc.API = scheme + addr
}

// deployJob registers a new job
func (sc *Nomad) deployJob(jobSpec string) (string, int, error) {

	res, err := goreq.Request{
		Method: "POST",
		Uri:    sc.API + "/v1/jobs",
		Body:   jobSpec,
	}.Do()

	if err != nil {
		return "", 0, err
	}
	defer res.Body.Close()

	respStr, _ := res.Body.ToString()
	return respStr, res.StatusCode, nil
}

// Deploy a cocoon code to the scheduler
func (sc *Nomad) Deploy(jobID, lang, url, tag, buildParams, link, memory, cpuShare string) (*DeploymentInfo, error) {

	var err error

	if len(jobID) == 0 {
		return nil, fmt.Errorf("job id is required")
	}

	if err = common.ValidateDeployment(url, lang, buildParams); err != nil {
		return nil, err
	}

	log.Debugf("Deploying cocoon code with language=%s, url=%s, tag=%s", lang, url, tag)

	if len(buildParams) > 0 {
		buildParams = crypto.ToBase64([]byte(buildParams))
	}

	var img string
	switch lang {
	case "go":
		img = "ncodes/cocoon-launcher:latest"
	}

	job := NewJob(jobID, 1)
	job.GetSpec().Region = "global"
	job.GetSpec().Datacenters = []string{"dc1"}
	job.GetSpec().TaskGroups[0].Tasks[0].Env["COCOON_CODE_URL"] = url
	job.GetSpec().TaskGroups[0].Tasks[0].Env["COCOON_CODE_TAG"] = tag
	job.GetSpec().TaskGroups[0].Tasks[0].Env["COCOON_CODE_LANG"] = lang
	job.GetSpec().TaskGroups[0].Tasks[0].Env["COCOON_BUILD_PARAMS"] = buildParams
	job.GetSpec().TaskGroups[0].Tasks[0].Env["COCOON_DISK_LIMIT"] = strconv.Itoa(SupportedDiskSpace[cpuShare])
	job.GetSpec().TaskGroups[0].Tasks[0].Env["COCOON_LINK"] = link
	job.GetSpec().TaskGroups[0].Tasks[0].Config.Image = img
	job.GetSpec().TaskGroups[0].Tasks[0].Resources.CPU = SupportedCPUShare[cpuShare]
	job.GetSpec().TaskGroups[0].Tasks[0].Resources.MemoryMB = SupportedMemory[memory]
	job.GetSpec().TaskGroups[0].Resources.CPU = SupportedCPUShare[cpuShare]
	job.GetSpec().TaskGroups[0].Resources.MemoryMB = SupportedMemory[memory]

	jobSpec, _ := util.ToJSON(job)
	resp, status, err := sc.deployJob(string(jobSpec))
	if err != nil {
		return nil, fmt.Errorf("system: failed to deploy job spec. %s", err)
	} else if status != 200 {
		return nil, fmt.Errorf("system: failed to deploy job spec. %s", resp)
	}

	var jobInfo map[string]interface{}
	if err = util.FromJSON([]byte(resp), &jobInfo); err != nil {
		return nil, fmt.Errorf("system: %s", resp)
	}

	return &DeploymentInfo{
		ID:     jobID,
		EvalID: jobInfo["EvalID"].(string),
	}, nil
}

// Getenv returns an environment variable value based on the schedulers
// naming convention.
func Getenv(env string) string {
	return os.Getenv("NOMAD_" + env)
}

// GetServices fetches all the instances of a service
func (sc *Nomad) GetServices(serviceID string) []Service {
	return nil
}
<commit_msg>use localhost instead of 127.0.0.1<commit_after>package scheduler

import (
	"fmt"
	"strconv"

	"os"

	"github.com/ellcrys/crypto"
	"github.com/ellcrys/util"
	"github.com/franela/goreq"
	"github.com/ncodes/cocoon/core/common"
	logging "github.com/op/go-logging"
)

var log = logging.MustGetLogger("nomad")

// SupportedCocoonCodeLang defines the supported chaincode language
var SupportedCocoonCodeLang = []string{"go"}

// SupportedMemory represents the allowed cocoon memory choices
var SupportedMemory = map[string]int{
	"512m": 512,
	"1g":   1024,
	"2g":   2048,
}

// SupportedCPUShare represents the allowed cocoon cpu share choices
var SupportedCPUShare = map[string]int{
	"1x": 100,
	"2x": 200,
}

// SupportedDiskSpace represents the allowed cocoon disk space
var SupportedDiskSpace = map[string]int{
	"1x": 300,
	"2x": 500,
}

// Nomad defines a nomad scheduler that implements
// scheduler.Scheduler interface. Every interaction with
// the scheduler is handled here.
type Nomad struct {
	schedulerAddr    string
	API              string
	ServiceDiscovery ServiceDiscovery
}

// NewNomad creates a nomad scheduler object
func NewNomad() *Nomad {
	return &Nomad{
		ServiceDiscovery: &NomadServiceDiscovery{
			ConsulAddr: util.Env("CONSUL_ADDR", "localhost:8500"),
			Protocol:   "http",
		},
	}
}

// GetName returns the scheduler name
func (sc *Nomad) GetName() string {
	return "nomad"
}

// SetAddr sets the nomad's API endpoint
func (sc *Nomad) SetAddr(addr string, https bool) {
	scheme := "http://"
	if https {
		scheme = "https://"
	}
	sc.API = scheme + addr
}

// deployJob registers a new job
func (sc *Nomad) deployJob(jobSpec string) (string, int, error) {

	res, err := goreq.Request{
		Method: "POST",
		Uri:    sc.API + "/v1/jobs",
		Body:   jobSpec,
	}.Do()

	if err != nil {
		return "", 0, err
	}
	defer res.Body.Close()

	respStr, _ := res.Body.ToString()
	return respStr, res.StatusCode, nil
}

// Deploy a cocoon code to the scheduler
func (sc *Nomad) Deploy(jobID, lang, url, tag, buildParams, link, memory, cpuShare string) (*DeploymentInfo, error) {

	var err error

	if len(jobID) == 0 {
		return nil, fmt.Errorf("job id is required")
	}

	if err = common.ValidateDeployment(url, lang, buildParams); err != nil {
		return nil, err
	}

	log.Debugf("Deploying cocoon code with language=%s, url=%s, tag=%s", lang, url, tag)

	if len(buildParams) > 0 {
		buildParams = crypto.ToBase64([]byte(buildParams))
	}

	var img string
	switch lang {
	case "go":
		img = "ncodes/cocoon-launcher:latest"
	}

	job := NewJob(jobID, 1)
	job.GetSpec().Region = "global"
	job.GetSpec().Datacenters = []string{"dc1"}
	job.GetSpec().TaskGroups[0].Tasks[0].Env["COCOON_CODE_URL"] = url
	job.GetSpec().TaskGroups[0].Tasks[0].Env["COCOON_CODE_TAG"] = tag
	job.GetSpec().TaskGroups[0].Tasks[0].Env["COCOON_CODE_LANG"] = lang
	job.GetSpec().TaskGroups[0].Tasks[0].Env["COCOON_BUILD_PARAMS"] = buildParams
	job.GetSpec().TaskGroups[0].Tasks[0].Env["COCOON_DISK_LIMIT"] = strconv.Itoa(SupportedDiskSpace[cpuShare])
	job.GetSpec().TaskGroups[0].Tasks[0].Env["COCOON_LINK"] = link
	job.GetSpec().TaskGroups[0].Tasks[0].Config.Image = img
	job.GetSpec().TaskGroups[0].Tasks[0].Resources.CPU = SupportedCPUShare[cpuShare]
	job.GetSpec().TaskGroups[0].Tasks[0].Resources.MemoryMB = SupportedMemory[memory]
	job.GetSpec().TaskGroups[0].Resources.CPU = SupportedCPUShare[cpuShare]
	job.GetSpec().TaskGroups[0].Resources.MemoryMB = SupportedMemory[memory]

	jobSpec, _ := util.ToJSON(job)
	resp, status, err := sc.deployJob(string(jobSpec))
	if err != nil {
		return nil, fmt.Errorf("system: failed to deploy job spec. %s", err)
	} else if status != 200 {
		return nil, fmt.Errorf("system: failed to deploy job spec. %s", resp)
	}

	var jobInfo map[string]interface{}
	if err = util.FromJSON([]byte(resp), &jobInfo); err != nil {
		return nil, fmt.Errorf("system: %s", resp)
	}

	return &DeploymentInfo{
		ID:     jobID,
		EvalID: jobInfo["EvalID"].(string),
	}, nil
}

// Getenv returns an environment variable value based on the schedulers
// naming convention.
func Getenv(env string) string {
	return os.Getenv("NOMAD_" + env)
}

// GetServices fetches all the instances of a service
func (sc *Nomad) GetServices(serviceID string) []Service {
	return nil
}
<|endoftext|>


<commit_before>package cli

import "fmt"
import "strings"

type paramable struct {
	*writer
	params       paramsList
	paramValues  map[string]Value
	paramsParsed bool
}

// Arg returns the i'th argument.  Arg(0) is the first remaining argument
// after flags have been processed.
func (cmd *paramable) Param(key string) Value {
	value, ok := cmd.paramValues[key]
	if ok {
		return value
	}
	var emptyString stringValue
	emptyString = ""
	return &emptyString
}

// Args returns the non-flag arguments.
func (cmd *paramable) Params() map[string]Value {
	return cmd.paramValues
}

// NArg is the number of arguments remaining after flags have been processed.
func (cmd *paramable) ParamCount() int {
	return len(cmd.paramValues)
}
// UsageString returns the params usage as a string
func (cmd *paramable) UsageString() string {
	var formattednames []string
	for i := 0; i < len(cmd.params); i++ {
		param := cmd.params[i]
		formattednames = append(formattednames, fmt.Sprintf("<%s>", param.Name))
	}
	return strings.Join(formattednames, " ")
}

// Set Param names from strings
func (cmd *paramable) DefineParams(names ...string) {
	var params []*Param
	for i := 0; i < len(names); i++ {
		name := names[i]
		param := &Param{Name: name}
		params = append(params, param)
	}
	cmd.params = params
}

func (cmd *paramable) parse(args []string) []string {
	var seenParams paramsList

	if len(cmd.params) == 0 {
		return args
	}
	i := 0
	for i < len(args) && i < len(cmd.params) {
		param := cmd.params[i]
		seenParams = append(seenParams, param)
		str := ""
		if cmd.paramValues == nil {
			cmd.paramValues = make(map[string]Value)
		}
		cmd.paramValues[param.Name] = newStringValue(args[i], &str)
		i++
	}
	missingParams := cmd.params.Compare(seenParams)
	if len(missingParams) > 0 {
		var msg string
		if len(missingParams) == 1 {
			msg = "missing param"
		} else {
			msg = "missing params"
		}
		cmd.errf("%s: %s", msg, strings.Join(missingParams.Names(), ", "))
	}

	return args[i:]
}
<commit_msg>remove paramcount<commit_after>package cli

import "fmt"
import "strings"

type paramable struct {
	*writer
	params       paramsList
	paramValues  map[string]Value
	paramsParsed bool
}

// Arg returns the i'th argument.  Arg(0) is the first remaining argument
// after flags have been processed.
func (cmd *paramable) Param(key string) Value {
	value, ok := cmd.paramValues[key]
	if ok {
		return value
	}
	var emptyString stringValue
	emptyString = ""
	return &emptyString
}

// Args returns the non-flag arguments.
func (cmd *paramable) Params() map[string]Value {
	return cmd.paramValues
}

// UsageString returns the params usage as a string
func (cmd *paramable) UsageString() string {
	var formattednames []string
	for i := 0; i < len(cmd.params); i++ {
		param := cmd.params[i]
		formattednames = append(formattednames, fmt.Sprintf("<%s>", param.Name))
	}
	return strings.Join(formattednames, " ")
}

// Set Param names from strings
func (cmd *paramable) DefineParams(names ...string) {
	var params []*Param
	for i := 0; i < len(names); i++ {
		name := names[i]
		param := &Param{Name: name}
		params = append(params, param)
	}
	cmd.params = params
}

func (cmd *paramable) parse(args []string) []string {
	var seenParams paramsList

	if len(cmd.params) == 0 {
		return args
	}
	i := 0
	for i < len(args) && i < len(cmd.params) {
		param := cmd.params[i]
		seenParams = append(seenParams, param)
		str := ""
		if cmd.paramValues == nil {
			cmd.paramValues = make(map[string]Value)
		}
		cmd.paramValues[param.Name] = newStringValue(args[i], &str)
		i++
	}
	missingParams := cmd.params.Compare(seenParams)
	if len(missingParams) > 0 {
		var msg string
		if len(missingParams) == 1 {
			msg = "missing param"
		} else {
			msg = "missing params"
		}
		cmd.errf("%s: %s", msg, strings.Join(missingParams.Names(), ", "))
	}

	return args[i:]
}
<|endoftext|>


<commit_before>package main

import (
	"container/heap"
	"ddtxn"
	"ddtxn/dlog"
	"ddtxn/prof"
	"flag"
	"fmt"
	"log"
	"math/rand"
	"os"
	"runtime"
	"sync"
	"time"
)

var nprocs = flag.Int("nprocs", 2, "GOMAXPROCS default 2")
var nsec = flag.Int("nsec", 2, "Time to run in seconds")
var clientGoRoutines = flag.Int("ngo", 0, "Number of goroutines/workers generating client requests.")
var nworkers = flag.Int("nw", 0, "Number of workers")
var nbidders = flag.Int("nb", 1000000, "Keys in store, default is 1M")
var prob = flag.Float64("contention", 100.0, "Probability contended key is in txn")
var readrate = flag.Int("rr", 0, "Read rate %.  Rest are writes")
var dataFile = flag.String("out", "single-data.out", "Filename for output")
var latency = flag.Bool("latency", false, "dummy")
var Retry = flag.Bool("retry", false, "Whether to retry aborted transactions until they commit.  Changes the composition of reads/writes issued to the system (but maintains the read rate ratio specified for transactions *completed*. Default false.")
var AtomicIncr = flag.Bool("atomic", false, "Use atomic increment function instead (no aborts)")

var retryCount = flag.Int("rc", 1, "Number of times to retry a transaction immediately")
var retryCountTotal = flag.Int("rt", 0, "Number of times to save and try a transaction again")

func main() {
	flag.Parse()
	runtime.GOMAXPROCS(*nprocs)

	if *clientGoRoutines == 0 {
		*clientGoRoutines = *nprocs
	}
	if *nworkers == 0 {
		*nworkers = *nprocs
	}
	s := ddtxn.NewStore()
	for i := 0; i < *nbidders; i++ {
		k := ddtxn.ProductKey(i)
		s.CreateKey(k, int32(0), ddtxn.SUM)
	}
	dlog.Printf("Done with Populate")

	coord := ddtxn.NewCoordinator(*nworkers, s)

	if *ddtxn.CountKeys {
		for i := 0; i < *nworkers; i++ {
			w := coord.Workers[i]
			w.NKeyAccesses = make([]int64, *nbidders)
		}
	}

	dlog.Printf("Done initializing single\n")

	p := prof.StartProfile()
	start := time.Now()
	sp := uint32(*nbidders / *nworkers)
	var wg sync.WaitGroup
	pkey := int(sp - 1)
	dlog.Printf("Partition size: %v; Contended key %v\n", sp/2, pkey)
	gave_up := make([]int64, *clientGoRoutines)
	for i := 0; i < *clientGoRoutines; i++ {
		wg.Add(1)
		go func(n int) {
			retries := make(ddtxn.RetryHeap, 0)
			heap.Init(&retries)
			end_time := time.Now().Add(time.Duration(*nsec) * time.Second)
			var local_seed uint32 = uint32(rand.Intn(10000000))
			wi := n % (*nworkers)
			w := coord.Workers[wi]
			top := (wi + 1) * int(sp)
			bottom := wi * int(sp)
			dlog.Printf("%v: Noncontended section: %v to %v\n", n, bottom, top)
			for {
				tm := time.Now()
				if !end_time.After(tm) {
					break
				}
				var t ddtxn.Query
				if len(retries) > 0 && retries[0].TS.Before(tm) {
					t = heap.Pop(&retries).(ddtxn.Query)
				} else {
					x := float64(ddtxn.RandN(&local_seed, 100))
					if x < *prob {
						// contended txn
						t.K1 = ddtxn.ProductKey(pkey)
					} else {
						// uncontended
						rnd := ddtxn.RandN(&local_seed, sp/2)
						lb := int(rnd)
						k := lb + wi*int(sp) + 1
						if k < bottom || k >= top+1 {
							log.Fatalf("%v: outside my range %v [%v-%v]\n", n, k, bottom, top)
						}
						t.K1 = ddtxn.ProductKey(k)
					}
					t.TXN = ddtxn.D_INCR_ONE
					y := int(ddtxn.RandN(&local_seed, 100))
					if y < *readrate {
						t.TXN = ddtxn.D_READ_ONE
					}
				}
				committed := false
				for i := 0; i < *retryCount; i++ {
					_, err := w.One(t)
					if err == ddtxn.EABORT {
						committed = false
					} else {
						committed = true
						break
					}
					t.I++
				}
				if !committed {
					if t.I > *retryCountTotal {
						gave_up[n]++
						continue
					}
					t.TS = tm.Add(time.Duration(t.I*100) * time.Microsecond)
					heap.Push(&retries, t)
					continue
				}
			}
			wg.Done()
			dlog.Printf("[%v] Length of retry queue on exit: %v\n", n, len(retries))
		}(i)
	}
	wg.Wait()
	coord.Finish()
	end := time.Since(start)
	p.Stop()

	stats := make([]int64, ddtxn.LAST_STAT)
	nitr, nwait, _ := ddtxn.CollectCounts(coord, stats)

	for i := 1; i < *clientGoRoutines; i++ {
		gave_up[0] = gave_up[0] + gave_up[i]
	}

	// nitr + NABORTS + ENOKEY is how many requests were issued.  A
	// stashed transaction eventually executes and contributes to
	// nitr.
	out := fmt.Sprintf(" nworkers: %v, nwmoved: %v, nrmoved: %v, sys: %v, total/sec: %v, abortrate: %.2f, stashrate: %.2f, rr: %v, nkeys: %v, done: %v, actual time: %v, nreads: %v, nincrs: %v, epoch changes: %v, throughput ns/txn: %v, naborts: %v, coord time: %v, coord stats time: %v, total worker time transitioning: %v, nstashed: %v, rlock: %v, wrratio: %v, nsamples: %v, getkeys: %v, ddwrites: %v, nolock: %v, failv: %v, nlocked: %v, stashdone: %v, nfast: %v, gaveup: %v ", *nworkers, ddtxn.WMoved, ddtxn.RMoved, *ddtxn.SysType, float64(nitr)/end.Seconds(), 100*float64(stats[ddtxn.NABORTS])/float64(nitr+stats[ddtxn.NABORTS]), 100*float64(stats[ddtxn.NSTASHED])/float64(nitr+stats[ddtxn.NABORTS]), *readrate, *nbidders, nitr, end, stats[ddtxn.D_READ_ONE], stats[ddtxn.D_INCR_ONE], ddtxn.NextEpoch, end.Nanoseconds()/nitr, stats[ddtxn.NABORTS], ddtxn.Time_in_IE, ddtxn.Time_in_IE1, nwait, stats[ddtxn.NSTASHED], *ddtxn.UseRLocks, *ddtxn.WRRatio, stats[ddtxn.NSAMPLES], stats[ddtxn.NGETKEYCALLS], stats[ddtxn.NDDWRITES], stats[ddtxn.NO_LOCK], stats[ddtxn.NFAIL_VERIFY], stats[ddtxn.NLOCKED], stats[ddtxn.NDIDSTASHED], ddtxn.Nfast, gave_up[0])
	fmt.Printf(out)
	fmt.Printf("\n")

	f, err := os.OpenFile(*dataFile, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
	if err != nil {
		panic(err)
	}
	defer f.Close()

	ddtxn.PrintStats(out, stats, f, coord, s, *nbidders)
}
<commit_msg>remove unnecessary flags<commit_after>package main

import (
	"container/heap"
	"ddtxn"
	"ddtxn/dlog"
	"ddtxn/prof"
	"flag"
	"fmt"
	"log"
	"math/rand"
	"os"
	"runtime"
	"sync"
	"time"
)

var nprocs = flag.Int("nprocs", 2, "GOMAXPROCS default 2")
var nsec = flag.Int("nsec", 2, "Time to run in seconds")
var clientGoRoutines = flag.Int("ngo", 0, "Number of goroutines/workers generating client requests.")
var nworkers = flag.Int("nw", 0, "Number of workers")
var nbidders = flag.Int("nb", 1000000, "Keys in store, default is 1M")
var prob = flag.Float64("contention", 100.0, "Probability contended key is in txn")
var readrate = flag.Int("rr", 0, "Read rate %.  Rest are writes")
var dataFile = flag.String("out", "single-data.out", "Filename for output")
var latency = flag.Bool("latency", false, "dummy")

var retryCount = flag.Int("rc", 1, "Number of times to retry a transaction immediately")
var retryCountTotal = flag.Int("rt", 0, "Number of times to save and try a transaction again")

func main() {
	flag.Parse()
	runtime.GOMAXPROCS(*nprocs)

	if *clientGoRoutines == 0 {
		*clientGoRoutines = *nprocs
	}
	if *nworkers == 0 {
		*nworkers = *nprocs
	}
	s := ddtxn.NewStore()
	for i := 0; i < *nbidders; i++ {
		k := ddtxn.ProductKey(i)
		s.CreateKey(k, int32(0), ddtxn.SUM)
	}
	dlog.Printf("Done with Populate")

	coord := ddtxn.NewCoordinator(*nworkers, s)

	if *ddtxn.CountKeys {
		for i := 0; i < *nworkers; i++ {
			w := coord.Workers[i]
			w.NKeyAccesses = make([]int64, *nbidders)
		}
	}

	dlog.Printf("Done initializing single\n")

	p := prof.StartProfile()
	start := time.Now()
	sp := uint32(*nbidders / *nworkers)
	var wg sync.WaitGroup
	pkey := int(sp - 1)
	dlog.Printf("Partition size: %v; Contended key %v\n", sp/2, pkey)
	gave_up := make([]int64, *clientGoRoutines)
	for i := 0; i < *clientGoRoutines; i++ {
		wg.Add(1)
		go func(n int) {
			retries := make(ddtxn.RetryHeap, 0)
			heap.Init(&retries)
			end_time := time.Now().Add(time.Duration(*nsec) * time.Second)
			var local_seed uint32 = uint32(rand.Intn(10000000))
			wi := n % (*nworkers)
			w := coord.Workers[wi]
			top := (wi + 1) * int(sp)
			bottom := wi * int(sp)
			dlog.Printf("%v: Noncontended section: %v to %v\n", n, bottom, top)
			for {
				tm := time.Now()
				if !end_time.After(tm) {
					break
				}
				var t ddtxn.Query
				if len(retries) > 0 && retries[0].TS.Before(tm) {
					t = heap.Pop(&retries).(ddtxn.Query)
				} else {
					x := float64(ddtxn.RandN(&local_seed, 100))
					if x < *prob {
						// contended txn
						t.K1 = ddtxn.ProductKey(pkey)
					} else {
						// uncontended
						rnd := ddtxn.RandN(&local_seed, sp/2)
						lb := int(rnd)
						k := lb + wi*int(sp) + 1
						if k < bottom || k >= top+1 {
							log.Fatalf("%v: outside my range %v [%v-%v]\n", n, k, bottom, top)
						}
						t.K1 = ddtxn.ProductKey(k)
					}
					t.TXN = ddtxn.D_INCR_ONE
					y := int(ddtxn.RandN(&local_seed, 100))
					if y < *readrate {
						t.TXN = ddtxn.D_READ_ONE
					}
				}
				committed := false
				for i := 0; i < *retryCount; i++ {
					_, err := w.One(t)
					if err == ddtxn.EABORT {
						committed = false
					} else {
						committed = true
						break
					}
					t.I++
				}
				if !committed {
					if t.I > *retryCountTotal {
						gave_up[n]++
						continue
					}
					t.TS = tm.Add(time.Duration(t.I*100) * time.Microsecond)
					heap.Push(&retries, t)
					continue
				}
			}
			wg.Done()
			dlog.Printf("[%v] Length of retry queue on exit: %v\n", n, len(retries))
		}(i)
	}
	wg.Wait()
	coord.Finish()
	end := time.Since(start)
	p.Stop()

	stats := make([]int64, ddtxn.LAST_STAT)
	nitr, nwait, _ := ddtxn.CollectCounts(coord, stats)

	for i := 1; i < *clientGoRoutines; i++ {
		gave_up[0] = gave_up[0] + gave_up[i]
	}

	// nitr + NABORTS + ENOKEY is how many requests were issued.  A
	// stashed transaction eventually executes and contributes to
	// nitr.
	out := fmt.Sprintf(" nworkers: %v, nwmoved: %v, nrmoved: %v, sys: %v, total/sec: %v, abortrate: %.2f, stashrate: %.2f, rr: %v, nkeys: %v, done: %v, actual time: %v, nreads: %v, nincrs: %v, epoch changes: %v, throughput ns/txn: %v, naborts: %v, coord time: %v, coord stats time: %v, total worker time transitioning: %v, nstashed: %v, rlock: %v, wrratio: %v, nsamples: %v, getkeys: %v, ddwrites: %v, nolock: %v, failv: %v, nlocked: %v, stashdone: %v, nfast: %v, gaveup: %v ", *nworkers, ddtxn.WMoved, ddtxn.RMoved, *ddtxn.SysType, float64(nitr)/end.Seconds(), 100*float64(stats[ddtxn.NABORTS])/float64(nitr+stats[ddtxn.NABORTS]), 100*float64(stats[ddtxn.NSTASHED])/float64(nitr+stats[ddtxn.NABORTS]), *readrate, *nbidders, nitr, end, stats[ddtxn.D_READ_ONE], stats[ddtxn.D_INCR_ONE], ddtxn.NextEpoch, end.Nanoseconds()/nitr, stats[ddtxn.NABORTS], ddtxn.Time_in_IE, ddtxn.Time_in_IE1, nwait, stats[ddtxn.NSTASHED], *ddtxn.UseRLocks, *ddtxn.WRRatio, stats[ddtxn.NSAMPLES], stats[ddtxn.NGETKEYCALLS], stats[ddtxn.NDDWRITES], stats[ddtxn.NO_LOCK], stats[ddtxn.NFAIL_VERIFY], stats[ddtxn.NLOCKED], stats[ddtxn.NDIDSTASHED], ddtxn.Nfast, gave_up[0])
	fmt.Printf(out)
	fmt.Printf("\n")

	f, err := os.OpenFile(*dataFile, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
	if err != nil {
		panic(err)
	}
	defer f.Close()

	ddtxn.PrintStats(out, stats, f, coord, s, *nbidders)
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/BjornTwitchBot/BjornBot/Godeps/_workspace/src/github.com/fabioxgn/go-bot"
	"math/rand"
	"time"
)

func eelfacts(command *bot.Cmd) (msg string, err error) {
	eelFacts := [19]string{
		"There are more than 700 different kinds, or species, of eels",
		"Depending on the species, eels can grow to be anywhere between 4 inches to 11 1/2 feet long",
		"Eels are smooth",
		"They eat a variety of animals such as worms, snails, frogs, shrimp, mussels, lizards and other small fish. They generally hunt for food at night.",
		"The moray eel is the most widespread eel in the world and all of the species live in tropical seas",
		"Electric eels are not related to eels, but are more closely related to catfish and carp",
		"an Electric Eels' attack is about five times the amount of power that is in a standard wall socket",
		"In 2010, Greenpeace International has added the American eel to its seafood red list, a list of fish that are commonly sold in supermarkets around the world, and which have a very high risk of being sourced from unsustainable fisheries",
		"American eel's hatch as Leptocephali, then become “glass eels”, then “elvers.” Upon reaching their fresh water destination, they transform one more time into “yellow eels.” American eels reach sexual maturity in approximately 5 to 25 years. They die after spawning",
		"the American eel is at very high risk of extinction in the wild",
		"Captive European Eels have lived as long as 80 years, with some claims of living as long as 155",
		"While many eels are farm fraised, they have no been breed in captivity",
		"The Japanese freshwater eel produces a fluorescent protein. This protein is the basis of a new test to assess dangerous blood toxins that can trigger liver disease",
		"The aptly named 'Giant marbled eel' can grow up to 2 meters (6.6 ft) for females and 1.5 meters (4.9 ft) for males and can weigh up to 20.5 kilograms (45 lb), making it the largest species of anguillid eels.",
		"In 1876, as a young student in Austria, Sigmund Freud dissected hundreds of eels in search of the male sex organs. He had to concede failure in his first major published research paper, and turned to other issues in frustration",
		"The electric eel is a South American electric fish. Despite the name, it is not an eel, but rather a knifefish.",
		"Garden eel's live in burrows on the sea floor and get their name from their practice of poking their heads from their burrows while most of their bodies remain hidden. Since they tend to live in groups, the many eel heads 'growing' from the sea floor resemble the plants in a garden. The largest can be as much as an acre!",
		"Reef-associated roving coral groupers have been observed to recruit giant morays to help them hunt. The invitation to hunt is initiated by head-shaking. This style of hunting may allow morays to flush prey from niches not accessible to groupers",
		"Ribbon eels are carnivores, preying on small fish and other marine creatures.  They can attract their prey with their flared nostrils and then clamp down on them with their strong jaws and retreat into their burrows.",
	}

	rand.Seed(time.Now().UnixNano())
	msg = eelFacts[rand.Intn(len(eelFacts))]
	return
}

func init() {
	bot.RegisterCommand(
		"eelfacts",
		"Provides random facts about eels",
		"",
		eelfacts)
}
<commit_msg>add a moray<commit_after>package main

import (
	"github.com/BjornTwitchBot/BjornBot/Godeps/_workspace/src/github.com/fabioxgn/go-bot"
	"math/rand"
	"time"
)

func eelfacts(command *bot.Cmd) (msg string, err error) {
	eelFacts := [20]string{
		"There are more than 700 different kinds, or species, of eels",
		"Depending on the species, eels can grow to be anywhere between 4 inches to 11 1/2 feet long",
		"Eels are smooth",
		"They eat a variety of animals such as worms, snails, frogs, shrimp, mussels, lizards and other small fish. They generally hunt for food at night.",
		"The moray eel is the most widespread eel in the world and all of the species live in tropical seas",
		"Electric eels are not related to eels, but are more closely related to catfish and carp",
		"an Electric Eels' attack is about five times the amount of power that is in a standard wall socket",
		"In 2010, Greenpeace International has added the American eel to its seafood red list, a list of fish that are commonly sold in supermarkets around the world, and which have a very high risk of being sourced from unsustainable fisheries",
		"American eel's hatch as Leptocephali, then become “glass eels”, then “elvers.” Upon reaching their fresh water destination, they transform one more time into “yellow eels.” American eels reach sexual maturity in approximately 5 to 25 years. They die after spawning",
		"the American eel is at very high risk of extinction in the wild",
		"Captive European Eels have lived as long as 80 years, with some claims of living as long as 155",
		"While many eels are farm fraised, they have no been breed in captivity",
		"The Japanese freshwater eel produces a fluorescent protein. This protein is the basis of a new test to assess dangerous blood toxins that can trigger liver disease",
		"The aptly named 'Giant marbled eel' can grow up to 2 meters (6.6 ft) for females and 1.5 meters (4.9 ft) for males and can weigh up to 20.5 kilograms (45 lb), making it the largest species of anguillid eels.",
		"In 1876, as a young student in Austria, Sigmund Freud dissected hundreds of eels in search of the male sex organs. He had to concede failure in his first major published research paper, and turned to other issues in frustration",
		"The electric eel is a South American electric fish. Despite the name, it is not an eel, but rather a knifefish.",
		"Garden eel's live in burrows on the sea floor and get their name from their practice of poking their heads from their burrows while most of their bodies remain hidden. Since they tend to live in groups, the many eel heads 'growing' from the sea floor resemble the plants in a garden. The largest can be as much as an acre!",
		"Reef-associated roving coral groupers have been observed to recruit giant morays to help them hunt. The invitation to hunt is initiated by head-shaking. This style of hunting may allow morays to flush prey from niches not accessible to groupers",
		"Ribbon eels are carnivores, preying on small fish and other marine creatures.  They can attract their prey with their flared nostrils and then clamp down on them with their strong jaws and retreat into their burrows.",
		"When you swim in a creek, and an eel bites your cheek, that’s a moray",
	}

	rand.Seed(time.Now().UnixNano())
	msg = eelFacts[rand.Intn(len(eelFacts))]
	return
}

func init() {
	bot.RegisterCommand(
		"eelfacts",
		"Provides random facts about eels",
		"",
		eelfacts)
}
<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 cli

import (
	"bufio"
	"bytes"
	"fmt"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	log "github.com/sirupsen/logrus"
	"github.com/spf13/cobra"

	"github.com/apache/mynewt-artifact/errors"
	"mynewt.apache.org/newt/newt/builder"
	"mynewt.apache.org/newt/newt/newtutil"
	"mynewt.apache.org/newt/newt/pkg"
	"mynewt.apache.org/newt/newt/project"
	"mynewt.apache.org/newt/newt/resolve"
	"mynewt.apache.org/newt/newt/target"
	"mynewt.apache.org/newt/util"
)

const TARGET_KEYWORD_ALL string = "all"
const TARGET_DEFAULT_DIR string = "targets"
const MFG_DEFAULT_DIR string = "mfgs"

func NewtUsage(cmd *cobra.Command, err error) {
	if err != nil {
		if errors.HasStackTrace(err) {
			log.Debugf("%+v", err)
		} else if ne, ok := err.(*util.NewtError); ok {
			log.Debugf("%s", ne.StackTrace)
		} else {
			panic(fmt.Sprintf("unexpected error type: %T", err))
		}

		fmt.Fprintf(os.Stderr, "Error: %s\n", err.Error())
	}

	if cmd != nil {
		fmt.Printf("%s - ", cmd.Name())
		cmd.Help()
	}
	os.Exit(1)
}

// Display help text with a max line width of 79 characters
func FormatHelp(text string) string {
	// first compress all new lines and extra spaces
	words := regexp.MustCompile("\\s+").Split(text, -1)
	linelen := 0
	fmtText := ""
	for _, word := range words {
		word = strings.Trim(word, "\n ") + " "
		tmplen := linelen + len(word)
		if tmplen >= 80 {
			fmtText += "\n"
			linelen = 0
		}
		fmtText += word
		linelen += len(word)
	}
	return fmtText
}

func ResolveTarget(name string) *target.Target {
	// Trim trailing slash from name.  This is necessary when tab
	// completion is used to specify the name.
	name = strings.TrimSuffix(name, "/")

	targetMap := target.GetTargets()

	// Check for fully-qualified name.
	if t := targetMap[name]; t != nil {
		return t
	}

	// Check the local "targets" directory.
	if t := targetMap[TARGET_DEFAULT_DIR+"/"+name]; t != nil {
		return t
	}

	// Check each repo alphabetically.
	fullNames := []string{}
	for fullName, _ := range targetMap {
		fullNames = append(fullNames, fullName)
	}
	for _, fullName := range util.SortFields(fullNames...) {
		if name == filepath.Base(fullName) {
			return targetMap[fullName]
		}
	}

	return nil
}

// Resolves a list of target names and checks for the optional "all" keyword
// among them.  Regardless of whether "all" is specified, all target names must
// be valid, or an error is reported.
//
// @return                      targets, all (t/f), err
func ResolveTargetsOrAll(names ...string) ([]*target.Target, bool, error) {
	targets := []*target.Target{}
	all := false

	for _, name := range names {
		if name == "all" {
			all = true
		} else {
			t := ResolveTarget(name)
			if t == nil {
				return nil, false,
					util.NewNewtError("Could not resolve target name: " + name)
			}

			targets = append(targets, t)
		}
	}

	return targets, all, nil
}

func ResolveTargets(names ...string) ([]*target.Target, error) {
	targets, all, err := ResolveTargetsOrAll(names...)
	if err != nil {
		return nil, err
	}
	if all {
		return nil,
			util.NewNewtError("Keyword \"all\" not allowed in thie context")
	}

	return targets, nil
}

func ResolveNewTargetName(name string) (string, error) {
	repoName, pkgName, err := newtutil.ParsePackageString(name)
	if err != nil {
		return "", err
	}

	if repoName != "" {
		return "", util.NewNewtError("Target name cannot contain repo; " +
			"must be local")
	}

	if pkgName == TARGET_KEYWORD_ALL {
		return "", util.NewNewtError("Target name " + TARGET_KEYWORD_ALL +
			" is reserved")
	}

	// "Naked" target names translate to "targets/<name>".
	if !strings.Contains(pkgName, "/") {
		pkgName = TARGET_DEFAULT_DIR + "/" + pkgName
	}

	if target.GetTargets()[pkgName] != nil {
		return "", util.NewNewtError("Target already exists: " + pkgName)
	}

	return pkgName, nil
}

func PackageNameList(pkgs []*pkg.LocalPackage) string {
	var buffer bytes.Buffer
	for i, pack := range pkgs {
		if i != 0 {
			buffer.WriteString(" ")
		}
		buffer.WriteString(pack.Name())
	}

	return buffer.String()
}

func ResetGlobalState() error {
	// Make sure the current working directory is at the project base.
	if err := os.Chdir(project.GetProject().Path()); err != nil {
		return util.NewNewtError("Failed to reset global state: " +
			err.Error())
	}

	target.ResetTargets()
	project.ResetProject()

	return nil
}

func TryGetProject() *project.Project {
	var p *project.Project
	var err error

	if p, err = project.TryGetProject(); err != nil {
		NewtUsage(nil, err)
	}

	for _, w := range p.Warnings() {
		util.ErrorMessage(util.VERBOSITY_QUIET, "* Warning: %s\n", w)
	}

	return p
}

func TryGetOrDownloadProject() *project.Project {
	var p *project.Project
	var err error

	if p, err = project.TryGetOrDownloadProject(); err != nil {
		NewtUsage(nil, err)
	}

	for _, w := range p.Warnings() {
		util.ErrorMessage(util.VERBOSITY_QUIET, "* Warning: %s\n", w)
	}

	return p
}

func ResolveUnittest(pkgName string) (*target.Target, error) {
	// Each unit test package gets its own target.  This target is a copy
	// of the base unit test package, just with an appropriate name.  The
	// reason each test needs a unique target is: syscfg and sysinit are
	// target-specific.  If each test package shares a target, they will
	// overwrite these generated headers each time they are run.  Worse, if
	// two tests are run back-to-back, the timestamps may indicate that the
	// headers have not changed between tests, causing build failures.
	baseTarget := ResolveTarget(TARGET_TEST_NAME)
	if baseTarget == nil {
		return nil, util.FmtNewtError("Can't find unit test target: %s",
			TARGET_TEST_NAME)
	}

	targetName := fmt.Sprintf("%s/%s/%s",
		TARGET_DEFAULT_DIR, TARGET_TEST_NAME,
		builder.TestTargetName(pkgName))

	t := ResolveTarget(targetName)
	if t == nil {
		targetName, err := ResolveNewTargetName(targetName)
		if err != nil {
			return nil, err
		}

		t = baseTarget.Clone(TryGetProject().LocalRepo(), targetName)
	}

	return t, nil
}

// @return Target
// @return LocalPackage         The package under test, if any.
// @return error
func ResolveTargetOrUnittest(pkgName string) (
	*target.Target, *pkg.LocalPackage, error) {

	// Argument can specify either a target or a unittest package.  Determine
	// which type the package is and construct a target builder appropriately.
	if t, err := resolveExistingTargetArg(pkgName); err == nil {
		return t, nil, nil
	}

	// Package wasn't a target.  Try for a unittest.
	proj := TryGetProject()
	pack, err := proj.ResolvePackage(proj.LocalRepo(), pkgName)
	if err != nil {
		return nil, nil, util.FmtNewtError(
			"Could not resolve target or unittest \"%s\"", pkgName)
	}

	if pack.Type() != pkg.PACKAGE_TYPE_UNITTEST {
		return nil, nil, util.FmtNewtError(
			"Package \"%s\" is of type %s; "+
				"must be target or unittest", pkgName,
			pkg.PackageTypeNames[pack.Type()])
	}

	t, err := ResolveUnittest(pack.Name())
	if err != nil {
		return nil, nil, err
	}

	return t, pack, nil
}

func ResolvePackages(pkgNames []string) ([]*pkg.LocalPackage, error) {
	proj := TryGetProject()

	lpkgs := []*pkg.LocalPackage{}
	for _, pkgName := range pkgNames {
		pack, err := proj.ResolvePackage(proj.LocalRepo(), pkgName)
		if err != nil {
			return nil, err
		}
		lpkgs = append(lpkgs, pack)
	}

	return lpkgs, nil
}

func ResolveRpkgs(res *resolve.Resolution, pkgNames []string) (
	[]*resolve.ResolvePackage, error) {

	lpkgs, err := ResolvePackages(pkgNames)
	if err != nil {
		return nil, err
	}

	rpkgs := []*resolve.ResolvePackage{}
	for _, lpkg := range lpkgs {
		rpkg := res.LpkgRpkgMap[lpkg]
		if rpkg == nil {
			return nil, util.FmtNewtError("Unexpected error; local package "+
				"%s lacks a corresponding resolve package", lpkg.FullName())
		}

		rpkgs = append(rpkgs, rpkg)
	}

	return rpkgs, nil
}

func TargetBuilderForTargetOrUnittest(pkgName string) (
	*builder.TargetBuilder, error) {

	t, testPkg, err := ResolveTargetOrUnittest(pkgName)
	if err != nil {
		return nil, err
	}

	if testPkg == nil {
		return builder.NewTargetBuilder(t)
	} else {
		return builder.NewTargetTester(t, testPkg)
	}
}

func PromptYesNo(dflt bool) bool {
	scanner := bufio.NewScanner(os.Stdin)
	rc := scanner.Scan()
	if !rc {
		return dflt
	}

	if strings.ToLower(scanner.Text()) == "y" {
		return true
	}

	if strings.ToLower(scanner.Text()) == "n" {
		return false
	}

	return dflt
}
<commit_msg>Remove "final-atom" target specifier type<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 cli

import (
	"bufio"
	"bytes"
	"fmt"
	"os"
	"regexp"
	"strings"

	log "github.com/sirupsen/logrus"
	"github.com/spf13/cobra"

	"github.com/apache/mynewt-artifact/errors"
	"mynewt.apache.org/newt/newt/builder"
	"mynewt.apache.org/newt/newt/newtutil"
	"mynewt.apache.org/newt/newt/pkg"
	"mynewt.apache.org/newt/newt/project"
	"mynewt.apache.org/newt/newt/resolve"
	"mynewt.apache.org/newt/newt/target"
	"mynewt.apache.org/newt/util"
)

const TARGET_KEYWORD_ALL string = "all"
const TARGET_DEFAULT_DIR string = "targets"
const MFG_DEFAULT_DIR string = "mfgs"

func NewtUsage(cmd *cobra.Command, err error) {
	if err != nil {
		if errors.HasStackTrace(err) {
			log.Debugf("%+v", err)
		} else if ne, ok := err.(*util.NewtError); ok {
			log.Debugf("%s", ne.StackTrace)
		} else {
			panic(fmt.Sprintf("unexpected error type: %T", err))
		}

		fmt.Fprintf(os.Stderr, "Error: %s\n", err.Error())
	}

	if cmd != nil {
		fmt.Printf("%s - ", cmd.Name())
		cmd.Help()
	}
	os.Exit(1)
}

// Display help text with a max line width of 79 characters
func FormatHelp(text string) string {
	// first compress all new lines and extra spaces
	words := regexp.MustCompile("\\s+").Split(text, -1)
	linelen := 0
	fmtText := ""
	for _, word := range words {
		word = strings.Trim(word, "\n ") + " "
		tmplen := linelen + len(word)
		if tmplen >= 80 {
			fmtText += "\n"
			linelen = 0
		}
		fmtText += word
		linelen += len(word)
	}
	return fmtText
}

func ResolveTarget(name string) *target.Target {
	// Trim trailing slash from name.  This is necessary when tab
	// completion is used to specify the name.
	name = strings.TrimSuffix(name, "/")

	targetMap := target.GetTargets()

	// Check for fully-qualified name.
	if t := targetMap[name]; t != nil {
		return t
	}

	// Check the local "targets" directory.
	if t := targetMap[TARGET_DEFAULT_DIR+"/"+name]; t != nil {
		return t
	}

	return nil
}

// Resolves a list of target names and checks for the optional "all" keyword
// among them.  Regardless of whether "all" is specified, all target names must
// be valid, or an error is reported.
//
// @return                      targets, all (t/f), err
func ResolveTargetsOrAll(names ...string) ([]*target.Target, bool, error) {
	targets := []*target.Target{}
	all := false

	for _, name := range names {
		if name == "all" {
			all = true
		} else {
			t := ResolveTarget(name)
			if t == nil {
				return nil, false,
					util.NewNewtError("Could not resolve target name: " + name)
			}

			targets = append(targets, t)
		}
	}

	return targets, all, nil
}

func ResolveTargets(names ...string) ([]*target.Target, error) {
	targets, all, err := ResolveTargetsOrAll(names...)
	if err != nil {
		return nil, err
	}
	if all {
		return nil,
			util.NewNewtError("Keyword \"all\" not allowed in thie context")
	}

	return targets, nil
}

func ResolveNewTargetName(name string) (string, error) {
	repoName, pkgName, err := newtutil.ParsePackageString(name)
	if err != nil {
		return "", err
	}

	if repoName != "" {
		return "", util.NewNewtError("Target name cannot contain repo; " +
			"must be local")
	}

	if pkgName == TARGET_KEYWORD_ALL {
		return "", util.NewNewtError("Target name " + TARGET_KEYWORD_ALL +
			" is reserved")
	}

	// "Naked" target names translate to "targets/<name>".
	if !strings.Contains(pkgName, "/") {
		pkgName = TARGET_DEFAULT_DIR + "/" + pkgName
	}

	if target.GetTargets()[pkgName] != nil {
		return "", util.NewNewtError("Target already exists: " + pkgName)
	}

	return pkgName, nil
}

func PackageNameList(pkgs []*pkg.LocalPackage) string {
	var buffer bytes.Buffer
	for i, pack := range pkgs {
		if i != 0 {
			buffer.WriteString(" ")
		}
		buffer.WriteString(pack.Name())
	}

	return buffer.String()
}

func ResetGlobalState() error {
	// Make sure the current working directory is at the project base.
	if err := os.Chdir(project.GetProject().Path()); err != nil {
		return util.NewNewtError("Failed to reset global state: " +
			err.Error())
	}

	target.ResetTargets()
	project.ResetProject()

	return nil
}

func TryGetProject() *project.Project {
	var p *project.Project
	var err error

	if p, err = project.TryGetProject(); err != nil {
		NewtUsage(nil, err)
	}

	for _, w := range p.Warnings() {
		util.ErrorMessage(util.VERBOSITY_QUIET, "* Warning: %s\n", w)
	}

	return p
}

func TryGetOrDownloadProject() *project.Project {
	var p *project.Project
	var err error

	if p, err = project.TryGetOrDownloadProject(); err != nil {
		NewtUsage(nil, err)
	}

	for _, w := range p.Warnings() {
		util.ErrorMessage(util.VERBOSITY_QUIET, "* Warning: %s\n", w)
	}

	return p
}

func ResolveUnittest(pkgName string) (*target.Target, error) {
	// Each unit test package gets its own target.  This target is a copy
	// of the base unit test package, just with an appropriate name.  The
	// reason each test needs a unique target is: syscfg and sysinit are
	// target-specific.  If each test package shares a target, they will
	// overwrite these generated headers each time they are run.  Worse, if
	// two tests are run back-to-back, the timestamps may indicate that the
	// headers have not changed between tests, causing build failures.
	baseTarget := ResolveTarget(TARGET_TEST_NAME)
	if baseTarget == nil {
		return nil, util.FmtNewtError("Can't find unit test target: %s",
			TARGET_TEST_NAME)
	}

	targetName := fmt.Sprintf("%s/%s/%s",
		TARGET_DEFAULT_DIR, TARGET_TEST_NAME,
		builder.TestTargetName(pkgName))

	t := ResolveTarget(targetName)
	if t == nil {
		targetName, err := ResolveNewTargetName(targetName)
		if err != nil {
			return nil, err
		}

		t = baseTarget.Clone(TryGetProject().LocalRepo(), targetName)
	}

	return t, nil
}

// @return Target
// @return LocalPackage         The package under test, if any.
// @return error
func ResolveTargetOrUnittest(pkgName string) (
	*target.Target, *pkg.LocalPackage, error) {

	// Argument can specify either a target or a unittest package.  Determine
	// which type the package is and construct a target builder appropriately.
	if t, err := resolveExistingTargetArg(pkgName); err == nil {
		return t, nil, nil
	}

	// Package wasn't a target.  Try for a unittest.
	proj := TryGetProject()
	pack, err := proj.ResolvePackage(proj.LocalRepo(), pkgName)
	if err != nil {
		return nil, nil, util.FmtNewtError(
			"Could not resolve target or unittest \"%s\"", pkgName)
	}

	if pack.Type() != pkg.PACKAGE_TYPE_UNITTEST {
		return nil, nil, util.FmtNewtError(
			"Package \"%s\" is of type %s; "+
				"must be target or unittest", pkgName,
			pkg.PackageTypeNames[pack.Type()])
	}

	t, err := ResolveUnittest(pack.Name())
	if err != nil {
		return nil, nil, err
	}

	return t, pack, nil
}

func ResolvePackages(pkgNames []string) ([]*pkg.LocalPackage, error) {
	proj := TryGetProject()

	lpkgs := []*pkg.LocalPackage{}
	for _, pkgName := range pkgNames {
		pack, err := proj.ResolvePackage(proj.LocalRepo(), pkgName)
		if err != nil {
			return nil, err
		}
		lpkgs = append(lpkgs, pack)
	}

	return lpkgs, nil
}

func ResolveRpkgs(res *resolve.Resolution, pkgNames []string) (
	[]*resolve.ResolvePackage, error) {

	lpkgs, err := ResolvePackages(pkgNames)
	if err != nil {
		return nil, err
	}

	rpkgs := []*resolve.ResolvePackage{}
	for _, lpkg := range lpkgs {
		rpkg := res.LpkgRpkgMap[lpkg]
		if rpkg == nil {
			return nil, util.FmtNewtError("Unexpected error; local package "+
				"%s lacks a corresponding resolve package", lpkg.FullName())
		}

		rpkgs = append(rpkgs, rpkg)
	}

	return rpkgs, nil
}

func TargetBuilderForTargetOrUnittest(pkgName string) (
	*builder.TargetBuilder, error) {

	t, testPkg, err := ResolveTargetOrUnittest(pkgName)
	if err != nil {
		return nil, err
	}

	if testPkg == nil {
		return builder.NewTargetBuilder(t)
	} else {
		return builder.NewTargetTester(t, testPkg)
	}
}

func PromptYesNo(dflt bool) bool {
	scanner := bufio.NewScanner(os.Stdin)
	rc := scanner.Scan()
	if !rc {
		return dflt
	}

	if strings.ToLower(scanner.Text()) == "y" {
		return true
	}

	if strings.ToLower(scanner.Text()) == "n" {
		return false
	}

	return dflt
}
<|endoftext|>


<commit_before>
package core

import ("fmt"
	"os"
	"strconv"
	"github.com/jackyb/go-sdl2/sdl"
	"github.com/op/go-nanomsg"
	"github.com/fire/go-ogre3d")

type InputState struct {
	yawSens float32
	pitchSens float32
	orientationFactor float32 // +1/-1 easy switch between look around and manipulate something
	yaw float32 // degrees, modulo [-180,180] range
	pitch float32 // degrees, clamped [-90,90] range
	roll float32
	// orientation ogre.Quaternion // current orientation
}

func InitCore() {
	sdl.Init(sdl.INIT_EVERYTHING)
	window := sdl.CreateWindow("es_core::SDL",
		sdl.WINDOWPOS_UNDEFINED,
		sdl.WINDOWPOS_UNDEFINED,
		800,
		600,
		sdl.WINDOW_SHOWN)
	if window == nil {
		panic(fmt.Sprintf("sdl.CreateWindow failed: %s\n", sdl.GetError()))
	}
	defer sdl.Quit()
	var info sdl.SysWMInfo
	if !window.GetWMInfo(&info) {
		panic(fmt.Sprintf("window.GetWMInfo failed.\n"))
	}
	// Parse and print info's version
	// Parse and print info's SYSWM_TYPE
	root := ogre.NewRoot("", "", "ogre.log")
	defer root.Destroy()
	wd, err := os.Getwd()
	if err != nil {
		panic(err)
	}
	root.LoadPlugin(wd  + "/../frameworks/RenderSystem_GL.framework")
	renderers := root.GetAvailableRenderers()
	if renderers.RenderSystemListSize() != 1 {
		panic(fmt.Sprintf("Failed to initalize RendererRenderSystem_GL"))
	}
	root.SetRenderSystem(renderers.RenderSystemListGet(0))
	root.Initialise(false, "es_core::ogre")
	params := ogre.CreateNameValuePairList()
	params.AddPair("macAPI", "cocoa")
	cocoaInfo := info.GetCocoaInfo()
	windowString := strconv.FormatUint(uint64(*(*uint32)(cocoaInfo.Window)), 10)
	params.AddPair("parentWindowHandle", windowString)

	renderWindow := root.CreateRenderWindow("es_core::ogre", 800, 600, false, params)
	renderWindow.SetVisible(true)

	nnGameSocket, err := nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.BUS)
        if err != nil {
                panic(err)
        }
        _, err = nnGameSocket.Bind("tcp://127.0.0.1:60206")
        if err != nil {
                panic(err)
        }

	nnRenderSocket, err := nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.BUS)
	if err != nil {
                panic(err)
        }
        _, err = nnRenderSocket.Bind("tcp://127.0.0.1:60207")
        if err != nil {
                panic(err)
        }

	nnInputPub, err := nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.PUB)
        if err != nil {
                panic(err)
        }
        _, err = nnInputPub.Bind("tcp://127.0.0.1:60208")
        if err != nil {
                panic(err)
        }

	nnInputPull, err := nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.PULL)
        if err != nil {
                panic(err)
        }
        _, err = nnInputPull.Bind("tcp://127.0.0.1:60209")
        if err != nil {
                panic(err)
        }
	go gameThread()
	var renderThreadParams RenderThreadParams
	renderThreadParams.root = root
	renderThreadParams.window = window
	renderThreadParams.ogreWindow = renderWindow

	go renderThread(renderThreadParams)

	window.SetGrab(true)
	sdl.SetRelativeMouseMode(true)

	shutdownRequested := false
	var is InputState
	is.yawSens = 0.1
	is.yaw = 0.0
	is.pitchSens = 0.1
	is.pitch = 0.0
	is.roll = 0.0
	is.orientationFactor = -1.0 // Look around config

	for !shutdownRequested {
		var inputPull string
		string, err := nnInputPull.RecvString()
	}
}
<commit_msg>Get nanomsg msgpack message and poll sdl.<commit_after>
package core

import ("fmt"
	"os"
	"strconv"
	"github.com/jackyb/go-sdl2/sdl"
	"github.com/op/go-nanomsg"
	"github.com/fire/go-ogre3d"
	"github.com/ugorji/go/codec")

type InputState struct {
	yawSens float32
	pitchSens float32
	orientationFactor float32 // +1/-1 easy switch between look around and manipulate something
	yaw float32 // degrees, modulo [-180,180] range
	pitch float32 // degrees, clamped [-90,90] range
	roll float32
	// orientation ogre.Quaternion // current orientation
}

func InitCore() {
	sdl.Init(sdl.INIT_EVERYTHING)
	window := sdl.CreateWindow("es_core::SDL",
		sdl.WINDOWPOS_UNDEFINED,
		sdl.WINDOWPOS_UNDEFINED,
		800,
		600,
		sdl.WINDOW_SHOWN)
	if window == nil {
		panic(fmt.Sprintf("sdl.CreateWindow failed: %s\n", sdl.GetError()))
	}
	defer sdl.Quit()
	var info sdl.SysWMInfo
	if !window.GetWMInfo(&info) {
		panic(fmt.Sprintf("window.GetWMInfo failed.\n"))
	}
	// Parse and print info's version
	// Parse and print info's SYSWM_TYPE
	root := ogre.NewRoot("", "", "ogre.log")
	defer root.Destroy()
	wd, err := os.Getwd()
	if err != nil {
		panic(err)
	}
	root.LoadPlugin(wd  + "/../frameworks/RenderSystem_GL.framework")
	renderers := root.GetAvailableRenderers()
	if renderers.RenderSystemListSize() != 1 {
		panic(fmt.Sprintf("Failed to initalize RendererRenderSystem_GL"))
	}
	root.SetRenderSystem(renderers.RenderSystemListGet(0))
	root.Initialise(false, "es_core::ogre")
	params := ogre.CreateNameValuePairList()
	params.AddPair("macAPI", "cocoa")
	cocoaInfo := info.GetCocoaInfo()
	windowString := strconv.FormatUint(uint64(*(*uint32)(cocoaInfo.Window)), 10)
	params.AddPair("parentWindowHandle", windowString)

	renderWindow := root.CreateRenderWindow("es_core::ogre", 800, 600, false, params)
	renderWindow.SetVisible(true)

	nnGameSocket, err := nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.BUS)
        if err != nil {
                panic(err)
        }
        _, err = nnGameSocket.Bind("tcp://127.0.0.1:60206")
        if err != nil {
                panic(err)
        }

	nnRenderSocket, err := nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.BUS)
	if err != nil {
                panic(err)
        }
        _, err = nnRenderSocket.Bind("tcp://127.0.0.1:60207")
        if err != nil {
                panic(err)
        }

	nnInputPub, err := nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.PUB)
        if err != nil {
                panic(err)
        }
        _, err = nnInputPub.Bind("tcp://127.0.0.1:60208")
        if err != nil {
                panic(err)
        }

	nnInputPull, err := nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.PULL)
        if err != nil {
                panic(err)
        }
        _, err = nnInputPull.Bind("tcp://127.0.0.1:60209")
        if err != nil {
                panic(err)
        }
	go gameThread()
	var renderThreadParams RenderThreadParams
	renderThreadParams.root = root
	renderThreadParams.window = window
	renderThreadParams.ogreWindow = renderWindow

	go renderThread(renderThreadParams)

	window.SetGrab(true)
	sdl.SetRelativeMouseMode(true)

	shutdownRequested := false
	var is InputState
	is.yawSens = 0.1
	is.yaw = 0.0
	is.pitchSens = 0.1
	is.pitch = 0.0
	is.roll = 0.0
	is.orientationFactor = -1.0 // Look around config

	// Msgpack
	var (
		v interface{} //Value to decode into
		mh codec.MsgpackHandle
	)

	for !shutdownRequested {
		var b []byte
		// We wait here.
		b, err = nnInputPull.Recv(0)
		fmt.Printf("Game push received:\n")
		if err != nil {
			fmt.Printf("%s\n", err)
		}
		dec := codec.NewDecoderBytes(b, &mh)
		err = dec.Decode(&v)
		if err != nil {
			fmt.Printf("%s\n", err)
		}

		// poll for events before processing the request
		// NOTE: this is how SDL builds the internal mouse and keyboard state
		// TODO: done this way does not meet the objectives of smooth, frame independent mouse view control,
		// Plus it throws some latency into the calling thread

		var event sdl.Event
		for event = sdl.PollEvent(); event != nil; event = sdl.PollEvent {
			switch t := event.(type) {
			case *sdl.KeyDownEvent:
				fmt.Printf("SDL keyboard event:\n")
			case *sdl.KeyUpEvent:
				fmt.Printf("SDL keyboard event:\n")
				if t.Keysym.Scancode == sdl.SCANCODE_ESCAPE {
					// Todo
					sendShutdown(nnRenderSocket, nnGameSocket)
					shutdownRequested = true
				}
			}
		}
	}
}

func sendShutdown (nnRenderSocket *nanomsg.Socket, nnGameSocket *nanomsg.Socket) {
	fmt.Printf("Render socket shutdown.\n")
	fmt.Printf("Game socket shutdown.\n")
}
<|endoftext|>


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

package octrace

import (
	"bytes"
	"encoding/json"
	"reflect"
	"sync"
	"testing"
	"time"

	commonpb "github.com/census-instrumentation/opencensus-proto/gen-go/agent/common/v1"
	agenttracepb "github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1"
	tracepb "github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1"
	"github.com/stretchr/testify/require"
	"go.opencensus.io/trace"

	"go.opentelemetry.io/collector/exporter/exportertest"
	"go.opentelemetry.io/collector/obsreport/obsreporttest"
)

// Ensure that if we add a metrics exporter that our target metrics
// will be recorded but also with the proper tag keys and values.
// See Issue https://github.com/census-instrumentation/opencensus-service/issues/63
//
// Note: we are intentionally skipping the ocgrpc.ServerDefaultViews as this
// test is to ensure exactness, but with the mentioned views registered, the
// output will be quite noisy.
func TestEnsureRecordedMetrics(t *testing.T) {
	doneFn, err := obsreporttest.SetupRecordedMetricsTest()
	require.NoError(t, err)
	defer doneFn()

	port, doneReceiverFn := ocReceiverOnGRPCServer(t, exportertest.NewNopTraceExporter())
	defer doneReceiverFn()

	n := 20
	// Now for the traceExporter that sends 0 length spans
	traceSvcClient, traceSvcDoneFn, err := makeTraceServiceClient(port)
	require.NoError(t, err, "Failed to create the trace service client: %v", err)
	spans := []*tracepb.Span{{TraceId: []byte("abcdefghijklmnop"), SpanId: []byte("12345678")}}
	for i := 0; i < n; i++ {
		err = traceSvcClient.Send(&agenttracepb.ExportTraceServiceRequest{Spans: spans, Node: &commonpb.Node{}})
		require.NoError(t, err, "Failed to send requests to the service: %v", err)
	}
	flush(traceSvcDoneFn)

	obsreporttest.CheckReceiverTracesViews(t, "oc_trace", "grpc", int64(n), 0)
}

func TestEnsureRecordedMetrics_zeroLengthSpansSender(t *testing.T) {
	doneFn, err := obsreporttest.SetupRecordedMetricsTest()
	require.NoError(t, err)
	defer doneFn()

	port, doneFn := ocReceiverOnGRPCServer(t, exportertest.NewNopTraceExporter())
	defer doneFn()

	n := 20
	// Now for the traceExporter that sends 0 length spans
	traceSvcClient, traceSvcDoneFn, err := makeTraceServiceClient(port)
	require.NoError(t, err, "Failed to create the trace service client: %v", err)
	for i := 0; i <= n; i++ {
		err = traceSvcClient.Send(&agenttracepb.ExportTraceServiceRequest{Spans: nil, Node: &commonpb.Node{}})
		require.NoError(t, err, "Failed to send requests to the service: %v", err)
	}
	flush(traceSvcDoneFn)

	obsreporttest.CheckReceiverTracesViews(t, "oc_trace", "grpc", 0, 0)
}

func TestExportSpanLinkingMaintainsParentLink(t *testing.T) {
	// Always sample for the purpose of examining all the spans in this test.
	trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})

	// TODO: File an issue with OpenCensus-Go to ask for a method to retrieve
	// the default sampler because the current method of blindly changing the
	// global sampler makes testing hard.
	// Denoise this test by setting the sampler to never sample
	defer trace.ApplyConfig(trace.Config{DefaultSampler: trace.NeverSample()})

	ocSpansSaver := new(testOCTraceExporter)
	trace.RegisterExporter(ocSpansSaver)
	defer trace.UnregisterExporter(ocSpansSaver)

	port, doneFn := ocReceiverOnGRPCServer(t, exportertest.NewNopTraceExporter())
	defer doneFn()

	traceSvcClient, traceSvcDoneFn, err := makeTraceServiceClient(port)
	require.NoError(t, err, "Failed to create the trace service client: %v", err)

	n := 5
	for i := 0; i < n; i++ {
		sl := []*tracepb.Span{{TraceId: []byte("abcdefghijklmnop"), SpanId: []byte{byte(i + 1), 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}}}
		err = traceSvcClient.Send(&agenttracepb.ExportTraceServiceRequest{Spans: sl, Node: &commonpb.Node{}})
		require.NoError(t, err, "Failed to send requests to the service: %v", err)
	}

	flush(traceSvcDoneFn)

	// Inspection time!
	ocSpansSaver.mu.Lock()
	defer ocSpansSaver.mu.Unlock()

	require.NotEqual(
		t,
		len(ocSpansSaver.spanData),
		0,
		"Unfortunately did not receive an exported span data. Please check this library's implementation or go.opencensus.io/trace",
	)

	gotSpanData := ocSpansSaver.spanData
	if g, w := len(gotSpanData), n+1; g != w {
		blob, _ := json.MarshalIndent(gotSpanData, "  ", " ")
		t.Fatalf("Spandata count: Got %d Want %d\n\nData: %s", g, w, blob)
	}

	receiverSpanData := gotSpanData[0]
	if g, w := len(receiverSpanData.Links), 1; g != w {
		t.Fatalf("Links count: Got %d Want %d\nGotSpanData: %#v", g, w, receiverSpanData)
	}

	// The rpc span is always last in the list
	rpcSpanData := gotSpanData[len(gotSpanData)-1]

	// Ensure that the link matches up exactly!
	wantLink := trace.Link{
		SpanID:  rpcSpanData.SpanID,
		TraceID: rpcSpanData.TraceID,
		Type:    trace.LinkTypeParent,
	}
	if g, w := receiverSpanData.Links[0], wantLink; !reflect.DeepEqual(g, w) {
		t.Errorf("Link:\nGot: %#v\nWant: %#v\n", g, w)
	}
	if g, w := receiverSpanData.Name, "receiver/oc_trace/TraceDataReceived"; g != w {
		t.Errorf("ReceiverExport span's SpanData.Name:\nGot:  %q\nWant: %q\n", g, w)
	}

	// And then for the receiverSpanData itself, it SHOULD NOT
	// have a ParentID, so let's enforce all the conditions below:
	// 1. That it doesn't have the RPC spanID as its ParentSpanID
	// 2. That it actually has no ParentSpanID i.e. has a blank SpanID
	if g, w := receiverSpanData.ParentSpanID[:], rpcSpanData.SpanID[:]; bytes.Equal(g, w) {
		t.Errorf("ReceiverSpanData.ParentSpanID unfortunately was linked to the RPC span\nGot:  %x\nWant: %x", g, w)
	}

	var blankSpanID trace.SpanID
	if g, w := receiverSpanData.ParentSpanID[:], blankSpanID[:]; !bytes.Equal(g, w) {
		t.Errorf("ReceiverSpanData unfortunately has a parent and isn't NULL\nGot:  %x\nWant: %x", g, w)
	}
}

type testOCTraceExporter struct {
	mu       sync.Mutex
	spanData []*trace.SpanData
}

func (tote *testOCTraceExporter) ExportSpan(sd *trace.SpanData) {
	tote.mu.Lock()
	defer tote.mu.Unlock()

	tote.spanData = append(tote.spanData, sd)
}

// TODO: Determine how to do this deterministic.
func flush(traceSvcDoneFn func()) {
	// Give it enough time to process the streamed spans.
	<-time.After(20 * time.Millisecond)

	// End the gRPC service to complete the RPC trace so that we
	// can examine the RPC trace as well.
	traceSvcDoneFn()

	// Give it some more time to complete the RPC trace and export.
	<-time.After(20 * time.Millisecond)
}
<commit_msg>OpenCensus Flaky Test Fix (#1863)<commit_after>// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package octrace

import (
	"bytes"
	"encoding/json"
	"reflect"
	"sync"
	"testing"
	"time"

	commonpb "github.com/census-instrumentation/opencensus-proto/gen-go/agent/common/v1"
	agenttracepb "github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1"
	tracepb "github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1"
	"github.com/stretchr/testify/require"
	"go.opencensus.io/trace"

	"go.opentelemetry.io/collector/exporter/exportertest"
	"go.opentelemetry.io/collector/obsreport/obsreporttest"
)

// Ensure that if we add a metrics exporter that our target metrics
// will be recorded but also with the proper tag keys and values.
// See Issue https://github.com/census-instrumentation/opencensus-service/issues/63
//
// Note: we are intentionally skipping the ocgrpc.ServerDefaultViews as this
// test is to ensure exactness, but with the mentioned views registered, the
// output will be quite noisy.
func TestEnsureRecordedMetrics(t *testing.T) {
	doneFn, err := obsreporttest.SetupRecordedMetricsTest()
	require.NoError(t, err)
	defer doneFn()

	port, doneReceiverFn := ocReceiverOnGRPCServer(t, exportertest.NewNopTraceExporter())
	defer doneReceiverFn()

	n := 20
	// Now for the traceExporter that sends 0 length spans
	traceSvcClient, traceSvcDoneFn, err := makeTraceServiceClient(port)
	require.NoError(t, err, "Failed to create the trace service client: %v", err)
	spans := []*tracepb.Span{{TraceId: []byte("abcdefghijklmnop"), SpanId: []byte("12345678")}}
	for i := 0; i < n; i++ {
		err = traceSvcClient.Send(&agenttracepb.ExportTraceServiceRequest{Spans: spans, Node: &commonpb.Node{}})
		require.NoError(t, err, "Failed to send requests to the service: %v", err)
	}
	flush(traceSvcDoneFn)

	obsreporttest.CheckReceiverTracesViews(t, "oc_trace", "grpc", int64(n), 0)
}

func TestEnsureRecordedMetrics_zeroLengthSpansSender(t *testing.T) {
	doneFn, err := obsreporttest.SetupRecordedMetricsTest()
	require.NoError(t, err)
	defer doneFn()

	port, doneFn := ocReceiverOnGRPCServer(t, exportertest.NewNopTraceExporter())
	defer doneFn()

	n := 20
	// Now for the traceExporter that sends 0 length spans
	traceSvcClient, traceSvcDoneFn, err := makeTraceServiceClient(port)
	require.NoError(t, err, "Failed to create the trace service client: %v", err)
	for i := 0; i <= n; i++ {
		err = traceSvcClient.Send(&agenttracepb.ExportTraceServiceRequest{Spans: nil, Node: &commonpb.Node{}})
		require.NoError(t, err, "Failed to send requests to the service: %v", err)
	}
	flush(traceSvcDoneFn)

	obsreporttest.CheckReceiverTracesViews(t, "oc_trace", "grpc", 0, 0)
}

func TestExportSpanLinkingMaintainsParentLink(t *testing.T) {
	// Always sample for the purpose of examining all the spans in this test.
	trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})

	// TODO: File an issue with OpenCensus-Go to ask for a method to retrieve
	// the default sampler because the current method of blindly changing the
	// global sampler makes testing hard.
	// Denoise this test by setting the sampler to never sample
	defer trace.ApplyConfig(trace.Config{DefaultSampler: trace.NeverSample()})

	ocSpansSaver := new(testOCTraceExporter)
	trace.RegisterExporter(ocSpansSaver)
	defer trace.UnregisterExporter(ocSpansSaver)

	port, doneFn := ocReceiverOnGRPCServer(t, exportertest.NewNopTraceExporter())
	defer doneFn()

	traceSvcClient, traceSvcDoneFn, err := makeTraceServiceClient(port)
	require.NoError(t, err, "Failed to create the trace service client: %v", err)

	n := 5
	for i := 0; i < n; i++ {
		sl := []*tracepb.Span{{TraceId: []byte("abcdefghijklmnop"), SpanId: []byte{byte(i + 1), 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}}}
		err = traceSvcClient.Send(&agenttracepb.ExportTraceServiceRequest{Spans: sl, Node: &commonpb.Node{}})
		require.NoError(t, err, "Failed to send requests to the service: %v", err)
	}

	flush(traceSvcDoneFn)

	// Inspection time!
	ocSpansSaver.mu.Lock()
	defer ocSpansSaver.mu.Unlock()

	require.NotEqual(
		t,
		len(ocSpansSaver.spanData),
		0,
		"Unfortunately did not receive an exported span data. Please check this library's implementation or go.opencensus.io/trace",
	)

	gotSpanData := ocSpansSaver.spanData
	if g, w := len(gotSpanData), n+1; g != w {
		blob, _ := json.MarshalIndent(gotSpanData, "  ", " ")
		t.Fatalf("Spandata count: Got %d Want %d\n\nData: %s", g, w, blob)
	}

	receiverSpanData := gotSpanData[0]
	if g, w := len(receiverSpanData.Links), 1; g != w {
		t.Fatalf("Links count: Got %d Want %d\nGotSpanData: %#v", g, w, receiverSpanData)
	}

	// The rpc span is always last in the list
	rpcSpanData := gotSpanData[len(gotSpanData)-1]

	// Ensure that the link matches up exactly!
	wantLink := trace.Link{
		SpanID:  rpcSpanData.SpanID,
		TraceID: rpcSpanData.TraceID,
		Type:    trace.LinkTypeParent,
	}
	if g, w := receiverSpanData.Links[0], wantLink; !reflect.DeepEqual(g, w) {
		t.Errorf("Link:\nGot: %#v\nWant: %#v\n", g, w)
	}
	if g, w := receiverSpanData.Name, "receiver/oc_trace/TraceDataReceived"; g != w {
		t.Errorf("ReceiverExport span's SpanData.Name:\nGot:  %q\nWant: %q\n", g, w)
	}

	// And then for the receiverSpanData itself, it SHOULD NOT
	// have a ParentID, so let's enforce all the conditions below:
	// 1. That it doesn't have the RPC spanID as its ParentSpanID
	// 2. That it actually has no ParentSpanID i.e. has a blank SpanID
	if g, w := receiverSpanData.ParentSpanID[:], rpcSpanData.SpanID[:]; bytes.Equal(g, w) {
		t.Errorf("ReceiverSpanData.ParentSpanID unfortunately was linked to the RPC span\nGot:  %x\nWant: %x", g, w)
	}

	var blankSpanID trace.SpanID
	if g, w := receiverSpanData.ParentSpanID[:], blankSpanID[:]; !bytes.Equal(g, w) {
		t.Errorf("ReceiverSpanData unfortunately has a parent and isn't NULL\nGot:  %x\nWant: %x", g, w)
	}
}

type testOCTraceExporter struct {
	mu       sync.Mutex
	spanData []*trace.SpanData
}

func (tote *testOCTraceExporter) ExportSpan(sd *trace.SpanData) {
	tote.mu.Lock()
	defer tote.mu.Unlock()

	tote.spanData = append(tote.spanData, sd)
}

// TODO: Determine how to do this deterministic.
func flush(traceSvcDoneFn func()) {
	// Give it enough time to process the streamed spans.
	<-time.After(40 * time.Millisecond)

	// End the gRPC service to complete the RPC trace so that we
	// can examine the RPC trace as well.
	traceSvcDoneFn()

	// Give it some more time to complete the RPC trace and export.
	<-time.After(40 * time.Millisecond)
}
<|endoftext|>