<commit_before>package rocket_bucket

import (
	"fmt"
	"net/http"
	"time"
)

type Server struct {
	Config   *Config
	Selector *Selector
}

func (s *Server) HandleRequest(w http.ResponseWriter, r *http.Request) {
	// handle when url is "/" but request is "/something"
	defer func() {
		if err := recover(); err != nil {
			Fatal("%v", err)
		}
	}()

	session := Session{}
	wasProcessedOk := session.Process(r, s.Selector, s.Config)

	// set response headers
	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("Last-Modified", s.Config.LastParsed.Format(time.RFC1123))

	if s.Config.Server.CacheMaxAge > 0 {
		w.Header().Set("Cache-Control",
			fmt.Sprintf("public, max-age=%d, must-revalidate", s.Config.Server.CacheMaxAge))
	}

	logString := fmt.Sprintf("processing_time=%.6f, response_code=%d, response_body=`%s`, remote_address=`%s`, user_id=`%s`, x_api_key=`%s`, log_only_response=`%s`",
		session.EndTime.Sub(session.StartTime).Seconds(), session.ResponseCode, session.ResponseBody, session.RemoteAddr, session.UserID, session.APIKey, session.PrivateLoggedResponseString)

	w.WriteHeader(session.ResponseCode)
	w.Write(session.ResponseBody)

	if wasProcessedOk {
		Info(logString)
	} else {
		Error(logString)
	}
}

func (s *Server) Run() {
	Info("listening: url=`%s`, port=`%d`", s.Config.Server.URL, s.Config.Server.Port)
	http.HandleFunc(s.Config.Server.URL, s.HandleRequest)
	http.ListenAndServe(fmt.Sprintf(":%d", s.Config.Server.Port), nil)
}
<commit_msg>ensuring cache control header only returns for success<commit_after>package rocket_bucket

import (
	"fmt"
	"net/http"
	"time"
)

type Server struct {
	Config   *Config
	Selector *Selector
}

func (s *Server) HandleRequest(w http.ResponseWriter, r *http.Request) {
	// handle when url is "/" but request is "/something"
	defer func() {
		if err := recover(); err != nil {
			Fatal("%v", err)
		}
	}()

	session := Session{}
	wasProcessedOk := session.Process(r, s.Selector, s.Config)

	// set response headers
	w.Header().Set("Content-Type", "application/json")

	logString := fmt.Sprintf("processing_time=%.6f, response_code=%d, response_body=`%s`, remote_address=`%s`, user_id=`%s`, x_api_key=`%s`, log_only_response=`%s`",
		session.EndTime.Sub(session.StartTime).Seconds(), session.ResponseCode, session.ResponseBody, session.RemoteAddr, session.UserID, session.APIKey, session.PrivateLoggedResponseString)

	if wasProcessedOk {
		w.Header().Set("Last-Modified", s.Config.LastParsed.Format(time.RFC1123))

		if s.Config.Server.CacheMaxAge > 0 {
			w.Header().Set("Cache-Control",
				fmt.Sprintf("public, max-age=%d, must-revalidate", s.Config.Server.CacheMaxAge))
		}

		Info(logString)
	} else {
		Error(logString)
	}

	w.WriteHeader(session.ResponseCode)
	w.Write(session.ResponseBody)
}

func (s *Server) Run() {
	Info("listening: url=`%s`, port=`%d`", s.Config.Server.URL, s.Config.Server.Port)
	http.HandleFunc(s.Config.Server.URL, s.HandleRequest)
	http.ListenAndServe(fmt.Sprintf(":%d", s.Config.Server.Port), nil)
}
<|endoftext|>


<commit_before>package agent

import (
	"fmt"
	"github.com/marouenj/consul/consul/structs"
	"net/http"
	"strings"
)

func (s *HTTPServer) CatalogRegister(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	var args structs.RegisterRequest
	if err := decodeBody(req, &args, nil); err != nil {
		resp.WriteHeader(400)
		resp.Write([]byte(fmt.Sprintf("Request decode failed: %v", err)))
		return nil, nil
	}

	// Setup the default DC if not provided
	if args.Datacenter == "" {
		args.Datacenter = s.agent.config.Datacenter
	}

	// Forward to the servers
	var out struct{}
	if err := s.agent.RPC("Catalog.Register", &args, &out); err != nil {
		return nil, err
	}
	return true, nil
}

func (s *HTTPServer) CatalogDeregister(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	var args structs.DeregisterRequest
	if err := decodeBody(req, &args, nil); err != nil {
		resp.WriteHeader(400)
		resp.Write([]byte(fmt.Sprintf("Request decode failed: %v", err)))
		return nil, nil
	}

	// Setup the default DC if not provided
	if args.Datacenter == "" {
		args.Datacenter = s.agent.config.Datacenter
	}

	// Forward to the servers
	var out struct{}
	if err := s.agent.RPC("Catalog.Deregister", &args, &out); err != nil {
		return nil, err
	}
	return true, nil
}

func (s *HTTPServer) CatalogDatacenters(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	var out []string
	if err := s.agent.RPC("Catalog.ListDatacenters", struct{}{}, &out); err != nil {
		return nil, err
	}
	return out, nil
}

func (s *HTTPServer) CatalogNodes(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Setup the request
	args := structs.DCSpecificRequest{}
	if done := s.parse(resp, req, &args.Datacenter, &args.QueryOptions); done {
		return nil, nil
	}

	var out structs.IndexedNodes
	defer setMeta(resp, &out.QueryMeta)
	if err := s.agent.RPC("Catalog.ListNodes", &args, &out); err != nil {
		return nil, err
	}
	return out.Nodes, nil
}

func (s *HTTPServer) CatalogServices(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Set default DC
	args := structs.DCSpecificRequest{}
	if done := s.parse(resp, req, &args.Datacenter, &args.QueryOptions); done {
		return nil, nil
	}

	var out structs.IndexedServices
	defer setMeta(resp, &out.QueryMeta)
	if err := s.agent.RPC("Catalog.ListServices", &args, &out); err != nil {
		return nil, err
	}
	return out.Services, nil
}

func (s *HTTPServer) CatalogServiceNodes(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Set default DC
	args := structs.ServiceSpecificRequest{}
	if done := s.parse(resp, req, &args.Datacenter, &args.QueryOptions); done {
		return nil, nil
	}

	// Check for a tag
	params := req.URL.Query()
	if _, ok := params["tag"]; ok {
		args.ServiceTag = params.Get("tag")
		args.TagFilter = true
	}

	// Pull out the service name
	args.ServiceName = strings.TrimPrefix(req.URL.Path, "/v1/catalog/service/")
	if args.ServiceName == "" {
		resp.WriteHeader(400)
		resp.Write([]byte("Missing service name"))
		return nil, nil
	}

	// Make the RPC request
	var out structs.IndexedServiceNodes
	defer setMeta(resp, &out.QueryMeta)
	if err := s.agent.RPC("Catalog.ServiceNodes", &args, &out); err != nil {
		return nil, err
	}
	return out.ServiceNodes, nil
}

func (s *HTTPServer) CatalogNodeServices(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Set default Datacenter
	args := structs.NodeSpecificRequest{}
	if done := s.parse(resp, req, &args.Datacenter, &args.QueryOptions); done {
		return nil, nil
	}

	// Pull out the node name
	args.Node = strings.TrimPrefix(req.URL.Path, "/v1/catalog/node/")
	if args.Node == "" {
		resp.WriteHeader(400)
		resp.Write([]byte("Missing node name"))
		return nil, nil
	}

	// Make the RPC request
	var out structs.IndexedNodeServices
	defer setMeta(resp, &out.QueryMeta)
	if err := s.agent.RPC("Catalog.NodeServices", &args, &out); err != nil {
		return nil, err
	}
	return out.NodeServices, nil
}
<commit_msg>add handlers for archetype catalog endpoints<commit_after>package agent

import (
	"fmt"
	"github.com/marouenj/consul/consul/structs"
	"net/http"
	"strings"
)

func (s *HTTPServer) CatalogRegister(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	var args structs.RegisterRequest
	if err := decodeBody(req, &args, nil); err != nil {
		resp.WriteHeader(400)
		resp.Write([]byte(fmt.Sprintf("Request decode failed: %v", err)))
		return nil, nil
	}

	// Setup the default DC if not provided
	if args.Datacenter == "" {
		args.Datacenter = s.agent.config.Datacenter
	}

	// Forward to the servers
	var out struct{}
	if err := s.agent.RPC("Catalog.Register", &args, &out); err != nil {
		return nil, err
	}
	return true, nil
}

func (s *HTTPServer) CatalogDeregister(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	var args structs.DeregisterRequest
	if err := decodeBody(req, &args, nil); err != nil {
		resp.WriteHeader(400)
		resp.Write([]byte(fmt.Sprintf("Request decode failed: %v", err)))
		return nil, nil
	}

	// Setup the default DC if not provided
	if args.Datacenter == "" {
		args.Datacenter = s.agent.config.Datacenter
	}

	// Forward to the servers
	var out struct{}
	if err := s.agent.RPC("Catalog.Deregister", &args, &out); err != nil {
		return nil, err
	}
	return true, nil
}

func (s *HTTPServer) CatalogDatacenters(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	var out []string
	if err := s.agent.RPC("Catalog.ListDatacenters", struct{}{}, &out); err != nil {
		return nil, err
	}
	return out, nil
}

func (s *HTTPServer) CatalogNodes(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Setup the request
	args := structs.DCSpecificRequest{}
	if done := s.parse(resp, req, &args.Datacenter, &args.QueryOptions); done {
		return nil, nil
	}

	var out structs.IndexedNodes
	defer setMeta(resp, &out.QueryMeta)
	if err := s.agent.RPC("Catalog.ListNodes", &args, &out); err != nil {
		return nil, err
	}
	return out.Nodes, nil
}

func (s *HTTPServer) CatalogServices(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Set default DC
	args := structs.DCSpecificRequest{}
	if done := s.parse(resp, req, &args.Datacenter, &args.QueryOptions); done {
		return nil, nil
	}

	var out structs.IndexedServices
	defer setMeta(resp, &out.QueryMeta)
	if err := s.agent.RPC("Catalog.ListServices", &args, &out); err != nil {
		return nil, err
	}
	return out.Services, nil
}

func (s *HTTPServer) CatalogArchetypes(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Set default DC
	args := structs.DCSpecificRequest{}
	if done := s.parse(resp, req, &args.Datacenter, &args.QueryOptions); done {
		return nil, nil
	}

	var out structs.IndexedArchetypes
	defer setMeta(resp, &out.QueryMeta)
	if err := s.agent.RPC("Catalog.ListArchetypes", &args, &out); err != nil {
		return nil, err
	}
	return out.Archetypes, nil
}

func (s *HTTPServer) CatalogServiceNodes(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Set default DC
	args := structs.ServiceSpecificRequest{}
	if done := s.parse(resp, req, &args.Datacenter, &args.QueryOptions); done {
		return nil, nil
	}

	// Check for a tag
	params := req.URL.Query()
	if _, ok := params["tag"]; ok {
		args.ServiceTag = params.Get("tag")
		args.TagFilter = true
	}

	// Pull out the service name
	args.ServiceName = strings.TrimPrefix(req.URL.Path, "/v1/catalog/service/")
	if args.ServiceName == "" {
		resp.WriteHeader(400)
		resp.Write([]byte("Missing service name"))
		return nil, nil
	}

	// Make the RPC request
	var out structs.IndexedServiceNodes
	defer setMeta(resp, &out.QueryMeta)
	if err := s.agent.RPC("Catalog.ServiceNodes", &args, &out); err != nil {
		return nil, err
	}
	return out.ServiceNodes, nil
}

func (s *HTTPServer) CatalogArchetypeNodes(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Set default DC
	args := structs.ArchetypeSpecificRequest{}
	if done := s.parse(resp, req, &args.Datacenter, &args.QueryOptions); done {
		return nil, nil
	}

	// Check for a tag
	params := req.URL.Query()
	if _, ok := params["tag"]; ok {
		args.ArchetypeTag = params.Get("tag")
		args.TagFilter = true
	}

	// Pull out the service name
	args.ArchetypeName = strings.TrimPrefix(req.URL.Path, "/v1/catalog/archetype/")
	if args.ArchetypeName == "" {
		resp.WriteHeader(400)
		resp.Write([]byte("Missing archetype name"))
		return nil, nil
	}

	// Make the RPC request
	var out structs.IndexedArchetypeNodes
	defer setMeta(resp, &out.QueryMeta)
	if err := s.agent.RPC("Catalog.ArchetypeNodes", &args, &out); err != nil {
		return nil, err
	}
	return out.ArchetypeNodes, nil
}

