<commit_before>/*
	Copyright (c) 2014-2015, Percona LLC and/or its affiliates. All rights reserved.

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU Affero General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Affero General Public License for more details.

	You should have received a copy of the GNU Affero General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>
*/

package event

import (
	"github.com/percona/go-mysql/log"
	"sort"
)

// Metrics encapsulate the metrics of an event like Query_time and Rows_sent.
type Metrics struct {
	TimeMetrics   map[string]*TimeStats   `json:",omitempty"`
	NumberMetrics map[string]*NumberStats `json:",omitempty"`
	BoolMetrics   map[string]*BoolStats   `json:",omitempty"`
}

// TimeStats are microsecond-based metrics like Query_time and Lock_time.
type TimeStats struct {
	vals       []float64 `json:"-"`
	Sum        float64
	Min        float64 `json:",omitempty"`
	Avg        float64 `json:",omitempty"`
	Med        float64 `json:",omitempty"` // median
	P95        float64 `json:",omitempty"` // 95th percentile
	Max        float64 `json:",omitempty"`
	outlierSum float64
}

// NumberStats are integer-based metrics like Rows_sent and Merge_passes.
type NumberStats struct {
	vals       []uint64 `json:"-"`
	Sum        uint64
	Min        uint64 `json:",omitempty"`
	Avg        uint64 `json:",omitempty"`
	Med        uint64 `json:",omitempty"` // median
	P95        uint64 `json:",omitempty"` // 95th percentile
	Max        uint64 `json:",omitempty"`
	outlierSum uint64
}

// BoolStats are boolean-based metrics like QC_Hit and Filesort.
type BoolStats struct {
	Sum        uint64 // %true = Sum/Cnt
	outlierSum uint64
}

// NewMetrics returns a pointer to an initialized Metrics structure.
func NewMetrics() *Metrics {
	m := &Metrics{
		TimeMetrics:   make(map[string]*TimeStats),
		NumberMetrics: make(map[string]*NumberStats),
		BoolMetrics:   make(map[string]*BoolStats),
	}
	return m
}

// AddEvent saves all the metrics of the event.
func (m *Metrics) AddEvent(e *log.Event, outlier bool) {

	for metric, val := range e.TimeMetrics {
		stats, seenMetric := m.TimeMetrics[metric]
		if !seenMetric {
			m.TimeMetrics[metric] = &TimeStats{
				vals: []float64{},
			}
			stats = m.TimeMetrics[metric]
		}
		if outlier {
			stats.outlierSum += val
		} else {
			stats.Sum += val
		}
		stats.vals = append(stats.vals, float64(val))
	}

	for metric, val := range e.NumberMetrics {
		stats, seenMetric := m.NumberMetrics[metric]
		if !seenMetric {
			m.NumberMetrics[metric] = &NumberStats{
				vals: []uint64{},
			}
			stats = m.NumberMetrics[metric]
		}
		if outlier {
			stats.outlierSum += val
		} else {
			stats.Sum += val
		}
		stats.vals = append(stats.vals, val)
	}

	for metric, val := range e.BoolMetrics {
		stats, ok := m.BoolMetrics[metric]
		if !ok {
			stats = &BoolStats{}
			m.BoolMetrics[metric] = stats
		}
		if val {
			if outlier {
				stats.outlierSum += 1
			} else {
				stats.Sum += 1
			}
		}
	}
}

type byUint64 []uint64

func (a byUint64) Len() int      { return len(a) }
func (a byUint64) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a byUint64) Less(i, j int) bool {
	return a[i] < a[j] // ascending order
}

// Finalize calculates the statistics of the added metrics. Call this function
// when done adding events.
func (m *Metrics) Finalize(rateLimit uint) {
	if rateLimit == 0 {
		rateLimit = 1
	}

	for _, s := range m.TimeMetrics {
		sort.Float64s(s.vals)
		cnt := len(s.vals)

		s.Min = s.vals[0]
		s.Avg = (s.Sum + s.outlierSum) / float64(cnt)
		s.Med = s.vals[(50*cnt)/100] // median = 50th percentile
		s.P95 = s.vals[(95*cnt)/100]
		s.Max = s.vals[cnt-1]

		// Update sum last because avg ^ needs the original value.
		s.Sum = (s.Sum * float64(rateLimit)) + s.outlierSum
	}

	for _, s := range m.NumberMetrics {
		sort.Sort(byUint64(s.vals))
		cnt := len(s.vals)

		s.Min = s.vals[0]
		s.Avg = (s.Sum + s.outlierSum) / uint64(cnt)
		s.Med = s.vals[(50*cnt)/100] // median = 50th percentile
		s.P95 = s.vals[(95*cnt)/100]
		s.Max = s.vals[cnt-1]

		// Update sum last because avg ^ needs the original value.
		s.Sum = (s.Sum * uint64(rateLimit)) + s.outlierSum
	}

	for _, s := range m.BoolMetrics {
		s.Sum = (s.Sum * uint64(rateLimit)) + s.outlierSum
	}
}
<commit_msg>Use consistent var name.<commit_after>/*
	Copyright (c) 2014-2015, Percona LLC and/or its affiliates. All rights reserved.

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU Affero General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Affero General Public License for more details.

	You should have received a copy of the GNU Affero General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>
*/

package event

import (
	"github.com/percona/go-mysql/log"
	"sort"
)

// Metrics encapsulate the metrics of an event like Query_time and Rows_sent.
type Metrics struct {
	TimeMetrics   map[string]*TimeStats   `json:",omitempty"`
	NumberMetrics map[string]*NumberStats `json:",omitempty"`
	BoolMetrics   map[string]*BoolStats   `json:",omitempty"`
}

// TimeStats are microsecond-based metrics like Query_time and Lock_time.
type TimeStats struct {
	vals       []float64 `json:"-"`
	Sum        float64
	Min        float64 `json:",omitempty"`
	Avg        float64 `json:",omitempty"`
	Med        float64 `json:",omitempty"` // median
	P95        float64 `json:",omitempty"` // 95th percentile
	Max        float64 `json:",omitempty"`
	outlierSum float64
}

// NumberStats are integer-based metrics like Rows_sent and Merge_passes.
type NumberStats struct {
	vals       []uint64 `json:"-"`
	Sum        uint64
	Min        uint64 `json:",omitempty"`
	Avg        uint64 `json:",omitempty"`
	Med        uint64 `json:",omitempty"` // median
	P95        uint64 `json:",omitempty"` // 95th percentile
	Max        uint64 `json:",omitempty"`
	outlierSum uint64
}

// BoolStats are boolean-based metrics like QC_Hit and Filesort.
type BoolStats struct {
	Sum        uint64 // %true = Sum/Cnt
	outlierSum uint64
}

// NewMetrics returns a pointer to an initialized Metrics structure.
func NewMetrics() *Metrics {
	m := &Metrics{
		TimeMetrics:   make(map[string]*TimeStats),
		NumberMetrics: make(map[string]*NumberStats),
		BoolMetrics:   make(map[string]*BoolStats),
	}
	return m
}

// AddEvent saves all the metrics of the event.
func (m *Metrics) AddEvent(e *log.Event, outlier bool) {

	for metric, val := range e.TimeMetrics {
		stats, seenMetric := m.TimeMetrics[metric]
		if !seenMetric {
			m.TimeMetrics[metric] = &TimeStats{
				vals: []float64{},
			}
			stats = m.TimeMetrics[metric]
		}
		if outlier {
			stats.outlierSum += val
		} else {
			stats.Sum += val
		}
		stats.vals = append(stats.vals, float64(val))
	}

	for metric, val := range e.NumberMetrics {
		stats, seenMetric := m.NumberMetrics[metric]
		if !seenMetric {
			m.NumberMetrics[metric] = &NumberStats{
				vals: []uint64{},
			}
			stats = m.NumberMetrics[metric]
		}
		if outlier {
			stats.outlierSum += val
		} else {
			stats.Sum += val
		}
		stats.vals = append(stats.vals, val)
	}

	for metric, val := range e.BoolMetrics {
		stats, seenMetric := m.BoolMetrics[metric]
		if !seenMetric {
			stats = &BoolStats{}
			m.BoolMetrics[metric] = stats
		}
		if val {
			if outlier {
				stats.outlierSum += 1
			} else {
				stats.Sum += 1
			}
		}
	}
}

type byUint64 []uint64

func (a byUint64) Len() int      { return len(a) }
func (a byUint64) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a byUint64) Less(i, j int) bool {
	return a[i] < a[j] // ascending order
}

// Finalize calculates the statistics of the added metrics. Call this function
// when done adding events.
func (m *Metrics) Finalize(rateLimit uint) {
	if rateLimit == 0 {
		rateLimit = 1
	}

	for _, s := range m.TimeMetrics {
		sort.Float64s(s.vals)
		cnt := len(s.vals)

		s.Min = s.vals[0]
		s.Avg = (s.Sum + s.outlierSum) / float64(cnt)
		s.Med = s.vals[(50*cnt)/100] // median = 50th percentile
		s.P95 = s.vals[(95*cnt)/100]
		s.Max = s.vals[cnt-1]

		// Update sum last because avg ^ needs the original value.
		s.Sum = (s.Sum * float64(rateLimit)) + s.outlierSum
	}

	for _, s := range m.NumberMetrics {
		sort.Sort(byUint64(s.vals))
		cnt := len(s.vals)

		s.Min = s.vals[0]
		s.Avg = (s.Sum + s.outlierSum) / uint64(cnt)
		s.Med = s.vals[(50*cnt)/100] // median = 50th percentile
		s.P95 = s.vals[(95*cnt)/100]
		s.Max = s.vals[cnt-1]

		// Update sum last because avg ^ needs the original value.
		s.Sum = (s.Sum * uint64(rateLimit)) + s.outlierSum
	}

	for _, s := range m.BoolMetrics {
		s.Sum = (s.Sum * uint64(rateLimit)) + s.outlierSum
	}
}
<|endoftext|>


<commit_before>package sftp

import (
	"fmt"
	"io"
	"path/filepath"
	"reflect"
	"sync"
	"syscall"
)

var maxTxPacket uint32 = 1 << 15

type handleHandler func(string) string

type Handlers struct {
	FileGet  FileReader
	FilePut  FileWriter
	FileCmd  FileCmder
	FileInfo FileInfoer
}

// Server that abstracts the sftp protocol for a http request-like protocol
type RequestServer struct {
	serverConn
	Handlers        Handlers
	pktChan         chan packet
	openRequests    map[string]*Request
	openRequestLock sync.RWMutex
}

// simple factory function
// one server per user-session
func NewRequestServer(rwc io.ReadWriteCloser) (*RequestServer, error) {
	s := &RequestServer{
		serverConn: serverConn{
			conn: conn{
				Reader:      rwc,
				WriteCloser: rwc,
			},
		},
		pktChan:      make(chan packet, sftpServerWorkerCount),
		openRequests: make(map[string]*Request),
	}

	return s, nil
}

func (rs *RequestServer) nextRequest(r *Request) string {
	rs.openRequestLock.Lock()
	defer rs.openRequestLock.Unlock()
	rs.openRequests[r.Filepath] = r
	return r.Filepath
}

func (rs *RequestServer) getRequest(handle string) (*Request, bool) {
	rs.openRequestLock.Lock()
	defer rs.openRequestLock.Unlock()
	r, ok := rs.openRequests[handle]
	return r, ok
}

func (rs *RequestServer) closeRequest(handle string) {
	rs.openRequestLock.Lock()
	defer rs.openRequestLock.Unlock()
	if _, ok := rs.openRequests[handle]; ok {
		delete(rs.openRequests, handle)
	}
}

// start serving requests from user session
func (rs *RequestServer) Serve() error {
	var wg sync.WaitGroup
	wg.Add(sftpServerWorkerCount)
	for i := 0; i < sftpServerWorkerCount; i++ {
		go func() {
			defer wg.Done()
			if err := rs.packetWorker(); err != nil {
				rs.conn.Close() // shuts down recvPacket
			}
		}()
	}

	var err error
	var pktType uint8
	var pktBytes []byte
	for {
		pktType, pktBytes, err = rs.recvPacket()
		if err != nil {
			break
		}
		pkt, err := makePacket(rxPacket{fxp(pktType), pktBytes})
		if err != nil {
			break
		}
		rs.pktChan <- pkt
	}

	close(rs.pktChan) // shuts down sftpServerWorkers
	wg.Wait()         // wait for all workers to exit
	return err
}

func (rs *RequestServer) packetWorker() error {
	for pkt := range rs.pktChan {
		fmt.Println("Incoming Packet: ", pkt, reflect.TypeOf(pkt))
		var handle string
		var rpkt resp_packet
		var err error
		switch pkt := pkt.(type) {
		case *sshFxInitPacket:
			rpkt = sshFxVersionPacket{sftpProtocolVersion, nil}
		case *sshFxpClosePacket:
			handle = pkt.getHandle()
			rs.closeRequest(handle)
			rpkt = statusFromError(pkt, nil)
		case *sshFxpRealpathPacket:
			rpkt = cleanPath(pkt)
		case isOpener:
			handle = rs.nextRequest(newRequest(pkt.getPath()))
			rpkt = sshFxpHandlePacket{pkt.id(), handle}
		case hasPath:
			handle = rs.nextRequest(newRequest(pkt.getPath()))
			rpkt = rs.request(handle, pkt)
		case hasHandle:
			handle = pkt.getHandle()
			rpkt = rs.request(handle, pkt)
		}

		fmt.Println("Reply Packet: ", rpkt, reflect.TypeOf(rpkt))
		err = rs.sendPacket(rpkt)
		if err != nil {
			return err
		}
	}
	return nil
}

