<commit_before>package user

import (
	"github.com/cloudfoundry/cli/cf/api"
	"github.com/cloudfoundry/cli/cf/api/spaces"
	"github.com/cloudfoundry/cli/cf/command_registry"
	"github.com/cloudfoundry/cli/cf/configuration/core_config"
	. "github.com/cloudfoundry/cli/cf/i18n"
	"github.com/cloudfoundry/cli/cf/models"
	"github.com/cloudfoundry/cli/cf/requirements"
	"github.com/cloudfoundry/cli/cf/terminal"
	"github.com/cloudfoundry/cli/flags"
	"github.com/cloudfoundry/cli/plugin/models"
)

type SpaceUsers struct {
	ui          terminal.UI
	config      core_config.Reader
	spaceRepo   spaces.SpaceRepository
	userRepo    api.UserRepository
	orgReq      requirements.OrganizationRequirement
	pluginModel *[]plugin_models.GetSpaceUsers_Model
	pluginCall  bool
}

func init() {
	command_registry.Register(&SpaceUsers{})
}

func (cmd *SpaceUsers) MetaData() command_registry.CommandMetadata {
	return command_registry.CommandMetadata{
		Name:        "space-users",
		Description: T("Show space users by role"),
		Usage:       T("CF_NAME space-users ORG SPACE"),
	}
}

func (cmd *SpaceUsers) Requirements(requirementsFactory requirements.Factory, fc flags.FlagContext) (reqs []requirements.Requirement, err error) {
	if len(fc.Args()) != 2 {
		cmd.ui.Failed(T("Incorrect Usage. Requires arguments\n\n") + command_registry.Commands.CommandUsage("space-users"))
	}

	cmd.orgReq = requirementsFactory.NewOrganizationRequirement(fc.Args()[0])

	reqs = []requirements.Requirement{
		requirementsFactory.NewLoginRequirement(),
		cmd.orgReq,
	}
	return
}

func (cmd *SpaceUsers) SetDependency(deps command_registry.Dependency, pluginCall bool) command_registry.Command {
	cmd.ui = deps.Ui
	cmd.config = deps.Config
	cmd.userRepo = deps.RepoLocator.GetUserRepository()
	cmd.spaceRepo = deps.RepoLocator.GetSpaceRepository()
	cmd.pluginCall = pluginCall
	cmd.pluginModel = deps.PluginModels.SpaceUsers

	return cmd
}

func (cmd *SpaceUsers) Execute(c flags.FlagContext) {
	spaceName := c.Args()[1]
	org := cmd.orgReq.GetOrganization()

	space, apiErr := cmd.spaceRepo.FindByNameInOrg(spaceName, org.Guid)
	if apiErr != nil {
		cmd.ui.Failed(apiErr.Error())
	}

	cmd.ui.Say(T("Getting users in org {{.TargetOrg}} / space {{.TargetSpace}} as {{.CurrentUser}}",
		map[string]interface{}{
			"TargetOrg":   terminal.EntityNameColor(org.Name),
			"TargetSpace": terminal.EntityNameColor(space.Name),
			"CurrentUser": terminal.EntityNameColor(cmd.config.Username()),
		}))

	var spaceRoleToDisplayName = map[string]string{
		models.SPACE_MANAGER:   T("SPACE MANAGER"),
		models.SPACE_DEVELOPER: T("SPACE DEVELOPER"),
		models.SPACE_AUDITOR:   T("SPACE AUDITOR"),
	}

	var usersMap = make(map[string]plugin_models.GetSpaceUsers_Model)

	listUsers := cmd.getUserLister()

	var users []models.UserFields
	for role, displayName := range spaceRoleToDisplayName {
		users, apiErr = listUsers(space.Guid, role)

		cmd.ui.Say("")
		cmd.ui.Say("%s", terminal.HeaderColor(displayName))

		if len(users) == 0 {
			cmd.ui.Say("none")
		} else {
			for _, user := range users {
				cmd.ui.Say("  %s", user.Username)

				if cmd.pluginCall {
					u, found := usersMap[user.Username]
					if !found {
						u = plugin_models.GetSpaceUsers_Model{}
						u.Username = user.Username
						u.Guid = user.Guid
						u.IsAdmin = user.IsAdmin
						u.Roles = make([]string, 1)
						u.Roles[0] = role
						usersMap[user.Username] = u
					} else {
						u.Roles = append(u.Roles, role)
						usersMap[user.Username] = u
					}
				}
			}
		}

		if apiErr != nil {
			cmd.ui.Failed(T("Failed fetching space-users for role {{.SpaceRoleToDisplayName}}.\n{{.Error}}",
				map[string]interface{}{
					"Error":                  apiErr.Error(),
					"SpaceRoleToDisplayName": displayName,
				}))
			return
		}
	}

	if cmd.pluginCall {
		for _, v := range usersMap {
			*(cmd.pluginModel) = append(*(cmd.pluginModel), v)
		}
	}
}

func (cmd *SpaceUsers) getUserLister() func(spaceGuid string, role string) ([]models.UserFields, error) {
	if cmd.config.IsMinApiVersion("2.21.0") {
		return cmd.userRepo.ListUsersInSpaceForRoleWithNoUAA
	}
	return cmd.userRepo.ListUsersInSpaceForRole
}
<commit_msg>Fail early when fetching users<commit_after>package user

import (
	"github.com/cloudfoundry/cli/cf/api"
	"github.com/cloudfoundry/cli/cf/api/spaces"
	"github.com/cloudfoundry/cli/cf/command_registry"
	"github.com/cloudfoundry/cli/cf/configuration/core_config"
	. "github.com/cloudfoundry/cli/cf/i18n"
	"github.com/cloudfoundry/cli/cf/models"
	"github.com/cloudfoundry/cli/cf/requirements"
	"github.com/cloudfoundry/cli/cf/terminal"
	"github.com/cloudfoundry/cli/flags"
	"github.com/cloudfoundry/cli/plugin/models"
)

type SpaceUsers struct {
	ui          terminal.UI
	config      core_config.Reader
	spaceRepo   spaces.SpaceRepository
	userRepo    api.UserRepository
	orgReq      requirements.OrganizationRequirement
	pluginModel *[]plugin_models.GetSpaceUsers_Model
	pluginCall  bool
}

func init() {
	command_registry.Register(&SpaceUsers{})
}

func (cmd *SpaceUsers) MetaData() command_registry.CommandMetadata {
	return command_registry.CommandMetadata{
		Name:        "space-users",
		Description: T("Show space users by role"),
		Usage:       T("CF_NAME space-users ORG SPACE"),
	}
}

func (cmd *SpaceUsers) Requirements(requirementsFactory requirements.Factory, fc flags.FlagContext) (reqs []requirements.Requirement, err error) {
	if len(fc.Args()) != 2 {
		cmd.ui.Failed(T("Incorrect Usage. Requires arguments\n\n") + command_registry.Commands.CommandUsage("space-users"))
	}

	cmd.orgReq = requirementsFactory.NewOrganizationRequirement(fc.Args()[0])

	reqs = []requirements.Requirement{
		requirementsFactory.NewLoginRequirement(),
		cmd.orgReq,
	}
	return
}

func (cmd *SpaceUsers) SetDependency(deps command_registry.Dependency, pluginCall bool) command_registry.Command {
	cmd.ui = deps.Ui
	cmd.config = deps.Config
	cmd.userRepo = deps.RepoLocator.GetUserRepository()
	cmd.spaceRepo = deps.RepoLocator.GetSpaceRepository()
	cmd.pluginCall = pluginCall
	cmd.pluginModel = deps.PluginModels.SpaceUsers

	return cmd
}

func (cmd *SpaceUsers) Execute(c flags.FlagContext) {
	spaceName := c.Args()[1]
	org := cmd.orgReq.GetOrganization()

	space, err := cmd.spaceRepo.FindByNameInOrg(spaceName, org.Guid)
	if err != nil {
		cmd.ui.Failed(err.Error())
	}

	cmd.ui.Say(T("Getting users in org {{.TargetOrg}} / space {{.TargetSpace}} as {{.CurrentUser}}",
		map[string]interface{}{
			"TargetOrg":   terminal.EntityNameColor(org.Name),
			"TargetSpace": terminal.EntityNameColor(space.Name),
			"CurrentUser": terminal.EntityNameColor(cmd.config.Username()),
		}))

	var spaceRoleToDisplayName = map[string]string{
		models.SPACE_MANAGER:   T("SPACE MANAGER"),
		models.SPACE_DEVELOPER: T("SPACE DEVELOPER"),
		models.SPACE_AUDITOR:   T("SPACE AUDITOR"),
	}

	var usersMap = make(map[string]plugin_models.GetSpaceUsers_Model)

	listUsers := cmd.getUserLister()

	for role, displayName := range spaceRoleToDisplayName {
		users, err := listUsers(space.Guid, role)
		if err != nil {
			cmd.ui.Failed(T("Failed fetching space-users for role {{.SpaceRoleToDisplayName}}.\n{{.Error}}",
				map[string]interface{}{
					"Error":                  err.Error(),
					"SpaceRoleToDisplayName": displayName,
				}))
			return
		}

		cmd.ui.Say("")
		cmd.ui.Say("%s", terminal.HeaderColor(displayName))

		if len(users) == 0 {
			cmd.ui.Say("none")
		} else {
			for _, user := range users {
				if cmd.pluginCall {
					u, found := usersMap[user.Username]
					if !found {
						u = plugin_models.GetSpaceUsers_Model{}
						u.Username = user.Username
						u.Guid = user.Guid
						u.IsAdmin = user.IsAdmin
						u.Roles = make([]string, 1)
						u.Roles[0] = role
						usersMap[user.Username] = u
					} else {
						u.Roles = append(u.Roles, role)
						usersMap[user.Username] = u
					}
				} else {
					cmd.ui.Say("  %s", user.Username)
				}
			}
		}
	}

	if cmd.pluginCall {
		for _, v := range usersMap {
			*(cmd.pluginModel) = append(*(cmd.pluginModel), v)
		}
	}
}

func (cmd *SpaceUsers) getUserLister() func(spaceGuid string, role string) ([]models.UserFields, error) {
	if cmd.config.IsMinApiVersion("2.21.0") {
		return cmd.userRepo.ListUsersInSpaceForRoleWithNoUAA
	}
	return cmd.userRepo.ListUsersInSpaceForRole
}
<|endoftext|>


<commit_before>package itest

import (
	"testing"

	"github.com/ligato/cn-infra/core"
	"github.com/ligato/cn-infra/flavors/generic"
	"github.com/ligato/cn-infra/flavors/local"
	"github.com/ligato/cn-infra/httpmux"
	"github.com/ligato/cn-infra/httpmux/mock"
	"github.com/onsi/gomega"
)

type suiteGenericFlavor struct {
	T *testing.T
	AgentT
	Given
	When
	Then
	mock.HttpMock
}

func MockGenericFlavor(mock *mock.HttpMock) *generic.FlavorGeneric {
	return &generic.FlavorGeneric{
		HTTP: *httpmux.FromExistingServer(mock.SetHandler),
	}
}

// TC01 asserts that injection works fine and agent starts & stops
func (t *suiteGenericFlavor) TC01StartStop() {
	flavor := MockGenericFlavor(&t.HttpMock)
	t.Setup(flavor, t.T)

	gomega.Expect(t.agent).ShouldNot(gomega.BeNil(), "agent is not initialized")

	defer t.Teardown()
}

// TC03 check that status check in flavor works
func (t *suiteGenericFlavor) TC03StatusCheck() {
	flavor := &local.FlavorLocal{}
	t.Setup(flavor, t.T)

	tstPlugin := core.PluginName("tstPlugin")
	flavor.StatusCheck.Register(tstPlugin, nil)
	flavor.StatusCheck.ReportStateChange(tstPlugin, "tst", nil)

	t.HttpMock.NewRequest("GET", flavor.ServiceLabel.GetAgentPrefix()+
		"/check/status/v1/agent", nil)
	//TODO assert flavor.StatusCheck using IDX map???

	defer t.Teardown()
}
<commit_msg> ODPM-361 http response assertion for generic flavor status check TC<commit_after>package itest

import (
	"testing"

	"github.com/ligato/cn-infra/core"
	"github.com/ligato/cn-infra/flavors/generic"
	"github.com/ligato/cn-infra/flavors/local"
	"github.com/ligato/cn-infra/httpmux"
	"github.com/ligato/cn-infra/httpmux/mock"
	"github.com/onsi/gomega"
)

type suiteGenericFlavor struct {
	T *testing.T
	AgentT
	Given
	When
	Then
	mock.HttpMock
}

// MockGenericFlavor initializes generic flavor with HTTP mock
func MockGenericFlavor(mock *mock.HttpMock) *generic.FlavorGeneric {
	return &generic.FlavorGeneric{
		HTTP: *httpmux.FromExistingServer(mock.SetHandler),
	}
}

// TC01 asserts that injection works fine and agent starts & stops
func (t *suiteGenericFlavor) TC01StartStop() {
	flavor := MockGenericFlavor(&t.HttpMock)
	t.Setup(flavor, t.T)

	gomega.Expect(t.agent).ShouldNot(gomega.BeNil(), "agent is not initialized")

	defer t.Teardown()
}