func (s *HTTPServer) CatalogNodeServices(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Set default Datacenter
	args := structs.NodeSpecificRequest{}
	if done := s.parse(resp, req, &args.Datacenter, &args.QueryOptions); done {
		return nil, nil
	}

	// Pull out the node name
	args.Node = strings.TrimPrefix(req.URL.Path, "/v1/catalog/node/")
	if args.Node == "" {
		resp.WriteHeader(400)
		resp.Write([]byte("Missing node name"))
		return nil, nil
	}

	// Make the RPC request
	var out structs.IndexedNodeServices
	defer setMeta(resp, &out.QueryMeta)
	if err := s.agent.RPC("Catalog.NodeServices", &args, &out); err != nil {
		return nil, err
	}
	return out.NodeServices, nil
}
<|endoftext|>


<commit_before>package v2

import (
	"code.cloudfoundry.org/cli/actor/sharedaction"
	"code.cloudfoundry.org/cli/actor/v2action"
	"code.cloudfoundry.org/cli/command"
	"code.cloudfoundry.org/cli/command/v2/shared"
)

//go:generate counterfeiter . OauthTokenActor

type OauthTokenActor interface {
	RefreshAccessToken(refreshToken string) (string, error)
}

type OauthTokenCommand struct {
	usage           interface{} `usage:"CF_NAME oauth-token"`
	relatedCommands interface{} `related_commands:"curl"`

	UI          command.UI
	Config      command.Config
	SharedActor command.SharedActor
	Actor       OauthTokenActor
}

func (cmd *OauthTokenCommand) Setup(config command.Config, ui command.UI) error {
	cmd.UI = ui
	cmd.Config = config
	cmd.SharedActor = sharedaction.NewActor()

	ccClient, uaaClient, err := shared.NewClients(config, ui, true)
	if err != nil {
		return err
	}
	cmd.Actor = v2action.NewActor(ccClient, uaaClient, config)

	return nil
}

func (cmd OauthTokenCommand) Execute(_ []string) error {
	err := cmd.SharedActor.CheckTarget(cmd.Config, false, false)
	if err != nil {
		return shared.HandleError(err)
	}

	accessToken, err := cmd.Actor.RefreshAccessToken(cmd.Config.RefreshToken())
	if err != nil {
		return err
	}

	cmd.UI.DisplayText(accessToken)
	return nil
}
<commit_msg>wrap oauth-token errors<commit_after>package v2

import (
	"code.cloudfoundry.org/cli/actor/sharedaction"
	"code.cloudfoundry.org/cli/actor/v2action"
	"code.cloudfoundry.org/cli/command"
	"code.cloudfoundry.org/cli/command/v2/shared"
)

//go:generate counterfeiter . OauthTokenActor

type OauthTokenActor interface {
	RefreshAccessToken(refreshToken string) (string, error)
}

type OauthTokenCommand struct {
	usage           interface{} `usage:"CF_NAME oauth-token"`
	relatedCommands interface{} `related_commands:"curl"`

	UI          command.UI
	Config      command.Config
	SharedActor command.SharedActor
	Actor       OauthTokenActor
}

func (cmd *OauthTokenCommand) Setup(config command.Config, ui command.UI) error {
	cmd.UI = ui
	cmd.Config = config
	cmd.SharedActor = sharedaction.NewActor()

	ccClient, uaaClient, err := shared.NewClients(config, ui, true)
	if err != nil {
		return err
	}
	cmd.Actor = v2action.NewActor(ccClient, uaaClient, config)

	return nil
}

func (cmd OauthTokenCommand) Execute(_ []string) error {
	err := cmd.SharedActor.CheckTarget(cmd.Config, false, false)
	if err != nil {
		return shared.HandleError(err)
	}

	accessToken, err := cmd.Actor.RefreshAccessToken(cmd.Config.RefreshToken())
	if err != nil {
		return shared.HandleError(err)
	}

	cmd.UI.DisplayText(accessToken)
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os/exec"
	"time"

	pb "github.com/brotherlogic/gobuildslave/proto"
	"golang.org/x/net/context"
)

const (
	pendWait = time.Minute
)

func (s *Server) runTransition(ctx context.Context, job *pb.JobAssignment) {
	stState := job.State
	switch job.State {
	case pb.State_ACKNOWLEDGED:
		key := s.scheduleBuild(ctx, job.Job)
		if job.Job.NonBootstrap {
			if key != "" {
				job.Server = s.Registry.Identifier
				job.State = pb.State_BUILT
				job.RunningVersion = key
			}
		} else {
			job.CommandKey = key
			job.State = pb.State_BUILDING
			job.Server = s.Registry.Identifier
		}
	case pb.State_BUILDING:
		if s.taskComplete(job.CommandKey) {
			job.State = pb.State_BUILT
		}
	case pb.State_BUILT:
		output := s.scheduler.getOutput(job.CommandKey)
		if len(output) > 0 {
			if job.BuildFail == 5 {
				s.deliverCrashReport(ctx, job, output)
			}
			job.BuildFail++
			job.State = pb.State_DIED
		} else {
			job.BuildFail = 0
			key := s.scheduleRun(job.Job)
			job.CommandKey = key
			job.StartTime = time.Now().Unix()
			job.State = pb.State_PENDING
		}
	case pb.State_PENDING:
		if time.Now().Add(-time.Minute).Unix() > job.StartTime {
			job.State = pb.State_RUNNING
		}
	case pb.State_RUNNING:
		if s.taskComplete(job.CommandKey) {
			output := s.scheduler.getOutput(job.CommandKey)
			s.deliverCrashReport(ctx, job, output)
			job.State = pb.State_DIED
		}

		// Restart this job if we need to
		if job.Job.NonBootstrap {
			version := s.getVersion(ctx, job.Job)
			if version != job.RunningVersion {
				s.Log(fmt.Sprintf("KILLING %v", job.Job.Name))
				s.scheduler.killJob(job.CommandKey)
				job.State = pb.State_ACKNOWLEDGED
			}
		}
	case pb.State_DIED:
		job.State = pb.State_ACKNOWLEDGED
	}
	if job.State != stState {
		s.Log(fmt.Sprintf("Job %v went from %v to %v", job.Job.Name, stState, job.State))
	}
}

type translator interface {
	build(job *pb.Job) *exec.Cmd
	run(job *pb.Job) *exec.Cmd
}

type checker interface {
	isAlive(ctx context.Context, job *pb.JobAssignment) bool
}

func (s *Server) getVersion(ctx context.Context, job *pb.Job) string {
	versions := s.builder.build(ctx, job)

	if len(versions) == 0 {
		s.Log(fmt.Sprintf("No versions received for %v", job.Name))
		return ""
	}

	return versions[0].Version

}

// scheduleBuild builds out the job, returning the current version
func (s *Server) scheduleBuild(ctx context.Context, job *pb.Job) string {
	if !job.NonBootstrap {
		c := s.translator.build(job)
		return s.scheduler.Schedule(&rCommand{command: c})
	}

	versions := s.builder.build(ctx, job)

	if len(versions) == 0 {
		s.Log(fmt.Sprintf("No versions received for %v", job.Name))
		return ""
	}

	s.Log(fmt.Sprintf("COPYING WITH %v", s.builder))
	err := s.builder.copy(ctx, versions[0])
	if err != nil {
		return ""
	}
	return versions[0].Version
}

func (s *Server) scheduleRun(job *pb.Job) string {
	c := s.translator.run(job)
	return s.scheduler.Schedule(&rCommand{command: c})
}

func (s *Server) taskComplete(key string) bool {
	return s.scheduler.schedulerComplete(key)
}
<commit_msg>More detail to long calc<commit_after>package main

import (
	"fmt"
	"os/exec"
	"time"

	pb "github.com/brotherlogic/gobuildslave/proto"
	pbt "github.com/brotherlogic/tracer/proto"

	"github.com/brotherlogic/goserver/utils"
	"golang.org/x/net/context"
)

const (
	pendWait = time.Minute
)

func (s *Server) runTransition(ctx context.Context, job *pb.JobAssignment) {
	utils.SendTrace(ctx, fmt.Sprintf("run_transition_%v", job.State), time.Now(), pbt.Milestone_MARKER, job.Job.Name)
	stState := job.State
	switch job.State {
	case pb.State_ACKNOWLEDGED:
		key := s.scheduleBuild(ctx, job.Job)
		if job.Job.NonBootstrap {
			if key != "" {
				job.Server = s.Registry.Identifier
				job.State = pb.State_BUILT
				job.RunningVersion = key
			}
		} else {
			job.CommandKey = key
			job.State = pb.State_BUILDING
			job.Server = s.Registry.Identifier
		}
	case pb.State_BUILDING:
		if s.taskComplete(job.CommandKey) {
			job.State = pb.State_BUILT
		}
	case pb.State_BUILT:
		output := s.scheduler.getOutput(job.CommandKey)
		if len(output) > 0 {
			if job.BuildFail == 5 {
				s.deliverCrashReport(ctx, job, output)
			}
			job.BuildFail++
			job.State = pb.State_DIED
		} else {
			job.BuildFail = 0
			key := s.scheduleRun(job.Job)
			job.CommandKey = key
			job.StartTime = time.Now().Unix()
			job.State = pb.State_PENDING
		}
	case pb.State_PENDING:
		if time.Now().Add(-time.Minute).Unix() > job.StartTime {
			job.State = pb.State_RUNNING
		}
	case pb.State_RUNNING:
		if s.taskComplete(job.CommandKey) {
			output := s.scheduler.getOutput(job.CommandKey)
			s.deliverCrashReport(ctx, job, output)
			job.State = pb.State_DIED
		}

		// Restart this job if we need to
		if job.Job.NonBootstrap {
			version := s.getVersion(ctx, job.Job)
			if version != job.RunningVersion {
				s.Log(fmt.Sprintf("KILLING %v", job.Job.Name))
				s.scheduler.killJob(job.CommandKey)
				job.State = pb.State_ACKNOWLEDGED
			}
		}
	case pb.State_DIED:
		job.State = pb.State_ACKNOWLEDGED
	}
	if job.State != stState {
		s.Log(fmt.Sprintf("Job %v went from %v to %v", job.Job.Name, stState, job.State))
	}
}

type translator interface {
	build(job *pb.Job) *exec.Cmd
	run(job *pb.Job) *exec.Cmd
}

type checker interface {
	isAlive(ctx context.Context, job *pb.JobAssignment) bool
}

func (s *Server) getVersion(ctx context.Context, job *pb.Job) string {
	versions := s.builder.build(ctx, job)

	if len(versions) == 0 {
		s.Log(fmt.Sprintf("No versions received for %v", job.Name))
		return ""
	}

	return versions[0].Version

}

// scheduleBuild builds out the job, returning the current version
func (s *Server) scheduleBuild(ctx context.Context, job *pb.Job) string {
	if !job.NonBootstrap {
		c := s.translator.build(job)
		return s.scheduler.Schedule(&rCommand{command: c})
	}

	versions := s.builder.build(ctx, job)

	if len(versions) == 0 {
		s.Log(fmt.Sprintf("No versions received for %v", job.Name))
		return ""
	}

	s.Log(fmt.Sprintf("COPYING WITH %v", s.builder))
	err := s.builder.copy(ctx, versions[0])
	if err != nil {
		return ""
	}
	return versions[0].Version
}

func (s *Server) scheduleRun(job *pb.Job) string {
	c := s.translator.run(job)
	return s.scheduler.Schedule(&rCommand{command: c})
}

func (s *Server) taskComplete(key string) bool {
	return s.scheduler.schedulerComplete(key)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"strings"
)

//=========================================================================================
func main() {
	// two different ways to execute an http.GET
	doGet("http://cnn.com/")
	fmt.Println("")
	doGetClient("http://cnn.com/")
	/**
	 * this does an minimal http.PUT
	 * you might have to add a "Content-Type: some value"
	 * to the request header if you put to a different system
	 * or put a different file type
	 **/
	// replace this url with your PUT enabled restful web server
	doPut("http://localhost:8080/exist/rest/db/eric/golang.xml")
	/** for reference the url above is for an exist-db instance
	 *  to find out more visit http://exist-db.org/
	 **/

}

//=========================================================================================
func doGet(url string) {
	response, err := http.Get(url)
	if err != nil {
		log.Fatal(err)
	} else {
		defer response.Body.Close()
		contents, err := ioutil.ReadAll(response.Body)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println("The calculated length is:", len(string(contents)), "for the url:", url)
		fmt.Println("   ", response.StatusCode)
		hdr := response.Header
		for key, value := range hdr {
			fmt.Println("   ", key, ":", value)
		}
	}
}