func cleanPath(pkt *sshFxpRealpathPacket) resp_packet {
	path := pkt.getPath()
	if !filepath.IsAbs(path) {
		path = "/" + path // all paths are absolute
	}
	cleaned_path := filepath.Clean(path)
	return &sshFxpNamePacket{
		ID: pkt.id(),
		NameAttrs: []sshFxpNameAttr{{
			Name:     cleaned_path,
			LongName: cleaned_path,
			Attrs:    emptyFileStat,
		}},
	}
}

func (rs *RequestServer) request(handle string, pkt packet) resp_packet {
	var rpkt resp_packet
	var err error
	if request, ok := rs.getRequest(handle); ok {
		// called here to keep packet handling out of request for testing
		request.populate(pkt)
		fmt.Println("Request Method: ", request.Method)
		rpkt, err = request.handle(rs.Handlers)
		if err != nil {
			rpkt = statusFromError(pkt, err)
		}
	} else {
		rpkt = statusFromError(pkt, syscall.EBADF)
	}
	return rpkt
}
<commit_msg>require handlers as arg to NewRequestServer<commit_after>package sftp

import (
	"fmt"
	"io"
	"path/filepath"
	"reflect"
	"sync"
	"syscall"
)

var maxTxPacket uint32 = 1 << 15

type handleHandler func(string) string

type Handlers struct {
	FileGet  FileReader
	FilePut  FileWriter
	FileCmd  FileCmder
	FileInfo FileInfoer
}

// Server that abstracts the sftp protocol for a http request-like protocol
type RequestServer struct {
	serverConn
	Handlers        Handlers
	pktChan         chan packet
	openRequests    map[string]*Request
	openRequestLock sync.RWMutex
}

// simple factory function
// one server per user-session
func NewRequestServer(rwc io.ReadWriteCloser, h Handlers) (*RequestServer, error) {
	s := &RequestServer{
		serverConn: serverConn{
			conn: conn{
				Reader:      rwc,
				WriteCloser: rwc,
			},
		},
		Handlers:     h,
		pktChan:      make(chan packet, sftpServerWorkerCount),
		openRequests: make(map[string]*Request),
	}

	return s, nil
}

func (rs *RequestServer) nextRequest(r *Request) string {
	rs.openRequestLock.Lock()
	defer rs.openRequestLock.Unlock()
	rs.openRequests[r.Filepath] = r
	return r.Filepath
}

func (rs *RequestServer) getRequest(handle string) (*Request, bool) {
	rs.openRequestLock.Lock()
	defer rs.openRequestLock.Unlock()
	r, ok := rs.openRequests[handle]
	return r, ok
}

func (rs *RequestServer) closeRequest(handle string) {
	rs.openRequestLock.Lock()
	defer rs.openRequestLock.Unlock()
	if _, ok := rs.openRequests[handle]; ok {
		delete(rs.openRequests, handle)
	}
}

// start serving requests from user session
func (rs *RequestServer) Serve() error {
	var wg sync.WaitGroup
	wg.Add(sftpServerWorkerCount)
	for i := 0; i < sftpServerWorkerCount; i++ {
		go func() {
			defer wg.Done()
			if err := rs.packetWorker(); err != nil {
				rs.conn.Close() // shuts down recvPacket
			}
		}()
	}

	var err error
	var pktType uint8
	var pktBytes []byte
	for {
		pktType, pktBytes, err = rs.recvPacket()
		if err != nil {
			break
		}
		pkt, err := makePacket(rxPacket{fxp(pktType), pktBytes})
		if err != nil {
			break
		}
		rs.pktChan <- pkt
	}

	close(rs.pktChan) // shuts down sftpServerWorkers
	wg.Wait()         // wait for all workers to exit
	return err
}

func (rs *RequestServer) packetWorker() error {
	for pkt := range rs.pktChan {
		fmt.Println("Incoming Packet: ", pkt, reflect.TypeOf(pkt))
		var handle string
		var rpkt resp_packet
		var err error
		switch pkt := pkt.(type) {
		case *sshFxInitPacket:
			rpkt = sshFxVersionPacket{sftpProtocolVersion, nil}
		case *sshFxpClosePacket:
			handle = pkt.getHandle()
			rs.closeRequest(handle)
			rpkt = statusFromError(pkt, nil)
		case *sshFxpRealpathPacket:
			rpkt = cleanPath(pkt)
		case isOpener:
			handle = rs.nextRequest(newRequest(pkt.getPath()))
			rpkt = sshFxpHandlePacket{pkt.id(), handle}
		case hasPath:
			handle = rs.nextRequest(newRequest(pkt.getPath()))
			rpkt = rs.request(handle, pkt)
		case hasHandle:
			handle = pkt.getHandle()
			rpkt = rs.request(handle, pkt)
		}

		fmt.Println("Reply Packet: ", rpkt, reflect.TypeOf(rpkt))
		err = rs.sendPacket(rpkt)
		if err != nil {
			return err
		}
	}
	return nil
}

func cleanPath(pkt *sshFxpRealpathPacket) resp_packet {
	path := pkt.getPath()
	if !filepath.IsAbs(path) {
		path = "/" + path // all paths are absolute
	}
	cleaned_path := filepath.Clean(path)
	return &sshFxpNamePacket{
		ID: pkt.id(),
		NameAttrs: []sshFxpNameAttr{{
			Name:     cleaned_path,
			LongName: cleaned_path,
			Attrs:    emptyFileStat,
		}},
	}
}

func (rs *RequestServer) request(handle string, pkt packet) resp_packet {
	var rpkt resp_packet
	var err error
	if request, ok := rs.getRequest(handle); ok {
		// called here to keep packet handling out of request for testing
		request.populate(pkt)
		fmt.Println("Request Method: ", request.Method)
		rpkt, err = request.handle(rs.Handlers)
		if err != nil {
			rpkt = statusFromError(pkt, err)
		}
	} else {
		rpkt = statusFromError(pkt, syscall.EBADF)
	}
	return rpkt
}
<|endoftext|>


<commit_before>package request

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"github.com/5sigma/spyder/config"
	"github.com/5sigma/spyder/endpoint"
	"github.com/robertkrimen/otto"
	"github.com/robertkrimen/otto/parser"
	_ "github.com/robertkrimen/otto/underscore"
	"io/ioutil"
	"net/http"
)

// ScriptEngine - A scripting engine used to execute hook scripts during the
// request process. It is built to execute arbitrary Javascript.
type ScriptEngine struct {
	VM             *otto.Otto
	Constants      map[string]string
	AssetPath      string
	Response       *Response
	EndpointConfig *endpoint.EndpointConfig
	Payload        []byte
	Request        *http.Request
	Debug          string
}

// NewScriptEngine - Generates a new script engine.
func NewScriptEngine(endpointConfig *endpoint.EndpointConfig) *ScriptEngine {
	vm := otto.New()

	eng := &ScriptEngine{
		VM:             vm,
		EndpointConfig: endpointConfig,
	}

	varObj, _ := vm.Object("$variables = {}")
	varObj.Set("set", eng.setLocalVar)
	varObj.Set("get", eng.getVar)

	vm.Set("$debug", eng.setDebug)
	vm.Set("$hmac", eng.hmac)

	reqObj, _ := eng.VM.Object("$request = {}")
	requestBytes := endpointConfig.RequestData()
	reqObj.Set("body", string(requestBytes))
	reqObj.Set("contentLength", len(requestBytes))
	headersObj, _ := eng.VM.Object(`$request.headers = {}`)
	headersObj.Set("get", eng.getReqHeader)
	headersObj.Set("set", eng.setReqHeader)
	reqObj.Set("setBody", eng.setPayload)

	return eng
}

//ExecuteFile - Executes a script contianed in a file.
func (eng *ScriptEngine) ExecuteFile(filepath string) error {
	data, err := ioutil.ReadFile(filepath)
	if err != nil {
		return err
	}
	err = eng.Execute(string(data))
	if err != nil {
		return err
	}
	return nil
}

// SetResponse - Used to set the web respone on the engine. It also makes this
// available to the script.
func (eng *ScriptEngine) SetResponse(res *Response) {
	eng.Response = res
	requestObj, _ := eng.VM.Object(`$request = {}`)
	requestObj.Set("url", res.Request.URL.String())
	requestObj.Set("contentLength", res.Request.ContentLength)

	responseObj, _ := eng.VM.Object(`$response = {}`)
	responseObj.Set("contentLength", res.Response.ContentLength)
	responseObj.Set("body", string(res.Content))
	eng.VM.Object(`$response.headers = {}`)
	responseObj.Set("get", eng.getResHeader)
}

// SetRequest - Sets the request on the engine. This also builds the functions
// to expose the request to scripts.
func (engine *ScriptEngine) SetRequest(request *http.Request) {
	eng.Request = request
	reqVal, _ := eng.VM.Get("$request")
	reqObj := reqVal.Object()
	reqObj.Set("contentLength", request.ContentLength)
}

// SetPayload - Sets the request payload on the engine. Also exposes it to
// scripts within the request object.
func (engine *ScriptEngine) SetPayload(payload []byte) {
	engine.Payload = payload
	reqVal, _ := engine.VM.Get("$request")
	reqObj := reqVal.Object()
	reqObj.Set("body", string(payload))
}

//Execute - Executes a Javascript.
func (engine *ScriptEngine) Execute(script string) error {
	_, err := eng.VM.Run(script)
	if err != nil {
		println(err.Error())
	}
	return err
}

// Validate - Validates that the Javascript is valid.
func (eng *ScriptEngine) Validate(script string) error {
	_, err := parser.ParseFile(nil, "", script, 0)
	return err
}

// jsThrow - Used to throw javascript errors from Go.
func jsThrow(call otto.FunctionCall, err error) {
	call.Otto.Call("new Error", nil, err.Error())
}

// setLocalVar - Sets a config value in the local config.
func (engine *ScriptEngine) setLocalVar(call otto.FunctionCall) otto.Value {
	key, _ := call.Argument(0).ToString()
	value, _ := call.Argument(1).ToString()
	config.LocalConfig.SetVariable(key, value)
	return otto.Value{}
}

// getVar - Returns a config variable.
func (engine *ScriptEngine) getVar(call otto.FunctionCall) otto.Value {
	key, _ := call.Argument(0).ToString()
	if config.LocalConfig.VariableExists(key) {
		v := config.LocalConfig.GetVariable(key)
		ov, _ := otto.ToValue(v)
		return ov
	}
	if config.GlobalConfig.VariableExists(key) {
		v := config.LocalConfig.GetVariable(key)
		ov, _ := otto.ToValue(v)
		return ov
	}
	return otto.Value{}
}

// getPayload - Returns the request payload.
func (engine *ScriptEngine) getPayload(call otto.FunctionCall) otto.Value {
	ov, _ := otto.ToValue(string(engine.Payload))
	return ov
}

// setPayload - Sets the payload value on the engine.
func (engine *ScriptEngine) setPayload(call otto.FunctionCall) otto.Value {
	val, _ := call.Argument(0).ToString()
	engine.Payload = []byte(val)
	return otto.Value{}
}

// hmac - Calcualtes an HMAC signature using SHA256
func (engine *ScriptEngine) hmac(call otto.FunctionCall) otto.Value {
	secretStr, _ := call.Argument(0).ToString()
	payloadStr, _ := call.Argument(1).ToString()
	secret := []byte(secretStr)
	h := hmac.New(sha256.New, secret)
	h.Write([]byte(payloadStr))
	sigBytes := h.Sum(nil)
	v, _ := otto.ToValue(hex.EncodeToString(sigBytes))
	return v
}

// getReqHeader - Returns a header from the request.
func (engine *ScriptEngine) getReqHeader(call otto.FunctionCall) otto.Value {
	headerName, _ := call.Argument(0).ToString()
	val := engine.Request.Header.Get(headerName)
	v, _ := otto.ToValue(val)
	return v
}

// setReqHeader - sets a header on the request.
func (engine *ScriptEngine) setReqHeader(call otto.FunctionCall) otto.Value {
	headerName, _ := call.Argument(0).ToString()
	headerValue, _ := call.Argument(1).ToString()
	if engine.Request != nil {
		engine.Request.Header.Set(headerName, headerValue)
	} else {
		engine.EndpointConfig.Headers[headerName] = []string{headerValue}
	}
	return otto.Value{}
}

// getResHeader - Returns a header from the response.
func (engine *ScriptEngine) getResHeader(call otto.FunctionCall) otto.Value {
	headerName, _ := call.Argument(0).ToString()
	val := engine.Response.Response.Header.Get(headerName)
	v, _ := otto.ToValue(val)
	return v
}

// setDebug - Sets the debug value on the engine. Used for testing.
func (engine *ScriptEngine) setDebug(call otto.FunctionCall) otto.Value {
	val, _ := call.Argument(0).ToString()
	engine.Debug = val
	return otto.Value{}
}
<commit_msg>Removed test file<commit_after>package request

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"github.com/5sigma/spyder/config"
	"github.com/5sigma/spyder/endpoint"
	"github.com/robertkrimen/otto"
	"github.com/robertkrimen/otto/parser"
	_ "github.com/robertkrimen/otto/underscore"
	"io/ioutil"
	"net/http"
)

// ScriptEngine - A scripting engine used to execute hook scripts during the
// request process. It is built to execute arbitrary Javascript.
type ScriptEngine struct {
	VM             *otto.Otto
	Constants      map[string]string
	AssetPath      string
	Response       *Response
	EndpointConfig *endpoint.EndpointConfig
	Payload        []byte
	Request        *http.Request
	Debug          string
}

