<commit_before>// Copyright © 2017 Circonus, Inc. <support@circonus.com>
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//

package promrecv

import (
	"bytes"
	"io/ioutil"
	"testing"

	"github.com/rs/zerolog"
)

// prometheus exposition formats example from: https://prometheus.io/docs/instrumenting/exposition_formats/
var promData = `
# HELP http_requests_total The total number of HTTP requests.
# TYPE http_requests_total counter
http_requests_total{method="post",code="200"} 1027 1395066363000
http_requests_total{method="post",code="400"}    3 1395066363000

# Escaping in label values:
msdos_file_access_time_seconds{path="C:\\DIR\\FILE.TXT",error="Cannot find file:\n\"FILE.TXT\""} 1.458255915e9

# Minimalistic line:
metric_without_timestamp_and_labels 12.47

# A weird metric from before the epoch:
something_weird{problem="division by zero"} +Inf -3982045

# A histogram, which has a pretty complex representation in the text format:
# HELP http_request_duration_seconds A histogram of the request duration.
# TYPE http_request_duration_seconds histogram
http_request_duration_seconds_bucket{le="0.05"} 24054
http_request_duration_seconds_bucket{le="0.1"} 33444
http_request_duration_seconds_bucket{le="0.2"} 100392
http_request_duration_seconds_bucket{le="0.5"} 129389
http_request_duration_seconds_bucket{le="1"} 133988
http_request_duration_seconds_bucket{le="+Inf"} 144320
http_request_duration_seconds_sum 53423
http_request_duration_seconds_count 144320

# Finally a summary, which has a complex representation, too:
# HELP rpc_duration_seconds A summary of the RPC duration in seconds.
# TYPE rpc_duration_seconds summary
rpc_duration_seconds{quantile="0.01"} 3102
rpc_duration_seconds{quantile="0.05"} 3272
rpc_duration_seconds{quantile="0.5"} 4773
rpc_duration_seconds{quantile="0.9"} 9001
rpc_duration_seconds{quantile="0.99"} 76656
rpc_duration_seconds_sum 1.7560473e+07
rpc_duration_seconds_count 2693

# HELP threads_started The number of threads started
# TYPE threads_started gauge
threads_started 3851.0

# test marker
test 1234
`

func TestFlush(t *testing.T) {
	t.Log("Testing Flush")

	zerolog.SetGlobalLevel(zerolog.Disabled)

	t.Log("\tno metrics")
	{
		m := Flush()
		if len(*m) != 0 {
			t.Fatalf("expected 0 metrics, got %d", len(*m))
		}
	}

	t.Log("\tw/metric(s)")
	{
		err := initCGM()
		if err != nil {
			t.Fatalf("expected no error, got %s", err)
		}
		metrics.SetText("test", "test")

		m := Flush()
		if len(*m) != 1 {
			t.Fatalf("expected 1 metric, got %d", len(*m))
		}
	}
}

func TestParse(t *testing.T) {
	t.Log("Testing Parse")

	zerolog.SetGlobalLevel(zerolog.Disabled)

	err := initCGM()
	if err != nil {
		t.Fatalf("expected no error, got %s", err)
	}

	t.Log("\tno data")
	{
		data := []byte{}
		r := ioutil.NopCloser(bytes.NewReader(data))
		err := Parse(r)
		if err != nil {
			t.Fatal("expected NO error, got (%s)", err)
		}
	}

	t.Log("\tblank/empty data")
	{
		data := []byte("")
		r := ioutil.NopCloser(bytes.NewReader(data))
		err := Parse(r)
		if err != nil {
			t.Fatal("expected NO error, got (%s)", err)
		}
	}

	t.Log("\tvalid data")
	{
		data := []byte(promData)
		r := ioutil.NopCloser(bytes.NewReader(data))
		err := Parse(r)
		if err != nil {
			t.Fatalf("expected NO error, got (%s)", err)
		}
		m := metrics.FlushMetrics()
		numExpected := 22
		if len(*m) != numExpected {
			t.Fatalf("expected %d metrics, got %d", numExpected, len(*m))
		}
		testMetric, ok := (*m)["prom`test"]
		if !ok {
			t.Fatalf("expected metric 'prom`test', %#v", m)
		}
		expect := float64(1234)
		if testMetric.Value.(float64) != expect {
			t.Fatalf("expected %v got %v", expect, testMetric.Value)
		}
	}
}
<commit_msg>fix: 2 t.Fatalf calls<commit_after>// Copyright © 2017 Circonus, Inc. <support@circonus.com>
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//

package promrecv

import (
	"bytes"
	"io/ioutil"
	"testing"

	"github.com/rs/zerolog"
)

// prometheus exposition formats example from: https://prometheus.io/docs/instrumenting/exposition_formats/
var promData = `
# HELP http_requests_total The total number of HTTP requests.
# TYPE http_requests_total counter
http_requests_total{method="post",code="200"} 1027 1395066363000
http_requests_total{method="post",code="400"}    3 1395066363000

# Escaping in label values:
msdos_file_access_time_seconds{path="C:\\DIR\\FILE.TXT",error="Cannot find file:\n\"FILE.TXT\""} 1.458255915e9

# Minimalistic line:
metric_without_timestamp_and_labels 12.47

# A weird metric from before the epoch:
something_weird{problem="division by zero"} +Inf -3982045

# A histogram, which has a pretty complex representation in the text format:
# HELP http_request_duration_seconds A histogram of the request duration.
# TYPE http_request_duration_seconds histogram
http_request_duration_seconds_bucket{le="0.05"} 24054
http_request_duration_seconds_bucket{le="0.1"} 33444
http_request_duration_seconds_bucket{le="0.2"} 100392
http_request_duration_seconds_bucket{le="0.5"} 129389
http_request_duration_seconds_bucket{le="1"} 133988
http_request_duration_seconds_bucket{le="+Inf"} 144320
http_request_duration_seconds_sum 53423
http_request_duration_seconds_count 144320

# Finally a summary, which has a complex representation, too:
# HELP rpc_duration_seconds A summary of the RPC duration in seconds.
# TYPE rpc_duration_seconds summary
rpc_duration_seconds{quantile="0.01"} 3102
rpc_duration_seconds{quantile="0.05"} 3272
rpc_duration_seconds{quantile="0.5"} 4773
rpc_duration_seconds{quantile="0.9"} 9001
rpc_duration_seconds{quantile="0.99"} 76656
rpc_duration_seconds_sum 1.7560473e+07
rpc_duration_seconds_count 2693

# HELP threads_started The number of threads started
# TYPE threads_started gauge
threads_started 3851.0

# test marker
test 1234
`

func TestFlush(t *testing.T) {
	t.Log("Testing Flush")

	zerolog.SetGlobalLevel(zerolog.Disabled)

	t.Log("\tno metrics")
	{
		m := Flush()
		if len(*m) != 0 {
			t.Fatalf("expected 0 metrics, got %d", len(*m))
		}
	}

	t.Log("\tw/metric(s)")
	{
		err := initCGM()
		if err != nil {
			t.Fatalf("expected no error, got %s", err)
		}
		metrics.SetText("test", "test")

		m := Flush()
		if len(*m) != 1 {
			t.Fatalf("expected 1 metric, got %d", len(*m))
		}
	}
}

func TestParse(t *testing.T) {
	t.Log("Testing Parse")

	zerolog.SetGlobalLevel(zerolog.Disabled)

	err := initCGM()
	if err != nil {
		t.Fatalf("expected no error, got %s", err)
	}

	t.Log("\tno data")
	{
		data := []byte{}
		r := ioutil.NopCloser(bytes.NewReader(data))
		err := Parse(r)
		if err != nil {
			t.Fatalf("expected NO error, got (%s)", err)
		}
	}

	t.Log("\tblank/empty data")
	{
		data := []byte("")
		r := ioutil.NopCloser(bytes.NewReader(data))
		err := Parse(r)
		if err != nil {
			t.Fatalf("expected NO error, got (%s)", err)
		}
	}

	t.Log("\tvalid data")
	{
		data := []byte(promData)
		r := ioutil.NopCloser(bytes.NewReader(data))
		err := Parse(r)
		if err != nil {
			t.Fatalf("expected NO error, got (%s)", err)
		}
		m := metrics.FlushMetrics()
		numExpected := 22
		if len(*m) != numExpected {
			t.Fatalf("expected %d metrics, got %d", numExpected, len(*m))
		}
		testMetric, ok := (*m)["prom`test"]
		if !ok {
			t.Fatalf("expected metric 'prom`test', %#v", m)
		}
		expect := float64(1234)
		if testMetric.Value.(float64) != expect {
			t.Fatalf("expected %v got %v", expect, testMetric.Value)
		}
	}
}
<|endoftext|>


<commit_before>package generator

import (
	"fmt"
	"strings"
	"text/template"

	pd "github.com/golang/protobuf/protoc-gen-go/descriptor"
)

type gatewayTemplate struct {
	Generator *Generator
	File      *File
	Imports   []*GoPackage
}

func (g *gatewayTemplate) GetRequestClass(msg *Message) string {
	if msg.File == g.File {
		return msg.GetName()
	}

	for _, pkg := range g.Imports {
		if msg.File.GoPkg.Path == pkg.Path {
			return fmt.Sprintf("%s.%s", pkg.Alias, msg.GetName())
		}
	}

	return ""
}

func (g *gatewayTemplate) PathTemplate(b *Binding) string {
	result := ""

	for _, param := range b.Path.Params {
		field := b.Method.RequestType.LookupField(param)
		lhs := fmt.Sprintf("req.%s", strings.Title(field.GetName()))
		rhs := "v"
		converter := g.ConvertStringField(field, lhs, rhs)

		if converter == "" {
			continue
		}

		result += fmt.Sprintf("if %s, ok := r.UserValue(%q).(string); ok { %s }\n", rhs, field.GetName(), converter)
	}

	return result
}

func (g *gatewayTemplate) QueryTemplate(b *Binding) string {
	result := ""
	excluded := map[string]bool{}

	// All fields are body
	if b.Body == "*" {
		return ""
	}

	// Exclude body field
	if b.Body != "" {
		excluded[b.Body] = true
	}

	// Exclude path params
	for _, param := range b.Path.Params {
		excluded[param] = true
	}

	for _, field := range b.Method.RequestType.Fields {
		if excluded[field.GetName()] {
			continue
		}

		lhs := fmt.Sprintf("req.%s", strings.Title(field.GetName()))
		rhs := "values"
		converter := g.ConvertStringArrayField(field, lhs, rhs, true)

		if converter == "" {
			continue
		}

		result += fmt.Sprintf("if %s := r.QueryArgs().PeekMulti(%q); len(%s) > 0 { %s }\n", rhs, field.GetName(), rhs, converter)
	}

	return result
}

func (g *gatewayTemplate) BodyTemplate(b *Binding) string {
	if b.Body == "" {
		return ""
	}

	result := ""

	if b.Body == "*" {
		result += "body := req\n"
	} else {
		result += fmt.Sprintf("body := req.%s\n", strings.Title(b.Body))
	}

	body := ""

	for _, field := range b.BodyType.Fields {
		lhs := fmt.Sprintf("body.%s", strings.Title(field.GetName()))
		rhs := "values"
		converter := g.ConvertStringArrayField(field, lhs, rhs, false)

		if converter == "" {
			continue
		}

		body += fmt.Sprintf("if %s, ok := query[%q]; ok && len(%s) > 0 { %s }\n", rhs, field.GetName(), rhs, converter)
	}

	result += fmt.Sprintf(`
if gateway.IsBodyURLEncoded(r) {
  query, err := url.ParseQuery(string(r.Request.Body()))

  if err != nil {
    return err
  }

  %s
} else {
  if err := json.Unmarshal(r.Request.Body(), body); err != nil {
    panic(err)
  }
}`, body)

	return result
}

func (g *gatewayTemplate) IsEmptyResponse(b *Binding) bool {
	return b.Method.ResponseType.FQMN == ".google.protobuf.Empty"
}

func (g *gatewayTemplate) ConvertStringField(field *Field, lhs string, rhs string) string {
	if fn, ok := convertStringFuncMap[field.GetType()]; ok {
		v := fmt.Sprintf(fn, rhs)
		return fmt.Sprintf("%s = %s", lhs, v)
	}

	return ""
}

func (g *gatewayTemplate) ConvertStringArrayField(field *Field, lhs string, rhs string, isBytes bool) string {
	if field.GetLabel() != pd.FieldDescriptorProto_LABEL_REPEATED {
		var v string

		if isBytes {
			v = fmt.Sprintf("string(%s[0])", rhs)
		} else {
			v = rhs + "[0]"
		}

		return g.ConvertStringField(field, lhs, v)
	}

	if elem, ok := protoTypeMap[field.GetType()]; ok {
		v := "v"

		if isBytes {
			v = "string(v)"
		}

		converter := g.ConvertStringField(field, lhs+"[i]", v)

		return fmt.Sprintf(`
%s = make([]%s, len(%s))

for i, v := range %s {
  %s
}`, lhs, elem, rhs, rhs, converter)
	}

	return ""
}

func (g *gatewayTemplate) GetQueryFields(m *Method, b *Binding) []*Field {
	result := []*Field{}
	excluded := map[string]bool{}

	// Exclude body params
	if b.Body == "*" {
		return result
	} else if b.Body != "" {
		excluded[b.Body] = true
	}

	// Exclude path params
	for _, p := range b.Path.Params {
		excluded[p] = true
	}

	for _, field := range m.RequestType.Fields {
		if !excluded[field.GetName()] {
			result = append(result, field)
		}
	}

	return result
}