//=========================================================================================
func doGetClient(url string) {
	client := &http.Client{}

	response, err := client.Get(url)
	if err != nil {
		log.Fatal(err)
	} else {
		defer response.Body.Close()
		contents, err := ioutil.ReadAll(response.Body)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println("The calculated length is:", len(string(contents)), "for the url:", url)
		fmt.Println("   ", response.StatusCode)
		hdr := response.Header
		for key, value := range hdr {
			fmt.Println("   ", key, ":", value)
		}
	}
}

//=========================================================================================
func doPut(url string) {
	client := &http.Client{}
	request, err := http.NewRequest("PUT", url, strings.NewReader("<golang>really</golang>"))
	request.SetBasicAuth("admin", "admin")
	request.ContentLength = 23
	response, err := client.Do(request)
	if err != nil {
		log.Fatal(err)
	} else {
		defer response.Body.Close()
		contents, err := ioutil.ReadAll(response.Body)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println("The calculated length is:", len(string(contents)), "for the url:", url)
		fmt.Println("   ", response.StatusCode)
		hdr := response.Header
		for key, value := range hdr {
			fmt.Println("   ", key, ":", value)
		}
		fmt.Println(contents)
	}
}
Contact GitHub API Training Shop Blog About
<commit_msg>Update httpClient.go<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"strings"
)

//=========================================================================================
func main() {
	// two different ways to execute an http.GET
	doGet("http://cnn.com/")
	fmt.Println("")
	doGetClient("http://cnn.com/")
	/**
	 * this does an minimal http.PUT
	 * you might have to add a "Content-Type: some value"
	 * to the request header if you put to a different system
	 * or put a different file type
	 **/
	// replace this url with your PUT enabled restful web server
	doPut("http://localhost:8080/exist/rest/db/eric/golang.xml")
	/** for reference the url above is for an exist-db instance
	 *  to find out more visit http://exist-db.org/
	 **/

}

//=========================================================================================
func doGet(url string) {
	response, err := http.Get(url)
	if err != nil {
		log.Fatal(err)
	} else {
		defer response.Body.Close()
		contents, err := ioutil.ReadAll(response.Body)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println("The calculated length is:", len(string(contents)), "for the url:", url)
		fmt.Println("   ", response.StatusCode)
		hdr := response.Header
		for key, value := range hdr {
			fmt.Println("   ", key, ":", value)
		}
	}
}

//=========================================================================================
func doGetClient(url string) {
	client := &http.Client{}

	response, err := client.Get(url)
	if err != nil {
		log.Fatal(err)
	} else {
		defer response.Body.Close()
		contents, err := ioutil.ReadAll(response.Body)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println("The calculated length is:", len(string(contents)), "for the url:", url)
		fmt.Println("   ", response.StatusCode)
		hdr := response.Header
		for key, value := range hdr {
			fmt.Println("   ", key, ":", value)
		}
	}
}

//=========================================================================================
func doPut(url string) {
	client := &http.Client{}
	request, err := http.NewRequest("PUT", url, strings.NewReader("<golang>really</golang>"))
	request.SetBasicAuth("admin", "admin")
	request.ContentLength = 23
	response, err := client.Do(request)
	if err != nil {
		log.Fatal(err)
	} else {
		defer response.Body.Close()
		contents, err := ioutil.ReadAll(response.Body)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println("The calculated length is:", len(string(contents)), "for the url:", url)
		fmt.Println("   ", response.StatusCode)
		hdr := response.Header
		for key, value := range hdr {
			fmt.Println("   ", key, ":", value)
		}
		fmt.Println(contents)
	}
}
<|endoftext|>


<commit_before>package main

import (
    "flag"
    "net/http"
)

func main() {

        flag.Parse()

	http.HandleFunc("/v1/authorize", Authorize)
	http.HandleFunc("/v1/sign", Sign)
	err := http.ListenAndServe(":12345", nil)
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}

}

func Authorize(w http.ResponseWriter, req *http.Request) {

}

func Sign(w http.ResponseWriter, req *http.Request) {

}
<commit_msg>Go fmt.<commit_after>package main

import (
	"flag"
	"net/http"
)

func main() {

	flag.Parse()

	http.HandleFunc("/v1/authorize", Authorize)
	http.HandleFunc("/v1/sign", Sign)
	err := http.ListenAndServe(":12345", nil)
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}

}

func Authorize(w http.ResponseWriter, req *http.Request) {

}

func Sign(w http.ResponseWriter, req *http.Request) {

}
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Contributor:
// - Aaron Meihm ameihm@mozilla.com

package main

import (
	"encoding/json"
	slib "github.com/mozilla/service-map/servicelib"
	"io/ioutil"
	"net/http"
	"testing"
)

func TestGetRRA(t *testing.T) {
	op := opContext{}
	op.newContext(dbconn, false, "127.0.0.1")
	rra, err := getRRA(op, 1)
	if err != nil {
		t.Fatalf("getRRA: %v", err)
	}
	if rra.Name != "test service" {
		t.Fatalf("getRRA: unexpected service name")
	}
	if rra.ConfiRepImpact != "high" {
		t.Fatalf("getRRA: unexpected impact for test service attribute")
	}
}

func TestServiceGetRRA(t *testing.T) {
	client := http.Client{}

	rr, err := client.Get(testserv.URL + "/api/v1/rra/id?id=1")
	if err != nil {
		t.Fatalf("client.Get: %v", err)
	}
	if rr.StatusCode != http.StatusOK {
		t.Fatalf("rra get response code %v", rr.StatusCode)
	}
	buf, err := ioutil.ReadAll(rr.Body)
	if err != nil {
		t.Fatalf("ioutil.ReadAll: %v", err)
	}
	rr.Body.Close()
	var rra slib.RRA
	err = json.Unmarshal(buf, &rra)
	if err != nil {
		t.Fatalf("json.Unmarshal: %v", err)
	}
	if rra.Name != "test service" {
		t.Fatalf("rra get rra had unexpected name")
	}
	if rra.ConfiRepImpact != "high" {
		t.Fatalf("rra get rra had unexpected service attribute value")
	}
	// The RRA should have one group associated with it
	if len(rra.Groups) != 1 {
		t.Fatalf("rra get rra associated with unexpected number of groups")
	}
}

func TestServiceGetNonExistRRA(t *testing.T) {
	client := http.Client{}

	rr, err := client.Get(testserv.URL + "/api/v1/rra/id?id=999")
	if err != nil {
		t.Fatalf("client.Get: %v", err)
	}
	if rr.StatusCode != http.StatusNotFound {
		t.Fatalf("rra get response code %v", rr.StatusCode)
	}
	rr.Body.Close()
}

func TestServiceRRAs(t *testing.T) {
	client := http.Client{}

	rr, err := client.Get(testserv.URL + "/api/v1/rras")
	if err != nil {
		t.Fatalf("client.Get: %v", err)
	}
	if rr.StatusCode != http.StatusOK {
		t.Fatalf("rras get response code %v", rr.StatusCode)
	}

	// The number of RRAs returned should correspond with the number of
	// valid test RRAs we have
	var rraresp slib.RRAsResponse
	dirlist, err := ioutil.ReadDir("./testdata/validrra")
	if err != nil {
		t.Fatalf("ioutil.ReadDir: %v", err)
	}
	buf, err := ioutil.ReadAll(rr.Body)
	if err != nil {
		t.Fatalf("ioutil.ReadAll: %v", err)
	}
	rr.Body.Close()
	err = json.Unmarshal(buf, &rraresp)
	if err != nil {
		t.Fatalf("json.Unmarshal: %v", err)
	}
	if len(dirlist) != len(rraresp.RRAs) {
		t.Fatalf("unexpected rra count from rras endpoint")
	}
}
<commit_msg>add base rra risk test<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Contributor:
// - Aaron Meihm ameihm@mozilla.com

package main

import (
	"encoding/json"
	slib "github.com/mozilla/service-map/servicelib"
	"io/ioutil"
	"net/http"
	"testing"
)

func TestGetRRA(t *testing.T) {
	op := opContext{}
	op.newContext(dbconn, false, "127.0.0.1")
	rra, err := getRRA(op, 1)
	if err != nil {
		t.Fatalf("getRRA: %v", err)
	}
	if rra.Name != "test service" {
		t.Fatalf("getRRA: unexpected service name")
	}
	if rra.ConfiRepImpact != "high" {
		t.Fatalf("getRRA: unexpected impact for test service attribute")
	}
}

func TestServiceGetRRA(t *testing.T) {
	client := http.Client{}

	rr, err := client.Get(testserv.URL + "/api/v1/rra/id?id=1")
	if err != nil {
		t.Fatalf("client.Get: %v", err)
	}
	if rr.StatusCode != http.StatusOK {
		t.Fatalf("rra get response code %v", rr.StatusCode)
	}
	buf, err := ioutil.ReadAll(rr.Body)
	if err != nil {
		t.Fatalf("ioutil.ReadAll: %v", err)
	}
	rr.Body.Close()
	var rra slib.RRA
	err = json.Unmarshal(buf, &rra)
	if err != nil {
		t.Fatalf("json.Unmarshal: %v", err)
	}
	if rra.Name != "test service" {
		t.Fatalf("rra get rra had unexpected name")
	}
	if rra.ConfiRepImpact != "high" {
		t.Fatalf("rra get rra had unexpected service attribute value")
	}
	// The RRA should have one group associated with it
	if len(rra.Groups) != 1 {
		t.Fatalf("rra get rra associated with unexpected number of groups")
	}
}

func TestServiceGetNonExistRRA(t *testing.T) {
	client := http.Client{}

	rr, err := client.Get(testserv.URL + "/api/v1/rra/id?id=999")
	if err != nil {
		t.Fatalf("client.Get: %v", err)
	}
	if rr.StatusCode != http.StatusNotFound {
		t.Fatalf("rra get response code %v", rr.StatusCode)
	}
	rr.Body.Close()
}

func TestServiceGetRRARisk(t *testing.T) {
	client := http.Client{}

	rr, err := client.Get(testserv.URL + "/api/v1/rra/risk?id=1")
	if err != nil {
		t.Fatalf("client.Get: %v", err)
	}
	if rr.StatusCode != http.StatusOK {
		t.Fatalf("rra get response code %v", rr.StatusCode)
	}
	rr.Body.Close()
}

func TestServiceRRAs(t *testing.T) {
	client := http.Client{}

	rr, err := client.Get(testserv.URL + "/api/v1/rras")
	if err != nil {
		t.Fatalf("client.Get: %v", err)
	}
	if rr.StatusCode != http.StatusOK {
		t.Fatalf("rras get response code %v", rr.StatusCode)
	}

	// The number of RRAs returned should correspond with the number of
	// valid test RRAs we have
	var rraresp slib.RRAsResponse
	dirlist, err := ioutil.ReadDir("./testdata/validrra")
	if err != nil {
		t.Fatalf("ioutil.ReadDir: %v", err)
	}
	buf, err := ioutil.ReadAll(rr.Body)
	if err != nil {
		t.Fatalf("ioutil.ReadAll: %v", err)
	}
	rr.Body.Close()
	err = json.Unmarshal(buf, &rraresp)
	if err != nil {
		t.Fatalf("json.Unmarshal: %v", err)
	}
	if len(dirlist) != len(rraresp.RRAs) {
		t.Fatalf("unexpected rra count from rras endpoint")
	}
}
<|endoftext|>


<commit_before>// Copyright 2015, David Howden
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package index

import (
	"reflect"
	"sort"
	"testing"
)

func stringSet(s []string) map[string]bool {
	ss := make(map[string]bool)
	for _, x := range s {
		ss[x] = true
	}
	return ss
}