// NewScriptEngine - Generates a new script engine.
func NewScriptEngine(endpointConfig *endpoint.EndpointConfig) *ScriptEngine {
	vm := otto.New()

	eng := &ScriptEngine{
		VM:             vm,
		EndpointConfig: endpointConfig,
	}

	varObj, _ := vm.Object("$variables = {}")
	varObj.Set("set", eng.setLocalVar)
	varObj.Set("get", eng.getVar)

	vm.Set("$debug", eng.setDebug)
	vm.Set("$hmac", eng.hmac)

	reqObj, _ := eng.VM.Object("$request = {}")
	requestBytes := endpointConfig.RequestData()
	reqObj.Set("body", string(requestBytes))
	reqObj.Set("contentLength", len(requestBytes))
	headersObj, _ := eng.VM.Object(`$request.headers = {}`)
	headersObj.Set("get", eng.getReqHeader)
	headersObj.Set("set", eng.setReqHeader)
	reqObj.Set("setBody", eng.setPayload)

	return eng
}

//ExecuteFile - Executes a script contianed in a file.
func (eng *ScriptEngine) ExecuteFile(filepath string) error {
	data, err := ioutil.ReadFile(filepath)
	if err != nil {
		return err
	}
	err = eng.Execute(string(data))
	if err != nil {
		return err
	}
	return nil
}

// SetResponse - Used to set the web respone on the engine. It also makes this
// available to the script.
func (eng *ScriptEngine) SetResponse(res *Response) {
	eng.Response = res
	requestObj, _ := eng.VM.Object(`$request = {}`)
	requestObj.Set("url", res.Request.URL.String())
	requestObj.Set("contentLength", res.Request.ContentLength)

	responseObj, _ := eng.VM.Object(`$response = {}`)
	responseObj.Set("contentLength", res.Response.ContentLength)
	responseObj.Set("body", string(res.Content))
	eng.VM.Object(`$response.headers = {}`)
	responseObj.Set("get", eng.getResHeader)
}

// SetRequest - Sets the request on the engine. This also builds the functions
// to expose the request to scripts.
func (engine *ScriptEngine) SetRequest(request *http.Request) {
	engine.Request = request
	reqVal, _ := engine.VM.Get("$request")
	reqObj := reqVal.Object()
	reqObj.Set("contentLength", request.ContentLength)
}

// SetPayload - Sets the request payload on the engine. Also exposes it to
// scripts within the request object.
func (engine *ScriptEngine) SetPayload(payload []byte) {
	engine.Payload = payload
	reqVal, _ := engine.VM.Get("$request")
	reqObj := reqVal.Object()
	reqObj.Set("body", string(payload))
}

//Execute - Executes a Javascript.
func (engine *ScriptEngine) Execute(script string) error {
	_, err := engine.VM.Run(script)
	if err != nil {
		println(err.Error())
	}
	return err
}

// Validate - Validates that the Javascript is valid.
func (eng *ScriptEngine) Validate(script string) error {
	_, err := parser.ParseFile(nil, "", script, 0)
	return err
}

// jsThrow - Used to throw javascript errors from Go.
func jsThrow(call otto.FunctionCall, err error) {
	call.Otto.Call("new Error", nil, err.Error())
}

// setLocalVar - Sets a config value in the local config.
func (engine *ScriptEngine) setLocalVar(call otto.FunctionCall) otto.Value {
	key, _ := call.Argument(0).ToString()
	value, _ := call.Argument(1).ToString()
	config.LocalConfig.SetVariable(key, value)
	return otto.Value{}
}

// getVar - Returns a config variable.
func (engine *ScriptEngine) getVar(call otto.FunctionCall) otto.Value {
	key, _ := call.Argument(0).ToString()
	if config.LocalConfig.VariableExists(key) {
		v := config.LocalConfig.GetVariable(key)
		ov, _ := otto.ToValue(v)
		return ov
	}
	if config.GlobalConfig.VariableExists(key) {
		v := config.LocalConfig.GetVariable(key)
		ov, _ := otto.ToValue(v)
		return ov
	}
	return otto.Value{}
}

// getPayload - Returns the request payload.
func (engine *ScriptEngine) getPayload(call otto.FunctionCall) otto.Value {
	ov, _ := otto.ToValue(string(engine.Payload))
	return ov
}

// setPayload - Sets the payload value on the engine.
func (engine *ScriptEngine) setPayload(call otto.FunctionCall) otto.Value {
	val, _ := call.Argument(0).ToString()
	engine.Payload = []byte(val)
	return otto.Value{}
}

// hmac - Calcualtes an HMAC signature using SHA256
func (engine *ScriptEngine) hmac(call otto.FunctionCall) otto.Value {
	secretStr, _ := call.Argument(0).ToString()
	payloadStr, _ := call.Argument(1).ToString()
	secret := []byte(secretStr)
	h := hmac.New(sha256.New, secret)
	h.Write([]byte(payloadStr))
	sigBytes := h.Sum(nil)
	v, _ := otto.ToValue(hex.EncodeToString(sigBytes))
	return v
}

// getReqHeader - Returns a header from the request.
func (engine *ScriptEngine) getReqHeader(call otto.FunctionCall) otto.Value {
	headerName, _ := call.Argument(0).ToString()
	val := engine.Request.Header.Get(headerName)
	v, _ := otto.ToValue(val)
	return v
}

// setReqHeader - sets a header on the request.
func (engine *ScriptEngine) setReqHeader(call otto.FunctionCall) otto.Value {
	headerName, _ := call.Argument(0).ToString()
	headerValue, _ := call.Argument(1).ToString()
	if engine.Request != nil {
		engine.Request.Header.Set(headerName, headerValue)
	} else {
		engine.EndpointConfig.Headers[headerName] = []string{headerValue}
	}
	return otto.Value{}
}

// getResHeader - Returns a header from the response.
func (engine *ScriptEngine) getResHeader(call otto.FunctionCall) otto.Value {
	headerName, _ := call.Argument(0).ToString()
	val := engine.Response.Response.Header.Get(headerName)
	v, _ := otto.ToValue(val)
	return v
}

// setDebug - Sets the debug value on the engine. Used for testing.
func (engine *ScriptEngine) setDebug(call otto.FunctionCall) otto.Value {
	val, _ := call.Argument(0).ToString()
	engine.Debug = val
	return otto.Value{}
}
<|endoftext|>


<commit_before>package registry

import (
	"fmt"
	"net/http"
	"net/http/httptest"
	"testing"
	"time"

	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
	"github.com/RangelReale/osincli"

	"github.com/openshift/origin/pkg/auth/api"
	"github.com/openshift/origin/pkg/auth/oauth/handlers"
	oapi "github.com/openshift/origin/pkg/oauth/api"
	"github.com/openshift/origin/pkg/oauth/registry/test"
	"github.com/openshift/origin/pkg/oauth/server/osinserver"
	"github.com/openshift/origin/pkg/oauth/server/osinserver/registrystorage"
)

type testHandlers struct {
	User         api.UserInfo
	Authenticate bool
	Err          error
	AuthNeed     bool
	AuthErr      error
	GrantNeed    bool
	GrantErr     error
}

func (h *testHandlers) AuthenticationNeeded(w http.ResponseWriter, req *http.Request) {
	h.AuthNeed = true
}

func (h *testHandlers) AuthenticationError(err error, w http.ResponseWriter, req *http.Request) {
	h.AuthErr = err
}

func (h *testHandlers) AuthenticateRequest(req *http.Request) (api.UserInfo, bool, error) {
	return h.User, h.Authenticate, h.Err
}

func (h *testHandlers) GrantNeeded(client api.Client, user api.UserInfo, grant *api.Grant, w http.ResponseWriter, req *http.Request) {
	h.GrantNeed = true
}

func (h *testHandlers) GrantError(err error, w http.ResponseWriter, req *http.Request) {
	h.GrantErr = err
}

type AccessTokenRegistry struct {
	Err                  error
	AccessTokens         *oapi.AccessTokenList
	AccessToken          *oapi.AccessToken
	DeletedAccessTokenId string
}

func (r *AccessTokenRegistry) ListAccessTokens(selector labels.Selector) (*oapi.AccessTokenList, error) {
	return r.AccessTokens, r.Err
}

func (r *AccessTokenRegistry) GetAccessToken(id string) (*oapi.AccessToken, error) {
	return r.AccessToken, r.Err
}

func (r *AccessTokenRegistry) CreateAccessToken(token *oapi.AccessToken) error {
	return r.Err
}

func (r *AccessTokenRegistry) UpdateAccessToken(token *oapi.AccessToken) error {
	return r.Err
}

func (r *AccessTokenRegistry) DeleteAccessToken(id string) error {
	r.DeletedAccessTokenId = id
	return r.Err
}

func TestRegistryAndServer(t *testing.T) {
	ch := make(chan *http.Request, 1)
	assertServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
		ch <- req
	}))

	validClient := &oapi.Client{
		Name:         "test",
		Secret:       "secret",
		RedirectURIs: []string{assertServer.URL + "/assert"},
	}
	validClientAuth := &oapi.ClientAuthorization{
		UserName:   "user",
		ClientName: "test",
	}

	testCases := map[string]struct {
		Client      *oapi.Client
		ClientAuth  *oapi.ClientAuthorization
		AuthSuccess bool
		AuthUser    api.UserInfo
		Scope       string
		Check       func(*testHandlers, *http.Request)
	}{
		"needs auth": {
			Client: validClient,
			Check: func(h *testHandlers, _ *http.Request) {
				if !h.AuthNeed || h.GrantNeed || h.AuthErr != nil || h.GrantErr != nil {
					t.Errorf("expected request to need authentication: %#v", h)
				}
			},
		},
		"needs grant": {
			Client:      validClient,
			AuthSuccess: true,
			AuthUser: &api.DefaultUserInfo{
				Name: "user",
			},
			Check: func(h *testHandlers, _ *http.Request) {
				if h.AuthNeed || !h.GrantNeed || h.AuthErr != nil || h.GrantErr != nil {
					t.Errorf("expected request to need to grant access: %#v", h)
				}
			},
		},
		"has non covered grant": {
			Client:      validClient,
			AuthSuccess: true,
			AuthUser: &api.DefaultUserInfo{
				Name: "user",
			},
			ClientAuth: &oapi.ClientAuthorization{
				UserName:   "user",
				ClientName: "test",
				Scopes:     []string{"test"},
			},
			Scope: "test other",
			Check: func(h *testHandlers, req *http.Request) {
				if h.AuthNeed || !h.GrantNeed || h.AuthErr != nil || h.GrantErr != nil {
					t.Errorf("expected request to need to grant access because of uncovered scopes: %#v", h)
				}
			},
		},
		"has covered grant": {
			Client:      validClient,
			AuthSuccess: true,
			AuthUser: &api.DefaultUserInfo{
				Name: "user",
			},
			ClientAuth: &oapi.ClientAuthorization{
				UserName:   "user",
				ClientName: "test",
				Scopes:     []string{"test", "other"},
			},
			Scope: "test other",
			Check: func(h *testHandlers, req *http.Request) {
				if h.AuthNeed || h.GrantNeed || h.AuthErr != nil || h.GrantErr != nil {
					t.Errorf("unexpected flow: %#v", h)
				}
			},
		},
		"has auth and grant": {
			Client:      validClient,
			AuthSuccess: true,
			AuthUser: &api.DefaultUserInfo{
				Name: "user",
			},
			ClientAuth: validClientAuth,
			Check: func(h *testHandlers, req *http.Request) {
				if h.AuthNeed || h.GrantNeed || h.AuthErr != nil || h.GrantErr != nil {
					t.Errorf("unexpected flow: %#v", h)
					return
				}
				if req == nil {
					t.Errorf("unexpected nil assertion request")
					return
				}
				if code := req.URL.Query().Get("code"); code == "" {
					t.Errorf("expected query param 'code', got: %#v", req)
				}
			},
		},
	}

	for _, testCase := range testCases {
		h := &testHandlers{}
		h.Authenticate = testCase.AuthSuccess
		h.User = testCase.AuthUser
		access, authorize := &test.AccessTokenRegistry{}, &test.AuthorizeTokenRegistry{}
		client := &test.ClientRegistry{
			Client: testCase.Client,
		}
		if testCase.Client == nil {
			client.Err = errors.NewNotFound("client", "unknown")
		}
		grant := &test.ClientAuthorizationRegistry{
			ClientAuthorization: testCase.ClientAuth,
		}
		if testCase.ClientAuth == nil {
			grant.Err = errors.NewNotFound("clientAuthorization", "test:test")
		}
		storage := registrystorage.New(access, authorize, client, NewUserConversion())
		config := osinserver.NewDefaultServerConfig()
		server := osinserver.New(
			config,
			storage,
			osinserver.AuthorizeHandlers{
				handlers.NewAuthorizeAuthenticator(
					h,
					h,
				),
				handlers.NewGrantCheck(
					NewClientAuthorizationGrantChecker(grant),
					h,
				),
			},
			osinserver.AccessHandlers{
				handlers.NewDenyAccessAuthenticator(),
			},
		)
		mux := http.NewServeMux()
		server.Install(mux, "")
		s := httptest.NewServer(mux)

		oaclientConfig := &osincli.ClientConfig{
			ClientId:     "test",
			ClientSecret: "secret",
			RedirectUrl:  assertServer.URL + "/assert",
			AuthorizeUrl: s.URL + "/authorize",
			TokenUrl:     s.URL + "/token",
			Scope:        testCase.Scope,
		}
		oaclient, err := osincli.NewClient(oaclientConfig)
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}

		aReq := oaclient.NewAuthorizeRequest(osincli.CODE)
		if _, err := http.Get(aReq.GetAuthorizeUrl().String()); err != nil {
			t.Fatalf("unexpected error: %v", err)
		}

		var req *http.Request
		select {
		case out := <-ch:
			req = out
		default:
		}

		testCase.Check(h, req)
	}
}