var (
	gatewayTmpl = template.Must(template.New("gateway").Parse(`
// Code generated by protoc-gen-fasthttp-grpc-gateway
// source: {{.File.GetName}}
// DO NOT EDIT!

package {{.File.GetPackageName}}

import (
  {{range $i := .Imports}}{{$i.String | printf "%s\n"}}{{end}}
)

{{range $svc := .File.Services}}
{{range $m := $svc.Methods}}
{{range $b := $m.Bindings}}
func request_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}(gateway *gateway.Gateway, ctx context.Context, r *fasthttp.RequestCtx, client {{$svc.GetName}}Client, req *{{$.GetRequestClass $m.RequestType}}) {
  var err error
  ctx, err = gateway.AnnotateContext(ctx, r)

  if err != nil {
    panic(err)
  }

  {{$.PathTemplate $b}}
  {{$.QueryTemplate $b}}
  {{$.BodyTemplate $b}}

  {{if ($.IsEmptyResponse $b)}}_{{else}}res{{end}}, err := client.{{$m.GetName}}(ctx, req)

  if err != nil {
    panic(err)
  }

  {{if $m.GetServerStreaming}}
  gateway.ResponseStreamMarshaler(r, res.Recv)
  {{else if ($.IsEmptyResponse $b)}}
  r.SetStatusCode(fasthttp.StatusNoContent)
  {{else}}
  gateway.ResponseMarshaler(r, res)
  {{end}}
}
{{end}}
{{end}}

func Register{{$svc.GetName}}Handler(ctx context.Context, gateway *gateway.Gateway, conn *grpc.ClientConn) {
  client := New{{$svc.GetName}}Client(conn)

  {{range $m := $svc.Methods}}
  {{range $b := $m.Bindings}}
  gateway.{{$b.HTTPMethod.String}}({{$b.Path.Path | printf "%q"}}, func (r *fasthttp.RequestCtx) {
    req := new({{$.GetRequestClass $m.RequestType}})
    request_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}(gateway, ctx, r, client, req)
  })
  {{end}}
  {{end}}
}

func Register{{$svc.GetName}}HandlerFromEndpoint(ctx context.Context, gateway *gateway.Gateway, endpoint string, opts ...grpc.DialOption) error {
  conn, err := grpc.Dial(endpoint, opts...)

  if err != nil {
    return err
  }

  Register{{$svc.GetName}}Handler(ctx, gateway, conn)
  return nil
}
{{end}}`))

	protoTypeMap = map[pd.FieldDescriptorProto_Type]string{
		pd.FieldDescriptorProto_TYPE_BYTES:    "[]byte",
		pd.FieldDescriptorProto_TYPE_STRING:   "string",
		pd.FieldDescriptorProto_TYPE_DOUBLE:   "float64",
		pd.FieldDescriptorProto_TYPE_FLOAT:    "float32",
		pd.FieldDescriptorProto_TYPE_INT64:    "int64",
		pd.FieldDescriptorProto_TYPE_SINT64:   "int64",
		pd.FieldDescriptorProto_TYPE_SFIXED64: "int64",
		pd.FieldDescriptorProto_TYPE_UINT64:   "uint64",
		pd.FieldDescriptorProto_TYPE_FIXED64:  "uint64",
		pd.FieldDescriptorProto_TYPE_INT32:    "int32",
		pd.FieldDescriptorProto_TYPE_SINT32:   "int32",
		pd.FieldDescriptorProto_TYPE_SFIXED32: "int32",
		pd.FieldDescriptorProto_TYPE_BOOL:     "bool",
		pd.FieldDescriptorProto_TYPE_UINT32:   "uint32",
		pd.FieldDescriptorProto_TYPE_FIXED32:  "uint32",
	}

	convertStringFuncMap = map[pd.FieldDescriptorProto_Type]string{
		pd.FieldDescriptorProto_TYPE_BYTES:    "string(%s)",
		pd.FieldDescriptorProto_TYPE_STRING:   "%s",
		pd.FieldDescriptorProto_TYPE_DOUBLE:   "gateway.ConvertStringToFloat64(%s)",
		pd.FieldDescriptorProto_TYPE_FLOAT:    "gateway.ConvertStringToFloat32(%s)",
		pd.FieldDescriptorProto_TYPE_INT64:    "gateway.ConvertStringToInt64(%s)",
		pd.FieldDescriptorProto_TYPE_SINT64:   "gateway.ConvertStringToInt64(%s)",
		pd.FieldDescriptorProto_TYPE_SFIXED64: "gateway.ConvertStringToInt64(%s)",
		pd.FieldDescriptorProto_TYPE_UINT64:   "gateway.ConvertStringToUint64(%s)",
		pd.FieldDescriptorProto_TYPE_FIXED64:  "gateway.ConvertStringToUint64(%s)",
		pd.FieldDescriptorProto_TYPE_INT32:    "gateway.ConvertStringToInt32(%s)",
		pd.FieldDescriptorProto_TYPE_SINT32:   "gateway.ConvertStringToInt32(%s)",
		pd.FieldDescriptorProto_TYPE_SFIXED32: "gateway.ConvertStringToInt32(%s)",
		pd.FieldDescriptorProto_TYPE_UINT32:   "gateway.ConvertStringToUint32(%s)",
		pd.FieldDescriptorProto_TYPE_FIXED32:  "gateway.ConvertStringToUint32(%s)",
		pd.FieldDescriptorProto_TYPE_BOOL:     "gateway.ConvertStringToBool(%s)",
	}
)
<commit_msg>Fix generator<commit_after>package generator

import (
	"fmt"
	"strings"
	"text/template"

	pd "github.com/golang/protobuf/protoc-gen-go/descriptor"
)

type gatewayTemplate struct {
	Generator *Generator
	File      *File
	Imports   []*GoPackage
}

func (g *gatewayTemplate) GetRequestClass(msg *Message) string {
	if msg.File == g.File {
		return msg.GetName()
	}

	for _, pkg := range g.Imports {
		if msg.File.GoPkg.Path == pkg.Path {
			return fmt.Sprintf("%s.%s", pkg.Alias, msg.GetName())
		}
	}

	return ""
}

func (g *gatewayTemplate) PathTemplate(b *Binding) string {
	result := ""

	for _, param := range b.Path.Params {
		field := b.Method.RequestType.LookupField(param)
		lhs := fmt.Sprintf("req.%s", strings.Title(field.GetName()))
		rhs := "v"
		converter := g.ConvertStringField(field, lhs, rhs)

		if converter == "" {
			continue
		}

		result += fmt.Sprintf("if %s, ok := r.UserValue(%q).(string); ok { %s }\n", rhs, field.GetName(), converter)
	}

	return result
}

func (g *gatewayTemplate) QueryTemplate(b *Binding) string {
	result := ""
	excluded := map[string]bool{}

	// All fields are body
	if b.Body == "*" {
		return ""
	}

	// Exclude body field
	if b.Body != "" {
		excluded[b.Body] = true
	}

	// Exclude path params
	for _, param := range b.Path.Params {
		excluded[param] = true
	}

	for _, field := range b.Method.RequestType.Fields {
		if excluded[field.GetName()] {
			continue
		}

		lhs := fmt.Sprintf("req.%s", strings.Title(field.GetName()))
		rhs := "values"
		converter := g.ConvertStringArrayField(field, lhs, rhs, true)

		if converter == "" {
			continue
		}

		result += fmt.Sprintf("if %s := r.QueryArgs().PeekMulti(%q); len(%s) > 0 { %s }\n", rhs, field.GetName(), rhs, converter)
	}

	return result
}

func (g *gatewayTemplate) BodyTemplate(b *Binding) string {
	if b.Body == "" {
		return ""
	}

	result := ""

	if b.Body == "*" {
		result += "body := req\n"
	} else {
		result += fmt.Sprintf("body := req.%s\n", strings.Title(b.Body))
	}

	body := ""

	for _, field := range b.BodyType.Fields {
		lhs := fmt.Sprintf("body.%s", strings.Title(field.GetName()))
		rhs := "values"
		converter := g.ConvertStringArrayField(field, lhs, rhs, false)

		if converter == "" {
			continue
		}

		body += fmt.Sprintf("if %s, ok := query[%q]; ok && len(%s) > 0 { %s }\n", rhs, field.GetName(), rhs, converter)
	}

	result += fmt.Sprintf(`
if gateway.IsBodyURLEncoded(r) {
  query, err := url.ParseQuery(string(r.Request.Body()))

  if err != nil {
    panic(err)
  }

  %s
} else {
  if err := json.Unmarshal(r.Request.Body(), body); err != nil {
    panic(err)
  }
}`, body)

	return result
}

func (g *gatewayTemplate) IsEmptyResponse(b *Binding) bool {
	return b.Method.ResponseType.FQMN == ".google.protobuf.Empty"
}

func (g *gatewayTemplate) ConvertStringField(field *Field, lhs string, rhs string) string {
	if fn, ok := convertStringFuncMap[field.GetType()]; ok {
		v := fmt.Sprintf(fn, rhs)
		return fmt.Sprintf("%s = %s", lhs, v)
	}

	return ""
}

func (g *gatewayTemplate) ConvertStringArrayField(field *Field, lhs string, rhs string, isBytes bool) string {
	if field.GetLabel() != pd.FieldDescriptorProto_LABEL_REPEATED {
		var v string

		if isBytes {
			v = fmt.Sprintf("string(%s[0])", rhs)
		} else {
			v = rhs + "[0]"
		}

		return g.ConvertStringField(field, lhs, v)
	}

	if elem, ok := protoTypeMap[field.GetType()]; ok {
		v := "v"

		if isBytes {
			v = "string(v)"
		}

		converter := g.ConvertStringField(field, lhs+"[i]", v)

		return fmt.Sprintf(`
%s = make([]%s, len(%s))

for i, v := range %s {
  %s
}`, lhs, elem, rhs, rhs, converter)
	}

	return ""
}

func (g *gatewayTemplate) GetQueryFields(m *Method, b *Binding) []*Field {
	result := []*Field{}
	excluded := map[string]bool{}

	// Exclude body params
	if b.Body == "*" {
		return result
	} else if b.Body != "" {
		excluded[b.Body] = true
	}

	// Exclude path params
	for _, p := range b.Path.Params {
		excluded[p] = true
	}

	for _, field := range m.RequestType.Fields {
		if !excluded[field.GetName()] {
			result = append(result, field)
		}
	}

	return result
}

var (
	gatewayTmpl = template.Must(template.New("gateway").Parse(`
// Code generated by protoc-gen-fasthttp-grpc-gateway
// source: {{.File.GetName}}
// DO NOT EDIT!

package {{.File.GetPackageName}}

import (
  {{range $i := .Imports}}{{$i.String | printf "%s\n"}}{{end}}
)

{{range $svc := .File.Services}}
{{range $m := $svc.Methods}}
{{range $b := $m.Bindings}}
func request_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}(g *gateway.Gateway, ctx context.Context, r *fasthttp.RequestCtx, client {{$svc.GetName}}Client, req *{{$.GetRequestClass $m.RequestType}}) {
  var err error
  ctx, err = gateway.AnnotateContext(ctx, r)

  if err != nil {
    panic(err)
  }

  {{$.PathTemplate $b}}
  {{$.QueryTemplate $b}}
  {{$.BodyTemplate $b}}

  {{if ($.IsEmptyResponse $b)}}_, err ={{else}}res, err :={{end}} client.{{$m.GetName}}(ctx, req)

  if err != nil {
    panic(err)
  }

  {{if $m.GetServerStreaming}}
  g.ResponseStreamMarshaler(r, func() (proto.Message, error) {
		return res.Recv()
	})
  {{else if ($.IsEmptyResponse $b)}}
  r.SetStatusCode(fasthttp.StatusNoContent)
  {{else}}
  g.ResponseMarshaler(r, res)
  {{end}}
}
{{end}}
{{end}}

func Register{{$svc.GetName}}Handler(ctx context.Context, g *gateway.Gateway, conn *grpc.ClientConn) {
  client := New{{$svc.GetName}}Client(conn)

  {{range $m := $svc.Methods}}
  {{range $b := $m.Bindings}}
  g.{{$b.HTTPMethod.String}}({{$b.Path.Path | printf "%q"}}, func (r *fasthttp.RequestCtx) {
    req := new({{$.GetRequestClass $m.RequestType}})
    request_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}(g, ctx, r, client, req)
  })
  {{end}}
  {{end}}
}

func Register{{$svc.GetName}}HandlerFromEndpoint(ctx context.Context, g *gateway.Gateway, endpoint string, opts ...grpc.DialOption) error {
  conn, err := grpc.Dial(endpoint, opts...)

  if err != nil {
    return err
  }

  Register{{$svc.GetName}}Handler(ctx, g, conn)
  return nil
}
{{end}}`))

	protoTypeMap = map[pd.FieldDescriptorProto_Type]string{
		pd.FieldDescriptorProto_TYPE_BYTES:    "[]byte",
		pd.FieldDescriptorProto_TYPE_STRING:   "string",
		pd.FieldDescriptorProto_TYPE_DOUBLE:   "float64",
		pd.FieldDescriptorProto_TYPE_FLOAT:    "float32",
		pd.FieldDescriptorProto_TYPE_INT64:    "int64",
		pd.FieldDescriptorProto_TYPE_SINT64:   "int64",
		pd.FieldDescriptorProto_TYPE_SFIXED64: "int64",
		pd.FieldDescriptorProto_TYPE_UINT64:   "uint64",
		pd.FieldDescriptorProto_TYPE_FIXED64:  "uint64",
		pd.FieldDescriptorProto_TYPE_INT32:    "int32",
		pd.FieldDescriptorProto_TYPE_SINT32:   "int32",
		pd.FieldDescriptorProto_TYPE_SFIXED32: "int32",
		pd.FieldDescriptorProto_TYPE_BOOL:     "bool",
		pd.FieldDescriptorProto_TYPE_UINT32:   "uint32",
		pd.FieldDescriptorProto_TYPE_FIXED32:  "uint32",
	}

	convertStringFuncMap = map[pd.FieldDescriptorProto_Type]string{
		pd.FieldDescriptorProto_TYPE_BYTES:    "string(%s)",
		pd.FieldDescriptorProto_TYPE_STRING:   "%s",
		pd.FieldDescriptorProto_TYPE_DOUBLE:   "gateway.ConvertStringToFloat64(%s)",
		pd.FieldDescriptorProto_TYPE_FLOAT:    "gateway.ConvertStringToFloat32(%s)",
		pd.FieldDescriptorProto_TYPE_INT64:    "gateway.ConvertStringToInt64(%s)",
		pd.FieldDescriptorProto_TYPE_SINT64:   "gateway.ConvertStringToInt64(%s)",
		pd.FieldDescriptorProto_TYPE_SFIXED64: "gateway.ConvertStringToInt64(%s)",
		pd.FieldDescriptorProto_TYPE_UINT64:   "gateway.ConvertStringToUint64(%s)",
		pd.FieldDescriptorProto_TYPE_FIXED64:  "gateway.ConvertStringToUint64(%s)",
		pd.FieldDescriptorProto_TYPE_INT32:    "gateway.ConvertStringToInt32(%s)",
		pd.FieldDescriptorProto_TYPE_SINT32:   "gateway.ConvertStringToInt32(%s)",
		pd.FieldDescriptorProto_TYPE_SFIXED32: "gateway.ConvertStringToInt32(%s)",
		pd.FieldDescriptorProto_TYPE_UINT32:   "gateway.ConvertStringToUint32(%s)",
		pd.FieldDescriptorProto_TYPE_FIXED32:  "gateway.ConvertStringToUint32(%s)",
		pd.FieldDescriptorProto_TYPE_BOOL:     "gateway.ConvertStringToBool(%s)",
	}
)
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"sort"
	"strings"

	"github.com/coreos/fleet/machine"
)