func TestPrefixMultiExpander(t *testing.T) {
	tests := []struct {
		words []string
		n     int
		in    string
		out   []string
	}{
		// Single word, prefix 3
		{
			[]string{"hello"},
			3,
			"hel",
			[]string{"hello"},
		},

		// Single word, prefix up to 4
		{
			[]string{"hello"},
			4,
			"hel",
			[]string{"hello"},
		},

		{
			[]string{"hello"},
			3,
			"he",
			[]string{"he"},
		},

		{
			[]string{"hello"},
			3,
			"x",
			[]string{"x"},
		},

		{
			[]string{"hello", "helloworld"},
			3,
			"hel",
			[]string{"hello", "helloworld"},
		},

		// // Two words, the same, different
		// {
		// 	[]string{"hello", "hellothere"},
		// 	10,
		// 	[]string{"", "h", "he", "hel", "hell", "hello", "hellot", "helloth", "hellothere"},
		// 	[]string{"", "", "", "", "", "", "hellothere", "hellothere", "hellothere"},
		// 	[]bool{false, false, false, false, false, false, true, true, true},
		// },
		//

		// Multiple unique words
		{
			[]string{"prokofiev", "shostakovich", "tchaikovsky", "rachmaninov", "rachmaninoff", "xenakis"},
			3,
			"pro",
			[]string{"prokofiev"},
		},

		// Multiple unique words
		{
			[]string{"prokofiev", "shostakovich", "tchaikovsky", "rachmaninov", "rachmaninoff", "xenakis"},
			3,
			"tch",
			[]string{"tchaikovsky"},
		},

		// Multiple unique words
		{
			[]string{"prokofiev", "shostakovich", "tchaikovsky", "rachmaninov", "rachmaninoff", "xenakis"},
			3,
			"rachmanin",
			[]string{"rachmaninoff", "rachmaninov"},
		}, // Multiple unique words
	}

	for ii, tt := range tests {
		pm := BuildPrefixMultiExpander(tt.words, tt.n)
		got := pm.Expand(tt.in)
		if !reflect.DeepEqual(stringSet(tt.out), stringSet(got)) {
			t.Errorf("[%d] Expand(%#v) = %#v expected: %#v (compared unordered)", ii, tt.in, got, tt.out)
		}
	}
}

func TestFlattenSearch(t *testing.T) {
	tests := []struct {
		in, out string
	}{
		{
			"",
			"",
		},
		{
			"Ravel",
			"ravel",
		},
		{
			"Dvorák",
			"dvorak",
		},
		{
			"Saint-Saëns",
			"saint saens",
		},
	}

	for ii, tt := range tests {
		got := removeNonAlphaNumeric(tt.in)
		if got != tt.out {
			t.Errorf("[%d] removeNonAlphaNumeric(%#v) = %#v, expected %#v", ii, tt.in, got, tt.out)
		}
	}
}

func TestWordIndex(t *testing.T) {
	tests := []struct {
		in    map[string][]Path
		out   map[string][]Path
		words []string
	}{
		{
			map[string][]Path{
				"gustav mahler": []Path{
					Path{"Root", "Gustav Mahler", "Symphony No 1", "0"},
					Path{"Root", "Gustav Mahler", "Symphony No 1", "1"},
					Path{"Root", "Gustav Mahler", "Symphony No 1", "2"},
				},
			},
			map[string][]Path{
				"gustav": []Path{
					Path{"Root", "Gustav Mahler", "Symphony No 1", "0"},
					Path{"Root", "Gustav Mahler", "Symphony No 1", "1"},
					Path{"Root", "Gustav Mahler", "Symphony No 1", "2"},
				},
				"mahler": []Path{
					Path{"Root", "Gustav Mahler", "Symphony No 1", "0"},
					Path{"Root", "Gustav Mahler", "Symphony No 1", "1"},
					Path{"Root", "Gustav Mahler", "Symphony No 1", "2"},
				},
			},
			[]string{"gustav", "mahler"},
		},
		{
			map[string][]Path{
				"gustav - mahler": []Path{
					Path{"Root", "Gustav Mahler", "Symphony No 1", "0"},
					Path{"Root", "Gustav Mahler", "Symphony No 1", "1"},
					Path{"Root", "Gustav Mahler", "Symphony No 1", "2"},
				},
			},
			map[string][]Path{
				"gustav": []Path{
					Path{"Root", "Gustav Mahler", "Symphony No 1", "0"},
					Path{"Root", "Gustav Mahler", "Symphony No 1", "1"},
					Path{"Root", "Gustav Mahler", "Symphony No 1", "2"},
				},
				"mahler": []Path{
					Path{"Root", "Gustav Mahler", "Symphony No 1", "0"},
					Path{"Root", "Gustav Mahler", "Symphony No 1", "1"},
					Path{"Root", "Gustav Mahler", "Symphony No 1", "2"},
				},
			},
			[]string{"gustav", "mahler"},
		},
	}

	for ii, tt := range tests {
		w := &wordIndex{
			fields: []string{},
			words:  make(map[string][]Path),
		}

		for s, ps := range tt.in {
			for _, p := range ps {
				w.AddString(s, p)
			}
		}

		for k, v := range tt.out {
			ps := w.Search(k)
			if !reflect.DeepEqual(ps, v) {
				t.Errorf("[%d] does't match: %#v, %#v", ii, ps, v)
			}
		}

		got := w.Words()
		sort.Strings(got)
		if !reflect.DeepEqual(got, tt.words) {
			t.Errorf("[%d] words don't match:\n%#v\n%#v\n", ii, got, tt.words)
		}
	}
}
<commit_msg>Renamed test<commit_after>// Copyright 2015, David Howden
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package index

import (
	"reflect"
	"sort"
	"testing"
)

func stringSet(s []string) map[string]bool {
	ss := make(map[string]bool)
	for _, x := range s {
		ss[x] = true
	}
	return ss
}

func TestPrefixMultiExpander(t *testing.T) {
	tests := []struct {
		words []string
		n     int
		in    string
		out   []string
	}{
		// Single word, prefix 3
		{
			[]string{"hello"},
			3,
			"hel",
			[]string{"hello"},
		},

		// Single word, prefix up to 4
		{
			[]string{"hello"},
			4,
			"hel",
			[]string{"hello"},
		},

		{
			[]string{"hello"},
			3,
			"he",
			[]string{"he"},
		},

		{
			[]string{"hello"},
			3,
			"x",
			[]string{"x"},
		},

		{
			[]string{"hello", "helloworld"},
			3,
			"hel",
			[]string{"hello", "helloworld"},
		},

		// // Two words, the same, different
		// {
		// 	[]string{"hello", "hellothere"},
		// 	10,
		// 	[]string{"", "h", "he", "hel", "hell", "hello", "hellot", "helloth", "hellothere"},
		// 	[]string{"", "", "", "", "", "", "hellothere", "hellothere", "hellothere"},
		// 	[]bool{false, false, false, false, false, false, true, true, true},
		// },
		//

		// Multiple unique words
		{
			[]string{"prokofiev", "shostakovich", "tchaikovsky", "rachmaninov", "rachmaninoff", "xenakis"},
			3,
			"pro",
			[]string{"prokofiev"},
		},

		// Multiple unique words
		{
			[]string{"prokofiev", "shostakovich", "tchaikovsky", "rachmaninov", "rachmaninoff", "xenakis"},
			3,
			"tch",
			[]string{"tchaikovsky"},
		},

		// Multiple unique words
		{
			[]string{"prokofiev", "shostakovich", "tchaikovsky", "rachmaninov", "rachmaninoff", "xenakis"},
			3,
			"rachmanin",
			[]string{"rachmaninoff", "rachmaninov"},
		}, // Multiple unique words
	}

	for ii, tt := range tests {
		pm := BuildPrefixMultiExpander(tt.words, tt.n)
		got := pm.Expand(tt.in)
		if !reflect.DeepEqual(stringSet(tt.out), stringSet(got)) {
			t.Errorf("[%d] Expand(%#v) = %#v expected: %#v (compared unordered)", ii, tt.in, got, tt.out)
		}
	}
}

func TestRemoveNonAlphaNumeric(t *testing.T) {
	tests := []struct {
		in, out string
	}{
		{
			"",
			"",
		},
		{
			"Ravel",
			"ravel",
		},
		{
			"Dvorák",
			"dvorak",
		},
		{
			"Saint-Saëns",
			"saint saens",
		},
	}

	for ii, tt := range tests {
		got := removeNonAlphaNumeric(tt.in)
		if got != tt.out {
			t.Errorf("[%d] removeNonAlphaNumeric(%#v) = %#v, expected %#v", ii, tt.in, got, tt.out)
		}
	}
}

func TestWordIndex(t *testing.T) {
	tests := []struct {
		in    map[string][]Path
		out   map[string][]Path
		words []string
	}{
		{
			map[string][]Path{
				"gustav mahler": []Path{
					Path{"Root", "Gustav Mahler", "Symphony No 1", "0"},
					Path{"Root", "Gustav Mahler", "Symphony No 1", "1"},
					Path{"Root", "Gustav Mahler", "Symphony No 1", "2"},
				},
			},
			map[string][]Path{
				"gustav": []Path{
					Path{"Root", "Gustav Mahler", "Symphony No 1", "0"},
					Path{"Root", "Gustav Mahler", "Symphony No 1", "1"},
					Path{"Root", "Gustav Mahler", "Symphony No 1", "2"},
				},
				"mahler": []Path{
					Path{"Root", "Gustav Mahler", "Symphony No 1", "0"},
					Path{"Root", "Gustav Mahler", "Symphony No 1", "1"},
					Path{"Root", "Gustav Mahler", "Symphony No 1", "2"},
				},
			},
			[]string{"gustav", "mahler"},
		},
		{
			map[string][]Path{
				"gustav - mahler": []Path{
					Path{"Root", "Gustav Mahler", "Symphony No 1", "0"},
					Path{"Root", "Gustav Mahler", "Symphony No 1", "1"},
					Path{"Root", "Gustav Mahler", "Symphony No 1", "2"},
				},
			},
			map[string][]Path{
				"gustav": []Path{
					Path{"Root", "Gustav Mahler", "Symphony No 1", "0"},
					Path{"Root", "Gustav Mahler", "Symphony No 1", "1"},
					Path{"Root", "Gustav Mahler", "Symphony No 1", "2"},
				},
				"mahler": []Path{
					Path{"Root", "Gustav Mahler", "Symphony No 1", "0"},
					Path{"Root", "Gustav Mahler", "Symphony No 1", "1"},
					Path{"Root", "Gustav Mahler", "Symphony No 1", "2"},
				},
			},
			[]string{"gustav", "mahler"},
		},
	}

	for ii, tt := range tests {
		w := &wordIndex{
			fields: []string{},
			words:  make(map[string][]Path),
		}

		for s, ps := range tt.in {
			for _, p := range ps {
				w.AddString(s, p)
			}
		}

		for k, v := range tt.out {
			ps := w.Search(k)
			if !reflect.DeepEqual(ps, v) {
				t.Errorf("[%d] does't match: %#v, %#v", ii, ps, v)
			}
		}

		got := w.Words()
		sort.Strings(got)
		if !reflect.DeepEqual(got, tt.words) {
			t.Errorf("[%d] words don't match:\n%#v\n%#v\n", ii, got, tt.words)
		}
	}
}
<|endoftext|>


<commit_before>package middleware

import (
	"net/http"
)

func copyHeaders(src, dest http.Header) {
	for k, v := range src {
		dest[k] = v
	}
}

// ErrorHandler lets you call an alternate http handler upon a certain response code.
// Note it will assume a 200 if the wrapped handler does not write anything
type ErrorHandler struct {
	Code    int
	Handler http.Handler
}

func (e ErrorHandler) Wrap(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		i := newErrorInterceptor(w, e.Code)
		next.ServeHTTP(i, r)
		if !i.gotCode {
			i.WriteHeader(http.StatusOK)
		}
		if i.intercepted {
			e.Handler.ServeHTTP(w, r)
		}
	})
}

// errorInterceptor wraps an underlying ResponseWriter and buffers all header changes, until it knows the return code.
// It then passes everything through, unless the code matches the target code, in which case it will discard everything.
type errorInterceptor struct {
	originalWriter http.ResponseWriter
	targetCode     int
	headers        http.Header
	gotCode        bool
	intercepted    bool
}

func newErrorInterceptor(w http.ResponseWriter, code int) *errorInterceptor {
	i := errorInterceptor{originalWriter: w, targetCode: code}
	i.headers = make(http.Header)
	copyHeaders(w.Header(), i.headers)
	return &i
}

func (i errorInterceptor) Header() http.Header {
	return i.headers
}

func (i errorInterceptor) WriteHeader(code int) {
	if i.gotCode {
		panic("errorInterceptor.WriteHeader() called twice")
	}

	i.gotCode = true
	if code == i.targetCode {
		i.intercepted = true
	} else {
		copyHeaders(i.headers, i.originalWriter.Header())
		i.originalWriter.WriteHeader(code)
	}
}

func (i errorInterceptor) Write(data []byte) (int, error) {
	if !i.gotCode {
		i.WriteHeader(http.StatusOK)
	}
	if !i.intercepted {
		return i.originalWriter.Write(data)
	}
	return len(data), nil
}
<commit_msg>appease linter<commit_after>package middleware

import (
	"net/http"
)

func copyHeaders(src, dest http.Header) {
	for k, v := range src {
		dest[k] = v
	}
}

// ErrorHandler lets you call an alternate http handler upon a certain response code.
// Note it will assume a 200 if the wrapped handler does not write anything
type ErrorHandler struct {
	Code    int
	Handler http.Handler
}