func TestAuthenticateTokenNotFound(t *testing.T) {
	tokenRegistry := &AccessTokenRegistry{Err: errors.NewNotFound("AccessToken", "token")}
	tokenAuthenticator := NewTokenAuthenticator(tokenRegistry)

	userInfo, found, err := tokenAuthenticator.AuthenticateToken("token")
	if found {
		t.Error("Found token, but it should be missing!")
	}
	if err != nil {
		t.Error("Unexpected error: %v", err)
	}
	if userInfo != nil {
		t.Error("Unexpected user: %v", userInfo)
	}
}
func TestAuthenticateTokenOtherGetError(t *testing.T) {
	tokenRegistry := &AccessTokenRegistry{Err: fmt.Errorf("get error")}
	tokenAuthenticator := NewTokenAuthenticator(tokenRegistry)

	userInfo, found, err := tokenAuthenticator.AuthenticateToken("token")
	if found {
		t.Error("Found token, but it should be missing!")
	}
	if err == nil {
		t.Error("Expected error is missing!")
	}
	if err.Error() != tokenRegistry.Err.Error() {
		t.Error("Expected error %v, but got error %v", tokenRegistry.Err, err)
	}
	if userInfo != nil {
		t.Error("Unexpected user: %v", userInfo)
	}
}
func TestAuthenticateTokenExpired(t *testing.T) {
	tokenRegistry := &AccessTokenRegistry{
		Err: nil,
		AccessToken: &oapi.AccessToken{
			TypeMeta: kapi.TypeMeta{CreationTimestamp: util.Time{time.Now().Add(-1 * time.Hour)}},
			AuthorizeToken: oapi.AuthorizeToken{
				ExpiresIn: 600, // 10 minutes
			},
		},
	}
	tokenAuthenticator := NewTokenAuthenticator(tokenRegistry)

	userInfo, found, err := tokenAuthenticator.AuthenticateToken("token")
	if found {
		t.Error("Found token, but it should be missing!")
	}
	if err != nil {
		t.Error("Unexpected error: %v", err)
	}
	if userInfo != nil {
		t.Error("Unexpected user: %v", userInfo)
	}
}
func TestAuthenticateTokenValidated(t *testing.T) {
	tokenRegistry := &AccessTokenRegistry{
		Err: nil,
		AccessToken: &oapi.AccessToken{
			TypeMeta: kapi.TypeMeta{CreationTimestamp: util.Time{time.Now()}},
			AuthorizeToken: oapi.AuthorizeToken{
				ExpiresIn: 600, // 10 minutes
			},
		},
	}
	tokenAuthenticator := NewTokenAuthenticator(tokenRegistry)

	userInfo, found, err := tokenAuthenticator.AuthenticateToken("token")
	if !found {
		t.Error("Did not find a token!")
	}
	if err != nil {
		t.Error("Unexpected error: %v", err)
	}
	if userInfo == nil {
		t.Error("Did not get a user!")
	}
}
<commit_msg>make use of common mock objects<commit_after>package registry

import (
	"fmt"
	"net/http"
	"net/http/httptest"
	"testing"
	"time"

	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
	"github.com/RangelReale/osincli"

	"github.com/openshift/origin/pkg/auth/api"
	"github.com/openshift/origin/pkg/auth/oauth/handlers"
	oapi "github.com/openshift/origin/pkg/oauth/api"
	"github.com/openshift/origin/pkg/oauth/registry/test"
	"github.com/openshift/origin/pkg/oauth/server/osinserver"
	"github.com/openshift/origin/pkg/oauth/server/osinserver/registrystorage"
)

type testHandlers struct {
	User         api.UserInfo
	Authenticate bool
	Err          error
	AuthNeed     bool
	AuthErr      error
	GrantNeed    bool
	GrantErr     error
}

func (h *testHandlers) AuthenticationNeeded(w http.ResponseWriter, req *http.Request) {
	h.AuthNeed = true
}

func (h *testHandlers) AuthenticationError(err error, w http.ResponseWriter, req *http.Request) {
	h.AuthErr = err
}

func (h *testHandlers) AuthenticateRequest(req *http.Request) (api.UserInfo, bool, error) {
	return h.User, h.Authenticate, h.Err
}

func (h *testHandlers) GrantNeeded(client api.Client, user api.UserInfo, grant *api.Grant, w http.ResponseWriter, req *http.Request) {
	h.GrantNeed = true
}

func (h *testHandlers) GrantError(err error, w http.ResponseWriter, req *http.Request) {
	h.GrantErr = err
}

func TestRegistryAndServer(t *testing.T) {
	ch := make(chan *http.Request, 1)
	assertServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
		ch <- req
	}))

	validClient := &oapi.Client{
		Name:         "test",
		Secret:       "secret",
		RedirectURIs: []string{assertServer.URL + "/assert"},
	}
	validClientAuth := &oapi.ClientAuthorization{
		UserName:   "user",
		ClientName: "test",
	}

	testCases := map[string]struct {
		Client      *oapi.Client
		ClientAuth  *oapi.ClientAuthorization
		AuthSuccess bool
		AuthUser    api.UserInfo
		Scope       string
		Check       func(*testHandlers, *http.Request)
	}{
		"needs auth": {
			Client: validClient,
			Check: func(h *testHandlers, _ *http.Request) {
				if !h.AuthNeed || h.GrantNeed || h.AuthErr != nil || h.GrantErr != nil {
					t.Errorf("expected request to need authentication: %#v", h)
				}
			},
		},
		"needs grant": {
			Client:      validClient,
			AuthSuccess: true,
			AuthUser: &api.DefaultUserInfo{
				Name: "user",
			},
			Check: func(h *testHandlers, _ *http.Request) {
				if h.AuthNeed || !h.GrantNeed || h.AuthErr != nil || h.GrantErr != nil {
					t.Errorf("expected request to need to grant access: %#v", h)
				}
			},
		},
		"has non covered grant": {
			Client:      validClient,
			AuthSuccess: true,
			AuthUser: &api.DefaultUserInfo{
				Name: "user",
			},
			ClientAuth: &oapi.ClientAuthorization{
				UserName:   "user",
				ClientName: "test",
				Scopes:     []string{"test"},
			},
			Scope: "test other",
			Check: func(h *testHandlers, req *http.Request) {
				if h.AuthNeed || !h.GrantNeed || h.AuthErr != nil || h.GrantErr != nil {
					t.Errorf("expected request to need to grant access because of uncovered scopes: %#v", h)
				}
			},
		},
		"has covered grant": {
			Client:      validClient,
			AuthSuccess: true,
			AuthUser: &api.DefaultUserInfo{
				Name: "user",
			},
			ClientAuth: &oapi.ClientAuthorization{
				UserName:   "user",
				ClientName: "test",
				Scopes:     []string{"test", "other"},
			},
			Scope: "test other",
			Check: func(h *testHandlers, req *http.Request) {
				if h.AuthNeed || h.GrantNeed || h.AuthErr != nil || h.GrantErr != nil {
					t.Errorf("unexpected flow: %#v", h)
				}
			},
		},
		"has auth and grant": {
			Client:      validClient,
			AuthSuccess: true,
			AuthUser: &api.DefaultUserInfo{
				Name: "user",
			},
			ClientAuth: validClientAuth,
			Check: func(h *testHandlers, req *http.Request) {
				if h.AuthNeed || h.GrantNeed || h.AuthErr != nil || h.GrantErr != nil {
					t.Errorf("unexpected flow: %#v", h)
					return
				}
				if req == nil {
					t.Errorf("unexpected nil assertion request")
					return
				}
				if code := req.URL.Query().Get("code"); code == "" {
					t.Errorf("expected query param 'code', got: %#v", req)
				}
			},
		},
	}

	for _, testCase := range testCases {
		h := &testHandlers{}
		h.Authenticate = testCase.AuthSuccess
		h.User = testCase.AuthUser
		access, authorize := &test.AccessTokenRegistry{}, &test.AuthorizeTokenRegistry{}
		client := &test.ClientRegistry{
			Client: testCase.Client,
		}
		if testCase.Client == nil {
			client.Err = errors.NewNotFound("client", "unknown")
		}
		grant := &test.ClientAuthorizationRegistry{
			ClientAuthorization: testCase.ClientAuth,
		}
		if testCase.ClientAuth == nil {
			grant.Err = errors.NewNotFound("clientAuthorization", "test:test")
		}
		storage := registrystorage.New(access, authorize, client, NewUserConversion())
		config := osinserver.NewDefaultServerConfig()
		server := osinserver.New(
			config,
			storage,
			osinserver.AuthorizeHandlers{
				handlers.NewAuthorizeAuthenticator(
					h,
					h,
				),
				handlers.NewGrantCheck(
					NewClientAuthorizationGrantChecker(grant),
					h,
				),
			},
			osinserver.AccessHandlers{
				handlers.NewDenyAccessAuthenticator(),
			},
		)
		mux := http.NewServeMux()
		server.Install(mux, "")
		s := httptest.NewServer(mux)

		oaclientConfig := &osincli.ClientConfig{
			ClientId:     "test",
			ClientSecret: "secret",
			RedirectUrl:  assertServer.URL + "/assert",
			AuthorizeUrl: s.URL + "/authorize",
			TokenUrl:     s.URL + "/token",
			Scope:        testCase.Scope,
		}
		oaclient, err := osincli.NewClient(oaclientConfig)
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}

		aReq := oaclient.NewAuthorizeRequest(osincli.CODE)
		if _, err := http.Get(aReq.GetAuthorizeUrl().String()); err != nil {
			t.Fatalf("unexpected error: %v", err)
		}

		var req *http.Request
		select {
		case out := <-ch:
			req = out
		default:
		}

		testCase.Check(h, req)
	}
}

func TestAuthenticateTokenNotFound(t *testing.T) {
	tokenRegistry := &test.AccessTokenRegistry{Err: errors.NewNotFound("AccessToken", "token")}
	tokenAuthenticator := NewTokenAuthenticator(tokenRegistry)

	userInfo, found, err := tokenAuthenticator.AuthenticateToken("token")
	if found {
		t.Error("Found token, but it should be missing!")
	}
	if err != nil {
		t.Error("Unexpected error: %v", err)
	}
	if userInfo != nil {
		t.Error("Unexpected user: %v", userInfo)
	}
}
func TestAuthenticateTokenOtherGetError(t *testing.T) {
	tokenRegistry := &test.AccessTokenRegistry{Err: fmt.Errorf("get error")}
	tokenAuthenticator := NewTokenAuthenticator(tokenRegistry)

	userInfo, found, err := tokenAuthenticator.AuthenticateToken("token")
	if found {
		t.Error("Found token, but it should be missing!")
	}
	if err == nil {
		t.Error("Expected error is missing!")
	}
	if err.Error() != tokenRegistry.Err.Error() {
		t.Error("Expected error %v, but got error %v", tokenRegistry.Err, err)
	}
	if userInfo != nil {
		t.Error("Unexpected user: %v", userInfo)
	}
}
func TestAuthenticateTokenExpired(t *testing.T) {
	tokenRegistry := &test.AccessTokenRegistry{
		Err: nil,
		AccessToken: &oapi.AccessToken{
			TypeMeta: kapi.TypeMeta{CreationTimestamp: util.Time{time.Now().Add(-1 * time.Hour)}},
			AuthorizeToken: oapi.AuthorizeToken{
				ExpiresIn: 600, // 10 minutes
			},
		},
	}
	tokenAuthenticator := NewTokenAuthenticator(tokenRegistry)

	userInfo, found, err := tokenAuthenticator.AuthenticateToken("token")
	if found {
		t.Error("Found token, but it should be missing!")
	}
	if err != nil {
		t.Error("Unexpected error: %v", err)
	}
	if userInfo != nil {
		t.Error("Unexpected user: %v", userInfo)
	}
}
func TestAuthenticateTokenValidated(t *testing.T) {
	tokenRegistry := &test.AccessTokenRegistry{
		Err: nil,
		AccessToken: &oapi.AccessToken{
			TypeMeta: kapi.TypeMeta{CreationTimestamp: util.Time{time.Now()}},
			AuthorizeToken: oapi.AuthorizeToken{
				ExpiresIn: 600, // 10 minutes
			},
		},
	}
	tokenAuthenticator := NewTokenAuthenticator(tokenRegistry)

	userInfo, found, err := tokenAuthenticator.AuthenticateToken("token")
	if !found {
		t.Error("Did not find a token!")
	}
	if err != nil {
		t.Error("Unexpected error: %v", err)
	}
	if userInfo == nil {
		t.Error("Did not get a user!")
	}
}
<|endoftext|>


<commit_before><commit_msg>kvm/arm64: set accessType when signal is SIGSEGV<commit_after><|endoftext|>


<commit_before>package main

/*
	This program runs all unit tests in the repository.
*/

import (
	"bufio"
	"bytes"
	"fmt"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"runtime"
	"strings"
	"sync"

	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/fileutil"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/testutils"
	"go.skia.org/infra/go/timer"
	"go.skia.org/infra/go/util"
)

const (
	// This gets filled out and printed when a test fails.
	TEST_FAILURE = `
============================= TEST FAILURE =============================
Test: %s

Command: %s

Error:
%s

Full output:
------------------------------------------------------------------------
%s
------------------------------------------------------------------------
`
)

var (
	// Error message shown when a required executable is not installed.
	ERR_NEED_INSTALL = "%s failed to run! Is it installed? Error: %v"

	// Directories with these names are skipped when searching for tests.
	NO_CRAWL_DIR_NAMES = []string{
		".git",
		".recipe_deps",
		"assets",
		"bower_components",
		"third_party",
		"node_modules",
	}

	// Directories with these paths, relative to the checkout root, are
	// skipped when searching for tests.
	NO_CRAWL_REL_PATHS = []string{
		"common",
	}

	POLYMER_PATHS = []string{
		"res/imp",
		"autoroll/res/imp",
		"fuzzer/res/imp",
		"status/res/imp",
	}
)