const (
	defaultListMachinesFields = "machine,ip,metadata"
)

var (
	listMachinesFieldsFlag string
	cmdListMachines        = &Command{
		Name:    "list-machines",
		Summary: "Enumerate the current hosts in the cluster",
		Usage:   "[-l|--full] [--no-legend]",
		Description: `Lists all active machines within the cluster. Previously active machines will not appear in this list.

For easily parsable output, you can remove the column headers:
	fleetctl list-machines --no-legend

Output the list without truncation:
	fleetctl list-machines --full`,
		Run: runListMachines,
	}

	listMachinesFields = map[string]machineToField{
		"machine": func(ms *machine.MachineState, full bool) string {
			return machineIDLegend(*ms, full)
		},
		"ip": func(ms *machine.MachineState, full bool) string {
			if len(ms.PublicIP) == 0 {
				return "-"
			}
			return ms.PublicIP
		},
		"metadata": func(ms *machine.MachineState, full bool) string {
			if len(ms.Metadata) == 0 {
				return "-"
			}
			return formatMetadata(ms.Metadata)
		},
	}
)

type machineToField func(ms *machine.MachineState, full bool) string

func init() {
	cmdListMachines.Flags.BoolVar(&sharedFlags.Full, "full", false, "Do not ellipsize fields on output")
	cmdListMachines.Flags.BoolVar(&sharedFlags.Full, "l", false, "Shorthand for --full")
	cmdListMachines.Flags.BoolVar(&sharedFlags.NoLegend, "no-legend", false, "Do not print a legend (column headers)")
	cmdListMachines.Flags.StringVar(&listMachinesFieldsFlag, "fields", defaultListMachinesFields, fmt.Sprintf("Columns to print for each Machine. Valid fields are %q", strings.Join(machineToFieldKeys(listMachinesFields), ",")))
}

func runListMachines(args []string) (exit int) {
	if listMachinesFieldsFlag == "" {
		fmt.Fprintf(os.Stderr, "Must define output format\n")
		return 1
	}

	cols := strings.Split(listMachinesFieldsFlag, ",")
	for _, s := range cols {
		if _, ok := listMachinesFields[s]; !ok {
			fmt.Fprintf(os.Stderr, "Invalid key in output format: %q\n", s)
			return 1
		}
	}

	machines, sortable, err := findAllMachines()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error retrieving list of active machines: %v\n", err)
		return 1
	}

	if !sharedFlags.NoLegend {
		fmt.Fprintln(out, strings.ToUpper(strings.Join(cols, "\t")))
	}

	for _, name := range sortable {
		var f []string
		ms := machines[name]
		for _, c := range cols {
			f = append(f, listMachinesFields[c](&ms, sharedFlags.Full))
		}
		fmt.Fprintln(out, strings.Join(f, "\t"))
	}

	out.Flush()
	return
}

func formatMetadata(metadata map[string]string) string {
	pairs := make([]string, len(metadata))
	idx := 0
	for key, value := range metadata {
		pairs[idx] = fmt.Sprintf("%s=%s", key, value)
		idx++
	}
	return strings.Join(pairs, ",")
}

// findAllMachines returns a map describing all the machines in the Registry, and a
// sort.StringSlice indicating their sorted order (based on their respective
// machine IDs). It returns any error encountered in communicating with the Registry.
func findAllMachines() (machines map[string]machine.MachineState, sortable sort.StringSlice, err error) {
	machines = make(map[string]machine.MachineState, 0)
	mm, err := cAPI.GetActiveMachines()
	if err != nil {
		return
	}

	for _, m := range mm {
		machines[m.ID] = m
		sortable = append(sortable, m.ID)
	}

	sortable.Sort()

	return
}

func machineToFieldKeys(m map[string]machineToField) (keys []string) {
	for k, _ := range m {
		keys = append(keys, k)
	}
	return
}
<commit_msg>fix(fleetctl): sort metadata explicitly by keys<commit_after>package main

import (
	"fmt"
	"os"
	"sort"
	"strings"

	"github.com/coreos/fleet/machine"
)

const (
	defaultListMachinesFields = "machine,ip,metadata"
)

var (
	listMachinesFieldsFlag string
	cmdListMachines        = &Command{
		Name:    "list-machines",
		Summary: "Enumerate the current hosts in the cluster",
		Usage:   "[-l|--full] [--no-legend]",
		Description: `Lists all active machines within the cluster. Previously active machines will not appear in this list.

For easily parsable output, you can remove the column headers:
	fleetctl list-machines --no-legend

Output the list without truncation:
	fleetctl list-machines --full`,
		Run: runListMachines,
	}

	listMachinesFields = map[string]machineToField{
		"machine": func(ms *machine.MachineState, full bool) string {
			return machineIDLegend(*ms, full)
		},
		"ip": func(ms *machine.MachineState, full bool) string {
			if len(ms.PublicIP) == 0 {
				return "-"
			}
			return ms.PublicIP
		},
		"metadata": func(ms *machine.MachineState, full bool) string {
			if len(ms.Metadata) == 0 {
				return "-"
			}
			return formatMetadata(ms.Metadata)
		},
	}
)

type machineToField func(ms *machine.MachineState, full bool) string

func init() {
	cmdListMachines.Flags.BoolVar(&sharedFlags.Full, "full", false, "Do not ellipsize fields on output")
	cmdListMachines.Flags.BoolVar(&sharedFlags.Full, "l", false, "Shorthand for --full")
	cmdListMachines.Flags.BoolVar(&sharedFlags.NoLegend, "no-legend", false, "Do not print a legend (column headers)")
	cmdListMachines.Flags.StringVar(&listMachinesFieldsFlag, "fields", defaultListMachinesFields, fmt.Sprintf("Columns to print for each Machine. Valid fields are %q", strings.Join(machineToFieldKeys(listMachinesFields), ",")))
}

func runListMachines(args []string) (exit int) {
	if listMachinesFieldsFlag == "" {
		fmt.Fprintf(os.Stderr, "Must define output format\n")
		return 1
	}

	cols := strings.Split(listMachinesFieldsFlag, ",")
	for _, s := range cols {
		if _, ok := listMachinesFields[s]; !ok {
			fmt.Fprintf(os.Stderr, "Invalid key in output format: %q\n", s)
			return 1
		}
	}

	machines, sortable, err := findAllMachines()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error retrieving list of active machines: %v\n", err)
		return 1
	}

	if !sharedFlags.NoLegend {
		fmt.Fprintln(out, strings.ToUpper(strings.Join(cols, "\t")))
	}

	for _, name := range sortable {
		var f []string
		ms := machines[name]
		for _, c := range cols {
			f = append(f, listMachinesFields[c](&ms, sharedFlags.Full))
		}
		fmt.Fprintln(out, strings.Join(f, "\t"))
	}

	out.Flush()
	return
}

func formatMetadata(metadata map[string]string) string {
	pairs := make([]string, len(metadata))
	idx := 0
	var sorted sort.StringSlice
	for k := range metadata {
		sorted = append(sorted, k)
	}
	sorted.Sort()
	for _, key := range sorted {
		value := metadata[key]
		pairs[idx] = fmt.Sprintf("%s=%s", key, value)
		idx++
	}
	return strings.Join(pairs, ",")
}

// findAllMachines returns a map describing all the machines in the Registry, and a
// sort.StringSlice indicating their sorted order (based on their respective
// machine IDs). It returns any error encountered in communicating with the Registry.
func findAllMachines() (machines map[string]machine.MachineState, sortable sort.StringSlice, err error) {
	machines = make(map[string]machine.MachineState, 0)
	mm, err := cAPI.GetActiveMachines()
	if err != nil {
		return
	}

	for _, m := range mm {
		machines[m.ID] = m
		sortable = append(sortable, m.ID)
	}

	sortable.Sort()

	return
}

func machineToFieldKeys(m map[string]machineToField) (keys []string) {
	for k, _ := range m {
		keys = append(keys, k)
	}
	return
}
<|endoftext|>


<commit_before>package trustmanager

import "errors"

const (
	keyExtension = "key"
)

// KeyFileStore persists and manages private keys on disk
type KeyFileStore struct {
	FileStore
}

// NewKeyFileStore returns a new KeyFileStore creating a private directory to
// hold the keys.
func NewKeyFileStore(baseDir string) (EncryptedFileStore, error) {
	fileStore, err := NewFileStore(baseDir, keyExtension)
	if err != nil {
		return nil, err
	}

	return &KeyFileStore{fileStore}, nil
}

// AddEncrypted stores the contents of a PEM-encoded private key as an encrypted PEM block
func (s *KeyFileStore) AddEncrypted(fileName string, pemKey []byte, passphrase string) error {

	privKey, err := ParsePEMPrivateKey(pemKey)
	if err != nil {
		return err
	}

	encryptedKey, err := EncryptPrivateKey(privKey, passphrase)
	if err != nil {
		return err
	}

	return s.Add(fileName, encryptedKey)
}

// GetDecrypted decrypts and returns the PEM Encoded private key given a flename
// and a passphrase
func (s *KeyFileStore) GetDecrypted(fileName string, passphrase string) ([]byte, error) {
	keyBytes, err := s.Get(fileName)
	if err != nil {
		return nil, errors.New("could not retrieve private key material")
	}

	// Gets an unencrypted PrivateKey.
	privKey, err := ParsePEMEncryptedPrivateKey(keyBytes, passphrase)
	if err != nil {
		return nil, err
	}

	return KeyToPEM(privKey)
}
<commit_msg>Fixing small nit<commit_after>package trustmanager

import "errors"

const (
	keyExtension = "key"
)

// KeyFileStore persists and manages private keys on disk
type KeyFileStore struct {
	FileStore
}

// NewKeyFileStore returns a new KeyFileStore creating a private directory to
// hold the keys.
func NewKeyFileStore(baseDir string) (*KeyFileStore, error) {
	fileStore, err := NewFileStore(baseDir, keyExtension)
	if err != nil {
		return nil, err
	}

	return &KeyFileStore{fileStore}, nil
}

// AddEncrypted stores the contents of a PEM-encoded private key as an encrypted PEM block
func (s *KeyFileStore) AddEncrypted(fileName string, pemKey []byte, passphrase string) error {

	privKey, err := ParsePEMPrivateKey(pemKey)
	if err != nil {
		return err
	}

	encryptedKey, err := EncryptPrivateKey(privKey, passphrase)
	if err != nil {
		return err
	}

	return s.Add(fileName, encryptedKey)
}

// GetDecrypted decrypts and returns the PEM Encoded private key given a flename
// and a passphrase
func (s *KeyFileStore) GetDecrypted(fileName string, passphrase string) ([]byte, error) {
	keyBytes, err := s.Get(fileName)
	if err != nil {
		return nil, errors.New("could not retrieve private key material")
	}

	// Gets an unencrypted PrivateKey.
	privKey, err := ParsePEMEncryptedPrivateKey(keyBytes, passphrase)
	if err != nil {
		return nil, err
	}

	return KeyToPEM(privKey)
}
<|endoftext|>


<commit_before>package plg_authenticate_saml

import (
	. "github.com/mickael-kerjean/filestash/server/common"
	"net/http"
)

func init() {
	Hooks.Register.AuthenticationMiddleware("saml", Saml{})
}

type Saml struct{}

func (this Saml) Setup() Form {
	return Form{
		Elmnts: []FormElement{
			{
				Name:  "type",
				Type:  "hidden",
				Value: "saml",
			},
			{
				Name:        "SP Metadata",
				Type:        "text",
				ReadOnly:    true,
				Value:       "",
				Placeholder: "<VISIT https://www.filestash.app/pricing>",
			},
			{
				Name:        "IDP Metadata",
				Type:        "text",
				ReadOnly:    true,
				Value:       "",
				Placeholder: "<VISIT https://www.filestash.app/pricing>",
			},
		},
	}
}

func (this Saml) EntryPoint(req *http.Request, res http.ResponseWriter) {
	http.Redirect(
		res, req,
		"/?error=saml is available for enterprise customer, see https://www.filestash.app/pricing/?modal=enterprise",
		http.StatusTemporaryRedirect,
	)
}

func (this Saml) Callback(formData map[string]string, idpParams map[string]string, res http.ResponseWriter) (map[string]string, error) {
	return nil, ErrNotImplemented
}
<commit_msg>fix (auth): signature change<commit_after>package plg_authenticate_saml

import (
	. "github.com/mickael-kerjean/filestash/server/common"
	"net/http"
)

func init() {
	Hooks.Register.AuthenticationMiddleware("saml", Saml{})
}

type Saml struct{}