// TC03 check that status check in flavor works
func (t *suiteGenericFlavor) TC03StatusCheck() {
	flavor := &local.FlavorLocal{}
	t.Setup(flavor, t.T)

	tstPlugin := core.PluginName("tstPlugin")
	flavor.StatusCheck.Register(tstPlugin, nil)
	flavor.StatusCheck.ReportStateChange(tstPlugin, "tst", nil)

	result, err := t.HttpMock.NewRequest("GET", flavor.ServiceLabel.GetAgentPrefix()+
		"/check/status/v1/agent", nil)
	gomega.Expect(err).Should(gomega.BeNil(), "logger is not initialized")
	gomega.Expect(result).ShouldNot(gomega.BeNil(), "http result is not initialized")
	gomega.Expect(result).Should(gomega.BeEquivalentTo(200))

	defer t.Teardown()
}
<|endoftext|>


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

// Package hookshot is a router that de-multiplexes and authorizes github webhooks.
package hookshot

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha1"
	"crypto/subtle"
	"fmt"
	"io/ioutil"
	"net/http"
)

const (
	// HeaderEvent is the name of the header that contains the type of event.
	HeaderEvent = "X-GitHub-Event"

	// HeaderSignature is the name of the header that contains the signature.
	HeaderSignature = "X-Hub-Signature"
)

var (
	// DefaultNotFoundHandler is the default NotFoundHandler for a Router instance.
	DefaultNotFoundHandler = http.HandlerFunc(http.NotFound)

	// DefaultUnauthorizedHandler is the default UnauthorizedHandler for a Router
	// instance, which responds with a 403 status and a plain text body.
	DefaultUnauthorizedHandler = http.HandlerFunc(unauthorized)
)

// Router demultiplexes github hooks.
type Router struct {
	// NotFoundHandler is called when a handler is not found for a given GitHub event.
	// The nil value for NotFoundHandler
	NotFoundHandler http.Handler

	routes routes
}

// NewRouter returns a new Router.
func NewRouter() *Router {
	return &Router{
		routes: make(routes),
	}
}

// Handle maps a github event to an http.Handler.
func (r *Router) Handle(event string, h http.Handler) {
	r.routes[event] = h
}

// HandleFunc maps a github event to an http.HandlerFunc.
func (r *Router) HandleFunc(event string, fn func(http.ResponseWriter, *http.Request)) {
	r.Handle(event, http.HandlerFunc(fn))
}

// Handler returns the http.Handler to use for the given request. It will
// always return a non nill Handler.
func (r *Router) Handler(req *http.Request) http.Handler {
	event := req.Header.Get(HeaderEvent)

	if h, ok := r.routes[event]; ok {
		return h
	}

	return r.notFoundHandler()
}

// ServeHTTP implements the http.Handler interface to route a request to an
// appropriate http.Handler, based on the value of the X-GitHub-Event header.
func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	h := r.Handler(req)
	h.ServeHTTP(w, req)
}

func (r *Router) notFoundHandler() http.Handler {
	if r.NotFoundHandler == nil {
		return DefaultNotFoundHandler
	}

	return r.NotFoundHandler
}

// routes maps a github event to an http.Handler.
type routes map[string]http.Handler

// SecretHandler is an http.Handler that will verify the authenticity of the
// request.
type SecretHandler struct {
	// The secret to use to verify the request.
	Secret string

	// SetHeader controls what happens when the X-Hub-Signature header value does
	// not match the calculated signature. Setting this value to true will set
	// the X-Calculated-Signature header in the response.
	//
	// It's recommended that you only enable this for debugging purposes.
	SetHeader bool

	// Handler is the http.Handler that will be called if the request is
	// authorized.
	Handler http.Handler

	// Unauthorized is the http.Handler that will be called if the request
	// is not authorized.
	Unauthorized http.Handler
}

// Authorize wraps an http.Handler to verify the authenticity of the request
// using the provided secret.
func Authorize(h http.Handler, secret string) *SecretHandler {
	return &SecretHandler{Handler: h, Secret: secret}
}

// ServeHTTP implements the http.Handler interface.
func (h *SecretHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	if h.Unauthorized == nil {
		h.Unauthorized = DefaultUnauthorizedHandler
	}

	// If a secret is provided, ensure that the request is verified.
	if h.Secret != "" {
		sig, ok := IsAuthorized(req, h.Secret)

		if h.SetHeader {
			w.Header().Set("X-Calculated-Signature", sig)
		}

		if !ok {
			h.Unauthorized.ServeHTTP(w, req)
			return
		}
	}

	h.Handler.ServeHTTP(w, req)
}

// Signature calculates the SHA1 HMAC signature of body, signed by the secret.
//
// When github-services makes a POST request, it includes a SHA1 HMAC signature
// of the request body, signed with the secret provided in the webhook configuration.
// See http://goo.gl/Oe4WwR.
func Signature(body []byte, secret string) string {
	mac := hmac.New(sha1.New, []byte(secret))
	mac.Write(body)
	return fmt.Sprintf("%x", mac.Sum(nil))
}

// IsAuthorized checks that the calculated signature for the request matches the provided signature in
// the request headers. Returns the calculated signature, and a boolean value
// indicating whether or not the calculated signature matches the
// X-Hub-Signature value.
func IsAuthorized(r *http.Request, secret string) (string, bool) {
	raw, er := ioutil.ReadAll(r.Body)
	if er != nil {
		return "", false
	}

	// Since we're reading the request from the network, r.Body will return EOF if any
	// downstream http.Handler attempts to read it. We set it to a new io.ReadCloser
	// that will read from the bytes in memory.
	r.Body = ioutil.NopCloser(bytes.NewReader(raw))

	sig := "sha1=" + Signature(raw, secret)
	return sig, compareStrings(r.Header.Get(HeaderSignature), sig)
}

// compareStrings compares two strings in constant time.
func compareStrings(a, b string) bool {
	if len(a) != len(b) {
		return false
	}

	return subtle.ConstantTimeCompare([]byte(a), []byte(b)) == 1
}

// unauthorized is the default UnauthorizedHandler.
func unauthorized(w http.ResponseWriter, r *http.Request) {
	http.Error(w, "The provided signature in the "+HeaderSignature+" header does not match.", 403)
}
<commit_msg>Implement ServeHTTPContext interface.<commit_after>// Copyright 2014 Eric Holmes.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package hookshot is a router that de-multiplexes and authorizes github webhooks.
package hookshot

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha1"
	"crypto/subtle"
	"fmt"
	"io/ioutil"
	"net/http"

	"golang.org/x/net/context"
)

const (
	// HeaderEvent is the name of the header that contains the type of event.
	HeaderEvent = "X-GitHub-Event"

	// HeaderSignature is the name of the header that contains the signature.
	HeaderSignature = "X-Hub-Signature"
)

var (
	// DefaultNotFoundHandler is the default NotFoundHandler for a Router instance.
	DefaultNotFoundHandler = http.HandlerFunc(http.NotFound)

	// DefaultUnauthorizedHandler is the default UnauthorizedHandler for a Router
	// instance, which responds with a 403 status and a plain text body.
	DefaultUnauthorizedHandler = http.HandlerFunc(unauthorized)
)

// Router demultiplexes github hooks.
type Router struct {
	// NotFoundHandler is called when a handler is not found for a given GitHub event.
	// The nil value for NotFoundHandler
	NotFoundHandler http.Handler

	routes routes
}

// NewRouter returns a new Router.
func NewRouter() *Router {
	return &Router{
		routes: make(routes),
	}
}

// Handle maps a github event to an http.Handler.
func (r *Router) Handle(event string, h http.Handler) {
	r.routes[event] = h
}

// HandleFunc maps a github event to an http.HandlerFunc.
func (r *Router) HandleFunc(event string, fn func(http.ResponseWriter, *http.Request)) {
	r.Handle(event, http.HandlerFunc(fn))
}

// Handler returns the http.Handler to use for the given request. It will
// always return a non nill Handler.
func (r *Router) Handler(req *http.Request) http.Handler {
	event := req.Header.Get(HeaderEvent)

	if h, ok := r.routes[event]; ok {
		return h
	}

	return r.notFoundHandler()
}

// ServeHTTP implements the http.Handler interface to route a request to an
// appropriate http.Handler, based on the value of the X-GitHub-Event header.
func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	r.ServeHTTPContext(context.Background(), w, req)
}

// contextHandler is an http handler that can propagate a context.Context.
type contextHandler interface {
	ServeHTTPContext(context.Context, http.ResponseWriter, *http.Request) error
}

// ServeHTTPContext implements the httpx.Handler interface.
func (r *Router) ServeHTTPContext(ctx context.Context, w http.ResponseWriter, req *http.Request) error {
	h := r.Handler(req)

	if h, ok := h.(contextHandler); ok {
		return h.ServeHTTPContext(ctx, w, req)
	}

	h.ServeHTTP(w, req)
	return nil
}

func (r *Router) notFoundHandler() http.Handler {
	if r.NotFoundHandler == nil {
		return DefaultNotFoundHandler
	}

	return r.NotFoundHandler
}

// routes maps a github event to an http.Handler.
type routes map[string]http.Handler

// SecretHandler is an http.Handler that will verify the authenticity of the
// request.
type SecretHandler struct {
	// The secret to use to verify the request.
	Secret string

	// SetHeader controls what happens when the X-Hub-Signature header value does
	// not match the calculated signature. Setting this value to true will set
	// the X-Calculated-Signature header in the response.
	//
	// It's recommended that you only enable this for debugging purposes.
	SetHeader bool

	// Handler is the http.Handler that will be called if the request is
	// authorized.
	Handler http.Handler

	// Unauthorized is the http.Handler that will be called if the request
	// is not authorized.
	Unauthorized http.Handler
}

// Authorize wraps an http.Handler to verify the authenticity of the request
// using the provided secret.
func Authorize(h http.Handler, secret string) *SecretHandler {
	return &SecretHandler{Handler: h, Secret: secret}
}

// ServeHTTP implements the http.Handler interface.
func (h *SecretHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	if h.Unauthorized == nil {
		h.Unauthorized = DefaultUnauthorizedHandler
	}

	// If a secret is provided, ensure that the request is verified.
	if h.Secret != "" {
		sig, ok := IsAuthorized(req, h.Secret)

		if h.SetHeader {
			w.Header().Set("X-Calculated-Signature", sig)
		}

		if !ok {
			h.Unauthorized.ServeHTTP(w, req)
			return
		}
	}

	h.Handler.ServeHTTP(w, req)
}

// Signature calculates the SHA1 HMAC signature of body, signed by the secret.
//
// When github-services makes a POST request, it includes a SHA1 HMAC signature
// of the request body, signed with the secret provided in the webhook configuration.
// See http://goo.gl/Oe4WwR.
func Signature(body []byte, secret string) string {
	mac := hmac.New(sha1.New, []byte(secret))
	mac.Write(body)
	return fmt.Sprintf("%x", mac.Sum(nil))
}

// IsAuthorized checks that the calculated signature for the request matches the provided signature in
// the request headers. Returns the calculated signature, and a boolean value
// indicating whether or not the calculated signature matches the
// X-Hub-Signature value.
func IsAuthorized(r *http.Request, secret string) (string, bool) {
	raw, er := ioutil.ReadAll(r.Body)
	if er != nil {
		return "", false
	}

	// Since we're reading the request from the network, r.Body will return EOF if any
	// downstream http.Handler attempts to read it. We set it to a new io.ReadCloser
	// that will read from the bytes in memory.
	r.Body = ioutil.NopCloser(bytes.NewReader(raw))

	sig := "sha1=" + Signature(raw, secret)
	return sig, compareStrings(r.Header.Get(HeaderSignature), sig)
}

// compareStrings compares two strings in constant time.
func compareStrings(a, b string) bool {
	if len(a) != len(b) {
		return false
	}

	return subtle.ConstantTimeCompare([]byte(a), []byte(b)) == 1
}

// unauthorized is the default UnauthorizedHandler.
func unauthorized(w http.ResponseWriter, r *http.Request) {
	http.Error(w, "The provided signature in the "+HeaderSignature+" header does not match.", 403)
}
<|endoftext|>


<commit_before>package htm

import (
	"fmt"
	"testing"

	"azul3d.org/lmath.v1"
)

func TestNewTree(t *testing.T) {
	tree := NewTree("S0", nil, 0, 1, 2)
	if tree.Name != "S0" {
		t.Fatal("Tree name not initialized.")
	}
	if len(tree.Indices) != 3 {
		t.Fatal("Tree indices not of correct length.")
	}
	if tree.Indices[0] != 0 && tree.Indices[1] != 1 && tree.Indices[2] != 2 {
		t.Fatal("Tree indicies not initialized.")
	}
}

func TestTreeSubDivide(t *testing.T) {
	verts := []lmath.Vec3{
		{1, 0, 0},
		{0, 1, 0},
		{0, 0, 1},
	}
	l1 := len(verts)
	tree := NewTree("S0", &verts, 0, 1, 2)
	tree.SubDivide(2)
	if len(verts) == l1 {
		t.Fatal("Vertices not updated.")
	}
	if len(verts) != 6 {
		t.Fatal("Vertices not of correct length.")
	}

	cmp := func(a float64, b string) bool { return fmt.Sprintf("%.3f", a) == b }

	if !cmp(verts[3].X, "0.000") || !cmp(verts[3].Y, "0.707") || !cmp(verts[3].Z, "0.707") {
		t.Fatal("First subdivision of tree not correct.")
	}
	if !cmp(verts[4].X, "0.707") || !cmp(verts[4].Y, "0.000") || !cmp(verts[4].Z, "0.707") {
		t.Fatal("Second subdivision of tree not correct.")
	}
	if !cmp(verts[5].X, "0.707") || !cmp(verts[5].Y, "0.707") || !cmp(verts[5].Z, "0.000") {
		t.Fatal("Third subdivision of tree not correct.")
	}
	if tree.Indices[0] != 0 || tree.Indices[1] != 1 || tree.Indices[2] != 2 {
		t.Fatal("Tree indices not initialized.")
	}
}