// Wrap implements Middleware
func (e ErrorHandler) Wrap(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		i := newErrorInterceptor(w, e.Code)
		next.ServeHTTP(i, r)
		if !i.gotCode {
			i.WriteHeader(http.StatusOK)
		}
		if i.intercepted {
			e.Handler.ServeHTTP(w, r)
		}
	})
}

// errorInterceptor wraps an underlying ResponseWriter and buffers all header changes, until it knows the return code.
// It then passes everything through, unless the code matches the target code, in which case it will discard everything.
type errorInterceptor struct {
	originalWriter http.ResponseWriter
	targetCode     int
	headers        http.Header
	gotCode        bool
	intercepted    bool
}

func newErrorInterceptor(w http.ResponseWriter, code int) *errorInterceptor {
	i := errorInterceptor{originalWriter: w, targetCode: code}
	i.headers = make(http.Header)
	copyHeaders(w.Header(), i.headers)
	return &i
}

// Header implements http.ResponseWriter
func (i errorInterceptor) Header() http.Header {
	return i.headers
}

// WriteHeader implements http.ResponseWriter
func (i errorInterceptor) WriteHeader(code int) {
	if i.gotCode {
		panic("errorInterceptor.WriteHeader() called twice")
	}

	i.gotCode = true
	if code == i.targetCode {
		i.intercepted = true
	} else {
		copyHeaders(i.headers, i.originalWriter.Header())
		i.originalWriter.WriteHeader(code)
	}
}

// Write implements http.ResponseWriter
func (i errorInterceptor) Write(data []byte) (int, error) {
	if !i.gotCode {
		i.WriteHeader(http.StatusOK)
	}
	if !i.intercepted {
		return i.originalWriter.Write(data)
	}
	return len(data), nil
}
<|endoftext|>


<commit_before>//go:build windows
// +build windows

// Copyright (c) 2021 Blacknon. All rights reserved.
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.

/*
common is a package that summarizes the common processing of lssh package.
*/

package sftp

import "golang.org/x/sys/windows"

func getFileStat(i interface{}) (uid, gid uint32, size int64) {
	if stat, ok := i.(*windows.Win32FileAttributeData); ok {
		size int64 = stat.FileSizeHigh
	}

	uid = nil
	gid = nil

	return
}
<commit_msg>update. test github actions<commit_after>//go:build windows
// +build windows

// Copyright (c) 2021 Blacknon. All rights reserved.
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.

/*
common is a package that summarizes the common processing of lssh package.
*/

package sftp

import "golang.org/x/sys/windows"

func getFileStat(i interface{}) (uid, gid uint32, size int64) {
	if stat, ok := i.(*windows.Win32FileAttributeData); ok {
		size int64 = stat.FileSizeHigh
	}

	uid = 0
	gid = 0

	return
}
<|endoftext|>


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

package dashboard

// This file handles operations on the CL entity kind.

import (
	"encoding/json"
	"fmt"
	"html/template"
	"io"
	"net/http"
	"net/url"
	"regexp"
	"sort"
	"strings"
	"time"

	"appengine"
	"appengine/datastore"
	"appengine/mail"
	"appengine/taskqueue"
	"appengine/urlfetch"
	"appengine/user"
)

func init() {
	http.HandleFunc("/assign", handleAssign)
	http.HandleFunc("/update-cl", handleUpdateCL)
}

const codereviewBase = "http://codereview.appspot.com"

var clRegexp = regexp.MustCompile(`\d+`)

// CL represents a code review.
type CL struct {
	Number string // e.g. "5903061"
	Closed bool
	Owner  string // email address

	Created, Modified time.Time

	Description []byte `datastore:",noindex"`
	FirstLine   string `datastore:",noindex"`
	LGTMs       []string

	// Mail information.
	Subject       string   `datastore:",noindex"`
	Recipients    []string `datastore:",noindex"`
	LastMessageID string   `datastore:",noindex"`

	// These are person IDs (e.g. "rsc"); they may be empty
	Author   string
	Reviewer string
}

// DisplayOwner returns the CL's owner, either as their email address
// or the person ID if it's a reviewer. It is for display only.
func (cl *CL) DisplayOwner() string {
	if p, ok := emailToPerson[cl.Owner]; ok {
		return p
	}
	return cl.Owner
}

func (cl *CL) FirstLineHTML() template.HTML {
	s := template.HTMLEscapeString(cl.FirstLine)
	// Embolden the package name.
	if i := strings.Index(s, ":"); i >= 0 {
		s = "" + s[:i] + "" + s[i:]
	}
	return template.HTML(s)
}

func (cl *CL) LGTMHTML() template.HTML {
	x := make([]string, len(cl.LGTMs))
	for i, s := range cl.LGTMs {
		s = template.HTMLEscapeString(s)
		if !strings.Contains(s, "@") {
			s = "" + s + ""
		}
		s = `<span class="email">` + s + ""
		x[i] = s
	}
	return template.HTML(strings.Join(x, ", "))
}

func (cl *CL) ModifiedAgo() string {
	// Just the first non-zero unit.
	units := [...]struct {
		suffix string
		unit   time.Duration
	}{
		{"d", 24 * time.Hour},
		{"h", time.Hour},
		{"m", time.Minute},
		{"s", time.Second},
	}
	d := time.Now().Sub(cl.Modified)
	for _, u := range units {
		if d > u.unit {
			return fmt.Sprintf("%d%s", d/u.unit, u.suffix)
		}
	}
	return "just now"
}

func handleAssign(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)

	if r.Method != "POST" {
		http.Error(w, "Bad method "+r.Method, 400)
		return
	}

	u := user.Current(c)
	if _, ok := emailToPerson[u.Email]; !ok {
		http.Error(w, "Not allowed", http.StatusUnauthorized)
		return
	}

	n, rev := r.FormValue("cl"), r.FormValue("r")
	if !clRegexp.MatchString(n) {
		c.Errorf("Bad CL %q", n)
		http.Error(w, "Bad CL", 400)
		return
	}
	if _, ok := preferredEmail[rev]; !ok && rev != "" {
		c.Errorf("Unknown reviewer %q", rev)
		http.Error(w, "Unknown reviewer", 400)
		return
	}

	key := datastore.NewKey(c, "CL", n, 0, nil)

	if rev != "" {
		// Make sure the reviewer is listed in Rietveld as a reviewer.
		url := codereviewBase + "/" + n + "/fields"
		resp, err := urlfetch.Client(c).Get(url + "?field=reviewers")
		if err != nil {
			c.Errorf("Retrieving CL reviewer list failed: %v", err)
			http.Error(w, err.Error(), 500)
			return
		}
		defer resp.Body.Close()
		if resp.StatusCode != 200 {
			c.Errorf("Retrieving CL reviewer list failed: got HTTP response %d", resp.StatusCode)
			http.Error(w, "Failed contacting Rietveld", 500)
			return
		}

		var apiResp struct {
			Reviewers []string `json:"reviewers"`
		}
		if err := json.NewDecoder(resp.Body).Decode(&apiResp); err != nil {
			// probably can't be retried
			msg := fmt.Sprintf("Malformed JSON from %v: %v", url, err)
			c.Errorf("%s", msg)
			http.Error(w, msg, 500)
			return
		}
		found := false
		for _, r := range apiResp.Reviewers {
			if emailToPerson[r] == rev {
				found = true
				break
			}
		}
		if !found {
			c.Infof("Adding %v as a reviewer of CL %v", rev, n)

			// We can't do this easily, as we need authentication to edit
			// an issue on behalf of a user, which is non-trivial. For now,
			// just send a mail with the body "R=<reviewer>", Cc'ing that person,
			// and rely on social convention.
			cl := new(CL)
			err := datastore.Get(c, key, cl)
			if err != nil {
				c.Errorf("%s", err)
				http.Error(w, err.Error(), 500)
				return
			}
			msg := &mail.Message{
				Sender: u.Email,
				To:     []string{preferredEmail[rev]},
				Cc:     cl.Recipients,
				// Take care to match Rietveld's subject line
				// so that Gmail will correctly thread mail.
				Subject: cl.Subject + " (issue " + n + ")",
				Body:    "R=" + rev + "\n\n(sent by gocodereview)",
			}
			// TODO(dsymonds): Use cl.LastMessageID as the In-Reply-To header
			// when the appengine/mail package supports that.
			if err := mail.Send(c, msg); err != nil {
				c.Errorf("mail.Send: %v", err)
			}
		}
	}

	// Update our own record.
	err := datastore.RunInTransaction(c, func(c appengine.Context) error {
		cl := new(CL)
		err := datastore.Get(c, key, cl)
		if err != nil {
			return err
		}
		cl.Reviewer = rev
		_, err = datastore.Put(c, key, cl)
		return err
	}, nil)
	if err != nil {
		msg := fmt.Sprintf("Assignment failed: %v", err)
		c.Errorf("%s", msg)
		http.Error(w, msg, 500)
		return
	}
	c.Infof("Assigned CL %v to %v", n, rev)
}

func UpdateCLLater(c appengine.Context, n string, delay time.Duration) {
	t := taskqueue.NewPOSTTask("/update-cl", url.Values{
		"cl": []string{n},
	})
	t.Delay = delay
	if _, err := taskqueue.Add(c, t, "update-cl"); err != nil {
		c.Errorf("Failed adding task: %v", err)
	}
}

func handleUpdateCL(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)

	n := r.FormValue("cl")
	if !clRegexp.MatchString(n) {
		c.Errorf("Bad CL %q", n)
		http.Error(w, "Bad CL", 400)
		return
	}

	if err := updateCL(c, n); err != nil {
		c.Errorf("Failed updating CL %v: %v", n, err)
		http.Error(w, "Failed update", 500)
		return
	}

	io.WriteString(w, "OK")
}

// updateCL updates a single CL. If a retryable failure occurs, an error is returned.
func updateCL(c appengine.Context, n string) error {
	c.Debugf("Updating CL %v", n)

	url := codereviewBase + "/api/" + n + "?messages=true"
	resp, err := urlfetch.Client(c).Get(url)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		return fmt.Errorf("Update: got HTTP response %d", resp.StatusCode)
	}

	var apiResp struct {
		Description string `json:"description"`
		Created     string `json:"created"`
		OwnerEmail  string `json:"owner_email"`
		Modified    string `json:"modified"`
		Closed      bool   `json:"closed"`
		Subject     string `json:"subject"`
		Messages    []struct {
			Text       string   `json:"text"`
			Sender     string   `json:"sender"`
			Recipients []string `json:"recipients"`
			Approval   bool     `json:"approval"`
		} `json:"messages"`
	}
	if err := json.NewDecoder(resp.Body).Decode(&apiResp); err != nil {
		// probably can't be retried
		c.Errorf("Malformed JSON from %v: %v", url, err)
		return nil
	}
	//c.Infof("RAW: %+v", apiResp)

	cl := &CL{
		Number:      n,
		Closed:      apiResp.Closed,
		Owner:       apiResp.OwnerEmail,
		Description: []byte(apiResp.Description),
		FirstLine:   apiResp.Description,
		Subject:     apiResp.Subject,
		Author:      emailToPerson[apiResp.OwnerEmail],
	}
	cl.Created, err = time.Parse("2006-01-02 15:04:05.000000", apiResp.Created)
	if err != nil {
		c.Errorf("Bad creation time %q: %v", apiResp.Created, err)
	}
	cl.Modified, err = time.Parse("2006-01-02 15:04:05.000000", apiResp.Modified)
	if err != nil {
		c.Errorf("Bad modification time %q: %v", apiResp.Modified, err)
	}
	if i := strings.Index(cl.FirstLine, "\n"); i >= 0 {
		cl.FirstLine = cl.FirstLine[:i]
	}
	lgtm := make(map[string]bool)
	rcpt := make(map[string]bool)
	for _, msg := range apiResp.Messages {
		s, rev := msg.Sender, false
		if p, ok := emailToPerson[s]; ok {
			s, rev = p, true
		}

		// CLs submitted by someone other than the CL owner do not immediately
		// transition to "closed". Let's simulate the intention by treating
		// messages starting with "*** Submitted as " from a reviewer as a
		// signal that the CL is now closed.
		if rev && strings.HasPrefix(msg.Text, "*** Submitted as ") {
			cl.Closed = true
		}

		if msg.Approval {
			lgtm[s] = true
		}

		for _, r := range msg.Recipients {
			rcpt[r] = true
		}
	}
	for l := range lgtm {
		cl.LGTMs = append(cl.LGTMs, l)
	}
	for r := range rcpt {
		cl.Recipients = append(cl.Recipients, r)
	}
	sort.Strings(cl.LGTMs)
	sort.Strings(cl.Recipients)

	key := datastore.NewKey(c, "CL", n, 0, nil)
	err = datastore.RunInTransaction(c, func(c appengine.Context) error {
		ocl := new(CL)
		err := datastore.Get(c, key, ocl)
		if err != nil && err != datastore.ErrNoSuchEntity {
			return err
		} else if err == nil {
			// LastMessageID and Reviewer need preserving.
			cl.LastMessageID = ocl.LastMessageID
			cl.Reviewer = ocl.Reviewer
		}
		_, err = datastore.Put(c, key, cl)
		return err
	}, nil)
	if err != nil {
		return err
	}
	c.Infof("Updated CL %v", n)
	return nil
}
<commit_msg>misc/dashboard/codereview: set In-Reply-To header to properly thread mail.<commit_after>// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package dashboard