func (this Saml) Setup() Form {
	return Form{
		Elmnts: []FormElement{
			{
				Name:  "type",
				Type:  "hidden",
				Value: "saml",
			},
			{
				Name:        "SP Metadata",
				Type:        "text",
				ReadOnly:    true,
				Value:       "",
				Placeholder: "<VISIT https://www.filestash.app/pricing>",
			},
			{
				Name:        "IDP Metadata",
				Type:        "text",
				ReadOnly:    true,
				Value:       "",
				Placeholder: "<VISIT https://www.filestash.app/pricing>",
			},
		},
	}
}

func (this Saml) EntryPoint(idpParams map[string]string, req *http.Request, res http.ResponseWriter) error {
	http.Redirect(
		res, req,
		"/?error=saml is available for enterprise customer, see https://www.filestash.app/pricing/?modal=enterprise",
		http.StatusTemporaryRedirect,
	)
	return nil
}

func (this Saml) Callback(formData map[string]string, idpParams map[string]string, res http.ResponseWriter) (map[string]string, error) {
	return nil, ErrNotImplemented
}
<|endoftext|>


<commit_before>/*

   Copyright 2016 Wenhui Shen <www.webx.top>

   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 echo

import (
	"errors"
	"html/template"
	"net/http"
	"regexp"
	"time"

	"github.com/webx-top/echo/param"
)

var (
	splitHTTPMethod = regexp.MustCompile(`[^A-Z]+`)

	methods = []string{
		CONNECT,
		DELETE,
		GET,
		HEAD,
		OPTIONS,
		PATCH,
		POST,
		PUT,
		TRACE,
	}

	//--------
	// Errors
	//--------

	ErrUnsupportedMediaType        error = NewHTTPError(http.StatusUnsupportedMediaType)
	ErrNotFound                    error = NewHTTPError(http.StatusNotFound)
	ErrUnauthorized                error = NewHTTPError(http.StatusUnauthorized)
	ErrForbidden                   error = NewHTTPError(http.StatusForbidden)
	ErrStatusRequestEntityTooLarge error = NewHTTPError(http.StatusRequestEntityTooLarge)
	ErrMethodNotAllowed            error = NewHTTPError(http.StatusMethodNotAllowed)
	ErrRendererNotRegistered             = errors.New("renderer not registered")
	ErrInvalidRedirectCode               = errors.New("invalid redirect status code")
	ErrNotFoundFileInput                 = errors.New("The specified name file input was not found")

	//----------------
	// Error handlers
	//----------------

	NotFoundHandler = HandlerFunc(func(c Context) error {
		return ErrNotFound
	})

	MethodNotAllowedHandler = HandlerFunc(func(c Context) error {
		return ErrMethodNotAllowed
	})

	_ MiddlewareFuncd = func(h Handler) HandlerFunc {
		return func(c Context) error {
			return h.Handle(c)
		}
	}

	globalVars = param.NewMap() //Custom global variable
)

func Set(key, value interface{}) {
	globalVars.Set(key, value)
}

func Get(key interface{}, defaults ...interface{}) interface{} {
	return globalVars.Get(key, defaults...)
}

func GetOk(key interface{}) (interface{}, bool) {
	return globalVars.GetOk(key)
}

func Has(key interface{}) bool {
	return globalVars.Has(key)
}

func Delete(key interface{}) {
	globalVars.Delete(key)
}

func Range(f func(key, value interface{}) bool) {
	globalVars.Range(f)
}

func GetOrSet(key, value interface{}) (actual interface{}, loaded bool) {
	return globalVars.GetOrSet(key, value)
}

func String(key interface{}, defaults ...interface{}) string {
	return globalVars.String(key, defaults...)
}

func Split(key interface{}, sep string, limit ...int) param.StringSlice {
	return globalVars.Split(key, sep, limit...)
}

func Trim(key interface{}, defaults ...interface{}) param.String {
	return globalVars.Trim(key, defaults...)
}

func HTML(key interface{}, defaults ...interface{}) template.HTML {
	return globalVars.HTML(key, defaults...)
}

func HTMLAttr(key interface{}, defaults ...interface{}) template.HTMLAttr {
	return globalVars.HTMLAttr(key, defaults...)
}

func JS(key interface{}, defaults ...interface{}) template.JS {
	return globalVars.JS(key, defaults...)
}

func CSS(key interface{}, defaults ...interface{}) template.CSS {
	return globalVars.CSS(key, defaults...)
}

func Bool(key interface{}, defaults ...interface{}) bool {
	return globalVars.Bool(key, defaults...)
}

func Float64(key interface{}, defaults ...interface{}) float64 {
	return globalVars.Float64(key, defaults...)
}

func Float32(key interface{}, defaults ...interface{}) float32 {
	return globalVars.Float32(key, defaults...)
}

func Int8(key interface{}, defaults ...interface{}) int8 {
	return globalVars.Int8(key, defaults...)
}

func Int16(key interface{}, defaults ...interface{}) int16 {
	return globalVars.Int16(key, defaults...)
}

func Int(key interface{}, defaults ...interface{}) int {
	return globalVars.Int(key, defaults...)
}

func Int32(key interface{}, defaults ...interface{}) int32 {
	return globalVars.Int32(key, defaults...)
}

func Int64(key interface{}, defaults ...interface{}) int64 {
	return globalVars.Int64(key, defaults...)
}

func Decr(key interface{}, n int64, defaults ...interface{}) int64 {
	return globalVars.Decr(key, n, defaults...)
}

func Incr(key interface{}, n int64, defaults ...interface{}) int64 {
	return globalVars.Incr(key, n, defaults...)
}

func Uint8(key interface{}, defaults ...interface{}) uint8 {
	return globalVars.Uint8(key, defaults...)
}

func Uint16(key interface{}, defaults ...interface{}) uint16 {
	return globalVars.Uint16(key, defaults...)
}

func Uint(key interface{}, defaults ...interface{}) uint {
	return globalVars.Uint(key, defaults...)
}

func Uint32(key interface{}, defaults ...interface{}) uint32 {
	return globalVars.Uint32(key, defaults...)
}

func Uint64(key interface{}, defaults ...interface{}) uint64 {
	return globalVars.Uint64(key, defaults...)
}

func Timestamp(key interface{}, defaults ...interface{}) time.Time {
	return globalVars.Timestamp(key, defaults...)
}

func DateTime(key interface{}, layouts ...string) time.Time {
	return globalVars.DateTime(key, layouts...)
}

func Children(key interface{}, keys ...interface{}) Store {
	r := GetStore(key)
	for _, key := range keys {
		r = GetStore(key)
	}
	return r
}

func GetStore(key interface{}, defaults ...interface{}) Store {
	return AsStore(globalVars.Get(key, defaults...))
}
<commit_msg>improved<commit_after>/*

   Copyright 2016 Wenhui Shen <www.webx.top>

   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 echo

import (
	"errors"
	"html/template"
	"net/http"
	"regexp"
	"time"

	"github.com/webx-top/echo/param"
)

var (
	splitHTTPMethod = regexp.MustCompile(`[^A-Z]+`)

	methods = []string{
		CONNECT,
		DELETE,
		GET,
		HEAD,
		OPTIONS,
		PATCH,
		POST,
		PUT,
		TRACE,
	}

	//--------
	// Errors
	//--------

	ErrUnsupportedMediaType        error = NewHTTPError(http.StatusUnsupportedMediaType)
	ErrNotFound                    error = NewHTTPError(http.StatusNotFound)
	ErrUnauthorized                error = NewHTTPError(http.StatusUnauthorized)
	ErrForbidden                   error = NewHTTPError(http.StatusForbidden)
	ErrStatusRequestEntityTooLarge error = NewHTTPError(http.StatusRequestEntityTooLarge)
	ErrMethodNotAllowed            error = NewHTTPError(http.StatusMethodNotAllowed)
	ErrRendererNotRegistered             = errors.New("renderer not registered")
	ErrInvalidRedirectCode               = errors.New("invalid redirect status code")
	ErrNotFoundFileInput                 = errors.New("The specified name file input was not found")

	//----------------
	// Error handlers
	//----------------

	NotFoundHandler = HandlerFunc(func(c Context) error {
		return ErrNotFound
	})

	MethodNotAllowedHandler = HandlerFunc(func(c Context) error {
		return ErrMethodNotAllowed
	})

	_ MiddlewareFuncd = func(h Handler) HandlerFunc {
		return func(c Context) error {
			return h.Handle(c)
		}
	}

	//----------------
	// Shortcut
	//----------------

	StringerMapStart = param.StringerMapStart
	StoreStart       = param.StoreStart
	HStart           = param.StoreStart

	//Custom global variable
	globalVars = param.NewMap()
)

func Set(key, value interface{}) {
	globalVars.Set(key, value)
}

func Get(key interface{}, defaults ...interface{}) interface{} {
	return globalVars.Get(key, defaults...)
}

func GetOk(key interface{}) (interface{}, bool) {
	return globalVars.GetOk(key)
}

func Has(key interface{}) bool {
	return globalVars.Has(key)
}

func Delete(key interface{}) {
	globalVars.Delete(key)
}

func Range(f func(key, value interface{}) bool) {
	globalVars.Range(f)
}

func GetOrSet(key, value interface{}) (actual interface{}, loaded bool) {
	return globalVars.GetOrSet(key, value)
}

func String(key interface{}, defaults ...interface{}) string {
	return globalVars.String(key, defaults...)
}

func Split(key interface{}, sep string, limit ...int) param.StringSlice {
	return globalVars.Split(key, sep, limit...)
}

func Trim(key interface{}, defaults ...interface{}) param.String {
	return globalVars.Trim(key, defaults...)
}

func HTML(key interface{}, defaults ...interface{}) template.HTML {
	return globalVars.HTML(key, defaults...)
}

func HTMLAttr(key interface{}, defaults ...interface{}) template.HTMLAttr {
	return globalVars.HTMLAttr(key, defaults...)
}

func JS(key interface{}, defaults ...interface{}) template.JS {
	return globalVars.JS(key, defaults...)
}

func CSS(key interface{}, defaults ...interface{}) template.CSS {
	return globalVars.CSS(key, defaults...)
}

func Bool(key interface{}, defaults ...interface{}) bool {
	return globalVars.Bool(key, defaults...)
}

func Float64(key interface{}, defaults ...interface{}) float64 {
	return globalVars.Float64(key, defaults...)
}

func Float32(key interface{}, defaults ...interface{}) float32 {
	return globalVars.Float32(key, defaults...)
}

func Int8(key interface{}, defaults ...interface{}) int8 {
	return globalVars.Int8(key, defaults...)
}

func Int16(key interface{}, defaults ...interface{}) int16 {
	return globalVars.Int16(key, defaults...)
}

func Int(key interface{}, defaults ...interface{}) int {
	return globalVars.Int(key, defaults...)
}

func Int32(key interface{}, defaults ...interface{}) int32 {
	return globalVars.Int32(key, defaults...)
}

func Int64(key interface{}, defaults ...interface{}) int64 {
	return globalVars.Int64(key, defaults...)
}

func Decr(key interface{}, n int64, defaults ...interface{}) int64 {
	return globalVars.Decr(key, n, defaults...)
}

func Incr(key interface{}, n int64, defaults ...interface{}) int64 {
	return globalVars.Incr(key, n, defaults...)
}

func Uint8(key interface{}, defaults ...interface{}) uint8 {
	return globalVars.Uint8(key, defaults...)
}

func Uint16(key interface{}, defaults ...interface{}) uint16 {
	return globalVars.Uint16(key, defaults...)
}

func Uint(key interface{}, defaults ...interface{}) uint {
	return globalVars.Uint(key, defaults...)
}

func Uint32(key interface{}, defaults ...interface{}) uint32 {
	return globalVars.Uint32(key, defaults...)
}

func Uint64(key interface{}, defaults ...interface{}) uint64 {
	return globalVars.Uint64(key, defaults...)
}

func Timestamp(key interface{}, defaults ...interface{}) time.Time {
	return globalVars.Timestamp(key, defaults...)
}

func DateTime(key interface{}, layouts ...string) time.Time {
	return globalVars.DateTime(key, layouts...)
}

func Children(key interface{}, keys ...interface{}) Store {
	r := GetStore(key)
	for _, key := range keys {
		r = GetStore(key)
	}
	return r
}

func GetStore(key interface{}, defaults ...interface{}) Store {
	return AsStore(globalVars.Get(key, defaults...))
}
<|endoftext|>


<commit_before>package main

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

	"github.com/motemen/ghq/cmdutil"
)

var remoteDummyURL = mustParseURL("https://example.com/git/repo")

func TestVCSBackend(t *testing.T) {
	tempDir := newTempDir(t)
	defer os.RemoveAll(tempDir)
	localDir := filepath.Join(tempDir, "repo")
	_commands := []*exec.Cmd{}
	lastCommand := func() *exec.Cmd { return _commands[len(_commands)-1] }
	defer func(orig func(cmd *exec.Cmd) error) {
		cmdutil.CommandRunner = orig
	}(cmdutil.CommandRunner)
	cmdutil.CommandRunner = func(cmd *exec.Cmd) error {
		_commands = append(_commands, cmd)
		if reflect.DeepEqual(cmd.Args, []string{"svn", "info", "https://example.com/git/repo/trunk"}) {
			return fmt.Errorf("[test] failed to svn info")
		}
		return nil
	}

	testCases := []struct {
		name   string
		f      func() error
		expect []string
		dir    string
	}{{
		name: "[git] clone",
		f: func() error {
			return GitBackend.Clone(&vcsGetOption{
				url: remoteDummyURL,
				dir: localDir,
			})
		},
		expect: []string{"git", "clone", remoteDummyURL.String(), localDir},
	}, {
		name: "[git] shallow clone",
		f: func() error {
			return GitBackend.Clone(&vcsGetOption{
				url:     remoteDummyURL,
				dir:     localDir,
				shallow: true,
				silent:  true,
			})
		},
		expect: []string{"git", "clone", "--depth", "1", remoteDummyURL.String(), localDir},
	}, {
		name: "[git] clone specific branch",
		f: func() error {
			return GitBackend.Clone(&vcsGetOption{
				url:    remoteDummyURL,
				dir:    localDir,
				branch: "hello",
			})
		},
		expect: []string{"git", "clone", "--branch", "hello", "--single-branch", remoteDummyURL.String(), localDir},
	}, {
		name: "[git] update",
		f: func() error {
			return GitBackend.Update(&vcsGetOption{
				dir: localDir,
			})
		},
		expect: []string{"git", "pull", "--ff-only"},
		dir:    localDir,
	}, {
		name: "[git] recursive",
		f: func() error {
			return GitBackend.Clone(&vcsGetOption{
				url:       remoteDummyURL,
				dir:       localDir,
				recursive: true,
			})
		},
		expect: []string{"git", "clone", "--recursive", remoteDummyURL.String(), localDir},
	}, {
		name: "[git] update recursive",
		f: func() error {
			return GitBackend.Update(&vcsGetOption{
				dir:       localDir,
				recursive: true,
			})
		},
		expect: []string{"git", "submodule", "update", "--init", "--recursive"},
		dir:    localDir,
	}, {
		name: "[svn] checkout",
		f: func() error {
			return SubversionBackend.Clone(&vcsGetOption{
				url: remoteDummyURL,
				dir: localDir,
			})
		},
		expect: []string{"svn", "checkout", remoteDummyURL.String(), localDir},
	}, {
		name: "[svn] checkout shallow",
		f: func() error {
			return SubversionBackend.Clone(&vcsGetOption{
				url:     remoteDummyURL,
				dir:     localDir,
				shallow: true,
			})
		},
		expect: []string{"svn", "checkout", "--depth", "immediates", remoteDummyURL.String(), localDir},
	}, {
		name: "[svn] checkout specific branch",
		f: func() error {
			return SubversionBackend.Clone(&vcsGetOption{
				url:    remoteDummyURL,
				dir:    localDir,
				branch: "hello",
			})
		},
		expect: []string{"svn", "checkout", remoteDummyURL.String() + "/branches/hello", localDir},
	}, {
		name: "[svn] update",
		f: func() error {
			return SubversionBackend.Update(&vcsGetOption{
				dir:    localDir,
				silent: true,
			})
		},
		expect: []string{"svn", "update"},
		dir:    localDir,
	}, {
		name: "[git-svn] clone",
		f: func() error {
			return GitsvnBackend.Clone(&vcsGetOption{
				url: remoteDummyURL,
				dir: localDir,
			})
		},
		expect: []string{"git", "svn", "clone", remoteDummyURL.String(), localDir},
	}, {
		name: "[git-svn] update",
		f: func() error {
			return GitsvnBackend.Update(&vcsGetOption{
				dir: localDir,
			})
		},
		expect: []string{"git", "svn", "rebase"},
		dir:    localDir,
	}, {
		name: "[git-svn] clone shallow",
		f: func() error {
			defer func(orig func(cmd *exec.Cmd) error) {
				cmdutil.CommandRunner = orig
			}(cmdutil.CommandRunner)
			cmdutil.CommandRunner = func(cmd *exec.Cmd) error {
				_commands = append(_commands, cmd)
				if reflect.DeepEqual(cmd.Args, []string{"svn", "info", "https://example.com/git/repo/trunk"}) {
					cmd.Stdout.Write([]byte(`Path: trunk
URL: https://svn.apache.org/repos/asf/subversion/trunk
Relative URL: ^/subversion/trunk
Repository Root: https://svn.apache.org/repos/asf
Repository UUID: 13f79535-47bb-0310-9956-ffa450edef68
Revision: 1872085
Node Kind: directory
Last Changed Author: julianfoad
Last Changed Rev: 1872031
Last Changed Date: 2019-08-16 15:16:45 +0900 (Fri, 16 Aug 2019)
`))
				}
				return nil
			}
			return GitsvnBackend.Clone(&vcsGetOption{
				url:     remoteDummyURL,
				dir:     localDir,
				shallow: true,
			})
		},
		expect: []string{"git", "svn", "clone", "-s", "-r1872031:HEAD", remoteDummyURL.String(), localDir},
	}, {
		name: "[git-svn] clone specific branch",
		f: func() error {
			return GitsvnBackend.Clone(&vcsGetOption{
				url:    remoteDummyURL,
				dir:    localDir,
				branch: "hello",
			})
		},
		expect: []string{"git", "svn", "clone", remoteDummyURL.String() + "/branches/hello", localDir},
	}, {
		name: "[hg] clone",
		f: func() error {
			return MercurialBackend.Clone(&vcsGetOption{
				url: remoteDummyURL,
				dir: localDir,
			})
		},
		expect: []string{"hg", "clone", remoteDummyURL.String(), localDir},
	}, {
		name: "[hg] update",
		f: func() error {
			return MercurialBackend.Update(&vcsGetOption{
				dir: localDir,
			})
		},
		expect: []string{"hg", "pull", "--update"},
		dir:    localDir,
	}, {
		name: "[hg] clone shallow",
		f: func() error {
			return MercurialBackend.Clone(&vcsGetOption{
				url:     remoteDummyURL,
				dir:     localDir,
				shallow: true,
			})
		},
		expect: []string{"hg", "clone", remoteDummyURL.String(), localDir},
	}, {
		name: "[hg] clone specific branch",
		f: func() error {
			return MercurialBackend.Clone(&vcsGetOption{
				url:    remoteDummyURL,
				dir:    localDir,
				branch: "hello",
			})
		},
		expect: []string{"hg", "clone", "--branch", "hello", remoteDummyURL.String(), localDir},
	}, {
		name: "[darcs] clone",
		f: func() error {
			return DarcsBackend.Clone(&vcsGetOption{
				url: remoteDummyURL,
				dir: localDir,
			})
		},
		expect: []string{"darcs", "get", remoteDummyURL.String(), localDir},
	}, {
		name: "[darcs] clone shallow",
		f: func() error {
			return DarcsBackend.Clone(&vcsGetOption{
				url:     remoteDummyURL,
				dir:     localDir,
				shallow: true,
			})
		},
		expect: []string{"darcs", "get", "--lazy", remoteDummyURL.String(), localDir},
	}, {
		name: "[darcs] update",
		f: func() error {
			return DarcsBackend.Update(&vcsGetOption{
				dir: localDir,
			})
		},
		expect: []string{"darcs", "pull"},
		dir:    localDir,
	}, {
		name: "[bzr] clone",
		f: func() error {
			return BazaarBackend.Clone(&vcsGetOption{
				url: remoteDummyURL,
				dir: localDir,
			})
		},
		expect: []string{"bzr", "branch", remoteDummyURL.String(), localDir},
	}, {
		name: "[bzr] update",
		f: func() error {
			return BazaarBackend.Update(&vcsGetOption{
				dir: localDir,
			})
		},
		expect: []string{"bzr", "pull", "--overwrite"},
		dir:    localDir,
	}, {
		name: "[bzr] clone shallow",
		f: func() error {
			return BazaarBackend.Clone(&vcsGetOption{
				url:     remoteDummyURL,
				dir:     localDir,
				shallow: true,
			})
		},
		expect: []string{"bzr", "branch", remoteDummyURL.String(), localDir},
	}, {
		name: "[fossil] clone",
		f: func() error {
			return FossilBackend.Clone(&vcsGetOption{
				url: remoteDummyURL,
				dir: localDir,
			})
		},
		expect: []string{"fossil", "open", fossilRepoName},
		dir:    localDir,
	}, {
		name: "[fossil] update",
		f: func() error {
			return FossilBackend.Update(&vcsGetOption{
				dir: localDir,
			})
		},
		expect: []string{"fossil", "update"},
		dir:    localDir,
	}}

	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			if err := tc.f(); err != nil {
				t.Errorf("error should be nil, but: %s", err)
			}
			c := lastCommand()
			if !reflect.DeepEqual(c.Args, tc.expect) {
				t.Errorf("\ngot:  %+v\nexpect: %+v", c.Args, tc.expect)
			}
			if c.Dir != tc.dir {
				t.Errorf("got: %s, expect: %s", c.Dir, tc.dir)
			}
		})
	}
}

func TestCvsDummyBackend(t *testing.T) {
	tempDir := newTempDir(t)
	defer os.RemoveAll(tempDir)
	localDir := filepath.Join(tempDir, "repo")

	if err := cvsDummyBackend.Clone(&vcsGetOption{
		url: remoteDummyURL,
		dir: localDir,
	}); err == nil {
		t.Error("error should be occurred, but nil")
	}

	if err := cvsDummyBackend.Clone(&vcsGetOption{
		url:     remoteDummyURL,
		dir:     localDir,
		shallow: true,
	}); err == nil {
		t.Error("error should be occurred, but nil")
	}

	if err := cvsDummyBackend.Update(&vcsGetOption{
		dir: localDir,
	}); err == nil {
		t.Error("error should be occurred, but nil")
	}
}

func TestBranchOptionIgnoredErrors(t *testing.T) {
	tempDir := newTempDir(t)
	defer os.RemoveAll(tempDir)
	localDir := filepath.Join(tempDir, "repo")

	if err := DarcsBackend.Clone(&vcsGetOption{
		url:    remoteDummyURL,
		dir:    localDir,
		branch: "hello",
	}); err == nil {
		t.Error("error should be occurred, but nil")
	}

	if err := FossilBackend.Clone(&vcsGetOption{
		url:    remoteDummyURL,
		dir:    localDir,
		branch: "hello",
	}); err == nil {
		t.Error("error should be occurred, but nil")
	}

	if err := BazaarBackend.Clone(&vcsGetOption{
		url:    remoteDummyURL,
		dir:    localDir,
		branch: "hello",
	}); err == nil {
		t.Error("error should be occurred, but nil")
	}
}
<commit_msg>add test TestVCSBAckend/[git]_switch_git-svn_on_update<commit_after>package main

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

	"github.com/motemen/ghq/cmdutil"
)

var remoteDummyURL = mustParseURL("https://example.com/git/repo")

func TestVCSBackend(t *testing.T) {
	tempDir := newTempDir(t)
	defer os.RemoveAll(tempDir)
	localDir := filepath.Join(tempDir, "repo")
	_commands := []*exec.Cmd{}
	lastCommand := func() *exec.Cmd { return _commands[len(_commands)-1] }
	defer func(orig func(cmd *exec.Cmd) error) {
		cmdutil.CommandRunner = orig
	}(cmdutil.CommandRunner)
	cmdutil.CommandRunner = func(cmd *exec.Cmd) error {
		_commands = append(_commands, cmd)
		if reflect.DeepEqual(cmd.Args, []string{"svn", "info", "https://example.com/git/repo/trunk"}) {
			return fmt.Errorf("[test] failed to svn info")
		}
		return nil
	}

	testCases := []struct {
		name   string
		f      func() error
		expect []string
		dir    string
	}{{
		name: "[git] clone",
		f: func() error {
			return GitBackend.Clone(&vcsGetOption{
				url: remoteDummyURL,
				dir: localDir,
			})
		},
		expect: []string{"git", "clone", remoteDummyURL.String(), localDir},
	}, {
		name: "[git] shallow clone",
		f: func() error {
			return GitBackend.Clone(&vcsGetOption{
				url:     remoteDummyURL,
				dir:     localDir,
				shallow: true,
				silent:  true,
			})
		},
		expect: []string{"git", "clone", "--depth", "1", remoteDummyURL.String(), localDir},
	}, {
		name: "[git] clone specific branch",
		f: func() error {
			return GitBackend.Clone(&vcsGetOption{
				url:    remoteDummyURL,
				dir:    localDir,
				branch: "hello",
			})
		},
		expect: []string{"git", "clone", "--branch", "hello", "--single-branch", remoteDummyURL.String(), localDir},
	}, {
		name: "[git] update",
		f: func() error {
			return GitBackend.Update(&vcsGetOption{
				dir: localDir,
			})
		},
		expect: []string{"git", "pull", "--ff-only"},
		dir:    localDir,
	}, {
		name: "[git] recursive",
		f: func() error {
			return GitBackend.Clone(&vcsGetOption{
				url:       remoteDummyURL,
				dir:       localDir,
				recursive: true,
			})
		},
		expect: []string{"git", "clone", "--recursive", remoteDummyURL.String(), localDir},
	}, {
		name: "[git] update recursive",
		f: func() error {
			return GitBackend.Update(&vcsGetOption{
				dir:       localDir,
				recursive: true,
			})
		},
		expect: []string{"git", "submodule", "update", "--init", "--recursive"},
		dir:    localDir,
	}, {
		name: "[git] switch git-svn on update",
		f: func() error {
			err := os.MkdirAll(filepath.Join(localDir, ".git", "svn"), 0755)
			if err != nil {
				return err
			}
			defer os.RemoveAll(filepath.Join(localDir, ".git"))
			return GitBackend.Update(&vcsGetOption{
				dir: localDir,
			})
		},
		expect: []string{"git", "svn", "rebase"},
		dir:    localDir,
	}, {
		name: "[svn] checkout",
		f: func() error {
			return SubversionBackend.Clone(&vcsGetOption{
				url: remoteDummyURL,
				dir: localDir,
			})
		},
		expect: []string{"svn", "checkout", remoteDummyURL.String(), localDir},
	}, {
		name: "[svn] checkout shallow",
		f: func() error {
			return SubversionBackend.Clone(&vcsGetOption{
				url:     remoteDummyURL,
				dir:     localDir,
				shallow: true,
			})
		},
		expect: []string{"svn", "checkout", "--depth", "immediates", remoteDummyURL.String(), localDir},
	}, {
		name: "[svn] checkout specific branch",
		f: func() error {
			return SubversionBackend.Clone(&vcsGetOption{
				url:    remoteDummyURL,
				dir:    localDir,
				branch: "hello",
			})
		},
		expect: []string{"svn", "checkout", remoteDummyURL.String() + "/branches/hello", localDir},
	}, {
		name: "[svn] update",
		f: func() error {
			return SubversionBackend.Update(&vcsGetOption{
				dir:    localDir,
				silent: true,
			})
		},
		expect: []string{"svn", "update"},
		dir:    localDir,
	}, {
		name: "[git-svn] clone",
		f: func() error {
			return GitsvnBackend.Clone(&vcsGetOption{
				url: remoteDummyURL,
				dir: localDir,
			})
		},
		expect: []string{"git", "svn", "clone", remoteDummyURL.String(), localDir},
	}, {
		name: "[git-svn] update",
		f: func() error {
			return GitsvnBackend.Update(&vcsGetOption{
				dir: localDir,
			})
		},
		expect: []string{"git", "svn", "rebase"},
		dir:    localDir,
	}, {
		name: "[git-svn] clone shallow",
		f: func() error {
			defer func(orig func(cmd *exec.Cmd) error) {
				cmdutil.CommandRunner = orig
			}(cmdutil.CommandRunner)
			cmdutil.CommandRunner = func(cmd *exec.Cmd) error {
				_commands = append(_commands, cmd)
				if reflect.DeepEqual(cmd.Args, []string{"svn", "info", "https://example.com/git/repo/trunk"}) {
					cmd.Stdout.Write([]byte(`Path: trunk
URL: https://svn.apache.org/repos/asf/subversion/trunk
Relative URL: ^/subversion/trunk
Repository Root: https://svn.apache.org/repos/asf
Repository UUID: 13f79535-47bb-0310-9956-ffa450edef68
Revision: 1872085
Node Kind: directory
Last Changed Author: julianfoad
Last Changed Rev: 1872031
Last Changed Date: 2019-08-16 15:16:45 +0900 (Fri, 16 Aug 2019)
`))
				}
				return nil
			}
			return GitsvnBackend.Clone(&vcsGetOption{
				url:     remoteDummyURL,
				dir:     localDir,
				shallow: true,
			})
		},
		expect: []string{"git", "svn", "clone", "-s", "-r1872031:HEAD", remoteDummyURL.String(), localDir},
	}, {
		name: "[git-svn] clone specific branch",
		f: func() error {
			return GitsvnBackend.Clone(&vcsGetOption{
				url:    remoteDummyURL,
				dir:    localDir,
				branch: "hello",
			})
		},
		expect: []string{"git", "svn", "clone", remoteDummyURL.String() + "/branches/hello", localDir},
	}, {
		name: "[hg] clone",
		f: func() error {
			return MercurialBackend.Clone(&vcsGetOption{
				url: remoteDummyURL,
				dir: localDir,
			})
		},
		expect: []string{"hg", "clone", remoteDummyURL.String(), localDir},
	}, {
		name: "[hg] update",
		f: func() error {
			return MercurialBackend.Update(&vcsGetOption{
				dir: localDir,
			})
		},
		expect: []string{"hg", "pull", "--update"},
		dir:    localDir,
	}, {
		name: "[hg] clone shallow",
		f: func() error {
			return MercurialBackend.Clone(&vcsGetOption{
				url:     remoteDummyURL,
				dir:     localDir,
				shallow: true,
			})
		},
		expect: []string{"hg", "clone", remoteDummyURL.String(), localDir},
	}, {
		name: "[hg] clone specific branch",
		f: func() error {
			return MercurialBackend.Clone(&vcsGetOption{
				url:    remoteDummyURL,
				dir:    localDir,
				branch: "hello",
			})
		},
		expect: []string{"hg", "clone", "--branch", "hello", remoteDummyURL.String(), localDir},
	}, {
		name: "[darcs] clone",
		f: func() error {
			return DarcsBackend.Clone(&vcsGetOption{
				url: remoteDummyURL,
				dir: localDir,
			})
		},
		expect: []string{"darcs", "get", remoteDummyURL.String(), localDir},
	}, {
		name: "[darcs] clone shallow",
		f: func() error {
			return DarcsBackend.Clone(&vcsGetOption{
				url:     remoteDummyURL,
				dir:     localDir,
				shallow: true,
			})
		},
		expect: []string{"darcs", "get", "--lazy", remoteDummyURL.String(), localDir},
	}, {
		name: "[darcs] update",
		f: func() error {
			return DarcsBackend.Update(&vcsGetOption{
				dir: localDir,
			})
		},
		expect: []string{"darcs", "pull"},
		dir:    localDir,
	}, {
		name: "[bzr] clone",
		f: func() error {
			return BazaarBackend.Clone(&vcsGetOption{
				url: remoteDummyURL,
				dir: localDir,
			})
		},
		expect: []string{"bzr", "branch", remoteDummyURL.String(), localDir},
	}, {
		name: "[bzr] update",
		f: func() error {
			return BazaarBackend.Update(&vcsGetOption{
				dir: localDir,
			})
		},
		expect: []string{"bzr", "pull", "--overwrite"},
		dir:    localDir,
	}, {
		name: "[bzr] clone shallow",
		f: func() error {
			return BazaarBackend.Clone(&vcsGetOption{
				url:     remoteDummyURL,
				dir:     localDir,
				shallow: true,
			})
		},
		expect: []string{"bzr", "branch", remoteDummyURL.String(), localDir},
	}, {
		name: "[fossil] clone",
		f: func() error {
			return FossilBackend.Clone(&vcsGetOption{
				url: remoteDummyURL,
				dir: localDir,
			})
		},
		expect: []string{"fossil", "open", fossilRepoName},
		dir:    localDir,
	}, {
		name: "[fossil] update",
		f: func() error {
			return FossilBackend.Update(&vcsGetOption{
				dir: localDir,
			})
		},
		expect: []string{"fossil", "update"},
		dir:    localDir,
	}}

	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			if err := tc.f(); err != nil {
				t.Errorf("error should be nil, but: %s", err)
			}
			c := lastCommand()
			if !reflect.DeepEqual(c.Args, tc.expect) {
				t.Errorf("\ngot:  %+v\nexpect: %+v", c.Args, tc.expect)
			}
			if c.Dir != tc.dir {
				t.Errorf("got: %s, expect: %s", c.Dir, tc.dir)
			}
		})
	}
}

func TestCvsDummyBackend(t *testing.T) {
	tempDir := newTempDir(t)
	defer os.RemoveAll(tempDir)
	localDir := filepath.Join(tempDir, "repo")

	if err := cvsDummyBackend.Clone(&vcsGetOption{
		url: remoteDummyURL,
		dir: localDir,
	}); err == nil {
		t.Error("error should be occurred, but nil")
	}

	if err := cvsDummyBackend.Clone(&vcsGetOption{
		url:     remoteDummyURL,
		dir:     localDir,
		shallow: true,
	}); err == nil {
		t.Error("error should be occurred, but nil")
	}

	if err := cvsDummyBackend.Update(&vcsGetOption{
		dir: localDir,
	}); err == nil {
		t.Error("error should be occurred, but nil")
	}
}

func TestBranchOptionIgnoredErrors(t *testing.T) {
	tempDir := newTempDir(t)
	defer os.RemoveAll(tempDir)
	localDir := filepath.Join(tempDir, "repo")

	if err := DarcsBackend.Clone(&vcsGetOption{
		url:    remoteDummyURL,
		dir:    localDir,
		branch: "hello",
	}); err == nil {
		t.Error("error should be occurred, but nil")
	}

	if err := FossilBackend.Clone(&vcsGetOption{
		url:    remoteDummyURL,
		dir:    localDir,
		branch: "hello",
	}); err == nil {
		t.Error("error should be occurred, but nil")
	}

	if err := BazaarBackend.Clone(&vcsGetOption{
		url:    remoteDummyURL,
		dir:    localDir,
		branch: "hello",
	}); err == nil {
		t.Error("error should be occurred, but nil")
	}
}
<|endoftext|>


<commit_before>// Copyright Microsoft Corp.
// All rights reserved.

package ipam

import (
	//"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"net/http/httptest"
	"os"
	"testing"
)

var plugin IpamPlugin
var mux *http.ServeMux

// Wraps the test run with plugin setup and teardown.
func TestMain(m *testing.M) {
	var err error

	// Create the plugin.
	plugin, err = NewPlugin("test", "")
	if err != nil {
		fmt.Printf("Failed to create IPAM plugin %v\n", err)
		return
	}

	err = plugin.Start(nil)
	if err != nil {
		fmt.Printf("Failed to start IPAM plugin %v\n", err)
		return
	}

	// Get the internal http mux as test hook.
	mux = plugin.(*ipamPlugin).Listener.GetMux()

	// Run tests.
	exitCode := m.Run()

	// Cleanup.
	plugin.Stop()

	os.Exit(exitCode)
}

// Decodes plugin's responses to test requests.
func decodeResponse(w *httptest.ResponseRecorder, response interface{}) error {
	if w.Code != http.StatusOK {
		return fmt.Errorf("Request failed with HTTP error %s", w.Code)
	}

	if w.Body == nil {
		return fmt.Errorf("Response body is empty")
	}

	return json.NewDecoder(w.Body).Decode(&response)
}

//
// Libnetwork remote IPAM API compliance tests
// https://github.com/docker/libnetwork/blob/master/docs/ipam.md
//

// Tests Plugin.Activate functionality.
func TestActivate(t *testing.T) {
	fmt.Println("Test: Activate")

	var resp struct {
		Implements []string
	}

	req, err := http.NewRequest(http.MethodGet, "/Plugin.Activate", nil)
	if err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()
	mux.ServeHTTP(w, req)

	err = decodeResponse(w, &resp)

	if err != nil || resp.Implements[0] != "IpamDriver" {
		t.Errorf("Activate response is invalid %+v", resp)
	}
}

// Tests IpamDriver.GetCapabilities functionality.
func TestGetCapabilities(t *testing.T) {
	fmt.Println("Test: GetCapabilities")

	var resp struct {
		RequiresMACAddress bool
	}

	req, err := http.NewRequest(http.MethodGet, "/IpamDriver.GetCapabilities", nil)
	if err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()
	mux.ServeHTTP(w, req)

	err = decodeResponse(w, &resp)

	if err != nil {
		t.Errorf("GetCapabilities response is invalid %+v", resp)
	}
}
<commit_msg>Added basic IPAM plugin tests<commit_after>// Copyright Microsoft Corp.
// All rights reserved.

package ipam

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net"
	"net/http"
	"net/http/httptest"
	"os"
	"testing"
)

var plugin IpamPlugin
var mux *http.ServeMux

var local *addressSpace
var global *addressSpace

var poolId1 string
var address1 string

// Wraps the test run with plugin setup and teardown.
func TestMain(m *testing.M) {
	var err error

	// Create the plugin.
	plugin, err = NewPlugin("test", "")
	if err != nil {
		fmt.Printf("Failed to create IPAM plugin %v\n", err)
		return
	}

	plugin.SetOption("source", "")

	err = plugin.Start(nil)
	if err != nil {
		fmt.Printf("Failed to start IPAM plugin %v\n", err)
		return
	}

	// Get the internal http mux as test hook.
	mux = plugin.(*ipamPlugin).Listener.GetMux()

	// Run tests.
	exitCode := m.Run()

	// Cleanup.
	plugin.Stop()

	os.Exit(exitCode)
}

// Decodes plugin's responses to test requests.
func decodeResponse(w *httptest.ResponseRecorder, response interface{}) error {
	if w.Code != http.StatusOK {
		return fmt.Errorf("Request failed with HTTP error %s", w.Code)
	}

	if w.Body == nil {
		return fmt.Errorf("Response body is empty")
	}

	return json.NewDecoder(w.Body).Decode(&response)
}

//
// Libnetwork remote IPAM API compliance tests
// https://github.com/docker/libnetwork/blob/master/docs/ipam.md
//

// Tests Plugin.Activate functionality.
func TestActivate(t *testing.T) {
	fmt.Println("Test: Activate")

	var resp struct {
		Implements []string
	}

	req, err := http.NewRequest(http.MethodGet, "/Plugin.Activate", nil)
	if err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()
	mux.ServeHTTP(w, req)

	err = decodeResponse(w, &resp)

	if err != nil || resp.Implements[0] != "IpamDriver" {
		t.Errorf("Activate response is invalid %+v", resp)
	}
}

// Tests IpamDriver.GetCapabilities functionality.
func TestGetCapabilities(t *testing.T) {
	fmt.Println("Test: GetCapabilities")

	var resp struct {
		RequiresMACAddress bool
	}

	req, err := http.NewRequest(http.MethodGet, getCapabilitiesPath, nil)
	if err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()
	mux.ServeHTTP(w, req)

	err = decodeResponse(w, &resp)

	if err != nil {
		t.Errorf("GetCapabilities response is invalid %+v", resp)
	}
}

// Tests address space management functionality.
func TestAddAddressSpace(t *testing.T) {
	fmt.Println("Test: AddAddressSpace")

	var err error

	// Configure the local default address space.
	local, err = newAddressSpace(localDefaultAddressSpaceId, localScope)
	if err != nil {
		t.Errorf("newAddressSpace failed %+v", err)
		return
	}

	addr1 := net.IPv4(192, 168, 1, 1)
	addr2 := net.IPv4(192, 168, 1, 2)
	subnet := net.IPNet{
		IP:   net.IPv4(192, 168, 1, 0),
		Mask: net.IPv4Mask(255, 255, 255, 0),
	}
	ap, err := local.newAddressPool(&subnet)
	ap.newAddressRecord(&addr1)
	ap.newAddressRecord(&addr2)

	addr1 = net.IPv4(192, 168, 2, 1)
	subnet = net.IPNet{
		IP:   net.IPv4(192, 168, 2, 0),
		Mask: net.IPv4Mask(255, 255, 255, 0),
	}
	ap, err = local.newAddressPool(&subnet)
	ap.newAddressRecord(&addr1)

	plugin.setAddressSpace(local)

	// Configure the global default address space.
	global, err = newAddressSpace(globalDefaultAddressSpaceId, globalScope)
	if err != nil {
		t.Errorf("newAddressSpace failed %+v", err)
		return
	}

	plugin.setAddressSpace(global)
}

// Tests IpamDriver.GetDefaultAddressSpaces functionality.
func TestGetDefaultAddressSpaces(t *testing.T) {
	fmt.Println("Test: GetDefaultAddressSpaces")

	var resp getDefaultAddressSpacesResponse

	req, err := http.NewRequest(http.MethodGet, getAddressSpacesPath, nil)
	if err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()
	mux.ServeHTTP(w, req)

	err = decodeResponse(w, &resp)

	if err != nil ||
		resp.LocalDefaultAddressSpace != localDefaultAddressSpaceId ||
		resp.GlobalDefaultAddressSpace != globalDefaultAddressSpaceId {
		t.Errorf("GetDefaultAddressSpaces response is invalid %+v", resp)
	}
}

// Tests IpamDriver.RequestPool functionality.
func TestRequestPool(t *testing.T) {
	fmt.Println("Test: RequestPool")

	var body bytes.Buffer
	var resp requestPoolResponse

	payload := &requestPoolRequest{
		AddressSpace: localDefaultAddressSpaceId,
	}

	json.NewEncoder(&body).Encode(payload)

	req, err := http.NewRequest(http.MethodGet, requestPoolPath, &body)
	if err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()
	mux.ServeHTTP(w, req)

	err = decodeResponse(w, &resp)

	if err != nil {
		t.Errorf("RequestPool response is invalid %+v", resp)
	}

	poolId1 = resp.PoolID
}

// Tests IpamDriver.RequestAddress functionality.
func TestRequestAddress(t *testing.T) {
	fmt.Println("Test: RequestAddress")

	var body bytes.Buffer
	var resp requestAddressResponse

	payload := &requestAddressRequest{
		PoolID:  poolId1,
		Address: "",
		Options: nil,
	}

	json.NewEncoder(&body).Encode(payload)

	req, err := http.NewRequest(http.MethodGet, requestAddressPath, &body)
	if err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()
	mux.ServeHTTP(w, req)

	err = decodeResponse(w, &resp)

	if err != nil {
		t.Errorf("RequestAddress response is invalid %+v", resp)
	}

	address1 = resp.Address
}

// Tests IpamDriver.ReleaseAddress functionality.
func TestReleaseAddress(t *testing.T) {
	fmt.Println("Test: ReleaseAddress")

	var body bytes.Buffer
	var resp releaseAddressResponse

	payload := &releaseAddressRequest{
		PoolID:  poolId1,
		Address: address1,
	}

	json.NewEncoder(&body).Encode(payload)

	req, err := http.NewRequest(http.MethodGet, releaseAddressPath, &body)
	if err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()
	mux.ServeHTTP(w, req)

	err = decodeResponse(w, &resp)

	if err != nil {
		t.Errorf("ReleaseAddress response is invalid %+v", resp)
	}
}

// Tests IpamDriver.ReleasePool functionality.
func TestReleasePool(t *testing.T) {
	fmt.Println("Test: ReleasePool")

	var body bytes.Buffer
	var resp releasePoolResponse

	payload := &releasePoolRequest{
		PoolID: poolId1,
	}

	json.NewEncoder(&body).Encode(payload)

	req, err := http.NewRequest(http.MethodGet, releasePoolPath, &body)
	if err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()
	mux.ServeHTTP(w, req)

	err = decodeResponse(w, &resp)

	if err != nil {
		t.Errorf("ReleasePool response is invalid %+v", resp)
	}
}
<|endoftext|>


<commit_before>// Copyright 2014 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"runtime"
	"testing"
)

// Test that RepoRootForImportPath creates the correct RepoRoot for a given importPath.
// TODO(cmang): Add tests for SVN and BZR.
func TestRepoRootForImportPath(t *testing.T) {
	switch runtime.GOOS {
	case "nacl", "android":
		t.Skipf("no networking available on %s", runtime.GOOS)
	}
	tests := []struct {
		path string
		want *repoRoot
	}{
		{
			"code.google.com/p/go",
			&repoRoot{
				vcs:  vcsHg,
				repo: "https://code.google.com/p/go",
			},
		},
		/*{
		        "code.google.com/r/go",
		        &repoRoot{
		                vcs:  vcsHg,
		                repo: "https://code.google.com/r/go",
		        },
		},*/
		{
			"github.com/golang/groupcache",
			&repoRoot{
				vcs:  vcsGit,
				repo: "https://github.com/golang/groupcache",
			},
		},
		// IBM DevOps Services tests
		{
			"hub.jazz.net/git/user1/pkgname",
			&repoRoot{
				vcs:  vcsGit,
				repo: "https://hub.jazz.net/git/user1/pkgname",
			},
		},
		{
			"hub.jazz.net/git/user1/pkgname/submodule/submodule/submodule",
			&repoRoot{
				vcs:  vcsGit,
				repo: "https://hub.jazz.net/git/user1/pkgname",
			},
		},
		{
			"hub.jazz.net",
			nil,
		},
		{
			"hub2.jazz.net",
			nil,
		},
		{
			"hub.jazz.net/someotherprefix",
			nil,
		},
		{
			"hub.jazz.net/someotherprefix/user1/pkgname",
			nil,
		},
		// Spaces are not valid in user names or package names
		{
			"hub.jazz.net/git/User 1/pkgname",
			nil,
		},
		{
			"hub.jazz.net/git/user1/pkg name",
			nil,
		},
		// Dots are not valid in user names
		{
			"hub.jazz.net/git/user.1/pkgname",
			nil,
		},
		{
			"hub.jazz.net/git/user/pkg.name",
			&repoRoot{
				vcs:  vcsGit,
				repo: "https://hub.jazz.net/git/user/pkg.name",
			},
		},
		// User names cannot have uppercase letters
		{
			"hub.jazz.net/git/USER/pkgname",
			nil,
		},
	}

	for _, test := range tests {
		got, err := repoRootForImportPath(test.path)
		want := test.want

		if want == nil {
			if err == nil {
				t.Errorf("RepoRootForImport(%q): Error expected but not received")
			}
			continue
		}
		if err != nil {
			t.Errorf("RepoRootForImport(%q): %v", test.path, err)
			continue
		}
		if got.vcs.name != want.vcs.name || got.repo != want.repo {
			t.Errorf("RepoRootForImport(%q) = VCS(%s) Repo(%s), want VCS(%s) Repo(%s)", test.path, got.vcs, got.repo, want.vcs, want.repo)
		}
	}
}
<commit_msg>cmd/go: fix build in airplane mode<commit_after>// Copyright 2014 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"runtime"
	"testing"
)