// cmdTest returns a test which runs a command and fails if the command fails.
func cmdTest(cmd []string, cwd, name, testType string) *test {
	return &test{
		Name: name,
		Cmd:  strings.Join(cmd, " "),
		run: func() (error, string) {
			command := exec.Command(cmd[0], cmd[1:]...)
			if cwd != "" {
				command.Dir = cwd
			}
			output, err := command.CombinedOutput()
			if err != nil {
				if _, err2 := exec.LookPath(cmd[0]); err2 != nil {
					return fmt.Errorf(ERR_NEED_INSTALL, cmd[0], err), string(output)
				}
			}
			return err, string(output)
		},
		Type: testType,
	}
}

func polylintTest(cwd, fileName string) *test {
	cmd := []string{"polylint", "--no-recursion", "--root", cwd, "--input", fileName}
	return &test{
		Name: fmt.Sprintf("polylint in %s", filepath.Join(cwd, fileName)),
		Cmd:  strings.Join(cmd, " "),
		run: func() (error, string) {
			command := exec.Command(cmd[0], cmd[1:]...)
			outputBytes, err := command.Output()
			if err != nil {
				if _, err2 := exec.LookPath(cmd[0]); err2 != nil {
					return fmt.Errorf(ERR_NEED_INSTALL, cmd[0], err), string(outputBytes)
				}
				return err, string(outputBytes)
			}

			unresolvedProblems := ""
			count := 0

			for s := bufio.NewScanner(bytes.NewBuffer(outputBytes)); s.Scan(); {
				badFileLine := s.Text()
				if !s.Scan() {
					return fmt.Errorf("Unexpected end of polylint output after %q:\n%s", badFileLine, string(outputBytes)), string(outputBytes)
				}
				problemLine := s.Text()
				if !strings.Contains(unresolvedProblems, badFileLine) {
					unresolvedProblems = fmt.Sprintf("%s\n%s\n%s", unresolvedProblems, badFileLine, problemLine)
					count++
				}
			}

			if unresolvedProblems == "" {
				return nil, ""
			}
			return fmt.Errorf("%d unresolved polylint problems:\n%s\n", count, unresolvedProblems), ""
		},
		Type: testutils.LARGE_TEST,
	}
}

// buildPolymerFolder runs the Makefile in the given folder.  This sets up the symbolic links so dependencies can be located for polylint.
func buildPolymerFolder(cwd string) error {
	cmd := cmdTest([]string{"make"}, cwd, fmt.Sprintf("Polymer build in %s", cwd), testutils.LARGE_TEST)
	return cmd.Run()
}

// polylintTestsForDir builds the folder once and then returns a list of tests for each Polymer file in the directory.  If the build fails, a dummy test is returned that prints an error message.
func polylintTestsForDir(cwd string, fileNames ...string) []*test {
	if err := buildPolymerFolder(cwd); err != nil {
		return []*test{
			&test{
				Name: filepath.Join(cwd, "make"),
				Cmd:  filepath.Join(cwd, "make"),
				run: func() (error, string) {
					return fmt.Errorf("Could not build Polymer files in %s: %s", cwd, err), ""
				},
				Type: testutils.LARGE_TEST,
			},
		}
	}
	tests := make([]*test, 0, len(fileNames))
	for _, name := range fileNames {
		tests = append(tests, polylintTest(cwd, name))
	}
	return tests
}

// findPolymerFiles returns all files that probably contain polymer content (i.e. end with sk.html) in a given directory.
func findPolymerFiles(dirPath string) []string {
	dir := fileutil.MustOpen(dirPath)
	files := make([]string, 0)
	for _, info := range fileutil.MustReaddir(dir) {
		if n := info.Name(); strings.HasSuffix(info.Name(), "sk.html") {
			files = append(files, n)
		}
	}
	return files
}

//polylintTests creates a list of *test from all directories in POLYMER_PATHS
func polylintTests() []*test {
	tests := make([]*test, 0)
	for _, path := range POLYMER_PATHS {
		tests = append(tests, polylintTestsForDir(path, findPolymerFiles(path)...)...)
	}
	return tests
}

// goTest returns a test which runs `go test` in the given cwd.
func goTest(cwd string, testType string, args ...string) *test {
	cmd := []string{"go", "test", "-v", "./go/...", "-parallel", "1"}
	cmd = append(cmd, args...)
	return cmdTest(cmd, cwd, fmt.Sprintf("go tests (%s) in %s", testType, cwd), testType)
}

// goTestSmall returns a test which runs `go test --small` in the given cwd.
func goTestSmall(cwd string) *test {
	return goTest(cwd, testutils.SMALL_TEST, "--small", "--timeout", testutils.TIMEOUT_SMALL)
}

// goTestMedium returns a test which runs `go test --medium` in the given cwd.
func goTestMedium(cwd string) *test {
	return goTest(cwd, testutils.MEDIUM_TEST, "--medium", "--timeout", testutils.TIMEOUT_MEDIUM)
}

// goTestLarge returns a test which runs `go test --large` in the given cwd.
func goTestLarge(cwd string) *test {
	return goTest(cwd, testutils.LARGE_TEST, "--large", "--timeout", testutils.TIMEOUT_LARGE)
}

// pythonTest returns a test which runs the given Python script and fails if
// the script fails.
func pythonTest(testPath string) *test {
	return cmdTest([]string{"python", testPath}, ".", path.Base(testPath), testutils.SMALL_TEST)
}

// test is a struct which represents a single test to run.
type test struct {
	Name string
	Cmd  string
	run  func() (error, string)
	Type string
}

// Run executes the function for the given test and returns an error if it fails.
func (t test) Run() error {
	if !util.In(t.Type, testutils.TEST_TYPES) {
		sklog.Fatalf("Test %q has invalid type %q", t.Name, t.Type)
	}
	if !testutils.ShouldRun(t.Type) {
		sklog.Infof("Not running %s tests; skipping %q", t.Type, t.Name)
		return nil
	}

	defer timer.New(t.Name).Stop()
	err, output := t.run()
	if err != nil {
		return fmt.Errorf(TEST_FAILURE, t.Name, t.Cmd, err, output)
	}
	return nil
}

// Find and run tests.
func main() {
	defer common.LogPanic()
	common.Init()

	// Ensure that we're actually going to run something.
	ok := false
	for _, tt := range testutils.TEST_TYPES {
		if testutils.ShouldRun(tt) {
			ok = true
		}
	}
	if !ok {
		sklog.Errorf("Must provide --small, --medium, and/or --large. This will cause an error in the future.")
	}

	defer timer.New("Finished").Stop()

	_, filename, _, _ := runtime.Caller(0)
	rootDir := path.Dir(filename)

	// If we are running full tests make sure we have the latest
	// pdfium_test installed.
	if testutils.ShouldRun(testutils.MEDIUM_TEST) || testutils.ShouldRun(testutils.LARGE_TEST) {
		sklog.Info("Installing pdfium_test if necessary.")
		pdfiumInstall := path.Join(rootDir, "pdfium", "install_pdfium.sh")
		if err := exec.Command(pdfiumInstall).Run(); err != nil {
			sklog.Fatalf("Failed to install pdfium_test: %v", err)
		}
		sklog.Info("Latest pdfium_test installed successfully.")
	}

	// Gather all of the tests to run.
	sklog.Info("Searching for tests.")
	tests := []*test{}

	// Search for Python tests and Go dirs to test in the repo.
	if err := filepath.Walk(rootDir, func(p string, info os.FileInfo, err error) error {
		basename := path.Base(p)
		if info.IsDir() {
			// Skip some directories.
			for _, skip := range NO_CRAWL_DIR_NAMES {
				if basename == skip {
					return filepath.SkipDir
				}
			}
			for _, skip := range NO_CRAWL_REL_PATHS {
				if p == path.Join(rootDir, skip) {
					return filepath.SkipDir
				}
			}

			if basename == "go" {
				tests = append(tests, goTestSmall(path.Dir(p)))
				tests = append(tests, goTestMedium(path.Dir(p)))
				tests = append(tests, goTestLarge(path.Dir(p)))
			}
		}
		if strings.HasSuffix(basename, "_test.py") {
			tests = append(tests, pythonTest(p))
		}
		return nil
	}); err != nil {
		sklog.Fatal(err)
	}

	// Other tests.
	tests = append(tests, cmdTest([]string{"go", "vet", "./..."}, ".", "go vet", testutils.SMALL_TEST))
	tests = append(tests, cmdTest([]string{"errcheck", "-ignore", ":Close", "go.skia.org/infra/..."}, ".", "errcheck", testutils.MEDIUM_TEST))
	tests = append(tests, polylintTests()...)
	tests = append(tests, cmdTest([]string{"python", "infra/bots/recipes.py", "simulation_test"}, ".", "recipe simulation test", testutils.MEDIUM_TEST))
	tests = append(tests, cmdTest([]string{"go", "run", "infra/bots/gen_tasks.go", "--test"}, ".", "gen_tasks.go --test", testutils.SMALL_TEST))
	tests = append(tests, cmdTest([]string{"python", "infra/bots/check_cq_cfg.py"}, ".", "check CQ config", testutils.SMALL_TEST))
	tests = append(tests, cmdTest([]string{"python", "go/testutils/uncategorized_tests.py"}, ".", "uncategorized tests", testutils.SMALL_TEST))

	goimportsCmd := []string{"goimports", "-l", "."}
	tests = append(tests, &test{
		Name: "goimports",
		Cmd:  strings.Join(goimportsCmd, " "),
		run: func() (error, string) {
			command := exec.Command(goimportsCmd[0], goimportsCmd[1:]...)
			output, err := command.Output()
			outStr := strings.Trim(string(output), "\n")
			if err != nil {
				if _, err2 := exec.LookPath(goimportsCmd[0]); err2 != nil {
					return fmt.Errorf(ERR_NEED_INSTALL, goimportsCmd[0], err), outStr
				}
				// Sometimes goimports returns exit code 2, but gives no reason.
				if outStr != "" {
					return err, fmt.Sprintf("goimports output: %q", outStr)
				}
			}
			diffFiles := strings.Split(outStr, "\n")
			if len(diffFiles) > 0 && !(len(diffFiles) == 1 && diffFiles[0] == "") {
				return fmt.Errorf("goimports found diffs in the following files:\n  - %s", strings.Join(diffFiles, ",\n  - ")), outStr
			}
			return nil, ""

		},
		Type: testutils.MEDIUM_TEST,
	})

	// Run the tests.
	sklog.Infof("Found %d tests.", len(tests))
	var mutex sync.Mutex
	errors := map[string]error{}
	var wg sync.WaitGroup
	for _, t := range tests {
		wg.Add(1)
		go func(t *test) {
			defer wg.Done()
			if err := t.Run(); err != nil {
				mutex.Lock()
				errors[t.Name] = err
				mutex.Unlock()
			}
		}(t)
	}
	wg.Wait()
	if len(errors) > 0 {
		for _, e := range errors {
			sklog.Error(e)
		}
		os.Exit(1)
	}
	sklog.Info("All tests succeeded.")
}
<commit_msg>run_unittests.go: Collect timing information for tests<commit_after>package main

/*
	This program runs all unit tests in the repository.
*/

import (
	"bufio"
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"regexp"
	"runtime"
	"strings"
	"sync"
	"time"

	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/fileutil"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/testutils"
	"go.skia.org/infra/go/timer"
	"go.skia.org/infra/go/util"
)

const (
	// This gets filled out and printed when a test fails.
	TEST_FAILURE = `
============================= TEST FAILURE =============================
Test: %s

Command: %s

Error:
%s

Full output:
------------------------------------------------------------------------
%s
------------------------------------------------------------------------
`
)

var (
	// Error message shown when a required executable is not installed.
	ERR_NEED_INSTALL = "%s failed to run! Is it installed? Error: %v"

	// Directories with these names are skipped when searching for tests.
	NO_CRAWL_DIR_NAMES = []string{
		".git",
		".recipe_deps",
		"assets",
		"bower_components",
		"third_party",
		"node_modules",
	}

	// Directories with these paths, relative to the checkout root, are
	// skipped when searching for tests.
	NO_CRAWL_REL_PATHS = []string{
		"common",
	}

	POLYMER_PATHS = []string{
		"res/imp",
		"autoroll/res/imp",
		"fuzzer/res/imp",
		"status/res/imp",
	}

	// goTestRegexp is a regular expression used for finding the durations
	// of tests.
	goTestRegexp = regexp.MustCompile("--- (\\w+):\\s+(\\w+)\\s+\\((.+)\\)")

	// Flags.

	// writeTimings is a file in which to write the test timings in JSON
	// format.
	writeTimings = flag.String("write_timings", "", "JSON file in which to write the test timings.")
)

// cmdTest returns a test which runs a command and fails if the command fails.
func cmdTest(cmd []string, cwd, name, testType string) *test {
	return &test{
		Name: name,
		Cmd:  strings.Join(cmd, " "),
		run: func() (string, error) {
			command := exec.Command(cmd[0], cmd[1:]...)
			if cwd != "" {
				command.Dir = cwd
			}
			output, err := command.CombinedOutput()
			if err != nil {
				if _, err2 := exec.LookPath(cmd[0]); err2 != nil {
					return string(output), fmt.Errorf(ERR_NEED_INSTALL, cmd[0], err)
				}
			}
			return string(output), err
		},
		Type: testType,
	}
}