// This file handles operations on the CL entity kind.

import (
	"encoding/json"
	"fmt"
	"html/template"
	"io"
	"net/http"
	netmail "net/mail"
	"net/url"
	"regexp"
	"sort"
	"strings"
	"time"

	"appengine"
	"appengine/datastore"
	"appengine/mail"
	"appengine/taskqueue"
	"appengine/urlfetch"
	"appengine/user"
)

func init() {
	http.HandleFunc("/assign", handleAssign)
	http.HandleFunc("/update-cl", handleUpdateCL)
}

const codereviewBase = "http://codereview.appspot.com"

var clRegexp = regexp.MustCompile(`\d+`)

// CL represents a code review.
type CL struct {
	Number string // e.g. "5903061"
	Closed bool
	Owner  string // email address

	Created, Modified time.Time

	Description []byte `datastore:",noindex"`
	FirstLine   string `datastore:",noindex"`
	LGTMs       []string

	// Mail information.
	Subject       string   `datastore:",noindex"`
	Recipients    []string `datastore:",noindex"`
	LastMessageID string   `datastore:",noindex"`

	// These are person IDs (e.g. "rsc"); they may be empty
	Author   string
	Reviewer string
}

// DisplayOwner returns the CL's owner, either as their email address
// or the person ID if it's a reviewer. It is for display only.
func (cl *CL) DisplayOwner() string {
	if p, ok := emailToPerson[cl.Owner]; ok {
		return p
	}
	return cl.Owner
}

func (cl *CL) FirstLineHTML() template.HTML {
	s := template.HTMLEscapeString(cl.FirstLine)
	// Embolden the package name.
	if i := strings.Index(s, ":"); i >= 0 {
		s = "" + s[:i] + "" + s[i:]
	}
	return template.HTML(s)
}

func (cl *CL) LGTMHTML() template.HTML {
	x := make([]string, len(cl.LGTMs))
	for i, s := range cl.LGTMs {
		s = template.HTMLEscapeString(s)
		if !strings.Contains(s, "@") {
			s = "" + s + ""
		}
		s = `<span class="email">` + s + ""
		x[i] = s
	}
	return template.HTML(strings.Join(x, ", "))
}

func (cl *CL) ModifiedAgo() string {
	// Just the first non-zero unit.
	units := [...]struct {
		suffix string
		unit   time.Duration
	}{
		{"d", 24 * time.Hour},
		{"h", time.Hour},
		{"m", time.Minute},
		{"s", time.Second},
	}
	d := time.Now().Sub(cl.Modified)
	for _, u := range units {
		if d > u.unit {
			return fmt.Sprintf("%d%s", d/u.unit, u.suffix)
		}
	}
	return "just now"
}

func handleAssign(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)

	if r.Method != "POST" {
		http.Error(w, "Bad method "+r.Method, 400)
		return
	}

	u := user.Current(c)
	if _, ok := emailToPerson[u.Email]; !ok {
		http.Error(w, "Not allowed", http.StatusUnauthorized)
		return
	}

	n, rev := r.FormValue("cl"), r.FormValue("r")
	if !clRegexp.MatchString(n) {
		c.Errorf("Bad CL %q", n)
		http.Error(w, "Bad CL", 400)
		return
	}
	if _, ok := preferredEmail[rev]; !ok && rev != "" {
		c.Errorf("Unknown reviewer %q", rev)
		http.Error(w, "Unknown reviewer", 400)
		return
	}

	key := datastore.NewKey(c, "CL", n, 0, nil)

	if rev != "" {
		// Make sure the reviewer is listed in Rietveld as a reviewer.
		url := codereviewBase + "/" + n + "/fields"
		resp, err := urlfetch.Client(c).Get(url + "?field=reviewers")
		if err != nil {
			c.Errorf("Retrieving CL reviewer list failed: %v", err)
			http.Error(w, err.Error(), 500)
			return
		}
		defer resp.Body.Close()
		if resp.StatusCode != 200 {
			c.Errorf("Retrieving CL reviewer list failed: got HTTP response %d", resp.StatusCode)
			http.Error(w, "Failed contacting Rietveld", 500)
			return
		}

		var apiResp struct {
			Reviewers []string `json:"reviewers"`
		}
		if err := json.NewDecoder(resp.Body).Decode(&apiResp); err != nil {
			// probably can't be retried
			msg := fmt.Sprintf("Malformed JSON from %v: %v", url, err)
			c.Errorf("%s", msg)
			http.Error(w, msg, 500)
			return
		}
		found := false
		for _, r := range apiResp.Reviewers {
			if emailToPerson[r] == rev {
				found = true
				break
			}
		}
		if !found {
			c.Infof("Adding %v as a reviewer of CL %v", rev, n)

			// We can't do this easily, as we need authentication to edit
			// an issue on behalf of a user, which is non-trivial. For now,
			// just send a mail with the body "R=<reviewer>", Cc'ing that person,
			// and rely on social convention.
			cl := new(CL)
			err := datastore.Get(c, key, cl)
			if err != nil {
				c.Errorf("%s", err)
				http.Error(w, err.Error(), 500)
				return
			}
			msg := &mail.Message{
				Sender: u.Email,
				To:     []string{preferredEmail[rev]},
				Cc:     cl.Recipients,
				// Take care to match Rietveld's subject line
				// so that Gmail will correctly thread mail.
				Subject: cl.Subject + " (issue " + n + ")",
				Body:    "R=" + rev + "\n\n(sent by gocodereview)",
			}
			if cl.LastMessageID != "" {
				msg.Headers = netmail.Header{
					"In-Reply-To": []string{cl.LastMessageID},
				}
			}
			if err := mail.Send(c, msg); err != nil {
				c.Errorf("mail.Send: %v", err)
			}
		}
	}

	// Update our own record.
	err := datastore.RunInTransaction(c, func(c appengine.Context) error {
		cl := new(CL)
		err := datastore.Get(c, key, cl)
		if err != nil {
			return err
		}
		cl.Reviewer = rev
		_, err = datastore.Put(c, key, cl)
		return err
	}, nil)
	if err != nil {
		msg := fmt.Sprintf("Assignment failed: %v", err)
		c.Errorf("%s", msg)
		http.Error(w, msg, 500)
		return
	}
	c.Infof("Assigned CL %v to %v", n, rev)
}

func UpdateCLLater(c appengine.Context, n string, delay time.Duration) {
	t := taskqueue.NewPOSTTask("/update-cl", url.Values{
		"cl": []string{n},
	})
	t.Delay = delay
	if _, err := taskqueue.Add(c, t, "update-cl"); err != nil {
		c.Errorf("Failed adding task: %v", err)
	}
}

func handleUpdateCL(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)

	n := r.FormValue("cl")
	if !clRegexp.MatchString(n) {
		c.Errorf("Bad CL %q", n)
		http.Error(w, "Bad CL", 400)
		return
	}

	if err := updateCL(c, n); err != nil {
		c.Errorf("Failed updating CL %v: %v", n, err)
		http.Error(w, "Failed update", 500)
		return
	}

	io.WriteString(w, "OK")
}

// updateCL updates a single CL. If a retryable failure occurs, an error is returned.
func updateCL(c appengine.Context, n string) error {
	c.Debugf("Updating CL %v", n)

	url := codereviewBase + "/api/" + n + "?messages=true"
	resp, err := urlfetch.Client(c).Get(url)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		return fmt.Errorf("Update: got HTTP response %d", resp.StatusCode)
	}

	var apiResp struct {
		Description string `json:"description"`
		Created     string `json:"created"`
		OwnerEmail  string `json:"owner_email"`
		Modified    string `json:"modified"`
		Closed      bool   `json:"closed"`
		Subject     string `json:"subject"`
		Messages    []struct {
			Text       string   `json:"text"`
			Sender     string   `json:"sender"`
			Recipients []string `json:"recipients"`
			Approval   bool     `json:"approval"`
		} `json:"messages"`
	}
	if err := json.NewDecoder(resp.Body).Decode(&apiResp); err != nil {
		// probably can't be retried
		c.Errorf("Malformed JSON from %v: %v", url, err)
		return nil
	}
	//c.Infof("RAW: %+v", apiResp)

	cl := &CL{
		Number:      n,
		Closed:      apiResp.Closed,
		Owner:       apiResp.OwnerEmail,
		Description: []byte(apiResp.Description),
		FirstLine:   apiResp.Description,
		Subject:     apiResp.Subject,
		Author:      emailToPerson[apiResp.OwnerEmail],
	}
	cl.Created, err = time.Parse("2006-01-02 15:04:05.000000", apiResp.Created)
	if err != nil {
		c.Errorf("Bad creation time %q: %v", apiResp.Created, err)
	}
	cl.Modified, err = time.Parse("2006-01-02 15:04:05.000000", apiResp.Modified)
	if err != nil {
		c.Errorf("Bad modification time %q: %v", apiResp.Modified, err)
	}
	if i := strings.Index(cl.FirstLine, "\n"); i >= 0 {
		cl.FirstLine = cl.FirstLine[:i]
	}
	lgtm := make(map[string]bool)
	rcpt := make(map[string]bool)
	for _, msg := range apiResp.Messages {
		s, rev := msg.Sender, false
		if p, ok := emailToPerson[s]; ok {
			s, rev = p, true
		}

		// CLs submitted by someone other than the CL owner do not immediately
		// transition to "closed". Let's simulate the intention by treating
		// messages starting with "*** Submitted as " from a reviewer as a
		// signal that the CL is now closed.
		if rev && strings.HasPrefix(msg.Text, "*** Submitted as ") {
			cl.Closed = true
		}

		if msg.Approval {
			lgtm[s] = true
		}

		for _, r := range msg.Recipients {
			rcpt[r] = true
		}
	}
	for l := range lgtm {
		cl.LGTMs = append(cl.LGTMs, l)
	}
	for r := range rcpt {
		cl.Recipients = append(cl.Recipients, r)
	}
	sort.Strings(cl.LGTMs)
	sort.Strings(cl.Recipients)

	key := datastore.NewKey(c, "CL", n, 0, nil)
	err = datastore.RunInTransaction(c, func(c appengine.Context) error {
		ocl := new(CL)
		err := datastore.Get(c, key, ocl)
		if err != nil && err != datastore.ErrNoSuchEntity {
			return err
		} else if err == nil {
			// LastMessageID and Reviewer need preserving.
			cl.LastMessageID = ocl.LastMessageID
			cl.Reviewer = ocl.Reviewer
		}
		_, err = datastore.Put(c, key, cl)
		return err
	}, nil)
	if err != nil {
		return err
	}
	c.Infof("Updated CL %v", n)
	return nil
}
<|endoftext|>


<commit_before>package version

// Version contains the LXD version number
var Version = "3.6"
<commit_msg>Release LXD 3.7<commit_after>package version

// Version contains the LXD version number
var Version = "3.7"
<|endoftext|>


<commit_before>/* This is a FLEXible file which can be used by both client and daemon.
 * Teehee.
 */
package version

var Version = "2.7"
var UserAgent = "LXD " + Version

/*
 * Please increment the api compat number every time you change the API.
 *
 * Version 1.0: ping
 */
var APIVersion = "1.0"
<commit_msg>Release LXD 2.8<commit_after>/* This is a FLEXible file which can be used by both client and daemon.
 * Teehee.
 */
package version

var Version = "2.8"
var UserAgent = "LXD " + Version

/*
 * Please increment the api compat number every time you change the API.
 *
 * Version 1.0: ping
 */
var APIVersion = "1.0"
<|endoftext|>


<commit_before>package falconPortal

import (
	"fmt"

	"github.com/Cepave/fe/g"
	"github.com/astaxie/beego/orm"
)