// Test that RepoRootForImportPath creates the correct RepoRoot for a given importPath.
// TODO(cmang): Add tests for SVN and BZR.
func TestRepoRootForImportPath(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test to avoid external network")
	}
	switch runtime.GOOS {
	case "nacl", "android":
		t.Skipf("no networking available on %s", runtime.GOOS)
	}
	tests := []struct {
		path string
		want *repoRoot
	}{
		{
			"code.google.com/p/go",
			&repoRoot{
				vcs:  vcsHg,
				repo: "https://code.google.com/p/go",
			},
		},
		/*{
		        "code.google.com/r/go",
		        &repoRoot{
		                vcs:  vcsHg,
		                repo: "https://code.google.com/r/go",
		        },
		},*/
		{
			"github.com/golang/groupcache",
			&repoRoot{
				vcs:  vcsGit,
				repo: "https://github.com/golang/groupcache",
			},
		},
		// IBM DevOps Services tests
		{
			"hub.jazz.net/git/user1/pkgname",
			&repoRoot{
				vcs:  vcsGit,
				repo: "https://hub.jazz.net/git/user1/pkgname",
			},
		},
		{
			"hub.jazz.net/git/user1/pkgname/submodule/submodule/submodule",
			&repoRoot{
				vcs:  vcsGit,
				repo: "https://hub.jazz.net/git/user1/pkgname",
			},
		},
		{
			"hub.jazz.net",
			nil,
		},
		{
			"hub2.jazz.net",
			nil,
		},
		{
			"hub.jazz.net/someotherprefix",
			nil,
		},
		{
			"hub.jazz.net/someotherprefix/user1/pkgname",
			nil,
		},
		// Spaces are not valid in user names or package names
		{
			"hub.jazz.net/git/User 1/pkgname",
			nil,
		},
		{
			"hub.jazz.net/git/user1/pkg name",
			nil,
		},
		// Dots are not valid in user names
		{
			"hub.jazz.net/git/user.1/pkgname",
			nil,
		},
		{
			"hub.jazz.net/git/user/pkg.name",
			&repoRoot{
				vcs:  vcsGit,
				repo: "https://hub.jazz.net/git/user/pkg.name",
			},
		},
		// User names cannot have uppercase letters
		{
			"hub.jazz.net/git/USER/pkgname",
			nil,
		},
	}

	for _, test := range tests {
		got, err := repoRootForImportPath(test.path)
		want := test.want

		if want == nil {
			if err == nil {
				t.Errorf("RepoRootForImport(%q): Error expected but not received")
			}
			continue
		}
		if err != nil {
			t.Errorf("RepoRootForImport(%q): %v", test.path, err)
			continue
		}
		if got.vcs.name != want.vcs.name || got.repo != want.repo {
			t.Errorf("RepoRootForImport(%q) = VCS(%s) Repo(%s), want VCS(%s) Repo(%s)", test.path, got.vcs, got.repo, want.vcs, want.repo)
		}
	}
}
<|endoftext|>