func TestNewHTM(t *testing.T) {
	h := New()
	if h.S0 == nil || h.S1 == nil || h.S2 == nil || h.S3 == nil {
		t.Fatal("Southern hemisphere not initialized.")
	}
	if h.N0 == nil || h.N1 == nil || h.N2 == nil || h.N3 == nil {
		t.Fatal("Northern hemisphere not initialized.")
	}
	if len(*h.Vertices) == 0 {
		t.Fatal("HTM vertices not initialized.")
	}
}

func TestHTMSubDivide2(t *testing.T) {
	h := New()
	h.SubDivide(2)
	if len(*h.Vertices) != 30 {
		t.Fatalf("Expected 30 vertices but got %v.", len(*h.Vertices))
	}
}

func TestHTMIndices(t *testing.T) {
	h := New()
	h.SubDivide(2)
	n := h.Indices()
	if len(n) != 96 {
		t.Fatalf("Expected 96 indices but got %v.", len(n))
	}
}

func TestTexCoords(t *testing.T) {
	h := New()
	h.SubDivide(2)
	tc := h.TexCoords()
	if (len(tc) % 2) != 0 {
		t.Fatal("Uneven UV mapping.")
	}
}

func TestLookupByCart(t *testing.T) {
	h := New()
	h.SubDivide(7)
	tr, err := h.LookupByCart(lmath.Vec3{0.9, 0.1, 0.1})
	if err != nil {
		t.Fatal(err)
	}
	if tr == nil {
		t.Fatal("Tree should not be nil.")
	}
}

func testNoDups(t *testing.T) {
	h := New()
	h.SubDivide(5)
	for _, v1 := range *h.Vertices {
		for _, v2 := range *h.Vertices {
			if v1.Equals(v2) {
				t.Fail()
			}
		}
	}
}

func BenchmarkL5(b *testing.B) {
	for n := 0; n < b.N; n++ {
		h := New()
		h.SubDivide(5)
	}
}

func BenchmarkL7(b *testing.B) {
	for n := 0; n < b.N; n++ {
		h := New()
		h.SubDivide(7)
	}
}

func BenchmarkL9(b *testing.B) {
	for n := 0; n < b.N; n++ {
		h := New()
		h.SubDivide(9)
	}
}

func BenchmarkL11(b *testing.B) {
	for n := 0; n < b.N; n++ {
		h := New()
		h.SubDivide(11)
	}
}

func BenchmarkLookupByCartL7(b *testing.B) {
	b.StopTimer()
	h := New()
	h.SubDivide(7)
	b.StartTimer()
	for n := 0; n < b.N; n++ {
		_, err := h.LookupByCart(lmath.Vec3{0.9, 0.1, 0.1})
		if err != nil {
			b.Fatal(err)
		}
	}
}
<commit_msg>fix tests for unexported fields<commit_after>package htm

import (
	"fmt"
	"testing"

	"azul3d.org/lmath.v1"
)

func TestNewTree(t *testing.T) {
	tree := NewTree("S0", nil, 0, 1, 2)
	if tree.Name != "S0" {
		t.Fatal("Tree name not initialized.")
	}
	if len(tree.indices) != 3 {
		t.Fatal("Tree indices not of correct length.")
	}
	if tree.indices[0] != 0 && tree.indices[1] != 1 && tree.indices[2] != 2 {
		t.Fatal("Tree indicies not initialized.")
	}
}

func TestTreeSubDivide(t *testing.T) {
	verts := []lmath.Vec3{
		{1, 0, 0},
		{0, 1, 0},
		{0, 0, 1},
	}
	l1 := len(verts)
	tree := NewTree("S0", &verts, 0, 1, 2)
	tree.SubDivide(2)
	if len(verts) == l1 {
		t.Fatal("Vertices not updated.")
	}
	if len(verts) != 6 {
		t.Fatal("Vertices not of correct length.")
	}

	cmp := func(a float64, b string) bool { return fmt.Sprintf("%.3f", a) == b }

	if !cmp(verts[3].X, "0.000") || !cmp(verts[3].Y, "0.707") || !cmp(verts[3].Z, "0.707") {
		t.Fatal("First subdivision of tree not correct.")
	}
	if !cmp(verts[4].X, "0.707") || !cmp(verts[4].Y, "0.000") || !cmp(verts[4].Z, "0.707") {
		t.Fatal("Second subdivision of tree not correct.")
	}
	if !cmp(verts[5].X, "0.707") || !cmp(verts[5].Y, "0.707") || !cmp(verts[5].Z, "0.000") {
		t.Fatal("Third subdivision of tree not correct.")
	}
	if tree.indices[0] != 0 || tree.indices[1] != 1 || tree.indices[2] != 2 {
		t.Fatal("Tree indices not initialized.")
	}
}

func TestNewHTM(t *testing.T) {
	h := New()
	if h.S0 == nil || h.S1 == nil || h.S2 == nil || h.S3 == nil {
		t.Fatal("Southern hemisphere not initialized.")
	}
	if h.N0 == nil || h.N1 == nil || h.N2 == nil || h.N3 == nil {
		t.Fatal("Northern hemisphere not initialized.")
	}
	if len(*h.Vertices) == 0 {
		t.Fatal("HTM vertices not initialized.")
	}
}

func TestHTMSubDivide2(t *testing.T) {
	h := New()
	h.SubDivide(2)
	if len(*h.Vertices) != 30 {
		t.Fatalf("Expected 30 vertices but got %v.", len(*h.Vertices))
	}
}

func TestHTMIndices(t *testing.T) {
	h := New()
	h.SubDivide(2)
	n := h.Indices()
	if len(n) != 96 {
		t.Fatalf("Expected 96 indices but got %v.", len(n))
	}
}

func TestTexCoords(t *testing.T) {
	h := New()
	h.SubDivide(2)
	tc := h.TexCoords()
	if (len(tc) % 2) != 0 {
		t.Fatal("Uneven UV mapping.")
	}
}

func TestLookupByCart(t *testing.T) {
	h := New()
	h.SubDivide(7)
	tr, err := h.LookupByCart(lmath.Vec3{0.9, 0.1, 0.1})
	if err != nil {
		t.Fatal(err)
	}
	if tr == nil {
		t.Fatal("Tree should not be nil.")
	}
}

func testNoDups(t *testing.T) {
	h := New()
	h.SubDivide(5)
	for _, v1 := range *h.Vertices {
		for _, v2 := range *h.Vertices {
			if v1.Equals(v2) {
				t.Fail()
			}
		}
	}
}

func BenchmarkL5(b *testing.B) {
	for n := 0; n < b.N; n++ {
		h := New()
		h.SubDivide(5)
	}
}

func BenchmarkL7(b *testing.B) {
	for n := 0; n < b.N; n++ {
		h := New()
		h.SubDivide(7)
	}
}

func BenchmarkL9(b *testing.B) {
	for n := 0; n < b.N; n++ {
		h := New()
		h.SubDivide(9)
	}
}

func BenchmarkL11(b *testing.B) {
	for n := 0; n < b.N; n++ {
		h := New()
		h.SubDivide(11)
	}
}

func BenchmarkLookupByCartL7(b *testing.B) {
	b.StopTimer()
	h := New()
	h.SubDivide(7)
	b.StartTimer()
	for n := 0; n < b.N; n++ {
		_, err := h.LookupByCart(lmath.Vec3{0.9, 0.1, 0.1})
		if err != nil {
			b.Fatal(err)
		}
	}
}
<|endoftext|>


<commit_before>package chanbuff

import "testing"

type ShardTest struct {
	NumberData int
	DataSize   int
	Expected   int
}

var tests = []ShardTest{
	ShardTest{10, 100, 1},
	ShardTest{800, 100, 2},
	ShardTest{90, 10000, 2},
	ShardTest{90, 10000, 2},
	ShardTest{8100, 100, 17},
}

func TestMakeRequestsLock(t *testing.T) {

	for _, test := range tests {

		data := genData(test.NumberData, test.DataSize)

		result := MakeRequestsLock(data)

		if len(result) != test.Expected {
			t.Error("For", test.NumberData,
				"Expected", test.Expected,
				"Got", len(result),
				"Size", test.DataSize)
		}

	}
}

func genData(amount int, size int) []Data {
	var data []Data

	for i := 0; i <= amount; i++ {
		bytes := make([]byte, size)
		datum := Data{bytes}
		data = append(data, datum)
	}

	return data

}
func BenchmarkChannel(b *testing.B) {
	data := genData(10000, 10000)

	for i := 0; i < b.N; i++ {

		SendDataChannel(data)
	}
}
func BenchmarkLock(b *testing.B) {
	data := genData(10000, 10000)

	for i := 0; i < b.N; i++ {

		SendDataLock(data)
	}
}
<commit_msg>Benchmarks too large<commit_after>package chanbuff

import "testing"

type ShardTest struct {
	NumberData int
	DataSize   int
	Expected   int
}

var tests = []ShardTest{
	ShardTest{10, 100, 1},
	ShardTest{800, 100, 2},
	ShardTest{90, 10000, 2},
	ShardTest{90, 10000, 2},
	ShardTest{8100, 100, 17},
}

func TestMakeRequestsLock(t *testing.T) {

	for _, test := range tests {

		data := genData(test.NumberData, test.DataSize)

		result := MakeRequestsLock(data)

		if len(result) != test.Expected {
			t.Error("For", test.NumberData,
				"Expected", test.Expected,
				"Got", len(result),
				"Size", test.DataSize)
		}

	}
}

func genData(amount int, size int) []Data {
	var data []Data

	for i := 0; i <= amount; i++ {
		bytes := make([]byte, size)
		datum := Data{bytes}
		data = append(data, datum)
	}

	return data

}
func BenchmarkChannel(b *testing.B) {
	data := genData(100, 10000)

	for i := 0; i < b.N; i++ {

		SendDataChannel(data)
	}
}
func BenchmarkLock(b *testing.B) {
	data := genData(100, 10000)

	for i := 0; i < b.N; i++ {

		SendDataLock(data)
	}
}
<|endoftext|>


<commit_before>package consul

import (
	"fmt"
	"sort"
	"strings"
	"sync"
	"time"

	"github.com/hashicorp/consul/consul/structs"
	"github.com/hashicorp/serf/coordinate"
)

// Coordinate manages queries and updates for network coordinates.
type Coordinate struct {
	// srv is a pointer back to the server.
	srv *Server

	// updates holds pending coordinate updates for the given nodes.
	updates map[string]*coordinate.Coordinate

	// updatesLock synchronizes access to the updates map.
	updatesLock sync.Mutex
}

// NewCoordinate returns a new Coordinate endpoint.
func NewCoordinate(srv *Server) *Coordinate {
	c := &Coordinate{
		srv:     srv,
		updates: make(map[string]*coordinate.Coordinate),
	}

	go c.batchUpdate()
	return c
}

// batchUpdate is a long-running routine that flushes pending coordinates to the
// Raft log in batches.
func (c *Coordinate) batchUpdate() {
	for {
		select {
		case <-time.After(c.srv.config.CoordinateUpdatePeriod):
			if err := c.batchApplyUpdates(); err != nil {
				c.srv.logger.Printf("[ERR] consul.coordinate: Batch update failed: %v", err)
			}
		case <-c.srv.shutdownCh:
			return
		}
	}
}

// batchApplyUpdates applies all pending updates to the Raft log in a series of
// batches.
func (c *Coordinate) batchApplyUpdates() error {
	// Grab the pending updates and release the lock so we can still handle
	// incoming messages.
	c.updatesLock.Lock()
	pending := c.updates
	c.updates = make(map[string]*coordinate.Coordinate)
	c.updatesLock.Unlock()

	// Enforce the rate limit.
	limit := c.srv.config.CoordinateUpdateBatchSize * c.srv.config.CoordinateUpdateMaxBatches
	size := len(pending)
	if size > limit {
		c.srv.logger.Printf("[WARN] consul.coordinate: Discarded %d coordinate updates", size-limit)
		size = limit
	}

	// Transform the map into a slice that we can feed to the Raft log in
	// batches.
	i := 0
	updates := make(structs.Coordinates, size)
	for node, coord := range pending {
		if !(i < size) {
			break
		}

		updates[i] = &structs.Coordinate{node, coord}
		i++
	}

	// Apply the updates to the Raft log in batches.
	for start := 0; start < size; start += c.srv.config.CoordinateUpdateBatchSize {
		end := start + c.srv.config.CoordinateUpdateBatchSize
		if end > size {
			end = size
		}

		// We set the "safe to ignore" flag on this update type so old
		// servers don't crash if they see one of these.
		t := structs.CoordinateBatchUpdateType | structs.IgnoreUnknownTypeFlag

		slice := updates[start:end]
		if _, err := c.srv.raftApply(t, slice); err != nil {
			return err
		}
	}
	return nil
}

// Update inserts or updates the LAN coordinate of a node.
func (c *Coordinate) Update(args *structs.CoordinateUpdateRequest, reply *struct{}) (err error) {
	if done, err := c.srv.forward("Coordinate.Update", args, args, reply); done {
		return err
	}

	// Since this is a coordinate coming from some place else we harden this
	// and look for dimensionality problems proactively.
	coord, err := c.srv.serfLAN.GetCoordinate()
	if err != nil {
		return err
	}
	if !coord.IsCompatibleWith(args.Coord) {
		return fmt.Errorf("rejected bad coordinate: %v", args.Coord)
	}

	// Add the coordinate to the map of pending updates.
	c.updatesLock.Lock()
	c.updates[args.Node] = args.Coord
	c.updatesLock.Unlock()
	return nil
}