func GetEventCases(startTime int64, endTime int64, priority int, status string, limit int, username string) (result []EventCases, err error) {
	config := g.Config()
	if limit == 0 || limit > config.FalconPortal.Limit {
		limit = config.FalconPortal.Limit
	}

	isadmin, tplids, err := GetCasePermission(username)
	if tplids == "" {
		tplids = "-1"
	}
	q := orm.NewOrm()
	q.Using("falcon_portal")
	flag := false
	queryTmp := ""
	if startTime != 0 && endTime != 0 {
		flag = true
		queryTmp = fmt.Sprintf(" %v update_at >= %d and  update_at <= %d", queryTmp, startTime, endTime)
	}
	if priority != -1 {
		if flag {
			queryTmp = fmt.Sprintf("%v and priority = %d", queryTmp, priority)
		} else {
			flag = true
			queryTmp = fmt.Sprintf("%v priority = %d", queryTmp, priority)
		}
	}
	if status != "ALL" {
		if flag {
			queryTmp = fmt.Sprintf("%v and status = '%s'", queryTmp, status)
		} else {
			flag = true
			queryTmp = fmt.Sprintf("%v status = '%s'", queryTmp, status)
		}
	}
	if queryTmp != "" && !isadmin {
		_, err = q.Raw(fmt.Sprintf("SELECT * FROM `event_cases` WHERE (tpl_creator = '%s' OR template_id in (%s)) AND %v order by update_at DESC limit %d", username, tplids, queryTmp, limit)).QueryRows(&result)
	} else {
		_, err = q.Raw(fmt.Sprintf("SELECT * FROM `event_cases` WHERE %v order by update_at DESC limit %d", queryTmp, limit)).QueryRows(&result)
	}

	if len(result) == 0 {
		result = []EventCases{}
	} else {
		for indx, event := range result {
			var eventArr []*Events
			q.Raw(fmt.Sprintf("SELECT * FROM `events` WHERE event_caseId = '%s' order by timestamp DESC", event.Id)).QueryRows(&eventArr)
			fmt.Sprintf("%v", eventArr)
			if len(eventArr) != 0 {
				event.Events = eventArr
			} else {
				event.Events = []*Events{}
			}
			event.Events = eventArr
			result[indx] = event
		}
	}
	return
}

func GetEvents(startTime int64, endTime int64, limit int) (result []EventsRsp, err error) {
	config := g.Config()
	if limit == 0 || limit > config.FalconPortal.Limit {
		limit = config.FalconPortal.Limit
	}

	q := orm.NewOrm()
	q.Using("falcon_portal")
	queryTmp := ""
	if startTime != 0 && endTime != 0 {
		queryTmp = fmt.Sprintf(" %v events.timestamp >= %d and  events.timestamp <= %d", queryTmp, startTime, endTime)
	}
	if queryTmp != "" {
		_, err = q.Raw(fmt.Sprintf(`SELECT events.id as id,
					events.step as step,
					events.cond as cond,
					events.timestamp as timestamp,
					events.event_caseId as eid,
					event_cases.tpl_creator as tpl_creator,
					event_cases.metric as metric,
					event_cases.endpoint as endpoint
					FROM events LEFT JOIN event_cases on event_cases.id = events.event_caseId
					WHERE %v ORDER BY events.timestamp DESC limit %d`, queryTmp, limit)).QueryRows(&result)
	} else {
		_, err = q.Raw(fmt.Sprintf(`SELECT
					events.id as id,
					events.step as step,
					events.cond as cond,
					events.timestamp as timestamp,
					events.event_caseId as eid,
					event_cases.tpl_creator as tpl_creator,
					event_cases.metric as metric,
					event_cases.endpoint as endpoint
					FROM events LEFT JOIN event_cases on event_cases.id = events.event_caseId
					ORDER BY events.timestamp DESC limit %d`, limit)).QueryRows(&result)
	}
	if len(result) == 0 {
		result = []EventsRsp{}
	}
	return
}

func CountNumOfTlp() (c int, err error) {
	var h []Tpl
	q := orm.NewOrm()
	q.Using("falcon_portal")
	_, err = q.Raw("select * from `tpl`").QueryRows(&h)
	c = len(h)
	return
}
<commit_msg>resloved conflicts for PR:#25<commit_after>package falconPortal

import (
	"fmt"

	"github.com/Cepave/fe/g"
	"github.com/astaxie/beego/orm"
)

func GetEventCases(startTime int64, endTime int64, priority int, status string, limit int, username string) (result []EventCases, err error) {
	config := g.Config()
	if limit == 0 || limit > config.FalconPortal.Limit {
		limit = config.FalconPortal.Limit
	}

	isadmin, tplids, err := GetCasePermission(username)
	if tplids == "" {
		tplids = "-1"
	}
	q := orm.NewOrm()
	q.Using("falcon_portal")
	flag := false
	queryTmp := ""
	if startTime != 0 && endTime != 0 {
		flag = true
		queryTmp = fmt.Sprintf(" %v update_at >= %d and  update_at <= %d", queryTmp, startTime, endTime)
	}
	if priority != -1 {
		if flag {
			queryTmp = fmt.Sprintf("%v and priority = %d", queryTmp, priority)
		} else {
			flag = true
			queryTmp = fmt.Sprintf("%v priority = %d", queryTmp, priority)
		}
	}
	if status != "ALL" {
		if flag {
			queryTmp = fmt.Sprintf("%v and status = '%s'", queryTmp, status)
		} else {
			flag = true
			queryTmp = fmt.Sprintf("%v status = '%s'", queryTmp, status)
		}
	}
	if queryTmp != "" && !isadmin {
		_, err = q.Raw(fmt.Sprintf("SELECT * FROM `event_cases` WHERE (tpl_creator = '%s' OR template_id in (%s)) AND %v order by update_at DESC limit %d", username, tplids, queryTmp, limit)).QueryRows(&result)
	} else {
		_, err = q.Raw(fmt.Sprintf("SELECT * FROM `event_cases` WHERE %v order by update_at DESC limit %d", queryTmp, limit)).QueryRows(&result)
	}

	if len(result) == 0 {
		result = []EventCases{}
	} else {
		for indx, event := range result {
			var eventArr []*Events
			q.Raw(fmt.Sprintf("SELECT * FROM `events` WHERE event_caseId = '%s' order by timestamp DESC", event.Id)).QueryRows(&eventArr)
			fmt.Sprintf("%v", eventArr)
			if len(eventArr) != 0 {
				event.Events = eventArr
			} else {
				event.Events = []*Events{}
			}
			result[indx] = event
		}
	}
	return
}

func GetEvents(startTime int64, endTime int64, limit int) (result []EventsRsp, err error) {
	config := g.Config()
	if limit == 0 || limit > config.FalconPortal.Limit {
		limit = config.FalconPortal.Limit
	}

	q := orm.NewOrm()
	q.Using("falcon_portal")
	queryTmp := ""
	if startTime != 0 && endTime != 0 {
		queryTmp = fmt.Sprintf(" %v events.timestamp >= %d and  events.timestamp <= %d", queryTmp, startTime, endTime)
	}
	if queryTmp != "" {
		_, err = q.Raw(fmt.Sprintf(`SELECT events.id as id,
					events.step as step,
					events.cond as cond,
					events.timestamp as timestamp,
					events.event_caseId as eid,
					event_cases.tpl_creator as tpl_creator,
					event_cases.metric as metric,
					event_cases.endpoint as endpoint
					FROM events LEFT JOIN event_cases on event_cases.id = events.event_caseId
					WHERE %v ORDER BY events.timestamp DESC limit %d`, queryTmp, limit)).QueryRows(&result)
	} else {
		_, err = q.Raw(fmt.Sprintf(`SELECT
					events.id as id,
					events.step as step,
					events.cond as cond,
					events.timestamp as timestamp,
					events.event_caseId as eid,
					event_cases.tpl_creator as tpl_creator,
					event_cases.metric as metric,
					event_cases.endpoint as endpoint
					FROM events LEFT JOIN event_cases on event_cases.id = events.event_caseId
					ORDER BY events.timestamp DESC limit %d`, limit)).QueryRows(&result)
	}
	if len(result) == 0 {
		result = []EventsRsp{}
	}
	return
}

func CountNumOfTlp() (c int, err error) {
	var h []Tpl
	q := orm.NewOrm()
	q.Using("falcon_portal")
	_, err = q.Raw("select * from `tpl`").QueryRows(&h)
	c = len(h)
	return
}
<|endoftext|>


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

package trace_test

import (
	"bytes"
	"internal/testenv"
	"internal/trace"
	"net"
	"os"
	"runtime"
	. "runtime/trace"
	"sync"
	"testing"
	"time"
)

// TestTraceSymbolize tests symbolization and that events has proper stacks.
// In particular that we strip bottom uninteresting frames like goexit,
// top uninteresting frames (runtime guts).
func TestTraceSymbolize(t *testing.T) {
	testenv.MustHaveGoBuild(t)

	buf := new(bytes.Buffer)
	if err := Start(buf); err != nil {
		t.Fatalf("failed to start tracing: %v", err)
	}
	defer Stop() // in case of early return

	// Now we will do a bunch of things for which we verify stacks later.
	// It is impossible to ensure that a goroutine has actually blocked
	// on a channel, in a select or otherwise. So we kick off goroutines
	// that need to block first in the hope that while we are executing
	// the rest of the test, they will block.
	go func() {
		select {}
	}()
	go func() {
		var c chan int
		c <- 0
	}()
	go func() {
		var c chan int
		<-c
	}()
	done1 := make(chan bool)
	go func() {
		<-done1
	}()
	done2 := make(chan bool)
	go func() {
		done2 <- true
	}()
	c1 := make(chan int)
	c2 := make(chan int)
	go func() {
		select {
		case <-c1:
		case <-c2:
		}
	}()
	var mu sync.Mutex
	mu.Lock()
	go func() {
		mu.Lock()
		mu.Unlock()
	}()
	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		wg.Wait()
	}()
	cv := sync.NewCond(&sync.Mutex{})
	go func() {
		cv.L.Lock()
		cv.Wait()
		cv.L.Unlock()
	}()
	ln, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		t.Fatalf("failed to listen: %v", err)
	}
	go func() {
		c, err := ln.Accept()
		if err != nil {
			t.Fatalf("failed to accept: %v", err)
		}
		c.Close()
	}()
	rp, wp, err := os.Pipe()
	if err != nil {
		t.Fatalf("failed to create a pipe: %v", err)
	}
	defer rp.Close()
	defer wp.Close()
	pipeReadDone := make(chan bool)
	go func() {
		var data [1]byte
		rp.Read(data[:])
		pipeReadDone <- true
	}()

	time.Sleep(time.Millisecond)
	runtime.GC()
	runtime.Gosched()
	time.Sleep(time.Millisecond) // the last chance for the goroutines above to block
	done1 <- true
	<-done2
	select {
	case c1 <- 0:
	case c2 <- 0:
	}
	mu.Unlock()
	wg.Done()
	cv.Signal()
	c, err := net.Dial("tcp", ln.Addr().String())
	if err != nil {
		t.Fatalf("failed to dial: %v", err)
	}
	c.Close()
	var data [1]byte
	wp.Write(data[:])
	<-pipeReadDone

	Stop()
	events, _ := parseTrace(t, buf)

	// Now check that the stacks are correct.
	type frame struct {
		Fn   string
		Line int
	}
	type eventDesc struct {
		Type byte
		Stk  []frame
	}
	want := []eventDesc{
		{trace.EvGCStart, []frame{
			{"runtime.GC", 0},
			{"runtime/trace_test.TestTraceSymbolize", 106},
			{"testing.tRunner", 0},
		}},
		{trace.EvGoStart, []frame{
			{"runtime/trace_test.TestTraceSymbolize.func1", 37},
		}},
		{trace.EvGoSched, []frame{
			{"runtime/trace_test.TestTraceSymbolize", 107},
			{"testing.tRunner", 0},
		}},
		{trace.EvGoCreate, []frame{
			{"runtime/trace_test.TestTraceSymbolize", 39},
			{"testing.tRunner", 0},
		}},
		{trace.EvGoStop, []frame{
			{"runtime.block", 0},
			{"runtime/trace_test.TestTraceSymbolize.func1", 38},
		}},
		{trace.EvGoStop, []frame{
			{"runtime.chansend1", 0},
			{"runtime/trace_test.TestTraceSymbolize.func2", 42},
		}},
		{trace.EvGoStop, []frame{
			{"runtime.chanrecv1", 0},
			{"runtime/trace_test.TestTraceSymbolize.func3", 46},
		}},
		{trace.EvGoBlockRecv, []frame{
			{"runtime.chanrecv1", 0},
			{"runtime/trace_test.TestTraceSymbolize.func4", 50},
		}},
		{trace.EvGoUnblock, []frame{
			{"runtime.chansend1", 0},
			{"runtime/trace_test.TestTraceSymbolize", 109},
			{"testing.tRunner", 0},
		}},
		{trace.EvGoBlockSend, []frame{
			{"runtime.chansend1", 0},
			{"runtime/trace_test.TestTraceSymbolize.func5", 54},
		}},
		{trace.EvGoUnblock, []frame{
			{"runtime.chanrecv1", 0},
			{"runtime/trace_test.TestTraceSymbolize", 110},
			{"testing.tRunner", 0},
		}},
		{trace.EvGoBlockSelect, []frame{
			{"runtime.selectgo", 0},
			{"runtime/trace_test.TestTraceSymbolize.func6", 59},
		}},
		{trace.EvGoUnblock, []frame{
			{"runtime.selectgo", 0},
			{"runtime/trace_test.TestTraceSymbolize", 111},
			{"testing.tRunner", 0},
		}},
		{trace.EvGoBlockSync, []frame{
			{"sync.(*Mutex).Lock", 0},
			{"runtime/trace_test.TestTraceSymbolize.func7", 67},
		}},
		{trace.EvGoUnblock, []frame{
			{"sync.(*Mutex).Unlock", 0},
			{"runtime/trace_test.TestTraceSymbolize", 115},
			{"testing.tRunner", 0},
		}},
		{trace.EvGoBlockSync, []frame{
			{"sync.(*WaitGroup).Wait", 0},
			{"runtime/trace_test.TestTraceSymbolize.func8", 73},
		}},
		{trace.EvGoUnblock, []frame{
			{"sync.(*WaitGroup).Add", 0},
			{"sync.(*WaitGroup).Done", 0},
			{"runtime/trace_test.TestTraceSymbolize", 116},
			{"testing.tRunner", 0},
		}},
		{trace.EvGoBlockCond, []frame{
			{"sync.(*Cond).Wait", 0},
			{"runtime/trace_test.TestTraceSymbolize.func9", 78},
		}},
		{trace.EvGoUnblock, []frame{
			{"sync.(*Cond).Signal", 0},
			{"runtime/trace_test.TestTraceSymbolize", 117},
			{"testing.tRunner", 0},
		}},
		{trace.EvGoSleep, []frame{
			{"time.Sleep", 0},
			{"runtime/trace_test.TestTraceSymbolize", 108},
			{"testing.tRunner", 0},
		}},
	}
	// Stacks for the following events are OS-dependent due to OS-specific code in net package.
	if runtime.GOOS != "windows" && runtime.GOOS != "plan9" {
		want = append(want, []eventDesc{
			{trace.EvGoBlockNet, []frame{
				{"net.(*netFD).accept", 0},
				{"net.(*TCPListener).accept", 0},
				{"net.(*TCPListener).Accept", 0},
				{"runtime/trace_test.TestTraceSymbolize.func10", 86},
			}},
			{trace.EvGoSysCall, []frame{
				{"syscall.read", 0},
				{"syscall.Read", 0},
				{"os.(*File).read", 0},
				{"os.(*File).Read", 0},
				{"runtime/trace_test.TestTraceSymbolize.func11", 101},
			}},
		}...)
	}
	matched := make([]bool, len(want))
	for _, ev := range events {
	wantLoop:
		for i, w := range want {
			if matched[i] || w.Type != ev.Type || len(w.Stk) != len(ev.Stk) {
				continue
			}

			for fi, f := range ev.Stk {
				wf := w.Stk[fi]
				if wf.Fn != f.Fn || wf.Line != 0 && wf.Line != f.Line {
					continue wantLoop
				}
			}
			matched[i] = true
		}
	}
	for i, m := range matched {
		if m {
			continue
		}
		w := want[i]
		t.Errorf("did not match event %v at %v:%v", trace.EventDescriptions[w.Type].Name, w.Stk[0].Fn, w.Stk[0].Line)
		t.Errorf("seen the following events of this type:")
		for _, ev := range events {
			if ev.Type != w.Type {
				continue
			}
			for _, f := range ev.Stk {
				t.Logf("  %v:%v", f.Fn, f.Line)
			}
			t.Logf("---")
		}
	}
}
<commit_msg>runtime/trace: deflake TestTraceSymbolize<commit_after>// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package trace_test