<commit_before>package lisp

type primitive func(*scope, []sexpr) sexpr

// (if cond expr1 expr2)
func primitiveIf(sc *scope, ss []sexpr) sexpr {
	if len(ss) < 2 || len(ss) > 3 {
		panic("Invalid number of arguments to primitive if")
	}
	cond := ss[0]
	cv := eval(sc, cond)
	if cv != nil {
		return eval(sc, ss[1])
	} else if len(ss) == 3 {
		return eval(sc, ss[2])
	}
	return Nil
}

// (for cond expr)
func primitiveFor(sc *scope, ss []sexpr) sexpr {
	if len(ss) != 2 {
		panic("Invalid number of arguments")
	}
	cond := ss[0]
	expr := ss[1]
	val := Nil
	cv := eval(sc, cond)
	for cv != nil {
		val = eval(sc, expr)
		cv = eval(sc, cond)
	}
	return val
}

// (lambda (arg1 ...) expr)
func primitiveLambda(sc *scope, ss []sexpr) sexpr {
	if len(ss) != 2 {
		panic("Invalid number of arguments")
	}
	_, ok := ss[0].(cons)
	if !ok && ss[0] != nil {
		panic("Invalid argument type")
	}
	expr := ss[1]
	evalScopeParent := newScope(sc)
	var args_ = ss[0]
	// TODO type check the args list
	return function(func(callScope *scope, ss []sexpr) sexpr {
		args := args_
		evalScope := newScope(evalScopeParent)
		// Match args with ss
		aC, ok := args.(cons)
		for args != nil {
			if !ok {
				// turn ss back into a cons
				unflatten(ss)
				break
			}
			arg := aC.car
			val := ss[0]
			s, k := arg.(sym)
			if !k {
				panic("Invalid parameter specification")
			}
			evalScope.define(s, val)

			ss = ss[1:]
			args = aC.cdr
			aC, ok = args.(cons)
		}
		return eval(evalScope, expr)
		/*if len(ss) != len(args) {
			panic("Invalid number of arguments")
		}
		evalScope := newScope(evalScopeParent)
		for i, arg := range args {
			val := ss[i]
			evalScope.define(arg.(sym), val)
		}
		return eval(evalScope, expr)*/
	})
}