func polylintTest(cwd, fileName string) *test {
	cmd := []string{"polylint", "--no-recursion", "--root", cwd, "--input", fileName}
	return &test{
		Name: fmt.Sprintf("polylint in %s", filepath.Join(cwd, fileName)),
		Cmd:  strings.Join(cmd, " "),
		run: func() (string, error) {
			command := exec.Command(cmd[0], cmd[1:]...)
			outputBytes, err := command.Output()
			if err != nil {
				if _, err2 := exec.LookPath(cmd[0]); err2 != nil {
					return string(outputBytes), fmt.Errorf(ERR_NEED_INSTALL, cmd[0], err)
				}
				return string(outputBytes), err
			}

			unresolvedProblems := ""
			count := 0

			for s := bufio.NewScanner(bytes.NewBuffer(outputBytes)); s.Scan(); {
				badFileLine := s.Text()
				if !s.Scan() {
					return string(outputBytes), fmt.Errorf("Unexpected end of polylint output after %q:\n%s", badFileLine, string(outputBytes))
				}
				problemLine := s.Text()
				if !strings.Contains(unresolvedProblems, badFileLine) {
					unresolvedProblems = fmt.Sprintf("%s\n%s\n%s", unresolvedProblems, badFileLine, problemLine)
					count++
				}
			}

			if unresolvedProblems == "" {
				return "", nil
			}
			return "", fmt.Errorf("%d unresolved polylint problems:\n%s\n", count, unresolvedProblems)
		},
		Type: testutils.LARGE_TEST,
	}
}

// buildPolymerFolder runs the Makefile in the given folder.  This sets up the symbolic links so dependencies can be located for polylint.
func buildPolymerFolder(cwd string) error {
	cmd := cmdTest([]string{"make"}, cwd, fmt.Sprintf("Polymer build in %s", cwd), testutils.LARGE_TEST)
	return cmd.Run()
}

// polylintTestsForDir builds the folder once and then returns a list of tests for each Polymer file in the directory.  If the build fails, a dummy test is returned that prints an error message.
func polylintTestsForDir(cwd string, fileNames ...string) []*test {
	if err := buildPolymerFolder(cwd); err != nil {
		return []*test{
			&test{
				Name: filepath.Join(cwd, "make"),
				Cmd:  filepath.Join(cwd, "make"),
				run: func() (string, error) {
					return "", fmt.Errorf("Could not build Polymer files in %s: %s", cwd, err)
				},
				Type: testutils.LARGE_TEST,
			},
		}
	}
	tests := make([]*test, 0, len(fileNames))
	for _, name := range fileNames {
		tests = append(tests, polylintTest(cwd, name))
	}
	return tests
}

// findPolymerFiles returns all files that probably contain polymer content
// (i.e. end with sk.html) in a given directory.
func findPolymerFiles(dirPath string) []string {
	dir := fileutil.MustOpen(dirPath)
	files := make([]string, 0)
	for _, info := range fileutil.MustReaddir(dir) {
		if n := info.Name(); strings.HasSuffix(info.Name(), "sk.html") {
			files = append(files, n)
		}
	}
	return files
}

//polylintTests creates a list of *test from all directories in POLYMER_PATHS
func polylintTests() []*test {
	tests := make([]*test, 0)
	for _, path := range POLYMER_PATHS {
		tests = append(tests, polylintTestsForDir(path, findPolymerFiles(path)...)...)
	}
	return tests
}

// goTest returns a test which runs `go test` in the given cwd.
func goTest(cwd string, testType string, args ...string) *test {
	cmd := []string{"go", "test", "-v", "./go/...", "-parallel", "1"}
	cmd = append(cmd, args...)
	t := cmdTest(cmd, cwd, fmt.Sprintf("go tests (%s) in %s", testType, cwd), testType)

	// Go tests print out their own timings. Parse them to obtain individual
	// test times.
	t.duration = func() map[string]time.Duration {
		rv := map[string]time.Duration{}
		split := strings.Split(t.output, "\n")
		for _, line := range split {
			m := goTestRegexp.FindStringSubmatch(line)
			if len(m) == 4 {
				if m[1] == "PASS" || m[1] == "FAIL" {
					d, err := time.ParseDuration(m[3])
					if err != nil {
						sklog.Errorf("Got invalid test duration: %q", m[3])
						continue
					}
					rv[m[2]] = d
				}
			}
		}
		return rv
	}
	return t
}

// goTestSmall returns a test which runs `go test --small` in the given cwd.
func goTestSmall(cwd string) *test {
	return goTest(cwd, testutils.SMALL_TEST, "--small", "--timeout", testutils.TIMEOUT_SMALL)
}

// goTestMedium returns a test which runs `go test --medium` in the given cwd.
func goTestMedium(cwd string) *test {
	return goTest(cwd, testutils.MEDIUM_TEST, "--medium", "--timeout", testutils.TIMEOUT_MEDIUM)
}

// goTestLarge returns a test which runs `go test --large` in the given cwd.
func goTestLarge(cwd string) *test {
	return goTest(cwd, testutils.LARGE_TEST, "--large", "--timeout", testutils.TIMEOUT_LARGE)
}

// pythonTest returns a test which runs the given Python script and fails if
// the script fails.
func pythonTest(testPath string) *test {
	return cmdTest([]string{"python", testPath}, ".", path.Base(testPath), testutils.SMALL_TEST)
}

// test is a struct which represents a single test to run.
type test struct {
	// Name is the human-friendly name of the test.
	Name string

	// Cmd is the command to run.
	Cmd string

	// duration is a function which returns the duration(s) of the test(s).
	duration func() map[string]time.Duration

	// output contains the output from the command. It is only populated
	// after Run() is called.
	output string

	// run is a function used to run the test. It returns any error and the
	// output of the test.
	run func() (string, error)

	// totalTime is the duration of the test, populated after Run().
	totalTime time.Duration

	// Type is the small/medium/large categorization of the test.
	Type string
}

// Run executes the function for the given test and returns an error if it fails.
func (t *test) Run() error {
	if !util.In(t.Type, testutils.TEST_TYPES) {
		sklog.Fatalf("Test %q has invalid type %q", t.Name, t.Type)
	}
	if !testutils.ShouldRun(t.Type) {
		sklog.Infof("Not running %s tests; skipping %q", t.Type, t.Name)
		return nil
	}

	started := time.Now()
	defer func() {
		t.totalTime = time.Now().Sub(started)
	}()
	output, err := t.run()
	if err != nil {
		return fmt.Errorf(TEST_FAILURE, t.Name, t.Cmd, err, output)
	}
	t.output = output
	return nil
}

// Duration returns the duration(s) of the test(s) which ran.
func (t *test) Duration() map[string]time.Duration {
	if t.duration == nil {
		return map[string]time.Duration{t.Name: t.totalTime}
	}
	return t.duration()
}

// Find and run tests.
func main() {
	defer common.LogPanic()
	common.Init()

	// Ensure that we're actually going to run something.
	ok := false
	for _, tt := range testutils.TEST_TYPES {
		if testutils.ShouldRun(tt) {
			ok = true
		}
	}
	if !ok {
		sklog.Errorf("Must provide --small, --medium, and/or --large. This will cause an error in the future.")
	}

	defer timer.New("Finished").Stop()

	_, filename, _, _ := runtime.Caller(0)
	rootDir := path.Dir(filename)

	// If we are running full tests make sure we have the latest
	// pdfium_test installed.
	if testutils.ShouldRun(testutils.MEDIUM_TEST) || testutils.ShouldRun(testutils.LARGE_TEST) {
		sklog.Info("Installing pdfium_test if necessary.")
		pdfiumInstall := path.Join(rootDir, "pdfium", "install_pdfium.sh")
		if err := exec.Command(pdfiumInstall).Run(); err != nil {
			sklog.Fatalf("Failed to install pdfium_test: %v", err)
		}
		sklog.Info("Latest pdfium_test installed successfully.")
	}

	// Gather all of the tests to run.
	sklog.Info("Searching for tests.")
	tests := []*test{}

	// Search for Python tests and Go dirs to test in the repo.
	if err := filepath.Walk(rootDir, func(p string, info os.FileInfo, err error) error {
		basename := path.Base(p)
		if info.IsDir() {
			// Skip some directories.
			for _, skip := range NO_CRAWL_DIR_NAMES {
				if basename == skip {
					return filepath.SkipDir
				}
			}
			for _, skip := range NO_CRAWL_REL_PATHS {
				if p == path.Join(rootDir, skip) {
					return filepath.SkipDir
				}
			}

			if basename == "go" {
				tests = append(tests, goTestSmall(path.Dir(p)))
				tests = append(tests, goTestMedium(path.Dir(p)))
				tests = append(tests, goTestLarge(path.Dir(p)))
			}
		}
		if strings.HasSuffix(basename, "_test.py") {
			tests = append(tests, pythonTest(p))
		}
		return nil
	}); err != nil {
		sklog.Fatal(err)
	}

	// Other tests.
	tests = append(tests, cmdTest([]string{"go", "vet", "./..."}, ".", "go vet", testutils.SMALL_TEST))
	tests = append(tests, cmdTest([]string{"errcheck", "-ignore", ":Close", "go.skia.org/infra/..."}, ".", "errcheck", testutils.MEDIUM_TEST))
	tests = append(tests, polylintTests()...)
	tests = append(tests, cmdTest([]string{"python", "infra/bots/recipes.py", "simulation_test"}, ".", "recipe simulation test", testutils.MEDIUM_TEST))
	tests = append(tests, cmdTest([]string{"go", "run", "infra/bots/gen_tasks.go", "--test"}, ".", "gen_tasks.go --test", testutils.SMALL_TEST))
	tests = append(tests, cmdTest([]string{"python", "infra/bots/check_cq_cfg.py"}, ".", "check CQ config", testutils.SMALL_TEST))
	tests = append(tests, cmdTest([]string{"python", "go/testutils/uncategorized_tests.py"}, ".", "uncategorized tests", testutils.SMALL_TEST))

	goimportsCmd := []string{"goimports", "-l", "."}
	tests = append(tests, &test{
		Name: "goimports",
		Cmd:  strings.Join(goimportsCmd, " "),
		run: func() (string, error) {
			command := exec.Command(goimportsCmd[0], goimportsCmd[1:]...)
			output, err := command.Output()
			outStr := strings.Trim(string(output), "\n")
			if err != nil {
				if _, err2 := exec.LookPath(goimportsCmd[0]); err2 != nil {
					return outStr, fmt.Errorf(ERR_NEED_INSTALL, goimportsCmd[0], err)
				}
				// Sometimes goimports returns exit code 2, but gives no reason.
				if outStr != "" {
					return fmt.Sprintf("goimports output: %q", outStr), err
				}
			}
			diffFiles := strings.Split(outStr, "\n")
			if len(diffFiles) > 0 && !(len(diffFiles) == 1 && diffFiles[0] == "") {
				return outStr, fmt.Errorf("goimports found diffs in the following files:\n  - %s", strings.Join(diffFiles, ",\n  - "))
			}
			return "", nil

		},
		Type: testutils.MEDIUM_TEST,
	})

	// Run the tests.
	sklog.Infof("Found %d tests.", len(tests))
	var mutex sync.Mutex
	errors := map[string]error{}
	var wg sync.WaitGroup
	for _, t := range tests {
		wg.Add(1)
		go func(t *test) {
			defer wg.Done()
			if err := t.Run(); err != nil {
				mutex.Lock()
				errors[t.Name] = err
				mutex.Unlock()
			}
		}(t)
	}
	wg.Wait()

	// Collect test durations.
	durations := map[string]time.Duration{}
	for _, t := range tests {
		for k, v := range t.Duration() {
			if _, ok := durations[k]; ok {
				sklog.Errorf("Duplicate test name %q; not keeping timing.", k)
				continue
			}
			durations[k] = v
		}
	}
	if *writeTimings != "" {
		b, err := json.MarshalIndent(durations, "", "  ")
		if err != nil {
			errors["encode output"] = err
		} else {
			if err := ioutil.WriteFile(*writeTimings, b, os.ModePerm); err != nil {
				errors["write output"] = err
			}
		}
	}
	if len(errors) > 0 {
		for _, e := range errors {
			sklog.Error(e)
		}
		os.Exit(1)
	}
	sklog.Info("All tests succeeded.")
}
<|endoftext|>


<commit_before>package main

import (
	"⚛sdl"
	"⚛sdl/ttf"
	"fmt"
	"flag"
	"math"
	"os"
	"clingon"
)

var (
	config      configuration
	console     *clingon.Console
	sdlrenderer *clingon.SDLRenderer
	running     bool
	r           *renderer
)

type configuration struct {
	consoleX, consoleY  int16
	consoleW, consoleH  uint16
	fullscreen, verbose bool
	fps                 float
	bgImage             string
}

type renderer struct {
	config                                 *configuration
	appSurface, bgImageSurface, cliSurface *sdl.Surface
	animateCLI                             bool
	t                                      float64
}

const (
	animation_step = math.Pi / 50
)