// ListDatacenters returns the list of datacenters and their respective nodes
// and the raw coordinates of those nodes (if no coordinates are available for
// any of the nodes, the node list may be empty).
func (c *Coordinate) ListDatacenters(args *struct{}, reply *[]structs.DatacenterMap) error {
	c.srv.remoteLock.RLock()
	defer c.srv.remoteLock.RUnlock()

	// Build up a map of all the DCs, sort it first since getDatacenterMaps
	// will preserve the order of this list in the output.
	dcs := make([]string, 0, len(c.srv.remoteConsuls))
	for dc := range c.srv.remoteConsuls {
		dcs = append(dcs, dc)
	}
	sort.Strings(dcs)
	maps := c.srv.getDatacenterMaps(dcs)

	// Strip the datacenter suffixes from all the node names.
	for i := range maps {
		suffix := fmt.Sprintf(".%s", maps[i].Datacenter)
		for j := range maps[i].Coordinates {
			node := maps[i].Coordinates[j].Node
			maps[i].Coordinates[j].Node = strings.TrimSuffix(node, suffix)
		}
	}

	*reply = maps
	return nil
}

// ListNodes returns the list of nodes with their raw network coordinates (if no
// coordinates are available for a node it won't appear in this list).
func (c *Coordinate) ListNodes(args *structs.DCSpecificRequest, reply *structs.IndexedCoordinates) error {
	if done, err := c.srv.forward("Coordinate.ListNodes", args, args, reply); done {
		return err
	}

	state := c.srv.fsm.State()
	return c.srv.blockingRPC(&args.QueryOptions,
		&reply.QueryMeta,
		state.GetQueryWatch("Coordinates"),
		func() error {
			index, coords, err := state.Coordinates()
			if err != nil {
				return err
			}

			reply.Index, reply.Coordinates = index, coords
			return nil
		})
}
<commit_msg>Changes batch update failure to a WARN since it's nbd.<commit_after>package consul

import (
	"fmt"
	"sort"
	"strings"
	"sync"
	"time"

	"github.com/hashicorp/consul/consul/structs"
	"github.com/hashicorp/serf/coordinate"
)

// Coordinate manages queries and updates for network coordinates.
type Coordinate struct {
	// srv is a pointer back to the server.
	srv *Server

	// updates holds pending coordinate updates for the given nodes.
	updates map[string]*coordinate.Coordinate

	// updatesLock synchronizes access to the updates map.
	updatesLock sync.Mutex
}

// NewCoordinate returns a new Coordinate endpoint.
func NewCoordinate(srv *Server) *Coordinate {
	c := &Coordinate{
		srv:     srv,
		updates: make(map[string]*coordinate.Coordinate),
	}

	go c.batchUpdate()
	return c
}

// batchUpdate is a long-running routine that flushes pending coordinates to the
// Raft log in batches.
func (c *Coordinate) batchUpdate() {
	for {
		select {
		case <-time.After(c.srv.config.CoordinateUpdatePeriod):
			if err := c.batchApplyUpdates(); err != nil {
				c.srv.logger.Printf("[WARN] consul.coordinate: Batch update failed: %v", err)
			}
		case <-c.srv.shutdownCh:
			return
		}
	}
}

// batchApplyUpdates applies all pending updates to the Raft log in a series of
// batches.
func (c *Coordinate) batchApplyUpdates() error {
	// Grab the pending updates and release the lock so we can still handle
	// incoming messages.
	c.updatesLock.Lock()
	pending := c.updates
	c.updates = make(map[string]*coordinate.Coordinate)
	c.updatesLock.Unlock()

	// Enforce the rate limit.
	limit := c.srv.config.CoordinateUpdateBatchSize * c.srv.config.CoordinateUpdateMaxBatches
	size := len(pending)
	if size > limit {
		c.srv.logger.Printf("[WARN] consul.coordinate: Discarded %d coordinate updates", size-limit)
		size = limit
	}

	// Transform the map into a slice that we can feed to the Raft log in
	// batches.
	i := 0
	updates := make(structs.Coordinates, size)
	for node, coord := range pending {
		if !(i < size) {
			break
		}

		updates[i] = &structs.Coordinate{node, coord}
		i++
	}

	// Apply the updates to the Raft log in batches.
	for start := 0; start < size; start += c.srv.config.CoordinateUpdateBatchSize {
		end := start + c.srv.config.CoordinateUpdateBatchSize
		if end > size {
			end = size
		}

		// We set the "safe to ignore" flag on this update type so old
		// servers don't crash if they see one of these.
		t := structs.CoordinateBatchUpdateType | structs.IgnoreUnknownTypeFlag

		slice := updates[start:end]
		if _, err := c.srv.raftApply(t, slice); err != nil {
			return err
		}
	}
	return nil
}

// Update inserts or updates the LAN coordinate of a node.
func (c *Coordinate) Update(args *structs.CoordinateUpdateRequest, reply *struct{}) (err error) {
	if done, err := c.srv.forward("Coordinate.Update", args, args, reply); done {
		return err
	}

	// Since this is a coordinate coming from some place else we harden this
	// and look for dimensionality problems proactively.
	coord, err := c.srv.serfLAN.GetCoordinate()
	if err != nil {
		return err
	}
	if !coord.IsCompatibleWith(args.Coord) {
		return fmt.Errorf("rejected bad coordinate: %v", args.Coord)
	}

	// Add the coordinate to the map of pending updates.
	c.updatesLock.Lock()
	c.updates[args.Node] = args.Coord
	c.updatesLock.Unlock()
	return nil
}

// ListDatacenters returns the list of datacenters and their respective nodes
// and the raw coordinates of those nodes (if no coordinates are available for
// any of the nodes, the node list may be empty).
func (c *Coordinate) ListDatacenters(args *struct{}, reply *[]structs.DatacenterMap) error {
	c.srv.remoteLock.RLock()
	defer c.srv.remoteLock.RUnlock()

	// Build up a map of all the DCs, sort it first since getDatacenterMaps
	// will preserve the order of this list in the output.
	dcs := make([]string, 0, len(c.srv.remoteConsuls))
	for dc := range c.srv.remoteConsuls {
		dcs = append(dcs, dc)
	}
	sort.Strings(dcs)
	maps := c.srv.getDatacenterMaps(dcs)

	// Strip the datacenter suffixes from all the node names.
	for i := range maps {
		suffix := fmt.Sprintf(".%s", maps[i].Datacenter)
		for j := range maps[i].Coordinates {
			node := maps[i].Coordinates[j].Node
			maps[i].Coordinates[j].Node = strings.TrimSuffix(node, suffix)
		}
	}

	*reply = maps
	return nil
}

// ListNodes returns the list of nodes with their raw network coordinates (if no
// coordinates are available for a node it won't appear in this list).
func (c *Coordinate) ListNodes(args *structs.DCSpecificRequest, reply *structs.IndexedCoordinates) error {
	if done, err := c.srv.forward("Coordinate.ListNodes", args, args, reply); done {
		return err
	}

	state := c.srv.fsm.State()
	return c.srv.blockingRPC(&args.QueryOptions,
		&reply.QueryMeta,
		state.GetQueryWatch("Coordinates"),
		func() error {
			index, coords, err := state.Coordinates()
			if err != nil {
				return err
			}

			reply.Index, reply.Coordinates = index, coords
			return nil
		})
}
<|endoftext|>


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

package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"sync"
	"time"

	"github.com/nats-io/go-nats"
	"github.com/nats-io/go-nats/bench"
)

// Some sane defaults
const (
	DefaultNumMsgs     = 100000
	DefaultNumPubs     = 1
	DefaultNumSubs     = 0
	DefaultMessageSize = 128
)

func usage() {
	log.Printf("Usage: nats-bench [-s server (%s)] [--tls] [-np NUM_PUBLISHERS] [-ns NUM_SUBSCRIBERS] [-n NUM_MSGS] [-ms MESSAGE_SIZE] [-csv csvfile] <subject>\n", nats.DefaultURL)
	flag.PrintDefaults()
}

var benchmark *bench.Benchmark

func main() {
	var urls = flag.String("s", nats.DefaultURL, "The nats server URLs (separated by comma)")
	var tls = flag.Bool("tls", false, "Use TLS Secure Connection")
	var numPubs = flag.Int("np", DefaultNumPubs, "Number of Concurrent Publishers")
	var numSubs = flag.Int("ns", DefaultNumSubs, "Number of Concurrent Subscribers")
	var numMsgs = flag.Int("n", DefaultNumMsgs, "Number of Messages to Publish")
	var msgSize = flag.Int("ms", DefaultMessageSize, "Size of the message.")
	var csvFile = flag.String("csv", "", "Save bench data to csv file")
	var userCreds = flag.String("creds", "", "User Credentials File")

	log.SetFlags(0)
	flag.Usage = usage
	flag.Parse()

	args := flag.Args()
	if len(args) != 1 {
		usage()
	}

	if *numMsgs <= 0 {
		log.Fatal("Number of messages should be greater than zero.")
	}

	// Connect Options.
	opts := []nats.Option{nats.Name("NATS Benchmark")}

	// Use UserCredentials
	if *userCreds != "" {
		opts = append(opts, nats.UserCredentials(*userCreds))
	}

	// Use TLS specfied
	if *tls {
		opts = append(opts, nats.Secure(nil))
	}

	benchmark = bench.NewBenchmark("NATS", *numSubs, *numPubs)

	var startwg sync.WaitGroup
	var donewg sync.WaitGroup

	donewg.Add(*numPubs + *numSubs)

	// Run Subscribers first
	startwg.Add(*numSubs)
	for i := 0; i < *numSubs; i++ {
		nc, err := nats.Connect(*urls, opts...)
		if err != nil {
			log.Fatalf("Can't connect: %v\n", err)
		}
		defer nc.Close()

		go runSubscriber(nc, &startwg, &donewg, *numMsgs, *msgSize)
	}
	startwg.Wait()

	// Now Publishers
	startwg.Add(*numPubs)
	pubCounts := bench.MsgsPerClient(*numMsgs, *numPubs)
	for i := 0; i < *numPubs; i++ {
		nc, err := nats.Connect(*urls, opts...)
		if err != nil {
			log.Fatalf("Can't connect: %v\n", err)
		}
		defer nc.Close()

		go runPublisher(nc, &startwg, &donewg, pubCounts[i], *msgSize)
	}

	log.Printf("Starting benchmark [msgs=%d, msgsize=%d, pubs=%d, subs=%d]\n", *numMsgs, *msgSize, *numPubs, *numSubs)

	startwg.Wait()
	donewg.Wait()

	benchmark.Close()

	fmt.Print(benchmark.Report())

	if len(*csvFile) > 0 {
		csv := benchmark.CSV()
		ioutil.WriteFile(*csvFile, []byte(csv), 0644)
		fmt.Printf("Saved metric data in csv file %s\n", *csvFile)
	}
}

func runPublisher(nc *nats.Conn, startwg, donewg *sync.WaitGroup, numMsgs int, msgSize int) {
	startwg.Done()

	args := flag.Args()
	subj := args[0]
	var msg []byte
	if msgSize > 0 {
		msg = make([]byte, msgSize)
	}

	start := time.Now()

	for i := 0; i < numMsgs; i++ {
		nc.Publish(subj, msg)
	}
	nc.Flush()
	benchmark.AddPubSample(bench.NewSample(numMsgs, msgSize, start, time.Now(), nc))

	donewg.Done()
}

func runSubscriber(nc *nats.Conn, startwg, donewg *sync.WaitGroup, numMsgs int, msgSize int) {
	args := flag.Args()
	subj := args[0]

	received := 0
	ch := make(chan time.Time, 2)
	sub, _ := nc.Subscribe(subj, func(msg *nats.Msg) {
		received++
		if received == 1 {
			ch <- time.Now()
		}
		if received >= numMsgs {
			ch <- time.Now()
		}
	})
	sub.SetPendingLimits(-1, -1)
	nc.Flush()
	startwg.Done()

	start := <-ch
	end := <-ch
	benchmark.AddSubSample(bench.NewSample(numMsgs, msgSize, start, end, nc))
	nc.Close()
	donewg.Done()
}
<commit_msg>Exit after usage<commit_after>// Copyright 2015-2018 The NATS Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"sync"
	"time"

	"github.com/nats-io/go-nats"
	"github.com/nats-io/go-nats/bench"
)

// Some sane defaults
const (
	DefaultNumMsgs     = 100000
	DefaultNumPubs     = 1
	DefaultNumSubs     = 0
	DefaultMessageSize = 128
)

func usage() {
	log.Printf("Usage: nats-bench [-s server (%s)] [--tls] [-np NUM_PUBLISHERS] [-ns NUM_SUBSCRIBERS] [-n NUM_MSGS] [-ms MESSAGE_SIZE] [-csv csvfile] <subject>\n", nats.DefaultURL)
	flag.PrintDefaults()
	os.Exit(1)
}

var benchmark *bench.Benchmark