// (let ((sym1 val1) ...) expr1 ...)
func primitiveLet(sc *scope, ss []sexpr) sexpr {
	if len(ss) < 1 {
		panic("Invalid number of arguments")
	}
	evalScope := newScope(sc)
	bindings := flatten(ss[0])
	for _, b := range bindings {
		bs := flatten(b)
		if len(bs) != 2 {
			panic("Invalid binding")
		}
		s, ok := bs[0].(sym)
		if !ok {
			panic("Invalid binding")
		}
		val := eval(sc, bs[1])
		evalScope.define(s, val)
	}

	prog := ss[1:]
	last := Nil
	for _, l := range prog {
		last = eval(evalScope, l)
	}
	return last
}

// (define keyword expression)
func primitiveDefine(sc *scope, ss []sexpr) sexpr {
	if len(ss) != 2 {
		panic("Invalid number of arguments")
	}
	idSym, ok := ss[0].(sym)
	if !ok {
		panic("Invalid argument")
	}
	val := eval(sc, ss[1])
	sc.defineHigh(idSym, val)
	return Nil
}

// (quote expr)
func primitiveQuote(sc *scope, ss []sexpr) sexpr {
	if len(ss) != 1 {
		panic("Invalid number of arguments")
	}
	return ss[0]
}

// (begin expr1 ...)
//
// This could be implemented (in large part, at least) as an ordinary function
// taking variable arguments; however, in the interest of clarity of behaviour,
// it is not.
func primitiveBegin(sc *scope, ss []sexpr) sexpr {
	last := Nil
	for _, l := range ss {
		last = eval(sc, l)
	}
	return last
}
<commit_msg>Adding error checking<commit_after>package lisp

type primitive func(*scope, []sexpr) sexpr

// (if cond expr1 expr2)
func primitiveIf(sc *scope, ss []sexpr) sexpr {
	if len(ss) < 2 || len(ss) > 3 {
		panic("Invalid number of arguments to primitive if")
	}
	cond := ss[0]
	cv := eval(sc, cond)
	if cv != nil {
		return eval(sc, ss[1])
	} else if len(ss) == 3 {
		return eval(sc, ss[2])
	}
	return Nil
}

// (for cond expr)
func primitiveFor(sc *scope, ss []sexpr) sexpr {
	if len(ss) != 2 {
		panic("Invalid number of arguments")
	}
	cond := ss[0]
	expr := ss[1]
	val := Nil
	cv := eval(sc, cond)
	for cv != nil {
		val = eval(sc, expr)
		cv = eval(sc, cond)
	}
	return val
}