func (r *renderer) render(updatedRects []sdl.Rect) {
	if updatedRects == nil { // Initially we must blit the entire surface
		if r.bgImageSurface != nil {
			r.appSurface.Blit(nil, r.bgImageSurface, nil)
		}
		r.appSurface.Blit(&sdl.Rect{config.consoleX, config.consoleY, 0, 0}, sdlrenderer.GetSurface(), nil)
		r.appSurface.Flip()
	} else { // Then we can keep updated only the changed regions
		if !r.animateCLI {
			for _, rect := range updatedRects {
				if r.bgImageSurface != nil {
					r.appSurface.Blit(
						&sdl.Rect{rect.X + r.config.consoleX, rect.Y + r.config.consoleY, 0, 0},
						r.bgImageSurface,
						&sdl.Rect{rect.X + r.config.consoleX, rect.Y + r.config.consoleY, rect.W, rect.H})
				}
				r.appSurface.Blit(
					&sdl.Rect{rect.X + r.config.consoleX, rect.Y + r.config.consoleY, 0, 0},
					sdlrenderer.GetSurface(), &rect)
				r.appSurface.UpdateRect(int32(rect.X+r.config.consoleX), int32(rect.Y+r.config.consoleY), uint32(rect.W), uint32(rect.H))
			}
		} else {
			if !console.Paused {
				if r.config.consoleY > 40 {
					r.config.consoleY = 40 + int16((480-40+1)*(1-math.Cos(r.t)))
					r.t -= animation_step
				}
				if r.config.consoleY <= 40 {
					r.t = 0
					r.config.consoleY = 40
					r.animateCLI = false
				}
			} else {
				if r.config.consoleY < 480 {
					r.config.consoleY = 40 + int16((480-40+1)*(1-math.Cos(r.t)))
					r.t += animation_step
				}
				if r.config.consoleY >= 480 {
					r.t = (math.Pi / 2)
					r.config.consoleY = 480
					r.animateCLI = false
				}
			}
			if r.bgImageSurface != nil {
				r.appSurface.Blit(nil, r.bgImageSurface, nil)
			}
			r.appSurface.Blit(&sdl.Rect{r.config.consoleX, r.config.consoleY, 0, 0}, sdlrenderer.GetSurface(), nil)
			r.appSurface.Flip()
		}
	}
}

// Initialization boilerplate
func initialize(config *configuration) {
	var bgImage, appSurface *sdl.Surface

	if sdl.Init(sdl.INIT_VIDEO) != 0 {
		panic(sdl.GetError())
	}

	if ttf.Init() != 0 {
		panic(sdl.GetError())
	}

	font := ttf.OpenFont(flag.Arg(0), 12)

	if font == nil {
		panic(sdl.GetError())
	}

	sdl.EnableUNICODE(1)

	if config.fullscreen {
		appSurface = sdl.SetVideoMode(640, 480, 32, sdl.FULLSCREEN)
		sdl.ShowCursor(sdl.DISABLE)
	} else {
		appSurface = sdl.SetVideoMode(640, 480, 32, 0)
	}
	if config.bgImage != "" {
		bgImage = sdl.Load(config.bgImage)
	}

	sdlrenderer = clingon.NewSDLRenderer(sdl.CreateRGBSurface(sdl.SRCALPHA, int(config.consoleW), int(config.consoleH), 32, 0, 0, 0, 0), font)
	sdlrenderer.GetSurface().SetAlpha(sdl.SRCALPHA, 0xaa)

	if config.fps > 0 {
		sdlrenderer.FPSCh() <- config.fps
	}

	console = clingon.NewConsole(sdlrenderer, &ShellEvaluator{})
	console.SetPrompt("shell:$ ")
	console.GreetingText = "Welcome to the CLIngon shell!\n=============================\nPress F10 to toggle/untoggle\n\n"

	r = &renderer{
		config:         config,
		appSurface:     appSurface,
		cliSurface:     sdlrenderer.GetSurface(),
		bgImageSurface: bgImage,
	}
}

func main() {
	// Handle options
	help := flag.Bool("help", false, "Show usage")
	verbose := flag.Bool("verbose", false, "Verbose output")
	fullscreen := flag.Bool("fullscreen", false, "Go fullscreen!")
	fps := flag.Float("fps", clingon.DEFAULT_SDL_RENDERER_FPS, "Frames per second")
	bgImage := flag.String("bg-image", "", "Background image file")

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "shell - A system shell based on CLIngon (Command Line INterface for Go Nerds\n\n")
		fmt.Fprintf(os.Stderr, "Usage:\n\n")
		fmt.Fprintf(os.Stderr, "\tshell [options] <fontfile> \n\n")
		fmt.Fprintf(os.Stderr, "Options are:\n\n")
		flag.PrintDefaults()
	}

	flag.Parse()

	if *help == true {
		flag.Usage()
		return
	}

	if len(flag.Args()) < 1 {
		flag.Usage()
		return
	}

	config = configuration{
		verbose:    *verbose,
		fps:        *fps,
		fullscreen: *fullscreen,
		bgImage:    *bgImage,
		consoleX:   40,
		consoleY:   40,
		consoleW:   560,
		consoleH:   400,
	}

	initialize(&config)
	r.render(nil)

	running = true

	go func() {
		for running {

			select {
			case event := <-sdl.Events:
				switch e := event.(type) {
				case sdl.QuitEvent:
					running = false
				case sdl.KeyboardEvent:
					keyName := sdl.GetKeyName(sdl.Key(e.Keysym.Sym))

					if config.verbose {
						fmt.Printf("\n")
						fmt.Printf("%v: %v", e.Keysym.Sym, ": ", keyName)

						fmt.Printf("%04x ", e.Type)

						for i := 0; i < len(e.Pad0); i++ {
							fmt.Printf("%02x ", e.Pad0[i])
						}
						fmt.Printf("\n")

						fmt.Printf("Type: %02x Which: %02x State: %02x Pad: %02x\n", e.Type, e.Which, e.State, e.Pad0[0])
						fmt.Printf("Scancode: %02x Sym: %08x Mod: %04x Unicode: %04x\n", e.Keysym.Scancode, e.Keysym.Sym, e.Keysym.Mod, e.Keysym.Unicode)
					}
					if (keyName == "escape") && (e.Type == sdl.KEYDOWN) {
						running = false
					} else if (keyName == "f10") && (e.Type == sdl.KEYDOWN) {
						console.Paused = !console.Paused
						r.animateCLI = true
					} else if (keyName == "up") && (e.Type == sdl.KEYDOWN) {
						console.ReadlineCh() <- clingon.HISTORY_PREV
					} else if (keyName == "down") && (e.Type == sdl.KEYDOWN) {
						console.ReadlineCh() <- clingon.HISTORY_NEXT
					} else if (keyName == "left") && (e.Type == sdl.KEYDOWN) {
						console.ReadlineCh() <- clingon.CURSOR_LEFT
					} else if (keyName == "right") && (e.Type == sdl.KEYDOWN) {
						console.ReadlineCh() <- clingon.CURSOR_RIGHT
					} else {
						unicode := e.Keysym.Unicode
						if unicode > 0 {
							console.CharCh() <- unicode
						}
					}

				}
			}

		}
	}()

	for running {
		select {
		case rects := <-sdlrenderer.UpdatedRectsCh():
			r.render(rects)
		}
	}

	sdl.Quit()
}
<commit_msg>Add the auto-fps option to the shell example<commit_after>package main

import (
	"⚛sdl"
	"⚛sdl/ttf"
	"fmt"
	"flag"
	"math"
	"os"
	"clingon"
)

var (
	config      configuration
	console     *clingon.Console
	sdlrenderer *clingon.SDLRenderer
	running     bool
	r           *renderer
)

type configuration struct {
	consoleX, consoleY  int16
	consoleW, consoleH  uint16
	fullscreen, verbose, autoFps bool
	fps                 float
	bgImage             string
}

type renderer struct {
	config                                 *configuration
	appSurface, bgImageSurface, cliSurface *sdl.Surface
	animateCLI                             bool
	t                                      float64
}

const (
	animation_step = math.Pi / 50
)

func (r *renderer) render(updatedRects []sdl.Rect) {
	if updatedRects == nil { // Initially we must blit the entire surface
		if r.bgImageSurface != nil {
			r.appSurface.Blit(nil, r.bgImageSurface, nil)
		}
		r.appSurface.Blit(&sdl.Rect{config.consoleX, config.consoleY, 0, 0}, sdlrenderer.GetSurface(), nil)
		r.appSurface.Flip()
	} else { // Then we can keep updated only the changed regions
		if !r.animateCLI {
			for _, rect := range updatedRects {
				if r.bgImageSurface != nil {
					r.appSurface.Blit(
						&sdl.Rect{rect.X + r.config.consoleX, rect.Y + r.config.consoleY, 0, 0},
						r.bgImageSurface,
						&sdl.Rect{rect.X + r.config.consoleX, rect.Y + r.config.consoleY, rect.W, rect.H})
				}
				r.appSurface.Blit(
					&sdl.Rect{rect.X + r.config.consoleX, rect.Y + r.config.consoleY, 0, 0},
					sdlrenderer.GetSurface(), &rect)
				r.appSurface.UpdateRect(int32(rect.X+r.config.consoleX), int32(rect.Y+r.config.consoleY), uint32(rect.W), uint32(rect.H))
			}
		} else {
			if !console.Paused {
				if r.config.consoleY > 40 {
					r.config.consoleY = 40 + int16((480-40+1)*(1-math.Cos(r.t)))
					r.t -= animation_step
				}
				if r.config.consoleY <= 40 {
					r.t = 0
					r.config.consoleY = 40
					r.animateCLI = false
				}
			} else {
				if r.config.consoleY < 480 {
					r.config.consoleY = 40 + int16((480-40+1)*(1-math.Cos(r.t)))
					r.t += animation_step
				}
				if r.config.consoleY >= 480 {
					r.t = (math.Pi / 2)
					r.config.consoleY = 480
					r.animateCLI = false
				}
			}
			if r.bgImageSurface != nil {
				r.appSurface.Blit(nil, r.bgImageSurface, nil)
			}
			r.appSurface.Blit(&sdl.Rect{r.config.consoleX, r.config.consoleY, 0, 0}, sdlrenderer.GetSurface(), nil)
			r.appSurface.Flip()
		}
	}
}

// Initialization boilerplate
func initialize(config *configuration) {
	var bgImage, appSurface *sdl.Surface

	if sdl.Init(sdl.INIT_VIDEO) != 0 {
		panic(sdl.GetError())
	}

	if ttf.Init() != 0 {
		panic(sdl.GetError())
	}

	font := ttf.OpenFont(flag.Arg(0), 12)

	if font == nil {
		panic(sdl.GetError())
	}

	sdl.EnableUNICODE(1)

	if config.fullscreen {
		appSurface = sdl.SetVideoMode(640, 480, 32, sdl.FULLSCREEN)
		sdl.ShowCursor(sdl.DISABLE)
	} else {
		appSurface = sdl.SetVideoMode(640, 480, 32, 0)
	}
	if config.bgImage != "" {
		bgImage = sdl.Load(config.bgImage)
	}

	sdlrenderer = clingon.NewSDLRenderer(sdl.CreateRGBSurface(sdl.SRCALPHA, int(config.consoleW), int(config.consoleH), 32, 0, 0, 0, 0), font)
	sdlrenderer.GetSurface().SetAlpha(sdl.SRCALPHA, 0xaa)

	if config.fps > 0 {
		sdlrenderer.FPSCh() <- config.fps
	}

	console = clingon.NewConsole(sdlrenderer, &ShellEvaluator{})
	console.SetPrompt("shell:$ ")
	console.GreetingText = "Welcome to the CLIngon shell!\n=============================\nPress F10 to toggle/untoggle\n\n"

	r = &renderer{
		config:         config,
		appSurface:     appSurface,
		cliSurface:     sdlrenderer.GetSurface(),
		bgImageSurface: bgImage,
	}
}

func main() {
	// Handle options
	help := flag.Bool("help", false, "Show usage")
	verbose := flag.Bool("verbose", false, "Verbose output")
	fullscreen := flag.Bool("fullscreen", false, "Go fullscreen!")
	fps := flag.Float("fps", clingon.DEFAULT_SDL_RENDERER_FPS, "Frames per second")
	autoFps := flag.Bool("auto-fps", false, "Automatically double the FPS ratio on animations")
	bgImage := flag.String("bg-image", "", "Background image file")

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "shell - A system shell based on CLIngon (Command Line INterface for Go Nerds\n\n")
		fmt.Fprintf(os.Stderr, "Usage:\n\n")
		fmt.Fprintf(os.Stderr, "\tshell [options] <fontfile> \n\n")
		fmt.Fprintf(os.Stderr, "Options are:\n\n")
		flag.PrintDefaults()
	}

	flag.Parse()

	if *help == true {
		flag.Usage()
		return
	}

	if len(flag.Args()) < 1 {
		flag.Usage()
		return
	}

	config = configuration{
		verbose:    *verbose,
		fps:        *fps,
                autoFps: *autoFps,
		fullscreen: *fullscreen,
		bgImage:    *bgImage,
		consoleX:   40,
		consoleY:   40,
		consoleW:   560,
		consoleH:   400,
	}

	initialize(&config)
	r.render(nil)

	running = true

	go func() {
		for running {

			select {
			case event := <-sdl.Events:
				switch e := event.(type) {
				case sdl.QuitEvent:
					running = false
				case sdl.KeyboardEvent:
					keyName := sdl.GetKeyName(sdl.Key(e.Keysym.Sym))

					if config.verbose {
						fmt.Printf("\n")
						fmt.Printf("%v: %v", e.Keysym.Sym, ": ", keyName)

						fmt.Printf("%04x ", e.Type)

						for i := 0; i < len(e.Pad0); i++ {
							fmt.Printf("%02x ", e.Pad0[i])
						}
						fmt.Printf("\n")

						fmt.Printf("Type: %02x Which: %02x State: %02x Pad: %02x\n", e.Type, e.Which, e.State, e.Pad0[0])
						fmt.Printf("Scancode: %02x Sym: %08x Mod: %04x Unicode: %04x\n", e.Keysym.Scancode, e.Keysym.Sym, e.Keysym.Mod, e.Keysym.Unicode)
					}
					if (keyName == "escape") && (e.Type == sdl.KEYDOWN) {
						running = false
					} else if (keyName == "f10") && (e.Type == sdl.KEYDOWN) {
						console.Paused = !console.Paused
						r.animateCLI = true
						if config.autoFps {
							sdlrenderer.FPSCh() <- config.fps * 2
						}
					} else if (keyName == "up") && (e.Type == sdl.KEYDOWN) {
						console.ReadlineCh() <- clingon.HISTORY_PREV
					} else if (keyName == "down") && (e.Type == sdl.KEYDOWN) {
						console.ReadlineCh() <- clingon.HISTORY_NEXT
					} else if (keyName == "left") && (e.Type == sdl.KEYDOWN) {
						console.ReadlineCh() <- clingon.CURSOR_LEFT
					} else if (keyName == "right") && (e.Type == sdl.KEYDOWN) {
						console.ReadlineCh() <- clingon.CURSOR_RIGHT
					} else {
						unicode := e.Keysym.Unicode
						if unicode > 0 {
							console.CharCh() <- unicode
						}
					}

				}
			}

		}
	}()

	for running {
		select {
		case rects := <-sdlrenderer.UpdatedRectsCh():
			r.render(rects)
		}
	}

	sdl.Quit()
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/op/go-logging"
	"net/http"
	"os/signal"
	"syscall"
	"os"
	"fox"
	"util"
)