func main() {
	var urls = flag.String("s", nats.DefaultURL, "The nats server URLs (separated by comma)")
	var tls = flag.Bool("tls", false, "Use TLS Secure Connection")
	var numPubs = flag.Int("np", DefaultNumPubs, "Number of Concurrent Publishers")
	var numSubs = flag.Int("ns", DefaultNumSubs, "Number of Concurrent Subscribers")
	var numMsgs = flag.Int("n", DefaultNumMsgs, "Number of Messages to Publish")
	var msgSize = flag.Int("ms", DefaultMessageSize, "Size of the message.")
	var csvFile = flag.String("csv", "", "Save bench data to csv file")
	var userCreds = flag.String("creds", "", "User Credentials File")

	log.SetFlags(0)
	flag.Usage = usage
	flag.Parse()

	args := flag.Args()
	if len(args) != 1 {
		usage()
	}

	if *numMsgs <= 0 {
		log.Fatal("Number of messages should be greater than zero.")
	}

	// Connect Options.
	opts := []nats.Option{nats.Name("NATS Benchmark")}

	// Use UserCredentials
	if *userCreds != "" {
		opts = append(opts, nats.UserCredentials(*userCreds))
	}

	// Use TLS specfied
	if *tls {
		opts = append(opts, nats.Secure(nil))
	}

	benchmark = bench.NewBenchmark("NATS", *numSubs, *numPubs)

	var startwg sync.WaitGroup
	var donewg sync.WaitGroup

	donewg.Add(*numPubs + *numSubs)

	// Run Subscribers first
	startwg.Add(*numSubs)
	for i := 0; i < *numSubs; i++ {
		nc, err := nats.Connect(*urls, opts...)
		if err != nil {
			log.Fatalf("Can't connect: %v\n", err)
		}
		defer nc.Close()

		go runSubscriber(nc, &startwg, &donewg, *numMsgs, *msgSize)
	}
	startwg.Wait()

	// Now Publishers
	startwg.Add(*numPubs)
	pubCounts := bench.MsgsPerClient(*numMsgs, *numPubs)
	for i := 0; i < *numPubs; i++ {
		nc, err := nats.Connect(*urls, opts...)
		if err != nil {
			log.Fatalf("Can't connect: %v\n", err)
		}
		defer nc.Close()

		go runPublisher(nc, &startwg, &donewg, pubCounts[i], *msgSize)
	}

	log.Printf("Starting benchmark [msgs=%d, msgsize=%d, pubs=%d, subs=%d]\n", *numMsgs, *msgSize, *numPubs, *numSubs)

	startwg.Wait()
	donewg.Wait()

	benchmark.Close()

	fmt.Print(benchmark.Report())

	if len(*csvFile) > 0 {
		csv := benchmark.CSV()
		ioutil.WriteFile(*csvFile, []byte(csv), 0644)
		fmt.Printf("Saved metric data in csv file %s\n", *csvFile)
	}
}

func runPublisher(nc *nats.Conn, startwg, donewg *sync.WaitGroup, numMsgs int, msgSize int) {
	startwg.Done()

	args := flag.Args()
	subj := args[0]
	var msg []byte
	if msgSize > 0 {
		msg = make([]byte, msgSize)
	}

	start := time.Now()

	for i := 0; i < numMsgs; i++ {
		nc.Publish(subj, msg)
	}
	nc.Flush()
	benchmark.AddPubSample(bench.NewSample(numMsgs, msgSize, start, time.Now(), nc))

	donewg.Done()
}

func runSubscriber(nc *nats.Conn, startwg, donewg *sync.WaitGroup, numMsgs int, msgSize int) {
	args := flag.Args()
	subj := args[0]

	received := 0
	ch := make(chan time.Time, 2)
	sub, _ := nc.Subscribe(subj, func(msg *nats.Msg) {
		received++
		if received == 1 {
			ch <- time.Now()
		}
		if received >= numMsgs {
			ch <- time.Now()
		}
	})
	sub.SetPendingLimits(-1, -1)
	nc.Flush()
	startwg.Done()

	start := <-ch
	end := <-ch
	benchmark.AddSubSample(bench.NewSample(numMsgs, msgSize, start, end, nc))
	nc.Close()
	donewg.Done()
}
<|endoftext|>


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

package templates

import (
	"fmt"
)

var masterTemplate = fmt.Sprintf(`<!DOCTYPE HTML>

	<meta charset="utf-8">
	<base href="{{ .BaseUrl }}">

	<title>{{.PageTitle}}</title>

	<link rel="schema.DC" href="http://purl.org/dc/terms/">
	<link rel="search" type="application/opensearchdescription+xml" title="{{.RepositoryName}}" href="/opensearch.xml" />

	<meta name="DC.date" content="{{.CreationDate}}">

	{{if .GeoLocation }}
	{{if .GeoLocation.Coordinates}}
	<meta name="geo.position" content="{{.GeoLocation.Coordinates}}">
	{{end}}

	{{if .GeoLocation.PlaceName}}
	<meta name="geo.placename" content="{{.GeoLocation.PlaceName}}">
	{{end}}
	{{end}}

	<link rel="canonical" href="{{.BaseUrl}}">
	<link rel="alternate" type="application/rss+xml" title="RSS" href="/rss.xml">
	<link rel="shortcut icon" href="/theme/favicon.ico">

	<link rel="stylesheet" href="/theme/deck.css" media="screen">
	<link rel="stylesheet" href="/theme/screen.css" media="screen">
	<link rel="stylesheet" href="/theme/print.css" media="print">
	<link rel="stylesheet" href="/theme/codehighlighting/highlight.css" media="screen, print">

{{ if .ToplevelNavigation}}

	{{range .ToplevelNavigation.Entries}}

		{{.Title}}

	{{end}}

{{end}}

	<form action="/search" method="GET">
		<input class="typeahead" type="text" name="q" placeholder="search" autocomplete="off">
		<input type="submit" style="visibility:hidden; position: fixed;"/>
	</form>

{{ if .BreadcrumbNavigation}}

	{{range .BreadcrumbNavigation.Entries}}

		{{.Title}}

	{{end}}

{{end}}

%s

	{{if .ItemNavigation}}

			{{if .ItemNavigation.Parent}}
			↑ Parent
			{{end}}

			{{if .ItemNavigation.Previous}}
			← Previous
			{{end}}

			{{if .ItemNavigation.Next}}
			Next →
			{{end}}

	{{end}}

	{{ if .Childs }}

Childs

	{{range .Childs}}

		{{.Title}}

{{.Description}}

	{{end}}

	{{end}}

	{{if .TagCloud}}

Tag Cloud

		{{range .TagCloud}}

			{{.Name}}

		{{end}}

	{{end}}

{{if or .PrintUrl .JsonUrl .RtfUrl}}

	{{if .PrintUrl}}
Print
{{end}}
	{{if .JsonUrl}}
JSON
{{end}}
	{{if .RtfUrl}}
Rich Text
{{end}}

{{end}}

Search

Tags

Sitemap

RSS Feed

`, ChildTemplatePlaceholder)
<commit_msg>Include a pagelevel hreflang tag in the default master template<commit_after>// Copyright 2014 Andreas Koch. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package templates

import (
	"fmt"
)

var masterTemplate = fmt.Sprintf(`<!DOCTYPE HTML>

	<meta charset="utf-8">
	<base href="{{ .BaseUrl }}">

	<title>{{.PageTitle}}</title>

	<link rel="schema.DC" href="http://purl.org/dc/terms/">
	<link rel="search" type="application/opensearchdescription+xml" title="{{.RepositoryName}}" href="/opensearch.xml" />

	<meta name="DC.date" content="{{.CreationDate}}">

	{{if .GeoLocation }}
	{{if .GeoLocation.Coordinates}}
	<meta name="geo.position" content="{{.GeoLocation.Coordinates}}">
	{{end}}

	{{if .GeoLocation.PlaceName}}
	<meta name="geo.placename" content="{{.GeoLocation.PlaceName}}">
	{{end}}
	{{end}}

	<link rel="canonical" href="{{.BaseUrl}}">
	<link rel="alternate" hreflang="{{.LanguageTag}}" href="{{.BaseUrl}}">
	<link rel="alternate" type="application/rss+xml" title="RSS" href="/rss.xml">
	<link rel="shortcut icon" href="/theme/favicon.ico">

	<link rel="stylesheet" href="/theme/deck.css" media="screen">
	<link rel="stylesheet" href="/theme/screen.css" media="screen">
	<link rel="stylesheet" href="/theme/print.css" media="print">
	<link rel="stylesheet" href="/theme/codehighlighting/highlight.css" media="screen, print">

{{ if .ToplevelNavigation}}

	{{range .ToplevelNavigation.Entries}}

		{{.Title}}

	{{end}}

{{end}}

	<form action="/search" method="GET">
		<input class="typeahead" type="text" name="q" placeholder="search" autocomplete="off">
		<input type="submit" style="visibility:hidden; position: fixed;"/>
	</form>

{{ if .BreadcrumbNavigation}}

	{{range .BreadcrumbNavigation.Entries}}

		{{.Title}}

	{{end}}

{{end}}

%s

	{{if .ItemNavigation}}

			{{if .ItemNavigation.Parent}}
			↑ Parent
			{{end}}

			{{if .ItemNavigation.Previous}}
			← Previous
			{{end}}

			{{if .ItemNavigation.Next}}
			Next →
			{{end}}

	{{end}}

	{{ if .Childs }}

Childs

	{{range .Childs}}

		{{.Title}}

{{.Description}}

	{{end}}

	{{end}}

	{{if .TagCloud}}

Tag Cloud

		{{range .TagCloud}}

			{{.Name}}

		{{end}}

	{{end}}

{{if or .PrintUrl .JsonUrl .RtfUrl}}

	{{if .PrintUrl}}
Print
{{end}}
	{{if .JsonUrl}}
JSON
{{end}}
	{{if .RtfUrl}}
Rich Text
{{end}}

{{end}}

Search

Tags

Sitemap

RSS Feed

`, ChildTemplatePlaceholder)
<|endoftext|>


<commit_before>package main

import (
	"testing"

	"github.com/stretchr/testify/assert"

	pubsub "google.golang.org/api/pubsub/v1"
)

const (
	workspace     = "/tmp/workspace"
	downloads_dir = workspace + "/downloads"
	uploads_dir   = workspace + "/uploads"
)

func NewBasicJob() *Job {
	return &Job{
		config: &CommandConfig{
			Template: []string{"./app.sh", "%{uploads_dir}", "%{download_files.0}"},
		},
		workspace:           workspace,
		downloads_dir:       downloads_dir,
		uploads_dir:         uploads_dir,
		localDownloadFiles:  []string{downloads_dir + "/bucket1/foo"},
		remoteDownloadFiles: []string{"gs://bucket1/foo"},
		message: &JobMessage{
			raw: &pubsub.ReceivedMessage{
				Message: &pubsub.PubsubMessage{
					Attributes: map[string]string{
						"array": "[100,200,300]",
						"map":   `{"foo":"A"}`,
					},
				},
			},
		},
	}
}

func TestJobBuildNormal(t *testing.T) {
	job := NewBasicJob()
	err := job.build()
	assert.NoError(t, err)
}

// Invalid index for the array "download_files"
func TestJobBuildWithInvalidIndexForArray(t *testing.T) {
	job := NewBasicJob()
	job.config.Template = []string{"./app.sh", "%{uploads_dir}", "%{download_files.1}"}
	err := job.build()

	if assert.Implements(t, (*RetryableError)(nil), err) {
		assert.False(t, (err.(RetryableError)).Retryable())
	}
}

// Key string is given for the array "download_files"
func TestJobBuildWithStringKeyForArray(t *testing.T) {
	job := NewBasicJob()
	job.config.Template = []string{"./app.sh", "%{uploads_dir}", "%{download_files.foo}"}
	err := job.build()
	if assert.Implements(t, (*RetryableError)(nil), err) {
		assert.False(t, (err.(RetryableError)).Retryable())
	}
}

// Invalid key given for the map "download_files"
func TestJobBuildWithInvalidKeyForMap(t *testing.T) {
	job := NewBasicJob()
	job.config.Template = []string{"./app.sh", "%{uploads_dir}", "%{download_files.baz}"}
	job.localDownloadFiles = map[string]interface{}{
		"foo": downloads_dir + "/bucket1/foo",
	}
	err := job.build()
	if assert.Implements(t, (*RetryableError)(nil), err) {
		assert.False(t, (err.(RetryableError)).Retryable())
	}
}

// Invalid index and invalid key for the array and map in attrs
func TestJobBuildWithInvalidIndexAndKeyInAttrs(t *testing.T) {
	job := NewBasicJob()
	job.config.Template = []string{"echo", "%{attrs.array.3}", "%{attrs.map.bar}"}
	err := job.build()
	if assert.Implements(t, (*RetryableError)(nil), err) {
		assert.False(t, (err.(RetryableError)).Retryable())
	}
	assert.Regexp(t, "Invalid index 3", err.Error())
	assert.Regexp(t, "Invalid key bar", err.Error())
}

// Invalid reference download_files in spite of no download_files given
func TestJobBuildWithInvalidDownloadFilesReference(t *testing.T) {
	job := NewBasicJob()
	job.config.Template = []string{"./app.sh", "%{uploads_dir}", "%{download_files}"}
	job.localDownloadFiles = nil
	err := job.build()
	if assert.Error(t, err) {
		if assert.Implements(t, (*RetryableError)(nil), err) {
			assert.False(t, (err.(RetryableError)).Retryable())
		}
		assert.Regexp(t, "No value found", err.Error())
		assert.Regexp(t, "download_files", err.Error())
	}
}
<commit_msg>:green_heart: Add test for Dryrun<commit_after>package main

import (
	"bytes"
	"os/exec"
	"testing"

	"github.com/stretchr/testify/assert"

	pubsub "google.golang.org/api/pubsub/v1"
)

const (
	workspace     = "/tmp/workspace"
	downloads_dir = workspace + "/downloads"
	uploads_dir   = workspace + "/uploads"
)