// (lambda (arg1 ...) expr)
func primitiveLambda(sc *scope, ss []sexpr) sexpr {
	if len(ss) != 2 {
		panic("Invalid number of arguments")
	}
	_, ok := ss[0].(cons)
	if !ok && ss[0] != nil {
		panic("Invalid argument type")
	}
	expr := ss[1]
	evalScopeParent := newScope(sc)
	var args_ = ss[0]
	// TODO type check the args list
	return function(func(callScope *scope, ss []sexpr) sexpr {
		args := args_
		evalScope := newScope(evalScopeParent)
		// Match args with ss
		aC, ok := args.(cons)
		for args != nil {
			if len(ss) == 0 {
				panic("Invalid number of arguments")
			}
			if !ok {
				// turn ss back into a cons
				unflatten(ss)
				break
			}
			arg := aC.car
			val := ss[0]
			s, k := arg.(sym)
			if !k {
				panic("Invalid parameter specification")
			}
			evalScope.define(s, val)

			ss = ss[1:]
			args = aC.cdr
			aC, ok = args.(cons)
		}
		if len(ss) > 0 {
			panic("Invalid number of arguments")
		}
		return eval(evalScope, expr)
	})
}

// (let ((sym1 val1) ...) expr1 ...)
func primitiveLet(sc *scope, ss []sexpr) sexpr {
	if len(ss) < 1 {
		panic("Invalid number of arguments")
	}
	evalScope := newScope(sc)
	bindings := flatten(ss[0])
	for _, b := range bindings {
		bs := flatten(b)
		if len(bs) != 2 {
			panic("Invalid binding")
		}
		s, ok := bs[0].(sym)
		if !ok {
			panic("Invalid binding")
		}
		val := eval(sc, bs[1])
		evalScope.define(s, val)
	}

	prog := ss[1:]
	last := Nil
	for _, l := range prog {
		last = eval(evalScope, l)
	}
	return last
}

// (define keyword expression)
func primitiveDefine(sc *scope, ss []sexpr) sexpr {
	if len(ss) != 2 {
		panic("Invalid number of arguments")
	}
	idSym, ok := ss[0].(sym)
	if !ok {
		panic("Invalid argument")
	}
	val := eval(sc, ss[1])
	sc.defineHigh(idSym, val)
	return Nil
}

// (quote expr)
func primitiveQuote(sc *scope, ss []sexpr) sexpr {
	if len(ss) != 1 {
		panic("Invalid number of arguments")
	}
	return ss[0]
}

// (begin expr1 ...)
//
// This could be implemented (in large part, at least) as an ordinary function
// taking variable arguments; however, in the interest of clarity of behaviour,
// it is not.
func primitiveBegin(sc *scope, ss []sexpr) sexpr {
	last := Nil
	for _, l := range ss {
		last = eval(sc, l)
	}
	return last
}
<|endoftext|>


<commit_before>// Copyright 2017 Cisco Systems, Inc.
//
// 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 (
	"testing"
	"time"

	"github.com/noironetworks/aci-containers/metadata"
	tu "github.com/noironetworks/aci-containers/testutil"
)

type annotTest struct {
	ns      string
	egannot string
	sgannot string
	desc    string
}

const egAnnot = "{\"policy-space\": \"testps\", \"name\": \"test|test-eg\"}"
const sgAnnot = "[{\"policy-space\": \"testps\", \"name\": \"test-sg\"}]"

var annotTests = []annotTest{
	{"testns", egAnnot, "", "egonly"},
	{"testns", egAnnot, sgAnnot, "both"},
	{"testns", "", sgAnnot, "sgonly"},
	{"testns", "", "", "neither"},
}

func waitForGroupAnnot(t *testing.T, cont *testAciController,
	egAnnot string, sgAnnot string, desc string) {
	tu.WaitFor(t, desc, 500*time.Millisecond,
		func(last bool) (bool, error) {
			if !tu.WaitCondition(t, last, func() bool {
				return len(cont.podUpdates) >= 1
			}, desc) {
				return false, nil
			}
			annot :=
				cont.podUpdates[len(cont.podUpdates)-1].ObjectMeta.Annotations
			return tu.WaitEqual(t, last, egAnnot,
				annot[metadata.CompEgAnnotation], desc) &&
				tu.WaitEqual(t, last, sgAnnot,
					annot[metadata.CompSgAnnotation], desc), nil
		})
}

func TestPodAnnotation(t *testing.T) {
	cont := testController()
	cont.run()

	for _, test := range annotTests {
		cont.podUpdates = nil
		cont.fakePodSource.Add(pod("testpod", test.ns, test.egannot, test.sgannot))
		waitForGroupAnnot(t, cont, test.egannot, test.sgannot, test.desc)
	}

	cont.stop()
}

func TestNamespaceAnnotation(t *testing.T) {
	cont := testController()
	cont.run()

	cont.fakePodSource.Add(pod("testns", "testpod", "", ""))
	waitForGroupAnnot(t, cont, "", "", "none")

	for _, test := range annotTests {
		cont.podUpdates = nil
		cont.fakeNamespaceSource.Add(namespace(test.ns, test.egannot, test.sgannot))
		waitForGroupAnnot(t, cont, test.egannot, test.sgannot, test.desc)
	}

	cont.fakeNamespaceSource.Delete(namespace("testns", "", ""))
	waitForGroupAnnot(t, cont, "", "", "none")

	cont.stop()
}

func TestDeploymentAnnotation(t *testing.T) {
	cont := testController()
	cont.run()

	cont.fakePodSource.Add(pod("testns", "testpod", "", ""))
	waitForGroupAnnot(t, cont, "", "", "none")

	for _, test := range annotTests {
		cont.podUpdates = nil
		cont.fakeDeploymentSource.Add(deployment(test.ns, "testdep", test.egannot, test.sgannot))
		waitForGroupAnnot(t, cont, test.egannot, test.sgannot, test.desc)
	}

	cont.fakeDeploymentSource.Delete(deployment("testns", "testdep", "", ""))
	waitForGroupAnnot(t, cont, "", "", "none")

	cont.stop()
}

func TestDeploymentAnnotationPre(t *testing.T) {
	cont := testController()
	cont.run()

	cont.fakePodSource.Add(pod("testns", "testpod", "", ""))
	waitForGroupAnnot(t, cont, "", "", "pod1")

	cont.podUpdates = nil
	cont.fakeDeploymentSource.Add(deployment("testns", "testdep", egAnnot, sgAnnot))
	waitForGroupAnnot(t, cont, egAnnot, sgAnnot, "pod1update")

	cont.podUpdates = nil
	cont.fakePodSource.Add(pod("testns", "testpod2", "", ""))
	waitForGroupAnnot(t, cont, egAnnot, sgAnnot, "pod2")

	cont.stop()
}
<commit_msg>Reorder tests so that the delete cases actually run.<commit_after>// Copyright 2017 Cisco Systems, Inc.
//
// 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 (
	"testing"
	"time"

	"github.com/noironetworks/aci-containers/metadata"
	tu "github.com/noironetworks/aci-containers/testutil"
)

type annotTest struct {
	ns      string
	egannot string
	sgannot string
	desc    string
}

const egAnnot = "{\"policy-space\": \"testps\", \"name\": \"test|test-eg\"}"
const sgAnnot = "[{\"policy-space\": \"testps\", \"name\": \"test-sg\"}]"

var annotTests = []annotTest{
	{"testns", egAnnot, "", "egonly"},
	{"testns", "", sgAnnot, "sgonly"},
	{"testns", "", "", "neither"},
	{"testns", egAnnot, sgAnnot, "both"},
}

func waitForGroupAnnot(t *testing.T, cont *testAciController,
	egAnnot string, sgAnnot string, desc string) {
	tu.WaitFor(t, desc, 500*time.Millisecond,
		func(last bool) (bool, error) {
			if !tu.WaitCondition(t, last, func() bool {
				return len(cont.podUpdates) >= 1
			}, desc) {
				return false, nil
			}
			annot :=
				cont.podUpdates[len(cont.podUpdates)-1].ObjectMeta.Annotations
			return tu.WaitEqual(t, last, egAnnot,
				annot[metadata.CompEgAnnotation], desc) &&
				tu.WaitEqual(t, last, sgAnnot,
					annot[metadata.CompSgAnnotation], desc), nil
		})
}

func TestPodAnnotation(t *testing.T) {
	cont := testController()
	cont.run()

	for _, test := range annotTests {
		cont.podUpdates = nil
		cont.fakePodSource.Add(pod("testpod", test.ns, test.egannot, test.sgannot))
		waitForGroupAnnot(t, cont, test.egannot, test.sgannot, test.desc)
	}

	cont.stop()
}

func TestNamespaceAnnotation(t *testing.T) {
	cont := testController()
	cont.run()

	cont.fakePodSource.Add(pod("testns", "testpod", "", ""))
	waitForGroupAnnot(t, cont, "", "", "none")

	for _, test := range annotTests {
		cont.podUpdates = nil
		cont.fakeNamespaceSource.Add(namespace(test.ns, test.egannot, test.sgannot))
		waitForGroupAnnot(t, cont, test.egannot, test.sgannot, test.desc)
	}

	cont.fakeNamespaceSource.Delete(namespace("testns", "", ""))
	waitForGroupAnnot(t, cont, "", "", "none")

	cont.stop()
}

func TestDeploymentAnnotation(t *testing.T) {
	cont := testController()
	cont.run()

	cont.fakePodSource.Add(pod("testns", "testpod", "", ""))
	waitForGroupAnnot(t, cont, "", "", "none")

	for _, test := range annotTests {
		cont.podUpdates = nil
		cont.fakeDeploymentSource.Add(deployment(test.ns, "testdep", test.egannot, test.sgannot))
		waitForGroupAnnot(t, cont, test.egannot, test.sgannot, test.desc)
	}

	log.Info("deleting")
	cont.fakeDeploymentSource.Delete(deployment("testns", "testdep", "", ""))
	waitForGroupAnnot(t, cont, "", "", "none")

	cont.stop()
}

func TestDeploymentAnnotationPre(t *testing.T) {
	cont := testController()
	cont.run()

	cont.fakePodSource.Add(pod("testns", "testpod", "", ""))
	waitForGroupAnnot(t, cont, "", "", "pod1")

	cont.podUpdates = nil
	cont.fakeDeploymentSource.Add(deployment("testns", "testdep", egAnnot, sgAnnot))
	waitForGroupAnnot(t, cont, egAnnot, sgAnnot, "pod1update")

	cont.podUpdates = nil
	cont.fakePodSource.Add(pod("testns", "testpod2", "", ""))
	waitForGroupAnnot(t, cont, egAnnot, sgAnnot, "pod2")

	cont.stop()
}
<|endoftext|>


<commit_before>// Copyright (c) 2014 Naoya SATO

package endian

var MiddleEndian middleEndian

type middleEndian struct{}

func (middleEndian) Uint16(b []byte) uint16 {
	return uint16(b[0]) | uint16(b[1]) << 8
}

func (middleEndian) PutUint16(b []byte, v uint16) {
	b[0] = byte(v)
	b[1] = byte(v >> 8)
}

func (middleEndian) Uint32(b []byte) uint32 {
	return uint32(b[2]) | uint32(b[3]) << 8 | uint32(b[0]) << 16 | uint32(b[1]) << 24
}

func (middleEndian) PutUint32(b []byte, v uint32) {
	b[0] = byte(v >> 16)
	b[1] = byte(v >> 24)
	b[2] = byte(v)
	b[3] = byte(v >> 8)
}

func (middleEndian) Uint64(b []byte) uint64 {
	return uint64(b[6]) | uint64(b[7]) << 8 | uint64(b[4]) << 16 | uint64(b[5]) << 24 |
	uint64(b[2]) << 32 | uint64(b[3]) << 40 | uint64(b[0]) << 48 | uint64(b[1]) << 56
}

func (middleEndian) PutUint64(b []byte, v uint64) {
	b[0] = byte(v >> 48)
	b[1] = byte(v >> 56)
	b[2] = byte(v >> 32)
	b[3] = byte(v >> 40)
	b[4] = byte(v >> 16)
	b[5] = byte(v >> 24)
	b[6] = byte(v)
	b[7] = byte(v >> 8)
}

func (middleEndian) String() string { return "MiddleEndian" }
<commit_msg>gofmt -w<commit_after>// Copyright (c) 2014 Naoya SATO

package endian

var MiddleEndian middleEndian

type middleEndian struct{}

func (middleEndian) Uint16(b []byte) uint16 {
	return uint16(b[0]) | uint16(b[1])<<8
}

func (middleEndian) PutUint16(b []byte, v uint16) {
	b[0] = byte(v)
	b[1] = byte(v >> 8)
}

func (middleEndian) Uint32(b []byte) uint32 {
	return uint32(b[2]) | uint32(b[3])<<8 | uint32(b[0])<<16 | uint32(b[1])<<24
}

func (middleEndian) PutUint32(b []byte, v uint32) {
	b[0] = byte(v >> 16)
	b[1] = byte(v >> 24)
	b[2] = byte(v)
	b[3] = byte(v >> 8)
}

func (middleEndian) Uint64(b []byte) uint64 {
	return uint64(b[6]) | uint64(b[7])<<8 | uint64(b[4])<<16 | uint64(b[5])<<24 |
		uint64(b[2])<<32 | uint64(b[3])<<40 | uint64(b[0])<<48 | uint64(b[1])<<56
}

func (middleEndian) PutUint64(b []byte, v uint64) {
	b[0] = byte(v >> 48)
	b[1] = byte(v >> 56)
	b[2] = byte(v >> 32)
	b[3] = byte(v >> 40)
	b[4] = byte(v >> 16)
	b[5] = byte(v >> 24)
	b[6] = byte(v)
	b[7] = byte(v >> 8)
}

func (middleEndian) String() string { return "MiddleEndian" }
<|endoftext|>