import (
	"bytes"
	"internal/testenv"
	"internal/trace"
	"net"
	"os"
	"runtime"
	. "runtime/trace"
	"sync"
	"testing"
	"time"
)

// TestTraceSymbolize tests symbolization and that events has proper stacks.
// In particular that we strip bottom uninteresting frames like goexit,
// top uninteresting frames (runtime guts).
func TestTraceSymbolize(t *testing.T) {
	testenv.MustHaveGoBuild(t)

	buf := new(bytes.Buffer)
	if err := Start(buf); err != nil {
		t.Fatalf("failed to start tracing: %v", err)
	}
	defer Stop() // in case of early return

	// Now we will do a bunch of things for which we verify stacks later.
	// It is impossible to ensure that a goroutine has actually blocked
	// on a channel, in a select or otherwise. So we kick off goroutines
	// that need to block first in the hope that while we are executing
	// the rest of the test, they will block.
	go func() {
		select {}
	}()
	go func() {
		var c chan int
		c <- 0
	}()
	go func() {
		var c chan int
		<-c
	}()
	done1 := make(chan bool)
	go func() {
		<-done1
	}()
	done2 := make(chan bool)
	go func() {
		done2 <- true
	}()
	c1 := make(chan int)
	c2 := make(chan int)
	go func() {
		select {
		case <-c1:
		case <-c2:
		}
	}()
	var mu sync.Mutex
	mu.Lock()
	go func() {
		mu.Lock()
		mu.Unlock()
	}()
	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		wg.Wait()
	}()
	cv := sync.NewCond(&sync.Mutex{})
	go func() {
		cv.L.Lock()
		cv.Wait()
		cv.L.Unlock()
	}()
	ln, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		t.Fatalf("failed to listen: %v", err)
	}
	go func() {
		c, err := ln.Accept()
		if err != nil {
			t.Fatalf("failed to accept: %v", err)
		}
		c.Close()
	}()
	rp, wp, err := os.Pipe()
	if err != nil {
		t.Fatalf("failed to create a pipe: %v", err)
	}
	defer rp.Close()
	defer wp.Close()
	pipeReadDone := make(chan bool)
	go func() {
		var data [1]byte
		rp.Read(data[:])
		pipeReadDone <- true
	}()

	time.Sleep(100 * time.Millisecond)
	runtime.GC()
	runtime.Gosched()
	time.Sleep(100 * time.Millisecond) // the last chance for the goroutines above to block
	done1 <- true
	<-done2
	select {
	case c1 <- 0:
	case c2 <- 0:
	}
	mu.Unlock()
	wg.Done()
	cv.Signal()
	c, err := net.Dial("tcp", ln.Addr().String())
	if err != nil {
		t.Fatalf("failed to dial: %v", err)
	}
	c.Close()
	var data [1]byte
	wp.Write(data[:])
	<-pipeReadDone

	Stop()
	events, _ := parseTrace(t, buf)

	// Now check that the stacks are correct.
	type frame struct {
		Fn   string
		Line int
	}
	type eventDesc struct {
		Type byte
		Stk  []frame
	}
	want := []eventDesc{
		{trace.EvGCStart, []frame{
			{"runtime.GC", 0},
			{"runtime/trace_test.TestTraceSymbolize", 106},
			{"testing.tRunner", 0},
		}},
		{trace.EvGoStart, []frame{
			{"runtime/trace_test.TestTraceSymbolize.func1", 37},
		}},
		{trace.EvGoSched, []frame{
			{"runtime/trace_test.TestTraceSymbolize", 107},
			{"testing.tRunner", 0},
		}},
		{trace.EvGoCreate, []frame{
			{"runtime/trace_test.TestTraceSymbolize", 39},
			{"testing.tRunner", 0},
		}},
		{trace.EvGoStop, []frame{
			{"runtime.block", 0},
			{"runtime/trace_test.TestTraceSymbolize.func1", 38},
		}},
		{trace.EvGoStop, []frame{
			{"runtime.chansend1", 0},
			{"runtime/trace_test.TestTraceSymbolize.func2", 42},
		}},
		{trace.EvGoStop, []frame{
			{"runtime.chanrecv1", 0},
			{"runtime/trace_test.TestTraceSymbolize.func3", 46},
		}},
		{trace.EvGoBlockRecv, []frame{
			{"runtime.chanrecv1", 0},
			{"runtime/trace_test.TestTraceSymbolize.func4", 50},
		}},
		{trace.EvGoUnblock, []frame{
			{"runtime.chansend1", 0},
			{"runtime/trace_test.TestTraceSymbolize", 109},
			{"testing.tRunner", 0},
		}},
		{trace.EvGoBlockSend, []frame{
			{"runtime.chansend1", 0},
			{"runtime/trace_test.TestTraceSymbolize.func5", 54},
		}},
		{trace.EvGoUnblock, []frame{
			{"runtime.chanrecv1", 0},
			{"runtime/trace_test.TestTraceSymbolize", 110},
			{"testing.tRunner", 0},
		}},
		{trace.EvGoBlockSelect, []frame{
			{"runtime.selectgo", 0},
			{"runtime/trace_test.TestTraceSymbolize.func6", 59},
		}},
		{trace.EvGoUnblock, []frame{
			{"runtime.selectgo", 0},
			{"runtime/trace_test.TestTraceSymbolize", 111},
			{"testing.tRunner", 0},
		}},
		{trace.EvGoBlockSync, []frame{
			{"sync.(*Mutex).Lock", 0},
			{"runtime/trace_test.TestTraceSymbolize.func7", 67},
		}},
		{trace.EvGoUnblock, []frame{
			{"sync.(*Mutex).Unlock", 0},
			{"runtime/trace_test.TestTraceSymbolize", 115},
			{"testing.tRunner", 0},
		}},
		{trace.EvGoBlockSync, []frame{
			{"sync.(*WaitGroup).Wait", 0},
			{"runtime/trace_test.TestTraceSymbolize.func8", 73},
		}},
		{trace.EvGoUnblock, []frame{
			{"sync.(*WaitGroup).Add", 0},
			{"sync.(*WaitGroup).Done", 0},
			{"runtime/trace_test.TestTraceSymbolize", 116},
			{"testing.tRunner", 0},
		}},
		{trace.EvGoBlockCond, []frame{
			{"sync.(*Cond).Wait", 0},
			{"runtime/trace_test.TestTraceSymbolize.func9", 78},
		}},
		{trace.EvGoUnblock, []frame{
			{"sync.(*Cond).Signal", 0},
			{"runtime/trace_test.TestTraceSymbolize", 117},
			{"testing.tRunner", 0},
		}},
		{trace.EvGoSleep, []frame{
			{"time.Sleep", 0},
			{"runtime/trace_test.TestTraceSymbolize", 108},
			{"testing.tRunner", 0},
		}},
	}
	// Stacks for the following events are OS-dependent due to OS-specific code in net package.
	if runtime.GOOS != "windows" && runtime.GOOS != "plan9" {
		want = append(want, []eventDesc{
			{trace.EvGoBlockNet, []frame{
				{"net.(*netFD).accept", 0},
				{"net.(*TCPListener).accept", 0},
				{"net.(*TCPListener).Accept", 0},
				{"runtime/trace_test.TestTraceSymbolize.func10", 86},
			}},
			{trace.EvGoSysCall, []frame{
				{"syscall.read", 0},
				{"syscall.Read", 0},
				{"os.(*File).read", 0},
				{"os.(*File).Read", 0},
				{"runtime/trace_test.TestTraceSymbolize.func11", 101},
			}},
		}...)
	}
	matched := make([]bool, len(want))
	for _, ev := range events {
	wantLoop:
		for i, w := range want {
			if matched[i] || w.Type != ev.Type || len(w.Stk) != len(ev.Stk) {
				continue
			}

			for fi, f := range ev.Stk {
				wf := w.Stk[fi]
				if wf.Fn != f.Fn || wf.Line != 0 && wf.Line != f.Line {
					continue wantLoop
				}
			}
			matched[i] = true
		}
	}
	for i, m := range matched {
		if m {
			continue
		}
		w := want[i]
		t.Errorf("did not match event %v at %v:%v", trace.EventDescriptions[w.Type].Name, w.Stk[0].Fn, w.Stk[0].Line)
		t.Errorf("seen the following events of this type:")
		for _, ev := range events {
			if ev.Type != w.Type {
				continue
			}
			for _, f := range ev.Stk {
				t.Logf("  %v:%v", f.Fn, f.Line)
			}
			t.Logf("---")
		}
	}
}
<|endoftext|>