func NewBasicJob() *Job {
	return &Job{
		config: &CommandConfig{
			Template: []string{"./app.sh", "%{uploads_dir}", "%{download_files.0}"},
		},
		workspace:           workspace,
		downloads_dir:       downloads_dir,
		uploads_dir:         uploads_dir,
		localDownloadFiles:  []string{downloads_dir + "/bucket1/foo"},
		remoteDownloadFiles: []string{"gs://bucket1/foo"},
		message: &JobMessage{
			raw: &pubsub.ReceivedMessage{
				Message: &pubsub.PubsubMessage{
					Attributes: map[string]string{
						"array": "[100,200,300]",
						"map":   `{"foo":"A"}`,
					},
				},
			},
		},
	}
}

func TestJobBuildNormal(t *testing.T) {
	job := NewBasicJob()
	err := job.build()
	assert.NoError(t, err)
}

// Invalid index for the array "download_files"
func TestJobBuildWithInvalidIndexForArray(t *testing.T) {
	job := NewBasicJob()
	job.config.Template = []string{"./app.sh", "%{uploads_dir}", "%{download_files.1}"}
	err := job.build()

	if assert.Implements(t, (*RetryableError)(nil), err) {
		assert.False(t, (err.(RetryableError)).Retryable())
	}
}

// Key string is given for the array "download_files"
func TestJobBuildWithStringKeyForArray(t *testing.T) {
	job := NewBasicJob()
	job.config.Template = []string{"./app.sh", "%{uploads_dir}", "%{download_files.foo}"}
	err := job.build()
	if assert.Implements(t, (*RetryableError)(nil), err) {
		assert.False(t, (err.(RetryableError)).Retryable())
	}
}

// Invalid key given for the map "download_files"
func TestJobBuildWithInvalidKeyForMap(t *testing.T) {
	job := NewBasicJob()
	job.config.Template = []string{"./app.sh", "%{uploads_dir}", "%{download_files.baz}"}
	job.localDownloadFiles = map[string]interface{}{
		"foo": downloads_dir + "/bucket1/foo",
	}
	err := job.build()
	if assert.Implements(t, (*RetryableError)(nil), err) {
		assert.False(t, (err.(RetryableError)).Retryable())
	}
}

// Invalid index and invalid key for the array and map in attrs
func TestJobBuildWithInvalidIndexAndKeyInAttrs(t *testing.T) {
	job := NewBasicJob()
	job.config.Template = []string{"echo", "%{attrs.array.3}", "%{attrs.map.bar}"}
	err := job.build()
	if assert.Implements(t, (*RetryableError)(nil), err) {
		assert.False(t, (err.(RetryableError)).Retryable())
	}
	assert.Regexp(t, "Invalid index 3", err.Error())
	assert.Regexp(t, "Invalid key bar", err.Error())
}

// Invalid reference download_files in spite of no download_files given
func TestJobBuildWithInvalidDownloadFilesReference(t *testing.T) {
	job := NewBasicJob()
	job.config.Template = []string{"./app.sh", "%{uploads_dir}", "%{download_files}"}
	job.localDownloadFiles = nil
	err := job.build()
	if assert.Error(t, err) {
		if assert.Implements(t, (*RetryableError)(nil), err) {
			assert.False(t, (err.(RetryableError)).Retryable())
		}
		assert.Regexp(t, "No value found", err.Error())
		assert.Regexp(t, "download_files", err.Error())
	}
}

func TestJobExecuteWithDryrun(t *testing.T) {
	patterns := []struct {
		dryrun   bool
		expected string
	}{
		{dryrun: false, expected: "foo\n"},
		{dryrun: true, expected: ""},
	}
	for _, ptn := range patterns {
		b := new(bytes.Buffer)
		cmd := exec.Command("echo", "foo")
		cmd.Stdout = b
		cmd.Stderr = b
		job := &Job{
			cmd: cmd,
			config: &CommandConfig{
				Dryrun: ptn.dryrun,
			},
		}
		err := job.execute()
		assert.NoError(t, err)
		assert.Equal(t, ptn.expected, b.String())
	}
}
<|endoftext|>


<commit_before>package server

import (
	log "github.com/Sirupsen/logrus"
	"github.com/casey-chow/tigertrade/server/models"
	"github.com/getsentry/raven-go"
	"github.com/julienschmidt/httprouter"
	"net/http"
)

// ContactListing reads the listing from the params and sends notification and confirmation emails
// to the listing owner and current user
func ContactListing(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	contactPost(w, r, ps, models.ReadListingAsPost, models.ContactListingPoster, models.ContactListingReader)
}

// ContactSeek reads the seek from the params and sends notification and confirmation emails
// to the seek owner and current user
func ContactSeek(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	contactPost(w, r, ps, models.ReadSeekAsPost, models.ContactSeekPoster, models.ContactSeekReader)
}

func contactPost(w http.ResponseWriter, r *http.Request, ps httprouter.Params,
	read models.PostReader, posterTemplate models.MailTemplate, readerTemplate models.MailTemplate) {

	id := ps.ByName("id")

	email, code, err := models.NewEmailInput(db, id, read)
	if err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while creating email struct")
		Error(w, code)
		return
	}

	// Get NetID of the user initiating the contact
	if email.Sender = getUsername(r); email.Sender == "" {
		Error(w, http.StatusUnauthorized)
		return
	}

	// Get Body from request
	if err := ParseJSONFromBody(r, &email); err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while parsing JSON file")
		Error(w, http.StatusUnprocessableEntity)
		return
	}

	// Send email
	email.Template = posterTemplate
	if code, err := models.SendNotificationEmail(email); err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while attempting to send email to poster")
		Error(w, code)
		return
	}
	email.Template = readerTemplate
	if code, err := models.SendConfirmationEmail(email); err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while attempting to send email to post reader")
		Error(w, code)
		return
	}

	w.WriteHeader(http.StatusNoContent)
}
<commit_msg>go fmt<commit_after>package server

import (
	log "github.com/Sirupsen/logrus"
	"github.com/casey-chow/tigertrade/server/models"
	"github.com/getsentry/raven-go"
	"github.com/julienschmidt/httprouter"
	"net/http"
)

// ContactListing reads the listing from the params and sends notification and confirmation emails
// to the listing owner and current user
func ContactListing(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	contactPost(w, r, ps, models.ReadListingAsPost, models.ContactListingPoster, models.ContactListingReader)
}

// ContactSeek reads the seek from the params and sends notification and confirmation emails
// to the seek owner and current user
func ContactSeek(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	contactPost(w, r, ps, models.ReadSeekAsPost, models.ContactSeekPoster, models.ContactSeekReader)
}

func contactPost(w http.ResponseWriter, r *http.Request, ps httprouter.Params,
	read models.PostReader, posterTemplate models.MailTemplate, readerTemplate models.MailTemplate) {

	id := ps.ByName("id")

	email, code, err := models.NewEmailInput(db, id, read)
	if err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while creating email struct")
		Error(w, code)
		return
	}

	// Get NetID of the user initiating the contact
	if email.Sender = getUsername(r); email.Sender == "" {
		Error(w, http.StatusUnauthorized)
		return
	}

	// Get Body from request
	if err := ParseJSONFromBody(r, &email); err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while parsing JSON file")
		Error(w, http.StatusUnprocessableEntity)
		return
	}

	// Send email
	email.Template = posterTemplate
	if code, err := models.SendNotificationEmail(email); err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while attempting to send email to poster")
		Error(w, code)
		return
	}
	email.Template = readerTemplate
	if code, err := models.SendConfirmationEmail(email); err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while attempting to send email to post reader")
		Error(w, code)
		return
	}

	w.WriteHeader(http.StatusNoContent)
}
<|endoftext|>


<commit_before>/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

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

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

// Tests to verify that example code behaves as expected.
// Run in this directory with `go test example_test.go`
//
package main

import (
	"bufio"
	"bytes"
	"flag"
	"fmt"
	"io"
	"log"
	"math/rand"
	"net"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"reflect"
	"testing"
	"time"
)

func fatalIf(t *testing.T, err error) {
	if err != nil {
		t.Fatalf("%s", err)
	}
}

// A demo broker process
type broker struct {
	cmd    *exec.Cmd
	addr   string
	runerr chan error
	err    error
}

// Try to connect to the broker to verify it is ready, give up after a timeout
func (b *broker) check() error {
	dialer := net.Dialer{Deadline: time.Now().Add(time.Second * 10)}
	for {
		c, err := dialer.Dial("tcp", b.addr)
		if err == nil { // Success
			c.Close()
			return nil
		}
		select {
		case runerr := <-b.runerr: // Broker exited.
			return runerr
		default:
		}
		if neterr, ok := err.(net.Error); ok && neterr.Timeout() { // Running but timed out
			b.stop()
			return fmt.Errorf("timed out waiting for broker")
		}
		time.Sleep(time.Second / 10)
	}
}

// Start the demo broker, wait till it is listening on *addr. No-op if already started.
func (b *broker) start(t *testing.T) error {
	if b.cmd == nil { // Not already started
		b.addr = fmt.Sprintf("127.0.0.1:%d", rand.Intn(10000)+10000)
		b.cmd = exampleCommand(t, *brokerName, "-addr", b.addr)
		b.runerr = make(chan error)
		b.cmd.Stderr, b.cmd.Stdout = os.Stderr, os.Stdout
		b.err = b.cmd.Start()
		if b.err == nil {
			go func() { b.runerr <- b.cmd.Wait() }()
		} else {
			b.runerr <- b.err
		}
		b.err = b.check()
	}
	return b.err
}

func (b *broker) stop() {
	if b != nil && b.cmd != nil {
		b.cmd.Process.Kill()
		<-b.runerr
	}
}

func checkEqual(want interface{}, got interface{}) error {
	if reflect.DeepEqual(want, got) {
		return nil
	}
	return fmt.Errorf("%#v != %#v", want, got)
}

// exampleCommand returns an exec.Cmd to run an example.
func exampleCommand(t *testing.T, prog string, arg ...string) (cmd *exec.Cmd) {
	args := []string{}
	if *debug {
		args = append(args, "-debug=true")
	}
	args = append(args, arg...)
	prog, err := filepath.Abs(path.Join(*dir, prog))
	fatalIf(t, err)
	if _, err := os.Stat(prog); err == nil {
		cmd = exec.Command(prog, args...)
	} else if _, err := os.Stat(prog + ".go"); err == nil {
		args = append([]string{"run", prog + ".go"}, args...)
		cmd = exec.Command("go", args...)
	} else {
		t.Fatalf("Cannot find binary or source for %s", prog)
	}
	cmd.Stderr = os.Stderr
	return cmd
}

// Run an example Go program, return the combined output as a string.
func runExample(t *testing.T, prog string, arg ...string) (string, error) {
	cmd := exampleCommand(t, prog, arg...)
	out, err := cmd.Output()
	return string(out), err
}

func prefix(prefix string, err error) error {
	if err != nil {
		return fmt.Errorf("%s: %s", prefix, err)
	}
	return nil
}

func runExampleWant(t *testing.T, want string, prog string, args ...string) error {
	out, err := runExample(t, prog, args...)
	if err != nil {
		return fmt.Errorf("%s failed: %s: %s", prog, err, out)
	}
	return prefix(prog, checkEqual(want, out))
}

func exampleArgs(args ...string) []string {
	for i := 0; i < *connections; i++ {
		args = append(args, fmt.Sprintf("%s/%s%d", testBroker.addr, "q", i))
	}
	return args
}

// Send then receive
func TestExampleSendReceive(t *testing.T) {
	if testing.Short() {
		t.Skip("Skip demo tests in short mode")
	}
	testBroker.start(t)
	err := runExampleWant(t,
		fmt.Sprintf("Received all %d acknowledgements\n", expected),
		"send",
		exampleArgs("-count", fmt.Sprintf("%d", *count))...)
	if err != nil {
		t.Fatal(err)
	}
	err = runExampleWant(t,
		fmt.Sprintf("Listening on %v connections\nReceived %v messages\n", *connections, *count**connections),
		"receive",
		exampleArgs("-count", fmt.Sprintf("%d", *count**connections))...)
	if err != nil {
		t.Fatal(err)
	}
}

var ready error

func init() { ready = fmt.Errorf("Ready") }

// Run receive in a goroutine.
// Send ready on errchan when it is listening.
// Send final error when it is done.
// Returns the Cmd, caller must Wait()
func goReceiveWant(t *testing.T, errchan chan<- error, want string, arg ...string) *exec.Cmd {
	cmd := exampleCommand(t, "receive", arg...)
	go func() {
		pipe, err := cmd.StdoutPipe()
		if err != nil {
			errchan <- err
			return
		}
		out := bufio.NewReader(pipe)
		cmd.Start()
		line, err := out.ReadString('\n')
		if err != nil && err != io.EOF {
			errchan <- err
			return
		}
		listening := "Listening on 3 connections\n"
		if line != listening {
			errchan <- checkEqual(listening, line)
			return
		}
		errchan <- ready
		buf := bytes.Buffer{}
		io.Copy(&buf, out) // Collect the rest of the output
		cmd.Wait()
		errchan <- checkEqual(want, buf.String())
		close(errchan)
	}()
	return cmd
}