var log = logging.MustGetLogger("FoxService")

func main()  {

	var port = flag.Int("port", 8090, "Port to bind to on the localhost interface")
	var slog = flag.Bool("syslog", false, "If present, logs are sent to syslog")
	flag.Parse()

	initConfig()
	setupLogging(slog)

	router := fox.NewRouter()
	log.Infof("Starting a server on localhost:%d", *port)
	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), router))
}

func initConfig()  {
	util.LoadConfig()

	sc := make(chan os.Signal, 1)

	signal.Notify(sc, syscall.SIGHUP)

	go func ()  {
		for {
			<-sc
			util.LoadConfig()
		}
	}()
}

func setupLogging(slog *bool)  {
	var b logging.Backend

	format := logging.MustStringFormatter(
    	`%{color}%{time:15:04:05.000} %{shortfunc} ▶ %{level:.4s} %{id:03x}%{color:reset} %{message}`,
	)

	if *slog  {
		b, _ = logging.NewSyslogBackend("Fox")
	}else{
		b = logging.NewLogBackend(os.Stdout, "", 0)
	}

	bFormatter := logging.NewBackendFormatter(b, format)
	logging.SetBackend(bFormatter)
}<commit_msg>Fixed the foxservice crash upon token submit<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/op/go-logging"
	"net/http"
	"os/signal"
	"syscall"
	"os"
	"fox"
	"util"
	"authn"
)

var log = logging.MustGetLogger("FoxService")

func main()  {

	var port = flag.Int("port", 8090, "Port to bind to on the localhost interface")
	var slog = flag.Bool("syslog", false, "If present, logs are sent to syslog")
	flag.Parse()

	initConfig()
	setupLogging(slog)

	router := fox.NewRouter()
	log.Infof("Starting a server on localhost:%d", *port)
	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), router))
}

func initConfig()  {
	util.LoadConfig()
	authn.InitValidator()

	sc := make(chan os.Signal, 1)

	signal.Notify(sc, syscall.SIGHUP)

	go func ()  {
		for {
			<-sc
			util.LoadConfig()
		}
	}()
}

func setupLogging(slog *bool)  {
	var b logging.Backend

	format := logging.MustStringFormatter(
    	`%{color}%{time:15:04:05.000} %{shortfunc} ▶ %{level:.4s} %{id:03x}%{color:reset} %{message}`,
	)

	if *slog  {
		b, _ = logging.NewSyslogBackend("Fox")
	}else{
		b = logging.NewLogBackend(os.Stdout, "", 0)
	}

	bFormatter := logging.NewBackendFormatter(b, format)
	logging.SetBackend(bFormatter)
}<|endoftext|>


<commit_before>package main

import (
	"dns"
	"flag"
	"fmt"
	"os"
	"strconv"
)

func q(w dns.RequestWriter, m *dns.Msg) {
	w.Send(m)
	r, err := w.Receive()
	if err != nil {
		fmt.Printf("%s\n", err.Error())
	}
	w.Write(r)
}

func main() {
	port := flag.Int("port", 53, "port number to use")
	report := flag.Bool("report", false, "show fingerprint for (yet) unknown server")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [OPTIONS...] [@server]\n", os.Args[0])
		flag.PrintDefaults()
	}

	conf, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
	nameserver := "@" + conf.Servers[0]
	flag.Parse()

	for i := 0; i < flag.NArg(); i++ {
		// If it starts with @ it is a nameserver
		if flag.Arg(i)[0] == '@' {
			nameserver = flag.Arg(i)
			break
		}
	}
	nameserver = string([]byte(nameserver)[1:]) // chop off @
	nameserver += ":" + strconv.Itoa(*port)
	c := dns.NewClient()
	prints, _ := fingerPrintFromFile("data/q")
	results := make([]*fingerprint, 0)
        if *report {
                fmt.Printf("# Fingerprint of <Nameserver> <version>\n# Supplied by <Name> on <Date>\n#\n")
        }
	for _, f := range prints {
		f1 := probe(c, nameserver, f)
		results = append(results, f1)
		if *report {
			fmt.Printf("%s\n", f1.String())
		}
	}
	if *report {
		return
	}

	// For now, just list them:
        files := []string{"Atlas", "Bind8", "Bind9", "MaraDNS", "Microsoft", "Nsd3", "PowerDNS"}
        fmt.Printf("%s\t%s\t%s\t\t\t\t\t\t\t\t%s\n", "Server type", "Diffs", "Fingerprint", "Recevied")
	for _, file := range files {
                diff := 0
		prints, _ := fingerPrintFromFile("data/" + file)
		for i, f := range prints {
			d := f.compare(results[i])
                        diff += d
                        fmt.Printf("%s\t%d\t%s %s\n", file, d, f.String(), results[i].String())
		}
                fmt.Printf("\t\t==\nDifferences:\t%d\n\n", diff)
	}
}
<commit_msg>ouput<commit_after>package main

import (
	"dns"
	"flag"
	"fmt"
	"os"
	"strconv"
)

func q(w dns.RequestWriter, m *dns.Msg) {
	w.Send(m)
	r, err := w.Receive()
	if err != nil {
		fmt.Printf("%s\n", err.Error())
	}
	w.Write(r)
}

func main() {
	port := flag.Int("port", 53, "port number to use")
	report := flag.Bool("report", false, "show fingerprint for (yet) unknown server")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [OPTIONS...] [@server]\n", os.Args[0])
		flag.PrintDefaults()
	}

	conf, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
	nameserver := "@" + conf.Servers[0]
	flag.Parse()

	for i := 0; i < flag.NArg(); i++ {
		// If it starts with @ it is a nameserver
		if flag.Arg(i)[0] == '@' {
			nameserver = flag.Arg(i)
			break
		}
	}
	nameserver = string([]byte(nameserver)[1:]) // chop off @
	nameserver += ":" + strconv.Itoa(*port)
	c := dns.NewClient()
	prints, _ := fingerPrintFromFile("data/q")
	results := make([]*fingerprint, 0)
        if *report {
                fmt.Printf("# Fingerprint of <Nameserver> <version>\n# Supplied by <Name> on <Date>\n#\n")
        }
	for _, f := range prints {
		f1 := probe(c, nameserver, f)
		results = append(results, f1)
		if *report {
			fmt.Printf("%s\n", f1.String())
		}
	}
	if *report {
		return
	}

	// For now, just list them:
        files := []string{"Atlas", "Bind8", "Bind9", "MaraDNS", "Microsoft", "Nsd3", "PowerDNS"}
        fmt.Printf("%s\t%s\t%s\t\t\t\t\t\t\t\t%s\n", "Server type", "Diffs", "Fingerprint", "Recevied")
	for _, file := range files {
                diff := 0
		prints, _ := fingerPrintFromFile("data/" + file)
		for i, f := range prints {
			d := f.compare(results[i])
                        diff += d
                        fmt.Printf("%s\t%d %s %s\n", file, d, f.String(), results[i].String())
		}
                fmt.Printf("\t\t=\nDifferences:\t%d\n\n", diff)
	}
}
<|endoftext|>


<commit_before>package main

import (
    "fmt"
    "log"
    "io/ioutil"
    "github.com/pirsquare/semantics3-go"
)

func main() {
    client := semantics3.NewClient("XXXXXXXX", "XXXXXXXX", "products")
    client.AddParams(map[string]interface{}{"upc": uint64(636926047593)})

    response, err := client.Get()
    if err != nil{
        log.Fatalln(err)
    }

    defer response.Body.Close()

    bits, err := ioutil.ReadAll(response.Body)
    if err != nil{
        log.Fatalln(err)
    }

    fmt.Println(string(bits))

}<commit_msg>fix name<commit_after>package main

import (
    "fmt"
    "log"
    "io/ioutil"
    "github.com/pirsquare/semantics3-golang"
)

func main() {
    client := semantics3.NewClient("XXXXXXXX", "XXXXXXXX", "products")
    client.AddParams(map[string]interface{}{"upc": uint64(636926047593)})

    response, err := client.Get()
    if err != nil{
        log.Fatalln(err)
    }

    defer response.Body.Close()

    bits, err := ioutil.ReadAll(response.Body)
    if err != nil{
        log.Fatalln(err)
    }

    fmt.Println(string(bits))

}<|endoftext|>


<commit_before>package main

import (
	// "fmt"
	"github.com/yassu/gnuplot.go"
	// "github.com/yassu/gnuplot.go/conf"
)

func main() {
	fun := gnuplot.NewFunction2d()
	fun.SetF(func(x float64) float64 {
		return x * x
	})
	fun.Configure("_xMin", []string{"-100"})
	fun.Configure("_xMax", []string{"100"})
	fun.Configure("_title", []string{"title1"})
	fun.Configure("w", []string{"dots"})

	c := gnuplot.NewCurve2d()
	c.SetC(func(t float64) [2]float64 {
		return [2]float64{t, -t * t}
	})
	c.Configure("_tMin", []string{"-100"})
	c.Configure("_tMax", []string{"100"})

	graph := gnuplot.NewGraph2d()
	graph.Configure("angles", []string{"degrees"})
	graph.Configure("key", []string{"false"})
	graph.AppendFunc(*fun)
	graph.AppendCurve(*c)
	graph.Run()
}
<commit_msg>update sample<commit_after>package main

import (
	"github.com/yassu/gnuplot.go"
)

func main() {
	fun := gnuplot.NewFunction2d()
	fun.SetF(func(x float64) float64 {
		return x * x
	})
	fun.Configure("_xMin", []string{"-100"})
	fun.Configure("_xMax", []string{"100"})
	fun.Configure("_title", []string{"title1"})
	fun.Configure("w", []string{"dots"})

	c := gnuplot.NewCurve2d()
	c.SetC(func(t float64) [2]float64 {
		return [2]float64{t, -t * t}
	})
	c.Configures(map[string][]string{
		"_tMin": []string{"-100"},
		"_tMax": []string{"100"}})

	graph := gnuplot.NewGraph2d()
	graph.Configure("angles", []string{"degrees"})
	graph.Configure("key", []string{"false"})
	graph.AppendFunc(*fun)
	graph.AppendCurve(*c)
	graph.Run()
}
<|endoftext|>


<commit_before>package gockle

import (
	"fmt"

	"github.com/maraino/go-mock"
)

var mySession = &SessionMock{}

func Example_dump() {
	var rows, _ = mySession.QuerySliceMap("select * from users")

	for _, row := range rows {
		fmt.Println(row)
	}
}

func Example_insert() {
	mySession.QueryExec("insert into users (id, name) values (123, 'me')")
}

func Example_print() {
	var i = mySession.QueryIterator("select * from users")

	for done := false; !done; {
		var m = map[string]interface{}{}

		done = i.ScanMap(m)

		fmt.Println(m)
	}
}

func init() {
	var i = &IteratorMock{}

	i.When("ScanMap", mock.Any).Call(func(m map[string]interface{}) bool {
		m["id"] = 123
		m["name"] = "me"

		return false
	})

	i.When("Close").Return(nil)

	mySession.When("QueryExec", mock.Any).Return(nil)
	mySession.When("QueryIterator", mock.Any).Return(i)
	mySession.When("QueryScanMap", mock.Any).Return(map[string]interface{}{"id": 1, "name": "me"}, nil)
}
<commit_msg>Put some Session examples into other types<commit_after>package gockle

import (
	"fmt"

	"github.com/maraino/go-mock"
)

var mySession = &SessionMock{}

func ExampleBatch() {
	var b = mySession.QueryBatch(BatchLogged)

	b.Query("insert into users (id, name) values (123, 'me')")
	b.Query("insert into users (id, name) values (456, 'you')")

	b.Exec()
}

func ExampleIterator() {
	var i = mySession.QueryIterator("select * from users")

	for done := false; !done; {
		var m = map[string]interface{}{}

		done = i.ScanMap(m)

		fmt.Println(m)
	}
}

func ExampleSession() {
	var rows, _ = mySession.QuerySliceMap("select * from users")

	for _, row := range rows {
		fmt.Println(row)
	}
}

func init() {
	var i = &IteratorMock{}

	i.When("ScanMap", mock.Any).Call(func(m map[string]interface{}) bool {
		m["id"] = 123
		m["name"] = "me"

		return false
	})

	i.When("Close").Return(nil)

	mySession.When("QueryExec", mock.Any).Return(nil)
	mySession.When("QueryIterator", mock.Any).Return(i)
	mySession.When("QueryScanMap", mock.Any).Return(map[string]interface{}{"id": 1, "name": "me"}, nil)
}
<|endoftext|>