// Start receiver first, wait till it is running, then send.
func TestExampleReceiveSend(t *testing.T) {
	if testing.Short() {
		t.Skip("Skip demo tests in short mode")
	}
	testBroker.start(t)

	// Start receiver, wait for "listening" message on stdout
	recvCmd := exampleCommand(t, "receive", exampleArgs(fmt.Sprintf("-count=%d", expected))...)
	pipe, err := recvCmd.StdoutPipe()
	if err != nil {
		t.Fatal(err)
	}
	recvCmd.Start()
	out := bufio.NewReader(pipe)
	line, err := out.ReadString('\n')
	if err := checkEqual("Listening on 3 connections\n", line); err != nil {
		t.Fatal(err)
	}

	if err := runExampleWant(t,
		fmt.Sprintf("Received all %d acknowledgements\n", expected),
		"send",
		exampleArgs("-count", fmt.Sprintf("%d", *count))...); err != nil {
		t.Fatal(err)
	}

	buf := bytes.Buffer{}
	io.Copy(&buf, out)
	if err := checkEqual(fmt.Sprintf("Received %d messages\n", expected), buf.String()); err != nil {
		t.Fatal(err)
	}
}

var testBroker *broker

var debug = flag.Bool("debug", false, "Debugging output from examples")
var brokerName = flag.String("broker", "broker", "Name of broker executable to run")
var count = flag.Int("count", 3, "Count of messages to send in tests")
var connections = flag.Int("connections", 3, "Number of connections to make in tests")
var dir = flag.String("dir", "electron", "Directory containing example sources or binaries")
var expected int

func TestMain(m *testing.M) {
	if out, err := exec.Command("go", "install", "qpid.apache.org/...").CombinedOutput(); err != nil {
		log.Fatalf("go install failed: %s\n%s", err, out)
	}
	expected = (*count) * (*connections)
	rand.Seed(time.Now().UTC().UnixNano())
	testBroker = &broker{} // Broker is started on-demand by tests.
	status := m.Run()
	testBroker.stop()
	os.Exit(status)
}
<commit_msg>PROTON-1580: go: example tests failing in URL parse<commit_after>/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

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

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

// Tests to verify that example code behaves as expected.
// Run in this directory with `go test example_test.go`
//
package main

import (
	"bufio"
	"bytes"
	"flag"
	"fmt"
	"io"
	"log"
	"math/rand"
	"net"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"reflect"
	"testing"
	"time"
)

func fatalIf(t *testing.T, err error) {
	if err != nil {
		t.Fatalf("%s", err)
	}
}

// A demo broker process
type broker struct {
	cmd    *exec.Cmd
	addr   string
	runerr chan error
	err    error
}

// Try to connect to the broker to verify it is ready, give up after a timeout
func (b *broker) check() error {
	dialer := net.Dialer{Deadline: time.Now().Add(time.Second * 10)}
	for {
		c, err := dialer.Dial("tcp", b.addr)
		if err == nil { // Success
			c.Close()
			return nil
		}
		select {
		case runerr := <-b.runerr: // Broker exited.
			return runerr
		default:
		}
		if neterr, ok := err.(net.Error); ok && neterr.Timeout() { // Running but timed out
			b.stop()
			return fmt.Errorf("timed out waiting for broker")
		}
		time.Sleep(time.Second / 10)
	}
}

// Start the demo broker, wait till it is listening on *addr. No-op if already started.
func (b *broker) start(t *testing.T) error {
	if b.cmd == nil { // Not already started
		b.addr = fmt.Sprintf("127.0.0.1:%d", rand.Intn(10000)+10000)
		b.cmd = exampleCommand(t, *brokerName, "-addr", b.addr)
		b.runerr = make(chan error)
		b.cmd.Stderr, b.cmd.Stdout = os.Stderr, os.Stdout
		b.err = b.cmd.Start()
		if b.err == nil {
			go func() { b.runerr <- b.cmd.Wait() }()
		} else {
			b.runerr <- b.err
		}
		b.err = b.check()
	}
	return b.err
}

func (b *broker) stop() {
	if b != nil && b.cmd != nil {
		b.cmd.Process.Kill()
		<-b.runerr
	}
}

func checkEqual(want interface{}, got interface{}) error {
	if reflect.DeepEqual(want, got) {
		return nil
	}
	return fmt.Errorf("%#v != %#v", want, got)
}

// exampleCommand returns an exec.Cmd to run an example.
func exampleCommand(t *testing.T, prog string, arg ...string) (cmd *exec.Cmd) {
	args := []string{}
	if *debug {
		args = append(args, "-debug=true")
	}
	args = append(args, arg...)
	prog, err := filepath.Abs(path.Join(*dir, prog))
	fatalIf(t, err)
	if _, err := os.Stat(prog); err == nil {
		cmd = exec.Command(prog, args...)
	} else if _, err := os.Stat(prog + ".go"); err == nil {
		args = append([]string{"run", prog + ".go"}, args...)
		cmd = exec.Command("go", args...)
	} else {
		t.Fatalf("Cannot find binary or source for %s", prog)
	}
	cmd.Stderr = os.Stderr
	return cmd
}

// Run an example Go program, return the combined output as a string.
func runExample(t *testing.T, prog string, arg ...string) (string, error) {
	cmd := exampleCommand(t, prog, arg...)
	out, err := cmd.Output()
	return string(out), err
}

func prefix(prefix string, err error) error {
	if err != nil {
		return fmt.Errorf("%s: %s", prefix, err)
	}
	return nil
}

func runExampleWant(t *testing.T, want string, prog string, args ...string) error {
	out, err := runExample(t, prog, args...)
	if err != nil {
		return fmt.Errorf("%s failed: %s: %s", prog, err, out)
	}
	return prefix(prog, checkEqual(want, out))
}

func exampleArgs(args ...string) []string {
	for i := 0; i < *connections; i++ {
		args = append(args, fmt.Sprintf("amqp://%s/%s%d", testBroker.addr, "q", i))
	}
	return args
}

// Send then receive
func TestExampleSendReceive(t *testing.T) {
	if testing.Short() {
		t.Skip("Skip demo tests in short mode")
	}
	testBroker.start(t)
	err := runExampleWant(t,
		fmt.Sprintf("Received all %d acknowledgements\n", expected),
		"send",
		exampleArgs("-count", fmt.Sprintf("%d", *count))...)
	if err != nil {
		t.Fatal(err)
	}
	err = runExampleWant(t,
		fmt.Sprintf("Listening on %v connections\nReceived %v messages\n", *connections, *count**connections),
		"receive",
		exampleArgs("-count", fmt.Sprintf("%d", *count**connections))...)
	if err != nil {
		t.Fatal(err)
	}
}

var ready error

func init() { ready = fmt.Errorf("Ready") }

// Run receive in a goroutine.
// Send ready on errchan when it is listening.
// Send final error when it is done.
// Returns the Cmd, caller must Wait()
func goReceiveWant(t *testing.T, errchan chan<- error, want string, arg ...string) *exec.Cmd {
	cmd := exampleCommand(t, "receive", arg...)
	go func() {
		pipe, err := cmd.StdoutPipe()
		if err != nil {
			errchan <- err
			return
		}
		out := bufio.NewReader(pipe)
		cmd.Start()
		line, err := out.ReadString('\n')
		if err != nil && err != io.EOF {
			errchan <- err
			return
		}
		listening := "Listening on 3 connections\n"
		if line != listening {
			errchan <- checkEqual(listening, line)
			return
		}
		errchan <- ready
		buf := bytes.Buffer{}
		io.Copy(&buf, out) // Collect the rest of the output
		cmd.Wait()
		errchan <- checkEqual(want, buf.String())
		close(errchan)
	}()
	return cmd
}

// Start receiver first, wait till it is running, then send.
func TestExampleReceiveSend(t *testing.T) {
	if testing.Short() {
		t.Skip("Skip demo tests in short mode")
	}
	testBroker.start(t)

	// Start receiver, wait for "listening" message on stdout
	recvCmd := exampleCommand(t, "receive", exampleArgs(fmt.Sprintf("-count=%d", expected))...)
	pipe, err := recvCmd.StdoutPipe()
	if err != nil {
		t.Fatal(err)
	}
	recvCmd.Start()
	out := bufio.NewReader(pipe)
	line, err := out.ReadString('\n')
	if err := checkEqual("Listening on 3 connections\n", line); err != nil {
		t.Fatal(err)
	}

	if err := runExampleWant(t,
		fmt.Sprintf("Received all %d acknowledgements\n", expected),
		"send",
		exampleArgs("-count", fmt.Sprintf("%d", *count))...); err != nil {
		t.Fatal(err)
	}

	buf := bytes.Buffer{}
	io.Copy(&buf, out)
	if err := checkEqual(fmt.Sprintf("Received %d messages\n", expected), buf.String()); err != nil {
		t.Fatal(err)
	}
}

var testBroker *broker

var debug = flag.Bool("debug", false, "Debugging output from examples")
var brokerName = flag.String("broker", "broker", "Name of broker executable to run")
var count = flag.Int("count", 3, "Count of messages to send in tests")
var connections = flag.Int("connections", 3, "Number of connections to make in tests")
var dir = flag.String("dir", "electron", "Directory containing example sources or binaries")
var expected int

func TestMain(m *testing.M) {
	if out, err := exec.Command("go", "install", "qpid.apache.org/...").CombinedOutput(); err != nil {
		log.Fatalf("go install failed: %s\n%s", err, out)
	}
	expected = (*count) * (*connections)
	rand.Seed(time.Now().UTC().UnixNano())
	testBroker = &broker{} // Broker is started on-demand by tests.
	status := m.Run()
	testBroker.stop()
	os.Exit(status)
}
<|endoftext|>


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

// Command helloworld is an example program that collects data for
// video size.
package main

import (
	"context"
	"fmt"
	"log"
	"math/rand"
	"time"

	"go.opencensus.io/examples/exporter"
	"go.opencensus.io/stats"
	"go.opencensus.io/stats/view"
	"go.opencensus.io/tag"
	"go.opencensus.io/trace"
)

var (
	// frontendKey allows us to breakdown the recorded data
	// by the frontend used when uploading the video.
	frontendKey tag.Key

	// videoSize will measure the size of processed videos.
	videoSize *stats.Int64Measure
)

func main() {
	ctx := context.Background()

	// Register an exporter to be able to retrieve
	// the data from the subscribed views.
	e := &exporter.PrintExporter{}
	view.RegisterExporter(e)
	trace.RegisterExporter(e)

	var err error
	frontendKey, err = tag.NewKey("my.org/keys/frontend")
	if err != nil {
		log.Fatal(err)
	}
	videoSize = stats.Int64("my.org/measure/video_size", "size of processed videos", stats.UnitBytes)

	// Create view to see the processed video size
	// distribution broken down by frontend.
	// Register will allow view data to be exported.
	if err := view.Register(&view.View{
		Name:        "my.org/views/video_size",
		Description: "processed video size over time",
		TagKeys:     []tag.Key{frontendKey},
		Measure:     videoSize,
		Aggregation: view.Distribution(0, 1<<16, 1<<32),
	}); err != nil {
		log.Fatalf("Cannot subscribe to the view: %v", err)
	}

	// Process the video.
	process(ctx)

	// Wait for a duration longer than reporting duration to ensure the stats
	// library reports the collected data.
	fmt.Println("Wait longer than the reporting duration...")
	time.Sleep(2 * time.Second)
}

// process processes the video and instruments the processing
// by creating a span and collecting metrics about the operation.
func process(ctx context.Context) {
	ctx, err := tag.New(ctx,
		tag.Insert(frontendKey, "mobile-ios9.3.5"),
	)
	if err != nil {
		log.Fatal(err)
	}
	ctx, span := trace.StartSpan(ctx, "my.org/ProcessVideo")
	defer span.End()
	// Process video.
	// Record the processed video size.

	// Sleep for [1,10] milliseconds to fake work.
	time.Sleep(time.Duration(rand.Intn(10)+1) * time.Millisecond)

	stats.Record(ctx, videoSize.M(25648))
}
<commit_msg>Set the report period shorter that the exported data could be printed (#785)<commit_after>// Copyright 2017, OpenCensus Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Command helloworld is an example program that collects data for
// video size.
package main

import (
	"context"
	"fmt"
	"log"
	"math/rand"
	"time"

	"go.opencensus.io/examples/exporter"
	"go.opencensus.io/stats"
	"go.opencensus.io/stats/view"
	"go.opencensus.io/tag"
	"go.opencensus.io/trace"
)

var (
	// frontendKey allows us to breakdown the recorded data
	// by the frontend used when uploading the video.
	frontendKey tag.Key

	// videoSize will measure the size of processed videos.
	videoSize *stats.Int64Measure
)

func main() {
	ctx := context.Background()

	// Register an exporter to be able to retrieve
	// the data from the subscribed views.
	e := &exporter.PrintExporter{}
	view.RegisterExporter(e)
	trace.RegisterExporter(e)

	var err error
	frontendKey, err = tag.NewKey("my.org/keys/frontend")
	if err != nil {
		log.Fatal(err)
	}
	videoSize = stats.Int64("my.org/measure/video_size", "size of processed videos", stats.UnitBytes)
	view.SetReportingPeriod(2 * time.Second)

	// Create view to see the processed video size
	// distribution broken down by frontend.
	// Register will allow view data to be exported.
	if err := view.Register(&view.View{
		Name:        "my.org/views/video_size",
		Description: "processed video size over time",
		TagKeys:     []tag.Key{frontendKey},
		Measure:     videoSize,
		Aggregation: view.Distribution(0, 1<<16, 1<<32),
	}); err != nil {
		log.Fatalf("Cannot subscribe to the view: %v", err)
	}

	// Process the video.
	process(ctx)

	// Wait for a duration longer than reporting duration to ensure the stats
	// library reports the collected data.
	fmt.Println("Wait longer than the reporting duration...")
	time.Sleep(2 * time.Second)
}

// process processes the video and instruments the processing
// by creating a span and collecting metrics about the operation.
func process(ctx context.Context) {
	ctx, err := tag.New(ctx,
		tag.Insert(frontendKey, "mobile-ios9.3.5"),
	)
	if err != nil {
		log.Fatal(err)
	}
	ctx, span := trace.StartSpan(ctx, "my.org/ProcessVideo")
	defer span.End()
	// Process video.
	// Record the processed video size.

	// Sleep for [1,10] milliseconds to fake work.
	time.Sleep(time.Duration(rand.Intn(10)+1) * time.Millisecond)

	stats.Record(ctx, videoSize.M(25648))
}
<|endoftext|>


<commit_before>package server

import (
	"code.google.com/p/go.net/websocket"
	"fmt"
	"github.com/golang/glog"
	"github.com/nelhage/livegrep/client"
	"time"
)

type searchConnection struct {
	srv        *server
	ws         *websocket.Conn
	backend    string
	client     client.Client
	errors     chan error
	incoming   chan Op
	outgoing   chan Op
	shutdown   bool
	lastQuery  *OpQuery
	dispatched time.Time
}

func (s *searchConnection) recvLoop() {
	var op Op
	for {
		if err := OpCodec.Receive(s.ws, &op); err != nil {
			glog.V(1).Infof("Error in receive: %s\n", err.Error())
			if _, ok := err.(*ProtocolError); ok {
				// TODO: is this a good idea?
				// s.outgoing <- &OpError{err.Error()}
				continue
			} else {
				s.errors <- err
				break
			}
		}
		glog.V(2).Infof("Incoming: %s", asJSON{op})
		s.incoming <- op
		if s.shutdown {
			break
		}
	}
	close(s.incoming)
}

func (s *searchConnection) sendLoop() {
	for op := range s.outgoing {
		glog.V(2).Infof("Outgoing: %s", asJSON{op})
		OpCodec.Send(s.ws, op)
	}
}

func query(q *OpQuery) *client.Query {
	return &client.Query{
		Line: q.Line,
		File: q.File,
		Repo: q.Repo,
	}
}

func (s *searchConnection) handle() {
	s.incoming = make(chan Op, 1)
	s.outgoing = make(chan Op, 1)
	s.errors = make(chan error, 1)

	go s.recvLoop()
	go s.sendLoop()
	defer close(s.outgoing)

	var nextQuery *OpQuery

	var search client.Search
	var results <-chan *client.Result
	var err error

SearchLoop:
	for {
		select {
		case op, ok := <-s.incoming:
			if !ok {
				break
			}
			switch t := op.(type) {
			case *OpQuery:
				nextQuery = t
			default:
				s.outgoing <- &OpError{fmt.Sprintf("Invalid opcode %s", op.Opcode())}
				break
			}

		case e := <-s.errors:
			glog.Infof("error reading from client: %s\n", e.Error())
			break SearchLoop
		case res, ok := <-results:
			if ok {
				s.outgoing <- &OpResult{s.lastQuery.Id, res}
			} else {
				st, err := search.Close()
				if err == nil {
					duration := time.Since(s.dispatched)
					s.outgoing <- &OpSearchDone{s.lastQuery.Id, int64(duration / time.Millisecond), st}
				} else {
					s.outgoing <- &OpQueryError{s.lastQuery.Id, err.Error()}
				}
				results = nil
				search = nil
			}
		}
		if nextQuery != nil && results == nil {
			if !s.shouldDispatch(nextQuery) {
				nextQuery = nil
				continue
			}
			if err := s.connectBackend(nextQuery.Backend); err != nil {
				s.outgoing <- &OpQueryError{nextQuery.Id, err.Error()}
				nextQuery = nil
				continue
			}
			q := query(nextQuery)
			glog.Infof("[%s] dispatching: %s", s.ws.Request().RemoteAddr, asJSON{q})
			search, err = s.client.Query(q)
			s.dispatched = time.Now()
			if err != nil {
				s.outgoing <- &OpQueryError{nextQuery.Id, err.Error()}
			} else {
				if search == nil {
					panic("nil search and nil error?")
				}
				s.lastQuery = nextQuery
				results = search.Results()
			}
			nextQuery = nil
		}
	}

	s.shutdown = true
}

func (s *searchConnection) shouldDispatch(q *OpQuery) bool {
	if s.lastQuery == nil {
		return true
	}
	if s.lastQuery.Backend != q.Backend ||
		s.lastQuery.Line != q.Line ||
		s.lastQuery.File != q.File ||
		s.lastQuery.Repo != q.Repo {
		return true
	}
	return false
}

func (s *searchConnection) connectBackend(backend string) error {
	if s.client == nil || s.backend != backend {
		if s.client != nil {
			s.client.Close()
		}
		s.backend = backend
		addr := ""
		for _, bk := range s.srv.config.Backends {
			if bk.Id == backend {
				addr = bk.Addr
				break
			}
		}
		if addr == "" {
			return fmt.Errorf("No such backend: %s", backend)
		}
		s.client = client.ClientWithRetry(func() (client.Client, error) {
			return client.Dial("tcp", addr)
		})
	}
	return nil
}

func (s *server) HandleWebsocket(ws *websocket.Conn) {
	c := &searchConnection{
		srv: s,
		ws:  ws,
	}
	c.handle()
}
<commit_msg>Log search times.<commit_after>package server

import (
	"code.google.com/p/go.net/websocket"
	"fmt"
	"github.com/golang/glog"
	"github.com/nelhage/livegrep/client"
	"time"
)

type searchConnection struct {
	srv        *server
	ws         *websocket.Conn
	backend    string
	client     client.Client
	errors     chan error
	incoming   chan Op
	outgoing   chan Op
	shutdown   bool
	lastQuery  *OpQuery
	dispatched time.Time
}

func (s *searchConnection) recvLoop() {
	var op Op
	for {
		if err := OpCodec.Receive(s.ws, &op); err != nil {
			glog.V(1).Infof("Error in receive: %s\n", err.Error())
			if _, ok := err.(*ProtocolError); ok {
				// TODO: is this a good idea?
				// s.outgoing <- &OpError{err.Error()}
				continue
			} else {
				s.errors <- err
				break
			}
		}
		glog.V(2).Infof("Incoming: %s", asJSON{op})
		s.incoming <- op
		if s.shutdown {
			break
		}
	}
	close(s.incoming)
}

func (s *searchConnection) sendLoop() {
	for op := range s.outgoing {
		glog.V(2).Infof("Outgoing: %s", asJSON{op})
		OpCodec.Send(s.ws, op)
	}
}

func query(q *OpQuery) *client.Query {
	return &client.Query{
		Line: q.Line,
		File: q.File,
		Repo: q.Repo,
	}
}

func (s *searchConnection) handle() {
	s.incoming = make(chan Op, 1)
	s.outgoing = make(chan Op, 1)
	s.errors = make(chan error, 1)

	go s.recvLoop()
	go s.sendLoop()
	defer close(s.outgoing)

	var nextQuery *OpQuery

	var search client.Search
	var results <-chan *client.Result
	var err error

SearchLoop:
	for {
		select {
		case op, ok := <-s.incoming:
			if !ok {
				break
			}
			switch t := op.(type) {
			case *OpQuery:
				nextQuery = t
			default:
				s.outgoing <- &OpError{fmt.Sprintf("Invalid opcode %s", op.Opcode())}
				break
			}

		case e := <-s.errors:
			glog.Infof("error reading from client: %s\n", e.Error())
			break SearchLoop
		case res, ok := <-results:
			if ok {
				s.outgoing <- &OpResult{s.lastQuery.Id, res}
			} else {
				st, err := search.Close()
				if err == nil {
					duration := time.Since(s.dispatched)
					glog.Infof("search done remote=%s id=%d query=%s millis=%d",
						s.ws.Request().RemoteAddr,
						s.lastQuery.Id,
						asJSON{query(s.lastQuery)},
						int64(duration/time.Millisecond))
					s.outgoing <- &OpSearchDone{s.lastQuery.Id, int64(duration / time.Millisecond), st}
				} else {
					s.outgoing <- &OpQueryError{s.lastQuery.Id, err.Error()}
				}
				results = nil
				search = nil
			}
		}
		if nextQuery != nil && results == nil {
			if !s.shouldDispatch(nextQuery) {
				nextQuery = nil
				continue
			}
			if err := s.connectBackend(nextQuery.Backend); err != nil {
				s.outgoing <- &OpQueryError{nextQuery.Id, err.Error()}
				nextQuery = nil
				continue
			}
			q := query(nextQuery)
			glog.Infof("dispatching remote=%s id=%d query=%s",
				s.ws.Request().RemoteAddr,
				nextQuery.Id,
				asJSON{q})
			search, err = s.client.Query(q)
			s.dispatched = time.Now()
			if err != nil {
				s.outgoing <- &OpQueryError{nextQuery.Id, err.Error()}
			} else {
				if search == nil {
					panic("nil search and nil error?")
				}
				s.lastQuery = nextQuery
				results = search.Results()
			}
			nextQuery = nil
		}
	}

	s.shutdown = true
}

func (s *searchConnection) shouldDispatch(q *OpQuery) bool {
	if s.lastQuery == nil {
		return true
	}
	if s.lastQuery.Backend != q.Backend ||
		s.lastQuery.Line != q.Line ||
		s.lastQuery.File != q.File ||
		s.lastQuery.Repo != q.Repo {
		return true
	}
	return false
}

func (s *searchConnection) connectBackend(backend string) error {
	if s.client == nil || s.backend != backend {
		if s.client != nil {
			s.client.Close()
		}
		s.backend = backend
		addr := ""
		for _, bk := range s.srv.config.Backends {
			if bk.Id == backend {
				addr = bk.Addr
				break
			}
		}
		if addr == "" {
			return fmt.Errorf("No such backend: %s", backend)
		}
		s.client = client.ClientWithRetry(func() (client.Client, error) {
			return client.Dial("tcp", addr)
		})
	}
	return nil
}

func (s *server) HandleWebsocket(ws *websocket.Conn) {
	c := &searchConnection{
		srv: s,
		ws:  ws,
	}
	c.handle()
}
<|endoftext|>


<commit_before>package server

import (
	"net/http"

	"github.com/gillesdemey/npm-registry/routes"
	"github.com/gillesdemey/npm-registry/storage"
	"github.com/gorilla/pat"
	"github.com/unrolled/render"
	"github.com/urfave/negroni"
	"golang.org/x/net/context"
)

func New(router *pat.Router, storage storage.Engine) *negroni.Negroni {
	n := negroni.Classic()
	render := render.New()

	// Attach storage and renderer on every request
	n.Use(negroni.HandlerFunc(func(w http.ResponseWriter, req *http.Request, next http.HandlerFunc) {
		var ctx = req.Context()
		ctx = context.WithValue(ctx, "storage", storage)
		ctx = context.WithValue(ctx, "renderer", render)
		next(w, req.WithContext(ctx))
	}))

	// favicon requests
	router.Get("/favicon.ico", routes.Noop)

	router.Get("/-/ping", routes.Ping)

	// TODO: logout
	router.Put("/-/user/{user}", routes.Login)

	// Print the username config to standard output.
	router.Get("/-/whoami", routes.Whoami)

	// tarballs
	router.Get("/{scope}/{pkg}/-/{filename}", routes.GetTarball)
	router.Get("/{pkg}/-/{filename}", routes.GetTarball)

	// packages
	router.Get("/{scope}/{pkg}", routes.GetPackageMetadata) // scoped package
	router.Get("/{pkg}", routes.GetPackageMetadata)

	// publish
	router.Put("/{scope}/{pkg}", routes.PublishPackage)
	router.Put("/{pkg}", routes.PublishPackage)

	// root
	router.Get("/", routes.Root)

	n.UseHandler(router)
	return n
}
<commit_msg>Simplifies context middleware handler<commit_after>package server

import (
	"net/http"

	"github.com/gillesdemey/npm-registry/routes"
	"github.com/gillesdemey/npm-registry/storage"
	"github.com/gorilla/pat"
	"github.com/unrolled/render"
	"github.com/urfave/negroni"
	"golang.org/x/net/context"
)

func New(router *pat.Router, storage storage.Engine) *negroni.Negroni {
	n := negroni.Classic()
	render := render.New()

	// Attach storage and renderer on every request
	n.UseFunc(func(w http.ResponseWriter, req *http.Request, next http.HandlerFunc) {
		var ctx = req.Context()
		ctx = context.WithValue(ctx, "storage", storage)
		ctx = context.WithValue(ctx, "renderer", render)
		next(w, req.WithContext(ctx))
	})

	// favicon requests
	router.Get("/favicon.ico", routes.Noop)

	router.Get("/-/ping", routes.Ping)

	// TODO: logout
	router.Put("/-/user/{user}", routes.Login)

	// Print the username config to standard output.
	router.Get("/-/whoami", routes.Whoami)

	// tarballs
	router.Get("/{scope}/{pkg}/-/{filename}", routes.GetTarball)
	router.Get("/{pkg}/-/{filename}", routes.GetTarball)

	// packages
	router.Get("/{scope}/{pkg}", routes.GetPackageMetadata) // scoped package
	router.Get("/{pkg}", routes.GetPackageMetadata)

	// publish
	router.Put("/{scope}/{pkg}", routes.PublishPackage)
	router.Put("/{pkg}", routes.PublishPackage)

	// root
	router.Get("/", routes.Root)

	n.UseHandler(router)
	return n
}
<|endoftext|>