<commit_before>package calcium

import (
	"bufio"
	"fmt"
	"io"
	"sync"
	"time"

	log "github.com/Sirupsen/logrus"
	enginetypes "github.com/docker/docker/api/types"
	"gitlab.ricebook.net/platform/core/types"
	"gitlab.ricebook.net/platform/core/utils"
	"golang.org/x/net/context"
)

func (c *calcium) RunAndWait(specs types.Specs, opts *types.DeployOptions, stdin io.ReadCloser) (chan *types.RunAndWaitMessage, error) {
	ch := make(chan *types.RunAndWaitMessage)

	// 强制为 json-file 输出
	entry, _ := specs.Entrypoints[opts.Entrypoint]
	entry.LogConfig = "journald"
	specs.Entrypoints[opts.Entrypoint] = entry

	// 默认给出1200秒的超时时间吧
	// 没别的地方好传了, 不如放这里好了, 不需要用的就默认0或者不传
	waitTimeout := entry.RunAndWaitTimeout
	if waitTimeout == 0 {
		waitTimeout = c.config.RunAndWaitTimeout
	}

	finalSendError := func(e error) {
		ch <- &types.RunAndWaitMessage{ContainerID: " error ", Data: []byte(e.Error())}
		close(ch)
	}

	// count = 1 && OpenStdin
	if opts.OpenStdin && opts.Count != 1 {
		err := fmt.Errorf("[RunAndWait] `Count` must be 1 if `OpenStdin` is true, `Count` is %d now", opts.Count)
		go finalSendError(err)
		return ch, err
	}

	// 创建容器, 有问题就gg
	createChan, err := c.CreateContainer(specs, opts)
	if err != nil {
		go finalSendError(err)
		log.Errorf("[RunAndWait] Create container error %s", err)
		return ch, err
	}

	// 来个goroutine处理剩下的事情
	// 基本上就是, attach拿日志写到channel, 以及等待容器结束后清理资源
	go func() {
		defer close(ch)
		logsOpts := enginetypes.ContainerLogsOptions{Follow: true, ShowStdout: true, ShowStderr: true}
		wg := sync.WaitGroup{}

		for message := range createChan {
			// 可能不成功, 可能没有容器id, 但是其实第一项足够判断了
			// 不成功就无视掉
			if !message.Success || message.ContainerID == "" {
				log.Errorf("[RunAndWait] Create container error, %s", message.Error)
				continue
			}

			// 找不到对应node也不管
			// 理论上不会这样
			node, err := c.store.GetNode(message.Podname, message.Nodename)
			if err != nil {
				log.Errorf("[RunAndWait] Can't find node, %v", err)
				continue
			}

			// 加个task
			wg.Add(1)

			// goroutine attach日志然后处理了写回给channel
			// 日志跟task无关, 不管wg
			go func(node *types.Node, containerID string) {
				defer wg.Done()
				defer log.Infof("[RunAndWait] Container %s finished and removed", containerID[:12])
				defer c.removeContainerSync([]string{containerID})

				ctx, cancel := context.WithTimeout(context.Background(), time.Duration(waitTimeout)*time.Second)
				defer cancel()
				resp, err := node.Engine.ContainerLogs(ctx, containerID, logsOpts)
				if err != nil {
					log.Errorf("[RunAndWait] Failed to get logs, %v", err)
					ch <- &types.RunAndWaitMessage{ContainerID: containerID,
						Data: []byte(fmt.Sprintf("[exitcode] unknown %v", err))}
					return
				}

				if opts.OpenStdin {
					go func() {
						r, err := node.Engine.ContainerAttach(
							context.Background(), containerID,
							enginetypes.ContainerAttachOptions{Stream: true, Stdin: true})
						defer r.Close()
						defer stdin.Close()
						if err != nil {
							log.Errorf("[RunAndWait] Failed to attach container, %v", err)
							return
						}
						io.Copy(r.Conn, stdin)
					}()
				}

				stream := utils.FuckDockerStream(resp)
				scanner := bufio.NewScanner(stream)
				for scanner.Scan() {
					data := scanner.Bytes()
					ch <- &types.RunAndWaitMessage{
						ContainerID: containerID,
						Data:        data,
					}
					log.Debugf("[RunAndWait] %s %s", containerID[:12], data)
				}

				if err := scanner.Err(); err != nil {
					log.Errorf("[RunAndWait] Parse log failed, %v", err)
					ch <- &types.RunAndWaitMessage{ContainerID: containerID,
						Data: []byte(fmt.Sprintf("[exitcode] unknown %v", err))}
					return
				}

				// 超时的情况下根本不会到这里
				// 不超时的情况下这里肯定会立即返回
				code, err := node.Engine.ContainerWait(context.Background(), containerID)
				exitData := []byte(fmt.Sprintf("[exitcode] %d", code))
				if err != nil {
					log.Errorf("[RunAndWait] %s run failed, %v", containerID[:12], err)
					exitData = []byte(fmt.Sprintf("[exitcode] unknown %v", err))
				}
				ch <- &types.RunAndWaitMessage{ContainerID: containerID, Data: exitData}
			}(node, message.ContainerID)
		}

		// 等待全部任务完成才可以关闭channel
		wg.Wait()
		log.Info("[RunAndWait] Finish run and wait for containers")
	}()

	return ch, nil
}
<commit_msg>remove final return error msg<commit_after>package calcium

import (
	"bufio"
	"fmt"
	"io"
	"sync"
	"time"

	log "github.com/Sirupsen/logrus"
	enginetypes "github.com/docker/docker/api/types"
	"gitlab.ricebook.net/platform/core/types"
	"gitlab.ricebook.net/platform/core/utils"
	"golang.org/x/net/context"
)

func (c *calcium) RunAndWait(specs types.Specs, opts *types.DeployOptions, stdin io.ReadCloser) (chan *types.RunAndWaitMessage, error) {
	ch := make(chan *types.RunAndWaitMessage)

	// 强制为 json-file 输出
	entry, _ := specs.Entrypoints[opts.Entrypoint]
	entry.LogConfig = "journald"
	specs.Entrypoints[opts.Entrypoint] = entry

	// 默认给出1200秒的超时时间吧
	// 没别的地方好传了, 不如放这里好了, 不需要用的就默认0或者不传
	waitTimeout := entry.RunAndWaitTimeout
	if waitTimeout == 0 {
		waitTimeout = c.config.RunAndWaitTimeout
	}

	// count = 1 && OpenStdin
	if opts.OpenStdin && opts.Count != 1 {
		close(ch)
		err := fmt.Errorf("[RunAndWait] `Count` must be 1 if `OpenStdin` is true, `Count` is %d now", opts.Count)
		return ch, err
	}

	// 创建容器, 有问题就gg
	createChan, err := c.CreateContainer(specs, opts)
	if err != nil {
		close(ch)
		log.Errorf("[RunAndWait] Create container error %s", err)
		return ch, err
	}

	// 来个goroutine处理剩下的事情
	// 基本上就是, attach拿日志写到channel, 以及等待容器结束后清理资源
	go func() {
		defer close(ch)
		logsOpts := enginetypes.ContainerLogsOptions{Follow: true, ShowStdout: true, ShowStderr: true}
		wg := sync.WaitGroup{}

		for message := range createChan {
			// 可能不成功, 可能没有容器id, 但是其实第一项足够判断了
			// 不成功就无视掉
			if !message.Success || message.ContainerID == "" {
				log.Errorf("[RunAndWait] Create container error, %s", message.Error)
				continue
			}

			// 找不到对应node也不管
			// 理论上不会这样
			node, err := c.store.GetNode(message.Podname, message.Nodename)
			if err != nil {
				log.Errorf("[RunAndWait] Can't find node, %v", err)
				continue
			}

			// 加个task
			wg.Add(1)

			// goroutine attach日志然后处理了写回给channel
			// 日志跟task无关, 不管wg
			go func(node *types.Node, containerID string) {
				defer wg.Done()
				defer log.Infof("[RunAndWait] Container %s finished and removed", containerID[:12])
				defer c.removeContainerSync([]string{containerID})

				ctx, cancel := context.WithTimeout(context.Background(), time.Duration(waitTimeout)*time.Second)
				defer cancel()
				resp, err := node.Engine.ContainerLogs(ctx, containerID, logsOpts)
				if err != nil {
					log.Errorf("[RunAndWait] Failed to get logs, %v", err)
					ch <- &types.RunAndWaitMessage{ContainerID: containerID,
						Data: []byte(fmt.Sprintf("[exitcode] unknown %v", err))}
					return
				}

				if opts.OpenStdin {
					go func() {
						r, err := node.Engine.ContainerAttach(
							context.Background(), containerID,
							enginetypes.ContainerAttachOptions{Stream: true, Stdin: true})
						defer r.Close()
						defer stdin.Close()
						if err != nil {
							log.Errorf("[RunAndWait] Failed to attach container, %v", err)
							return
						}
						io.Copy(r.Conn, stdin)
					}()
				}

				stream := utils.FuckDockerStream(resp)
				scanner := bufio.NewScanner(stream)
				for scanner.Scan() {
					data := scanner.Bytes()
					ch <- &types.RunAndWaitMessage{
						ContainerID: containerID,
						Data:        data,
					}
					log.Debugf("[RunAndWait] %s %s", containerID[:12], data)
				}

				if err := scanner.Err(); err != nil {
					log.Errorf("[RunAndWait] Parse log failed, %v", err)
					ch <- &types.RunAndWaitMessage{ContainerID: containerID,
						Data: []byte(fmt.Sprintf("[exitcode] unknown %v", err))}
					return
				}

				// 超时的情况下根本不会到这里
				// 不超时的情况下这里肯定会立即返回
				code, err := node.Engine.ContainerWait(context.Background(), containerID)
				exitData := []byte(fmt.Sprintf("[exitcode] %d", code))
				if err != nil {
					log.Errorf("[RunAndWait] %s run failed, %v", containerID[:12], err)
					exitData = []byte(fmt.Sprintf("[exitcode] unknown %v", err))
				}
				ch <- &types.RunAndWaitMessage{ContainerID: containerID, Data: exitData}
			}(node, message.ContainerID)
		}

		// 等待全部任务完成才可以关闭channel
		wg.Wait()
		log.Info("[RunAndWait] Finish run and wait for containers")
	}()

	return ch, nil
}
<|endoftext|>


<commit_before>/*
Copyright IBM Corp. 2016 All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

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

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

package main

//WARNING - this chaincode's ID is hard-coded in chaincode_example04 to illustrate one way of
//calling chaincode from a chaincode. If this example is modified, chaincode_example04.go has
//to be modified as well with the new ID of chaincode_example02.
//chaincode_example05 show's how chaincode ID can be passed in as a parameter instead of
//hard-coding.

import (
	"errors"
	"fmt"
	"strconv"
	"bytes"
	"github.com/hyperledger/fabric/core/chaincode/shim"
)

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	var A, B string    // Entities
	var Aval, Bval int // Asset holdings
	var err error

	if len(args) != 4 {
		return nil, errors.New("Incorrect number of arguments. Expecting 4")
	}

	// Initialize the chaincode
	A = args[0]
	Aval, err = strconv.Atoi(args[1])
	if err != nil {
		return nil, errors.New("Expecting integer value for asset holding")
	}
	B = args[2]
	Bval, err = strconv.Atoi(args[3])
	if err != nil {
		return nil, errors.New("Expecting integer value for asset holding")
	}
	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)

	// Write the state to the ledger
	err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
	if err != nil {
		return nil, err
	}

	err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
	if err != nil {
		return nil, err
	}

	return nil, nil
}

func (t *SimpleChaincode) write(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
    var key, value string
    //var err error
    fmt.Println("Storing the parameters in hyperledger fabric...")

    /*if len(args) != 2 {
        return nil, errors.New("Incorrect number of arguments. Expecting 2. name of the key and value to set")
    }*/

	if(len(args)%2 != 0) {
		  fmt.Printf("Incorrect number of arguments. One of the keys or values is missing.")
		  fmt.Println("")

    }else{
	     for i := 0; i < len(args); i++ {
	     if(i%2 == 0){
		     if args[i] != "" {
                  fmt.Printf("Key: %s", args[i])
				  fmt.Println("")
				  key = args[i]
				  i++
             }
		     if(i!=len(args)) {
			      fmt.Printf("Value: %s", args[i])
			      fmt.Println("")
				  value = args[i]
			 }

			 //check if the state exists. If not initialize the state
			Avalbytes, err := stub.GetState(key)
			if err != nil {
				jsonResp := "{\"Error\":\"Failed to get state for " + key + "\"}"
				return nil, errors.New(jsonResp)
			}

			if Avalbytes == nil {
				Avalbytes = []byte("0")
				//err = stub.PutState(key, Avalbytes)

				//jsonResp := "{\"Error\":\"Nil amount for " + key + "\"}"
				//return nil, errors.New(jsonResp)
			}

		        err = stub.PutState(key, []byte(value))  //write the variable into the chaincode state
			 if err != nil {
				return nil, err
			 }
		 }
    }
	}

	/*
    key = args[0]                            //rename for fun
    value = args[1]
    err = stub.PutState(key, []byte(value))  //write the variable into the chaincode state
    if err != nil {
        return nil, err
    }
	*/

    return nil, nil
}

// Transaction makes payment of X units from A to B
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	if function == "delete" {
		// Deletes an entity from its state
		return t.delete(stub, args)
	}
	if function == "write" {
		fmt.Println("Calling write()")
        return t.write(stub, args)
    }

	var A, B string    // Entities
	var Aval, Bval int // Asset holdings
	var X int          // Transaction value
	var err error

	if len(args) != 3 {
		return nil, errors.New("Incorrect number of arguments. Expecting 3")
	}

	A = args[0]
	B = args[1]

	// Get the state from the ledger
	// TODO: will be nice to have a GetAllState call to ledger
	Avalbytes, err := stub.GetState(A)
	if err != nil {
		return nil, errors.New("Failed to get state")
	}
	if Avalbytes == nil {
		return nil, errors.New("Entity not found")
	}
	Aval, _ = strconv.Atoi(string(Avalbytes))

	Bvalbytes, err := stub.GetState(B)
	if err != nil {
		return nil, errors.New("Failed to get state")
	}
	if Bvalbytes == nil {
		return nil, errors.New("Entity not found")
	}
	Bval, _ = strconv.Atoi(string(Bvalbytes))

	// Perform the execution
	X, err = strconv.Atoi(args[2])
	Aval = Aval - X
	Bval = Bval + X
	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)

	//Store state for transactions
	var transacted, historyval string
	transacted = "T_"+args[0]+"|"+args[1]
	Tvalbytes, err := stub.GetState(transacted)
	if err != nil {
		return nil, errors.New("Failed to get transacted state")
	}
	if Tvalbytes == nil {
		historyval = args[2]
	}else{
		historyval = string(Tvalbytes)
		historyval = historyval+","+args[2]
	}
	err = stub.PutState(transacted, []byte(historyval))
	if err != nil {
		return nil, err
	}

	//Store state for sponsor transactions
	var s_transactions, s_history string
	s_transactions = "T_"+args[0]
	Svalbytes, err := stub.GetState(s_transactions)
	if err != nil {
		return nil, errors.New("Failed to get sponsor transacted state")
	}
	if Svalbytes == nil {
		s_history = args[1]+"|"+args[2]
	}else{
		s_history = string(Svalbytes)
		s_history = s_history+","+args[1]+"|"+args[2]
	}
	err = stub.PutState(s_transactions, []byte(s_history))
	if err != nil {
		return nil, err
	}

	//Store state for Idea transactions
	var i_transactions, i_history string
	i_transactions = "T_"+args[1]
	Ivalbytes, err := stub.GetState(i_transactions)
	if err != nil {
		return nil, errors.New("Failed to get idea transacted state")
	}
	if Ivalbytes == nil {
		i_history = args[0]+"|"+args[2]
	}else{
		i_history = string(Ivalbytes)
		i_history = i_history+","+args[0]+"|"+args[2]
	}
	err = stub.PutState(i_transactions, []byte(i_history))
	if err != nil {
		return nil, err
	}

	// Write the state back to the ledger
	err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
	if err != nil {
		return nil, err
	}

	err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
	if err != nil {
		return nil, err
	}

	return nil, nil
}

// Deletes an entity from state
func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting 1")
	}

	A := args[0]

	// Delete the key from the state in ledger
	err := stub.DelState(A)
	if err != nil {
		return nil, errors.New("Failed to delete state")
	}

	return nil, nil
}

// Query callback representing the query of a chaincode
func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	/*if function != "query" {
		return nil, errors.New("Invalid query function name. Expecting \"query\"")
	}*/

	if function == "queryAll" {
		fmt.Println("Calling QueryAll()")
        return t.queryAll(stub, args)
    }

	if function == "queryTransact" {
		fmt.Println("Calling QueryTransact()")
        return t.queryTransact(stub, args)
    }

	var A string // Entities
	var err error

	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting name of the person to query")
	}

	A = args[0]

	// Get the state from the ledger
	Avalbytes, err := stub.GetState(A)
	if err != nil {
		jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"
		return nil, errors.New(jsonResp)
	}

	if Avalbytes == nil {
		Avalbytes = []byte("0")
		//jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}"
		//return nil, errors.New(jsonResp)
	}

	jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}"
	fmt.Printf("Query Response:%s\n", jsonResp)
	return Avalbytes, nil
}

// Query callback representing the query of a chaincode
func (t *SimpleChaincode) queryAll(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {

	//var A string // Entities
	//var err error

	/*if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting name of the person to query")
	}*/
    var RetValue []byte
	var buffer bytes.Buffer
    var jsonRespString string
		for i := 0; i < len(args); i++ {
		    Avalbytes, err := stub.GetState(args[i])
			if err != nil {
				jsonResp := "{\"Error\":\"Failed to get state for " + args[i] + "\"}"
				return nil, errors.New(jsonResp)
			}

			if Avalbytes == nil {
				Avalbytes = []byte("0")
				//jsonResp := "{\"Error\":\"Nil amount for " + args[i] + "\"}"
				//return nil, errors.New(jsonResp)
			}
			if(i!=len(args)-1) {
			   jsonRespString =  string(Avalbytes)+","
			}else{
			   jsonRespString =  string(Avalbytes)
			}
			buffer.WriteString(jsonRespString)
			RetValue = []byte(buffer.String())

		}
		jsonResp := "{"+buffer.String()+"}"
		fmt.Printf("Query Response:%s\n", jsonResp)
		return RetValue, nil

	/*
	A = args[0]

	// Get the state from the ledger
	Avalbytes, err := stub.GetState(A)
	if err != nil {
		jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"
		return nil, errors.New(jsonResp)
	}

	if Avalbytes == nil {
		jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}"
		return nil, errors.New(jsonResp)
	}

	jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}"
	fmt.Printf("Query Response:%s\n", jsonResp)
	return Avalbytes, nil
	*/
}

// Query callback representing the query of a chaincode
func (t *SimpleChaincode) queryTransact(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {

	//var A string // Entities
	//var err error

	/*if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting name of the person to query")
	}*/
    var RetValue []byte
	var buffer bytes.Buffer
    var jsonRespString, queryparam string
	queryparam = "T_"+args[0]

		Tvalbytes, err := stub.GetState(queryparam)
		if err != nil {
			jsonResp := "{\"Error\":\"Failed to get state for " + args[0] + "\"}"
			return nil, errors.New(jsonResp)
		}

		if Tvalbytes == nil {
			Tvalbytes = []byte("0")
			//jsonResp := "{\"Error\":\"Nil amount for " + args[i] + "\"}"
			//return nil, errors.New(jsonResp)
		}

		jsonRespString =  string(Tvalbytes)
		buffer.WriteString(jsonRespString)
		RetValue = []byte(buffer.String())
		jsonResp := "{"+buffer.String()+"}"
		fmt.Printf("Query Response:%s\n", jsonResp)
		return RetValue, nil

	/*
	A = args[0]

	// Get the state from the ledger
	Avalbytes, err := stub.GetState(A)
	if err != nil {
		jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"
		return nil, errors.New(jsonResp)
	}

	if Avalbytes == nil {
		jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}"
		return nil, errors.New(jsonResp)
	}

	jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}"
	fmt.Printf("Query Response:%s\n", jsonResp)
	return Avalbytes, nil
	*/
}

func main() {
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}
<commit_msg>Update accumshare.go<commit_after>/*
Copyright IBM Corp. 2016 All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

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

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

package main

import (
	"errors"
	"fmt"
	"strconv"

	"github.com/hyperledger/fabric/core/chaincode/shim"
)

var myLogger = shim.NewLogger("AuthorizableCounter")

// AuthorizableCounterChaincode is an example that use Attribute Based Access Control to control the access to a counter by users with an specific role.
// In this case only users which TCerts contains the attribute position with the value "Software Engineer" will be able to increment the counter.
type AuthorizableCounterChaincode struct {
}

//Init the chaincode asigned the value "0" to the counter in the state.
func (t *AuthorizableCounterChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	myLogger.Debug("Init function called...")
        err := stub.PutState("counter", []byte("0"))
	return nil, err
}

//Invoke Transaction makes increment counter
func (t *AuthorizableCounterChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	myLogger.Debug("*****************************************Increment Function *************************************************")
        if function != "increment" {
		return nil, errors.New("Invalid invoke function name. Expecting \"increment\"")
	}
	val, err := stub.ReadCertAttribute("position")
	fmt.Printf("Position => %v error %v \n", string(val), err)
        myLogger.Debug("Position----------------------",string(val))
	isOk, _ := stub.VerifyAttribute("position", []byte("Software Engineer")) // Here the ABAC API is called to verify the attribute, just if the value is verified the counter will be incremented.
        myLogger.Debug("isOK-----------------",isOk)
	if isOk {
                myLogger.Debug("************************Incrementing counter***********************")
		counter, err := stub.GetState("counter")
		if err != nil {
			return nil, err
		}
		var cInt int
		cInt, err = strconv.Atoi(string(counter))
		if err != nil {
			return nil, err
		}
		cInt = cInt + 1
		counter = []byte(strconv.Itoa(cInt))
		stub.PutState("counter", counter)
	}
	return nil, nil

}

// Query callback representing the query of a chaincode
func (t *AuthorizableCounterChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	if function != "read" {
		return nil, errors.New("Invalid query function name. Expecting \"read\"")
	}
	var err error

	// Get the state from the ledger
	Avalbytes, err := stub.GetState("counter")
	if err != nil {
		jsonResp := "{\"Error\":\"Failed to get state for counter\"}"
		return nil, errors.New(jsonResp)
	}

	if Avalbytes == nil {
		jsonResp := "{\"Error\":\"Nil amount for counter\"}"
		return nil, errors.New(jsonResp)
	}

	jsonResp := "{\"Name\":\"counter\",\"Amount\":\"" + string(Avalbytes) + "\"}"
	fmt.Printf("Query Response:%s\n", jsonResp)
	return Avalbytes, nil
}

func main() {
	err := shim.Start(new(AuthorizableCounterChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}
<|endoftext|>


<commit_before>package rpc

import (
	"errors"
	"fmt"
	"sync"
	"time"
)

type NetworkInstrumenterStorage interface {
	Put(tag string, record InstrumentationRecord) error
}

func RPCInstrumentTag(methodType MethodType, method string) string {
	return fmt.Sprintf("%s %s", methodType, method)
}

type InstrumentationRecord struct {
	Ctime time.Time
	Dur   time.Duration
	Size  int64
}

type DummyInstrumentationStorage struct{}

func NewDummyInstrumentationStorage() *DummyInstrumentationStorage {
	return &DummyInstrumentationStorage{}
}

var _ NetworkInstrumenterStorage = (*DummyInstrumentationStorage)(nil)

func (d *DummyInstrumentationStorage) Put(tag string, record InstrumentationRecord) error { return nil }

type MemoryInstrumentationStorage struct {
	sync.Mutex
	storage map[string][]InstrumentationRecord
}

var _ NetworkInstrumenterStorage = (*MemoryInstrumentationStorage)(nil)

func NewMemoryInstrumentationStorage() *MemoryInstrumentationStorage {
	return &MemoryInstrumentationStorage{
		storage: make(map[string][]InstrumentationRecord),
	}
}

func (s *MemoryInstrumentationStorage) Put(tag string, record InstrumentationRecord) error {
	s.Lock()
	defer s.Unlock()
	s.storage[tag] = append(s.storage[tag], record)
	return nil
}

type NetworkInstrumenter struct {
	*InstrumentationRecord
	storage NetworkInstrumenterStorage
	tag     string
}

func NewNetworkInstrumenter(storage NetworkInstrumenterStorage, tag string) *NetworkInstrumenter {
	return &NetworkInstrumenter{
		InstrumentationRecord: &InstrumentationRecord{
			Ctime: time.Now(),
		},
		tag:     tag,
		storage: storage,
	}
}

func (r *NetworkInstrumenter) IncrementSize(size int64) {
	if r.InstrumentationRecord != nil {
		r.Size += size
	}
}

func (r *NetworkInstrumenter) EndCall() {
	if r.InstrumentationRecord != nil {
		r.Dur = time.Since(r.Ctime)
	}
}

func (r *NetworkInstrumenter) RecordAndFinish(size int64) error {
	r.IncrementSize(size)
	r.EndCall()
	return r.Finish()
}

func (r *NetworkInstrumenter) Finish() error {
	if r.InstrumentationRecord == nil {
		return errors.New("record already finished")
	}
	rec := *r.InstrumentationRecord
	r.InstrumentationRecord = nil
	return r.storage.Put(r.tag, rec)
}
<commit_msg>Update rpc/instrument.go<commit_after>package rpc

import (
	"errors"
	"fmt"
	"sync"
	"time"
)

type NetworkInstrumenterStorage interface {
	Put(tag string, record InstrumentationRecord) error
}

func RPCInstrumentTag(methodType MethodType, method string) string {
	return fmt.Sprintf("%s %s", methodType, method)
}

type InstrumentationRecord struct {
	Ctime time.Time
	Dur   time.Duration
	Size  int64
}

type DummyInstrumentationStorage struct{}

func NewDummyInstrumentationStorage() *DummyInstrumentationStorage {
	return &DummyInstrumentationStorage{}
}

var _ NetworkInstrumenterStorage = (*DummyInstrumentationStorage)(nil)

func (d *DummyInstrumentationStorage) Put(tag string, record InstrumentationRecord) error { return nil }

type MemoryInstrumentationStorage struct {
	sync.Mutex
	storage map[string][]InstrumentationRecord
}

var _ NetworkInstrumenterStorage = (*MemoryInstrumentationStorage)(nil)

func NewMemoryInstrumentationStorage() *MemoryInstrumentationStorage {
	return &MemoryInstrumentationStorage{
		storage: make(map[string][]InstrumentationRecord),
	}
}

func (s *MemoryInstrumentationStorage) Put(tag string, record InstrumentationRecord) error {
	s.Lock()
	defer s.Unlock()
	s.storage[tag] = append(s.storage[tag], record)
	return nil
}

type NetworkInstrumenter struct {
	*InstrumentationRecord
	storage NetworkInstrumenterStorage
	tag     string
}

// NewNetworkInstrumenter records network usage of a single call.
// Not safe for concurrent use.
func NewNetworkInstrumenter(storage NetworkInstrumenterStorage, tag string) *NetworkInstrumenter {
	return &NetworkInstrumenter{
		InstrumentationRecord: &InstrumentationRecord{
			Ctime: time.Now(),
		},
		tag:     tag,
		storage: storage,
	}
}

func (r *NetworkInstrumenter) IncrementSize(size int64) {
	if r.InstrumentationRecord != nil {
		r.Size += size
	}
}

func (r *NetworkInstrumenter) EndCall() {
	if r.InstrumentationRecord != nil {
		r.Dur = time.Since(r.Ctime)
	}
}

func (r *NetworkInstrumenter) RecordAndFinish(size int64) error {
	r.IncrementSize(size)
	r.EndCall()
	return r.Finish()
}

func (r *NetworkInstrumenter) Finish() error {
	if r.InstrumentationRecord == nil {
		return errors.New("record already finished")
	}
	rec := *r.InstrumentationRecord
	r.InstrumentationRecord = nil
	return r.storage.Put(r.tag, rec)
}
<|endoftext|>


<commit_before>package v8js

import (
	"encoding/json"
	"errors"
	"fmt"
	log "github.com/Sirupsen/logrus"
	"github.com/ry/v8worker"
	"reflect"
)

func (vu *VUContext) RegisterModules(w *v8worker.Worker) error {
	vu.mods = map[string]Module{
		"global": Module{
			"sleep": vu.Sleep,
		},
		"console": Module{
			"log": vu.ConsoleLog,
		},
		"http": Module{
			"get": vu.HTTPGet,
		},
	}

	for modname, mod := range vu.mods {
		jsMod := fmt.Sprintf(`
		speedboat._modules["%s"] = {};
		`, modname)
		for name, mem := range mod {
			t := reflect.TypeOf(mem)

			if t.Kind() != reflect.Func {
				return errors.New("Not a function: " + modname + "." + name)
			}

			jsFn := fmt.Sprintf(`speedboat._modules["%s"]["%s"] = function() {
				var args = [];
			`, modname, name)

			numArgs := t.NumIn()
			if !t.IsVariadic() {
				jsFn += fmt.Sprintf(`
					if (arguments.length != %d) {
						throw new Error("wrong number of arguments");
					}
				`, t.NumIn())
			} else {
				numArgs--
			}

			for i := 0; i < numArgs; i++ {
				aT := t.In(i)
				jsFn += fmt.Sprintf("args.push(speedboat._require.%s(arguments[%d]));", aT.Kind().String(), i)
			}
			if t.IsVariadic() {
				varArg := t.In(numArgs)
				eT := varArg.Elem()
				jsFn += fmt.Sprintf(`
					for (var i = %d; i < arguments.length; i++) {
						args.push(speedboat._require.%s(arguments[i]));
					}
				`, numArgs, eT.Kind().String())
			}

			jsFn += `
				$sendSync(JSON.stringify({
					m: '` + modname + `',
					f: '` + name + `',
					a: args,
				}));
			}`
			jsMod += "\n\n" + jsFn
		}

		if err := w.Load("module:"+modname, jsMod); err != nil {
			return err
		}
	}

	// Make functions in the "global" module global, preimport console
	makeGlobals := `
	for (key in speedboat._modules['global']) {
		eval(key + " = speedboat._modules['global']['" + key + "'];");
	}
	var console = speedboat._modules['console'];
	`
	if err := w.Load("internal:preload", makeGlobals); err != nil {
		return err
	}

	return nil
}

func (vu *VUContext) Recv(raw string) {
}

func (vu *VUContext) RecvSync(raw string) string {
	call := struct {
		Mod  string        `json:"m"`
		Fn   string        `json:"f"`
		Args []interface{} `json:"a"`
	}{}
	if err := json.Unmarshal([]byte(raw), &call); err != nil {
		log.WithError(err).Error("Malformed call")
		return ""
	}
	log.WithFields(log.Fields{
		"mod":  call.Mod,
		"fn":   call.Fn,
		"args": call.Args,
	}).Debug("Sync call")

	mod, ok := vu.mods[call.Mod]
	if !ok {
		log.WithField("mod", call.Mod).Error("Unknown module")
		return ""
	}

	fn, ok := mod[call.Fn]
	if !ok {
		log.WithFields(log.Fields{
			"mod": call.Mod,
			"fn":  call.Fn,
		}).Error("Unknown function")
		return ""
	}

	args := make([]reflect.Value, len(call.Args))
	for i, arg := range call.Args {
		args[i] = reflect.ValueOf(arg)
	}

	defer func() {
		if err := recover(); err != nil {
			log.WithField("error", err).Error("Go call panicked")
		}
	}()
	fnV := reflect.ValueOf(fn)
	log.WithField("T", fnV.Type().String()).Debug("Function")
	reflect.ValueOf(fn).Call(args)

	return ""
}
<commit_msg>console.warn(), console.error()<commit_after>package v8js

import (
	"encoding/json"
	"errors"
	"fmt"
	log "github.com/Sirupsen/logrus"
	"github.com/ry/v8worker"
	"reflect"
)

func (vu *VUContext) RegisterModules(w *v8worker.Worker) error {
	vu.mods = map[string]Module{
		"global": Module{
			"sleep": vu.Sleep,
		},
		"console": Module{
			"log":   vu.ConsoleLog,
			"warn":  vu.ConsoleWarn,
			"error": vu.ConsoleError,
		},
		"http": Module{
			"get": vu.HTTPGet,
		},
	}

	for modname, mod := range vu.mods {
		jsMod := fmt.Sprintf(`
		speedboat._modules["%s"] = {};
		`, modname)
		for name, mem := range mod {
			t := reflect.TypeOf(mem)

			if t.Kind() != reflect.Func {
				return errors.New("Not a function: " + modname + "." + name)
			}

			jsFn := fmt.Sprintf(`speedboat._modules["%s"]["%s"] = function() {
				var args = [];
			`, modname, name)

			numArgs := t.NumIn()
			if !t.IsVariadic() {
				jsFn += fmt.Sprintf(`
					if (arguments.length != %d) {
						throw new Error("wrong number of arguments");
					}
				`, t.NumIn())
			} else {
				numArgs--
			}

			for i := 0; i < numArgs; i++ {
				aT := t.In(i)
				jsFn += fmt.Sprintf("args.push(speedboat._require.%s(arguments[%d]));", aT.Kind().String(), i)
			}
			if t.IsVariadic() {
				varArg := t.In(numArgs)
				eT := varArg.Elem()
				jsFn += fmt.Sprintf(`
					for (var i = %d; i < arguments.length; i++) {
						args.push(speedboat._require.%s(arguments[i]));
					}
				`, numArgs, eT.Kind().String())
			}

			jsFn += `
				$sendSync(JSON.stringify({
					m: '` + modname + `',
					f: '` + name + `',
					a: args,
				}));
			}`
			jsMod += "\n\n" + jsFn
		}

		if err := w.Load("module:"+modname, jsMod); err != nil {
			return err
		}
	}

	// Make functions in the "global" module global, preimport console
	makeGlobals := `
	for (key in speedboat._modules['global']) {
		eval(key + " = speedboat._modules['global']['" + key + "'];");
	}
	var console = speedboat._modules['console'];
	`
	if err := w.Load("internal:preload", makeGlobals); err != nil {
		return err
	}

	return nil
}

func (vu *VUContext) Recv(raw string) {
}

func (vu *VUContext) RecvSync(raw string) string {
	call := struct {
		Mod  string        `json:"m"`
		Fn   string        `json:"f"`
		Args []interface{} `json:"a"`
	}{}
	if err := json.Unmarshal([]byte(raw), &call); err != nil {
		log.WithError(err).Error("Malformed call")
		return ""
	}
	log.WithFields(log.Fields{
		"mod":  call.Mod,
		"fn":   call.Fn,
		"args": call.Args,
	}).Debug("Sync call")

	mod, ok := vu.mods[call.Mod]
	if !ok {
		log.WithField("mod", call.Mod).Error("Unknown module")
		return ""
	}

	fn, ok := mod[call.Fn]
	if !ok {
		log.WithFields(log.Fields{
			"mod": call.Mod,
			"fn":  call.Fn,
		}).Error("Unknown function")
		return ""
	}

	args := make([]reflect.Value, len(call.Args))
	for i, arg := range call.Args {
		args[i] = reflect.ValueOf(arg)
	}

	defer func() {
		if err := recover(); err != nil {
			log.WithField("error", err).Error("Go call panicked")
		}
	}()
	fnV := reflect.ValueOf(fn)
	log.WithField("T", fnV.Type().String()).Debug("Function")
	reflect.ValueOf(fn).Call(args)

	return ""
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"strconv"

	"github.com/docopt/docopt-go"
	"github.com/platform9/fission/controller"
	"github.com/platform9/fission/kubewatcher"
	"github.com/platform9/fission/poolmgr"
	"github.com/platform9/fission/router"
)

func runController(port int, etcdUrl string, filepath string) {
	// filePath will be created if it doesn't exist.
	fileStore := controller.MakeFileStore(filepath)

	rs, err := controller.MakeResourceStore(fileStore, []string{etcdUrl})
	if err != nil {
		log.Fatalf("Error: %v", err)
	}

	api := controller.MakeAPI(rs)
	api.Serve(port)
	log.Fatalf("Error: Controller exited.")
}

func runRouter(port int, controllerUrl string, poolmgrUrl string) {
	router.Start(port, controllerUrl, poolmgrUrl)
	log.Fatalf("Error: Router exited.")
}

func runPoolmgr(port int, controllerUrl string, namespace string) {
	err := poolmgr.StartPoolmgr(controllerUrl, namespace, port)
	if err != nil {
		log.Fatalf("Error starting poolmgr: %v", err)
	}
}

func runKubeWatcher(controllerUrl, routerUrl string) {
	err := kubewatcher.Start(controllerUrl, routerUrl)
	if err != nil {
		log.Fatalf("Error starting kubewatcher: %v", err)
	}
}

func getPort(portArg interface{}) int {
	portArgStr := portArg.(string)
	port, err := strconv.Atoi(portArgStr)
	if err != nil {
		log.Fatalf("Error: invalid port number '%v'", portArgStr)
	}
	return port
}

func getStringArgWithDefault(arg interface{}, defaultValue string) string {
	if arg != nil {
		return arg.(string)
	} else {
		return defaultValue
	}
}

func main() {
	usage := `fission-bundle: Package of all fission microservices: controller, router, poolmgr.

Use it to start one or more of the fission servers:

 Controller keeps track of functions, triggers, environments.

 Pool manager maintains a pool of generalized function containers, and specializes them on-demand. Poolmgr must be run from a pod in a Kubernetes cluster.

 Router implements HTTP triggers: it routes to running instances, working with the controller and poolmgr.

Usage:
  fission-bundle --controllerPort=<port> [--etcdUrl=<etcdUrl>] --filepath=<filepath>
  fission-bundle --routerPort=<port> [--controllerUrl=<url> --poolmgrUrl=<url>]
  fission-bundle --poolmgrPort=<port> [--controllerUrl=<url>]
  fission-bundle --kubewatcher [--controllerUrl=<url> --routerUrl=<url>]
Options:
  --controllerPort=<port>  Port that the controller should listen on.
  --routerPort=<port>      Port that the router should listen on.
  --poolmgrPort=<port>     Port that the poolmgr should listen on.
  --controllerUrl=<url>    Controller URL. Not required if --controllerPort is specified.
  --poolmgrUrl=<url>       Poolmgr URL. Not required if --poolmgrPort is specified.
  --routerUrl=<url>        Router URL.
  --etcdUrl=<etcdUrl>      Etcd URL.
  --filepath=<filepath>    Directory to store functions in.
  --namespace=<namespace>  Kubernetes namespace in which to run function containers. Defaults to 'fission-function'.
`
	arguments, err := docopt.Parse(usage, nil, true, "fission-bundle", false)
	if err != nil {
		log.Fatalf("Error: %v", err)
	}

	namespace := getStringArgWithDefault(arguments["--namespace"], "fission-function")

	controllerUrl := getStringArgWithDefault(arguments["--controllerUrl"], "http://controller.fission")
	etcdUrl := getStringArgWithDefault(arguments["--etcdUrl"], "http://etcd:2379")
	poolmgrUrl := getStringArgWithDefault(arguments["--poolmgrUrl"], "http://poolmgr.fission")
	routerUrl := getStringArgWithDefault(arguments["--routerUrl"], "http://router.fission")

	if arguments["--controllerPort"] != nil {
		port := getPort(arguments["--controllerPort"])
		runController(port, etcdUrl, arguments["--filepath"].(string))
	}

	if arguments["--routerPort"] != nil {
		port := getPort(arguments["--routerPort"])
		runRouter(port, controllerUrl, poolmgrUrl)
	}

	if arguments["--poolmgrPort"] != nil {
		port := getPort(arguments["--poolmgrPort"])
		runPoolmgr(port, controllerUrl, namespace)
	}

	if arguments["--kubewatcher"] != nil {
		runKubeWatcher(controllerUrl, routerUrl)
	}

	select {}
}
<commit_msg>Bugfix in fission-bundle arg parsing<commit_after>package main

import (
	"log"
	"strconv"

	"github.com/docopt/docopt-go"
	"github.com/platform9/fission/controller"
	"github.com/platform9/fission/kubewatcher"
	"github.com/platform9/fission/poolmgr"
	"github.com/platform9/fission/router"
)

func runController(port int, etcdUrl string, filepath string) {
	// filePath will be created if it doesn't exist.
	fileStore := controller.MakeFileStore(filepath)

	rs, err := controller.MakeResourceStore(fileStore, []string{etcdUrl})
	if err != nil {
		log.Fatalf("Error: %v", err)
	}

	api := controller.MakeAPI(rs)
	api.Serve(port)
	log.Fatalf("Error: Controller exited.")
}

func runRouter(port int, controllerUrl string, poolmgrUrl string) {
	router.Start(port, controllerUrl, poolmgrUrl)
	log.Fatalf("Error: Router exited.")
}

func runPoolmgr(port int, controllerUrl string, namespace string) {
	err := poolmgr.StartPoolmgr(controllerUrl, namespace, port)
	if err != nil {
		log.Fatalf("Error starting poolmgr: %v", err)
	}
}

func runKubeWatcher(controllerUrl, routerUrl string) {
	err := kubewatcher.Start(controllerUrl, routerUrl)
	if err != nil {
		log.Fatalf("Error starting kubewatcher: %v", err)
	}
}

func getPort(portArg interface{}) int {
	portArgStr := portArg.(string)
	port, err := strconv.Atoi(portArgStr)
	if err != nil {
		log.Fatalf("Error: invalid port number '%v'", portArgStr)
	}
	return port
}

func getStringArgWithDefault(arg interface{}, defaultValue string) string {
	if arg != nil {
		return arg.(string)
	} else {
		return defaultValue
	}
}

func main() {
	usage := `fission-bundle: Package of all fission microservices: controller, router, poolmgr.

Use it to start one or more of the fission servers:

 Controller keeps track of functions, triggers, environments.

 Pool manager maintains a pool of generalized function containers, and specializes them on-demand. Poolmgr must be run from a pod in a Kubernetes cluster.

 Router implements HTTP triggers: it routes to running instances, working with the controller and poolmgr.

Usage:
  fission-bundle --controllerPort=<port> [--etcdUrl=<etcdUrl>] --filepath=<filepath>
  fission-bundle --routerPort=<port> [--controllerUrl=<url> --poolmgrUrl=<url>]
  fission-bundle --poolmgrPort=<port> [--controllerUrl=<url>]
  fission-bundle --kubewatcher [--controllerUrl=<url> --routerUrl=<url>]
Options:
  --controllerPort=<port>  Port that the controller should listen on.
  --routerPort=<port>      Port that the router should listen on.
  --poolmgrPort=<port>     Port that the poolmgr should listen on.
  --controllerUrl=<url>    Controller URL. Not required if --controllerPort is specified.
  --poolmgrUrl=<url>       Poolmgr URL. Not required if --poolmgrPort is specified.
  --routerUrl=<url>        Router URL.
  --etcdUrl=<etcdUrl>      Etcd URL.
  --filepath=<filepath>    Directory to store functions in.
  --namespace=<namespace>  Kubernetes namespace in which to run function containers. Defaults to 'fission-function'.
  --kubewatcher            Start Kubernetes events watcher.
`
	arguments, err := docopt.Parse(usage, nil, true, "fission-bundle", false)
	if err != nil {
		log.Fatalf("Error: %v", err)
	}

	namespace := getStringArgWithDefault(arguments["--namespace"], "fission-function")

	controllerUrl := getStringArgWithDefault(arguments["--controllerUrl"], "http://controller.fission")
	etcdUrl := getStringArgWithDefault(arguments["--etcdUrl"], "http://etcd:2379")
	poolmgrUrl := getStringArgWithDefault(arguments["--poolmgrUrl"], "http://poolmgr.fission")
	routerUrl := getStringArgWithDefault(arguments["--routerUrl"], "http://router.fission")

	if arguments["--controllerPort"] != nil {
		port := getPort(arguments["--controllerPort"])
		runController(port, etcdUrl, arguments["--filepath"].(string))
	}

	if arguments["--routerPort"] != nil {
		port := getPort(arguments["--routerPort"])
		runRouter(port, controllerUrl, poolmgrUrl)
	}

	if arguments["--poolmgrPort"] != nil {
		port := getPort(arguments["--poolmgrPort"])
		runPoolmgr(port, controllerUrl, namespace)
	}

	if arguments["--kubewatcher"] == true {
		runKubeWatcher(controllerUrl, routerUrl)
	}

	select {}
}
<|endoftext|>


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

package webpagereplay

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

const errStatus = http.StatusInternalServerError

func makeLogger(req *http.Request) func(msg string, args ...interface{}) {
	prefix := fmt.Sprintf("ServeHTTP(%s): ", req.URL)
	return func(msg string, args ...interface{}) {
		log.Print(prefix + fmt.Sprintf(msg, args...))
	}
}

// fixupRequestURL adds a scheme and host to req.URL.
// Adding the scheme is necessary since RoundTrip doesn't like an empty scheme.
// Adding the host is optional, but makes req.URL print more nicely.
func fixupRequestURL(req *http.Request, scheme string) {
	req.URL.Scheme = scheme
	if req.URL.Host == "" {
		req.URL.Host = req.Host
	}
}

// NewReplayingProxy constructs an HTTP proxy that replays responses from an archive.
// The proxy is listening for requests on a port that uses the given scheme (e.g., http, https).
func NewReplayingProxy(a *Archive, scheme string, transformers []ResponseTransformer) http.Handler {
	return &replayingProxy{a, scheme, transformers}
}

type replayingProxy struct {
	a            *Archive
	scheme       string
	transformers []ResponseTransformer
}

func (proxy *replayingProxy) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	if req.URL.Path == "/web-page-replay-generate-200" {
		w.WriteHeader(200)
		return
	}
	if req.URL.Path == "/web-page-replay-command-exit" {
		log.Printf("Shutting down. Received /web-page-replay-command-exit")
		os.Exit(0)
		return
	}
	fixupRequestURL(req, proxy.scheme)
	logf := makeLogger(req)

	// Lookup the response in the archive.
	_, storedResp, err := proxy.a.FindRequest(req, proxy.scheme)
	if err != nil {
		logf("couldn't find matching request: %v", err)
		w.WriteHeader(http.StatusNotFound)
		return
	}
	defer storedResp.Body.Close()

	// Check if the stored Content-Encoding matches an encoding allowed by the client.
	// If not, transform the response body to match the client's Accept-Encoding.
	clientAE := strings.ToLower(req.Header.Get("Accept-Encoding"))
	originCE := strings.ToLower(storedResp.Header.Get("Content-Encoding"))
	if !strings.Contains(clientAE, originCE) {
		logf("translating Content-Encoding [%s] -> [%s]", originCE, clientAE)
		body, err := ioutil.ReadAll(storedResp.Body)
		if err != nil {
			logf("error reading response body from archive: %v", err)
			w.WriteHeader(http.StatusNotFound)
			return
		}
		body, err = decompressBody(originCE, body)
		if err != nil {
			logf("error decompressing response body: %v", err)
			w.WriteHeader(http.StatusNotFound)
			return
		}
		body, ce, err := compressBody(clientAE, body)
		if err != nil {
			logf("error recompressing response body: %v", err)
			w.WriteHeader(http.StatusNotFound)
			return
		}
		storedResp.Header.Set("Content-Encoding", ce)
		storedResp.Body = ioutil.NopCloser(bytes.NewReader(body))
		// ContentLength has changed, so update the outgoing headers accordingly.
		if storedResp.ContentLength >= 0 {
			storedResp.ContentLength = int64(len(body))
			storedResp.Header.Set("Content-Length", strconv.Itoa(len(body)))
		}
	}

	// Transform.
	for _, t := range proxy.transformers {
		t.Transform(req, storedResp)
	}

	// Forward the response.
	logf("serving %v response (http2: %v)", storedResp.StatusCode)
	for k, v := range storedResp.Header {
		w.Header()[k] = append([]string{}, v...)
	}
	w.WriteHeader(storedResp.StatusCode)
	if _, err := io.Copy(w, storedResp.Body); err != nil {
		logf("warning: client response truncated: %v", err)
	}
}

// NewRecordingProxy constructs an HTTP proxy that records responses into an archive.
// The proxy is listening for requests on a port that uses the given scheme (e.g., http, https).
func NewRecordingProxy(a *WritableArchive, scheme string, transformers []ResponseTransformer) http.Handler {
	return &recordingProxy{&http.Transport{}, a, scheme, transformers}
}

type recordingProxy struct {
	tr           *http.Transport
	a            *WritableArchive
	scheme       string
	transformers []ResponseTransformer
}

func (proxy *recordingProxy) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	if req.URL.Path == "/web-page-replay-generate-200" {
		w.WriteHeader(200)
		return
	}
	if req.URL.Path == "/web-page-replay-command-exit" {
		log.Printf("Shutting down. Received /web-page-replay-command-exit")
		if err := proxy.a.Close(); err != nil {
			log.Printf("Error flushing archive: %v", err)
		}
		os.Exit(0)
		return
	}
	fixupRequestURL(req, proxy.scheme)
	logf := makeLogger(req)
	// Read the entire request body (for POST) before forwarding to the server
	// so we can save the entire request in the archive.
	var requestBody []byte
	if req.Body != nil {
		var err error
		requestBody, err = ioutil.ReadAll(req.Body)
		if err != nil {
			logf("read request body failed: %v", err)
			w.WriteHeader(errStatus)
			return
		}
		req.Body = ioutil.NopCloser(bytes.NewReader(requestBody))
	}

	// Make the external request.
	// If RoundTrip fails, convert the response to a 500.
	resp, err := proxy.tr.RoundTrip(req)
	if err != nil {
		logf("RoundTrip failed: %v", err)
		resp = &http.Response{
			Status:     http.StatusText(errStatus),
			StatusCode: errStatus,
			Proto:      req.Proto,
			ProtoMajor: req.ProtoMajor,
			ProtoMinor: req.ProtoMinor,
			Body:       ioutil.NopCloser(bytes.NewReader(nil)),
		}
	}

	// Transform.
	for _, t := range proxy.transformers {
		t.Transform(req, resp)
	}

	// Copy the entire response body.
	responseBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		logf("warning: origin response truncated: %v", err)
	}
	resp.Body.Close()

	// Forward the response.
	logf("serving %v, %v bytes", resp.StatusCode, len(responseBody))
	for k, v := range resp.Header {
		w.Header()[k] = append([]string{}, v...)
	}
	w.WriteHeader(resp.StatusCode)
	if n, err := io.Copy(w, bytes.NewReader(responseBody)); err != nil {
		logf("warning: client response truncated (%d/%d bytes): %v", n, len(responseBody), err)
	}

	// Restore the req/resp body before archiving.
	// The req body was consumed by RoundTrip, and the resp body was consumed by the above io.Copy.
	if req.Body != nil {
		req.Body = ioutil.NopCloser(bytes.NewReader(requestBody))
	}
	resp.Body = ioutil.NopCloser(bytes.NewReader(responseBody))
	if err := proxy.a.RecordRequest(proxy.scheme, req, resp); err != nil {
		logf("failed recording request: %v", err)
	}
}
<commit_msg>[wpr-go] Use nil req.Body as appropriate for outgoing requests in http.Transport.RoundTrip()<commit_after>// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package webpagereplay

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

const errStatus = http.StatusInternalServerError

func makeLogger(req *http.Request) func(msg string, args ...interface{}) {
	prefix := fmt.Sprintf("ServeHTTP(%s): ", req.URL)
	return func(msg string, args ...interface{}) {
		log.Print(prefix + fmt.Sprintf(msg, args...))
	}
}

// fixupRequestURL adds a scheme and host to req.URL.
// Adding the scheme is necessary since RoundTrip doesn't like an empty scheme.
// Adding the host is optional, but makes req.URL print more nicely.
func fixupRequestURL(req *http.Request, scheme string) {
	req.URL.Scheme = scheme
	if req.URL.Host == "" {
		req.URL.Host = req.Host
	}
}

// NewReplayingProxy constructs an HTTP proxy that replays responses from an archive.
// The proxy is listening for requests on a port that uses the given scheme (e.g., http, https).
func NewReplayingProxy(a *Archive, scheme string, transformers []ResponseTransformer) http.Handler {
	return &replayingProxy{a, scheme, transformers}
}

type replayingProxy struct {
	a            *Archive
	scheme       string
	transformers []ResponseTransformer
}

func (proxy *replayingProxy) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	if req.URL.Path == "/web-page-replay-generate-200" {
		w.WriteHeader(200)
		return
	}
	if req.URL.Path == "/web-page-replay-command-exit" {
		log.Printf("Shutting down. Received /web-page-replay-command-exit")
		os.Exit(0)
		return
	}
	fixupRequestURL(req, proxy.scheme)
	logf := makeLogger(req)

	// Lookup the response in the archive.
	_, storedResp, err := proxy.a.FindRequest(req, proxy.scheme)
	if err != nil {
		logf("couldn't find matching request: %v", err)
		w.WriteHeader(http.StatusNotFound)
		return
	}
	defer storedResp.Body.Close()

	// Check if the stored Content-Encoding matches an encoding allowed by the client.
	// If not, transform the response body to match the client's Accept-Encoding.
	clientAE := strings.ToLower(req.Header.Get("Accept-Encoding"))
	originCE := strings.ToLower(storedResp.Header.Get("Content-Encoding"))
	if !strings.Contains(clientAE, originCE) {
		logf("translating Content-Encoding [%s] -> [%s]", originCE, clientAE)
		body, err := ioutil.ReadAll(storedResp.Body)
		if err != nil {
			logf("error reading response body from archive: %v", err)
			w.WriteHeader(http.StatusNotFound)
			return
		}
		body, err = decompressBody(originCE, body)
		if err != nil {
			logf("error decompressing response body: %v", err)
			w.WriteHeader(http.StatusNotFound)
			return
		}
		body, ce, err := compressBody(clientAE, body)
		if err != nil {
			logf("error recompressing response body: %v", err)
			w.WriteHeader(http.StatusNotFound)
			return
		}
		storedResp.Header.Set("Content-Encoding", ce)
		storedResp.Body = ioutil.NopCloser(bytes.NewReader(body))
		// ContentLength has changed, so update the outgoing headers accordingly.
		if storedResp.ContentLength >= 0 {
			storedResp.ContentLength = int64(len(body))
			storedResp.Header.Set("Content-Length", strconv.Itoa(len(body)))
		}
	}

	// Transform.
	for _, t := range proxy.transformers {
		t.Transform(req, storedResp)
	}

	// Forward the response.
	logf("serving %v response (http2: %v)", storedResp.StatusCode)
	for k, v := range storedResp.Header {
		w.Header()[k] = append([]string{}, v...)
	}
	w.WriteHeader(storedResp.StatusCode)
	if _, err := io.Copy(w, storedResp.Body); err != nil {
		logf("warning: client response truncated: %v", err)
	}
}

// NewRecordingProxy constructs an HTTP proxy that records responses into an archive.
// The proxy is listening for requests on a port that uses the given scheme (e.g., http, https).
func NewRecordingProxy(a *WritableArchive, scheme string, transformers []ResponseTransformer) http.Handler {
	return &recordingProxy{&http.Transport{}, a, scheme, transformers}
}

type recordingProxy struct {
	tr           *http.Transport
	a            *WritableArchive
	scheme       string
	transformers []ResponseTransformer
}

func (proxy *recordingProxy) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	if req.URL.Path == "/web-page-replay-generate-200" {
		w.WriteHeader(200)
		return
	}
	if req.URL.Path == "/web-page-replay-command-exit" {
		log.Printf("Shutting down. Received /web-page-replay-command-exit")
		if err := proxy.a.Close(); err != nil {
			log.Printf("Error flushing archive: %v", err)
		}
		os.Exit(0)
		return
	}
	fixupRequestURL(req, proxy.scheme)
	logf := makeLogger(req)
	// https://github.com/golang/go/issues/16036. Server requests always
	// have non-nil body even for GET and HEAD. This prevents http.Transport
	// from retrying requests on dead reused conns. Catapult Issue 3706.
	if req.ContentLength == 0 {
		req.Body = nil
	}
	// Read the entire request body (for POST) before forwarding to the server
	// so we can save the entire request in the archive.
	var requestBody []byte
	if req.Body != nil {
		var err error
		requestBody, err = ioutil.ReadAll(req.Body)
		if err != nil {
			logf("read request body failed: %v", err)
			w.WriteHeader(errStatus)
			return
		}
		req.Body = ioutil.NopCloser(bytes.NewReader(requestBody))
	}

	// Make the external request.
	// If RoundTrip fails, convert the response to a 500.
	resp, err := proxy.tr.RoundTrip(req)
	if err != nil {
		logf("RoundTrip failed: %v", err)
		resp = &http.Response{
			Status:     http.StatusText(errStatus),
			StatusCode: errStatus,
			Proto:      req.Proto,
			ProtoMajor: req.ProtoMajor,
			ProtoMinor: req.ProtoMinor,
			Body:       ioutil.NopCloser(bytes.NewReader(nil)),
		}
	}

	// Transform.
	for _, t := range proxy.transformers {
		t.Transform(req, resp)
	}

	// Copy the entire response body.
	responseBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		logf("warning: origin response truncated: %v", err)
	}
	resp.Body.Close()

	// Forward the response.
	logf("serving %v, %v bytes", resp.StatusCode, len(responseBody))
	for k, v := range resp.Header {
		w.Header()[k] = append([]string{}, v...)
	}
	w.WriteHeader(resp.StatusCode)
	if n, err := io.Copy(w, bytes.NewReader(responseBody)); err != nil {
		logf("warning: client response truncated (%d/%d bytes): %v", n, len(responseBody), err)
	}

	// Restore the req/resp body before archiving.
	// The req body was consumed by RoundTrip, and the resp body was consumed by the above io.Copy.
	if req.Body != nil {
		req.Body = ioutil.NopCloser(bytes.NewReader(requestBody))
	}
	resp.Body = ioutil.NopCloser(bytes.NewReader(responseBody))
	if err := proxy.a.RecordRequest(proxy.scheme, req, resp); err != nil {
		logf("failed recording request: %v", err)
	}
}
<|endoftext|>


<commit_before>package numgo

import (
	"math"
	"runtime"
	"testing"
)

func init() {
	debug = true
}

func TestAddC(t *testing.T) {
	a := Arange(21)

	if b := a.AddC(2).Equals(Arange(2, 23)); !b.All().At(0) {
		t.Log(b)
		t.Log(a)
		t.Fail()
	}
}

func TestSubtrC(t *testing.T) {
	a := Arange(21)
	if b := a.SubtrC(2).Equals(Arange(-2, 19)); !b.All().At(0) {
		t.Log(b)
		t.Log(a)
		t.Fail()
	}

}

func TestAdd(t *testing.T) {
	a, b := Arange(20), Arange(20)
	a.Add(b)
	runtime.GC()

	if c := a.Add(b.Reshape(2, 10)); c.err != ShapeError {
		t.Log("Shape tests failed.  Expected nil, returned:", c)
		t.Fail()
	}
	runtime.GC()
	if c := Arange(20).Reshape(2, 10).Add(b.Reshape(2, 10)); c.Equals(Arange(0, 40, 2).Reshape(2, 10)).All().At(0) == false {
		t.Log("Addition on multiple axis failed.  Expected 0-40 with increment by 2.")
		t.Log("Recieved:", c)
		t.Fail()
	}
	runtime.GC()

	a = Arange(20)
	a.Reshape(2, 2, 5)
	runtime.GC()
	a.Add(Arange(5))
	runtime.GC()
	for i, v := range a.data {
		if int(v) != i%5*2+i/5*5 {
			t.Log("Incorrect result at:", i, "Expected", i%5*2+i/5*5, "Got", v)
			t.Fail()
		}
	}
	runtime.GC()
	a.AddC(1)
	tst := Arange(20).Reshape(2, 2, 5).Add(Arange(1, 6))
	runtime.GC()
	if e := a.Equals(tst); !e.All().At(0) {
		t.Log(e.data)
		t.Log(Arange(1, 6))
		t.Log(Arange(20))
		t.Log(a.Flatten())
		t.Log(tst.Flatten())
		t.Fail()
	}
	runtime.GC()
}

func TestSubtr(t *testing.T) {
	a := Arange(20).Reshape(2, 10).Subtr(Arange(10))
	runtime.GC()
	for i := 0; i < 2; i++ {
		tmp := a.SliceElement(i)
		for _, v := range tmp {
			if v != float64(i*10) {
				t.Log("Subtract resulted in unexpected value.")
				t.Log("At", i, "Expected: ", float64(i*10), "Got:", v)
				t.Fail()
			}
		}
	}

	a = Arange(20).Reshape(2, 2, 5).Subtr(Arange(5))
	for i := 0; i < 2; i++ {
		tmp := a.SliceElement(i)
		for _, v := range tmp {
			if v != float64(i/5*5) {
				t.Log("Subtract resulted in unexpected value.")
				t.Log("Expected: ", i*5, "Got:", v)
				t.Fail()
			}
		}
	}

	a = Arange(20).Reshape(2, 1, 1, 2, 5).Subtr(Arange(5))
	for i := 0; i < 2; i++ {
		tmp := a.SliceElement(i, 0, 0)
		for _, v := range tmp {
			if v != float64(i/5*5) {
				t.Log("Subtract resulted in unexpected value.")
				t.Log("Expected: ", i*5, "Got:", v)
				t.Fail()
			}
		}
	}
}

func TestMult(t *testing.T) {
	a := Arange(1, 100, .5)
	if len(a.data) != (100-1)/.5 {
		t.Log("Expected:", (100-1)/.5, "Got:", len(a.data))
		t.FailNow()
	}

	a = Full(math.NaN(), 4, 4)
	for _, v := range a.data {
		if !math.IsNaN(v) {
			t.Log("Expected NaN, got ", v)
			t.FailNow()
		}
	}
}

func TestFMA12(t *testing.T) {
	a := Arange(1, 100, .5)
	if len(a.data) != (100-1)/.5 {
		t.Log("Expected:", (100-1)/.5, "Got:", len(a.data))
		t.FailNow()
	}

	b := a.C().FMA12(2, a)
	c := a.C().MultC(2).Add(a)
	if e := b.Equals(c); !e.All().At(0) {
		t.Log(a, "\n", b, "\n", c)
		t.Fail()
	}
}

func TestFMA21(t *testing.T) {
	a := Arange(1, 100, .5)
	if len(a.data) != (100-1)/.5 {
		t.Log("Expected:", (100-1)/.5, "Got:", len(a.data))
		t.FailNow()
	}

	b := a.C().FMA21(2, a)
	c := a.C().Mult(a).AddC(2)
	if e := b.Equals(c); !e.All().At(0) {
		t.Log(a, "\n", b, "\n", c)
		t.Fail()
	}
}

func BenchmarkSubtrC(b *testing.B) {
	a := Arange(5003)

	b.ResetTimer()
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		a.SubtrC(5)
	}
	runtime.GC()
}

func BenchmarkAddC_AVX(b *testing.B) {
	avxSupt = true
	a := Arange(5003)

	b.ResetTimer()
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		a.AddC(5)
	}
	runtime.GC()
}

func BenchmarkAddC_noAVX(b *testing.B) {
	avxSupt = false
	a := Arange(5003)

	b.ResetTimer()
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		a.AddC(5)
	}
	runtime.GC()
}

func BenchmarkMultC(b *testing.B) {
	a := Arange(1003)

	b.ResetTimer()
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		a.MultC(2)
	}
	b.StopTimer()
	runtime.GC()
}

func BenchmarkDivC(b *testing.B) {
	a := Arange(1003)

	b.ResetTimer()
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		a.SubtrC(5)
	}
	b.StopTimer()
	runtime.GC()
}

func BenchmarkAdd(b *testing.B) {
	a, n := NewArray64(nil, 10, 10, 12), Arange(12)

	b.ResetTimer()
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		a.Add(n)
	}
	b.StopTimer()
	runtime.GC()
}

func BenchmarkSubtr(b *testing.B) {
	a, n := NewArray64(nil, 10, 10, 12), Arange(12)

	b.ResetTimer()
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		a.Subtr(n)
	}
	b.StopTimer()
	runtime.GC()
}

func BenchmarkMult(b *testing.B) {
	a, n := NewArray64(nil, 10, 10, 12), Arange(1, 13)

	b.ResetTimer()
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		a.Mult(n)
	}
	b.StopTimer()
	runtime.GC()
}

func BenchmarkDiv(b *testing.B) {
	a, n := NewArray64(nil, 10, 10, 12), Arange(1, 13)

	b.ResetTimer()
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		a.Div(n)
	}
	b.StopTimer()
	runtime.GC()
}

func BenchmarkFMA12_FMA(b *testing.B) {
	if !fmaSupt {
		b.Skip()
	}
	a := Arange(1, 1000000, .5)
	if len(a.data) != (1000000-1)/.5 {
		b.Log("Expected:", (1000000-1)/.5, "Got:", len(a.data))
		b.FailNow()
	}

	b.ResetTimer()
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		a.FMA12(2, a)
	}
	b.StopTimer()
	runtime.GC()
}

func BenchmarkFMA12_noFMA(b *testing.B) {
	if !fmaSupt {
		b.Skip()
	}
	tmp := fmaSupt
	fmaSupt = false
	a := Arange(1, 1000000, .5)
	if len(a.data) != (1000000-1)/.5 {
		b.Log("Expected:", (1000000-1)/.5, "Got:", len(a.data))
		b.FailNow()
	}

	b.ResetTimer()
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		a.FMA12(2, a)
	}
	b.StopTimer()
	fmaSupt = tmp
	runtime.GC()
}
<commit_msg>Benchmark skip correction<commit_after>package numgo

import (
	"math"
	"runtime"
	"testing"
)

func init() {
	debug = true
}

func TestAddC(t *testing.T) {
	a := Arange(21)

	if b := a.AddC(2).Equals(Arange(2, 23)); !b.All().At(0) {
		t.Log(b)
		t.Log(a)
		t.Fail()
	}
}

func TestSubtrC(t *testing.T) {
	a := Arange(21)
	if b := a.SubtrC(2).Equals(Arange(-2, 19)); !b.All().At(0) {
		t.Log(b)
		t.Log(a)
		t.Fail()
	}

}

func TestAdd(t *testing.T) {
	a, b := Arange(20), Arange(20)
	a.Add(b)
	runtime.GC()

	if c := a.Add(b.Reshape(2, 10)); c.err != ShapeError {
		t.Log("Shape tests failed.  Expected nil, returned:", c)
		t.Fail()
	}
	runtime.GC()
	if c := Arange(20).Reshape(2, 10).Add(b.Reshape(2, 10)); c.Equals(Arange(0, 40, 2).Reshape(2, 10)).All().At(0) == false {
		t.Log("Addition on multiple axis failed.  Expected 0-40 with increment by 2.")
		t.Log("Recieved:", c)
		t.Fail()
	}
	runtime.GC()

	a = Arange(20)
	a.Reshape(2, 2, 5)
	runtime.GC()
	a.Add(Arange(5))
	runtime.GC()
	for i, v := range a.data {
		if int(v) != i%5*2+i/5*5 {
			t.Log("Incorrect result at:", i, "Expected", i%5*2+i/5*5, "Got", v)
			t.Fail()
		}
	}
	runtime.GC()
	a.AddC(1)
	tst := Arange(20).Reshape(2, 2, 5).Add(Arange(1, 6))
	runtime.GC()
	if e := a.Equals(tst); !e.All().At(0) {
		t.Log(e.data)
		t.Log(Arange(1, 6))
		t.Log(Arange(20))
		t.Log(a.Flatten())
		t.Log(tst.Flatten())
		t.Fail()
	}
	runtime.GC()
}

func TestSubtr(t *testing.T) {
	a := Arange(20).Reshape(2, 10).Subtr(Arange(10))
	runtime.GC()
	for i := 0; i < 2; i++ {
		tmp := a.SliceElement(i)
		for _, v := range tmp {
			if v != float64(i*10) {
				t.Log("Subtract resulted in unexpected value.")
				t.Log("At", i, "Expected: ", float64(i*10), "Got:", v)
				t.Fail()
			}
		}
	}

	a = Arange(20).Reshape(2, 2, 5).Subtr(Arange(5))
	for i := 0; i < 2; i++ {
		tmp := a.SliceElement(i)
		for _, v := range tmp {
			if v != float64(i/5*5) {
				t.Log("Subtract resulted in unexpected value.")
				t.Log("Expected: ", i*5, "Got:", v)
				t.Fail()
			}
		}
	}

	a = Arange(20).Reshape(2, 1, 1, 2, 5).Subtr(Arange(5))
	for i := 0; i < 2; i++ {
		tmp := a.SliceElement(i, 0, 0)
		for _, v := range tmp {
			if v != float64(i/5*5) {
				t.Log("Subtract resulted in unexpected value.")
				t.Log("Expected: ", i*5, "Got:", v)
				t.Fail()
			}
		}
	}
}

func TestMult(t *testing.T) {
	a := Arange(1, 100, .5)
	if len(a.data) != (100-1)/.5 {
		t.Log("Expected:", (100-1)/.5, "Got:", len(a.data))
		t.FailNow()
	}

	a = Full(math.NaN(), 4, 4)
	for _, v := range a.data {
		if !math.IsNaN(v) {
			t.Log("Expected NaN, got ", v)
			t.FailNow()
		}
	}
}

func TestFMA12(t *testing.T) {
	a := Arange(1, 100, .5)
	if len(a.data) != (100-1)/.5 {
		t.Log("Expected:", (100-1)/.5, "Got:", len(a.data))
		t.FailNow()
	}

	b := a.C().FMA12(2, a)
	c := a.C().MultC(2).Add(a)
	if e := b.Equals(c); !e.All().At(0) {
		t.Log(a, "\n", b, "\n", c)
		t.Fail()
	}
}

func TestFMA21(t *testing.T) {
	a := Arange(1, 100, .5)
	if len(a.data) != (100-1)/.5 {
		t.Log("Expected:", (100-1)/.5, "Got:", len(a.data))
		t.FailNow()
	}

	b := a.C().FMA21(2, a)
	c := a.C().Mult(a).AddC(2)
	if e := b.Equals(c); !e.All().At(0) {
		t.Log(a, "\n", b, "\n", c)
		t.Fail()
	}
}

func BenchmarkSubtrC(b *testing.B) {
	a := Arange(5003)

	b.ResetTimer()
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		a.SubtrC(5)
	}
	runtime.GC()
}

func BenchmarkAddC_AVX(b *testing.B) {
	avxSupt = true
	a := Arange(5003)

	b.ResetTimer()
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		a.AddC(5)
	}
	runtime.GC()
}

func BenchmarkAddC_noAVX(b *testing.B) {
	avxSupt = false
	a := Arange(5003)

	b.ResetTimer()
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		a.AddC(5)
	}
	runtime.GC()
}

func BenchmarkMultC(b *testing.B) {
	a := Arange(1003)

	b.ResetTimer()
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		a.MultC(2)
	}
	b.StopTimer()
	runtime.GC()
}

func BenchmarkDivC(b *testing.B) {
	a := Arange(1003)

	b.ResetTimer()
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		a.SubtrC(5)
	}
	b.StopTimer()
	runtime.GC()
}

func BenchmarkAdd(b *testing.B) {
	a, n := NewArray64(nil, 10, 10, 12), Arange(12)

	b.ResetTimer()
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		a.Add(n)
	}
	b.StopTimer()
	runtime.GC()
}

func BenchmarkSubtr(b *testing.B) {
	a, n := NewArray64(nil, 10, 10, 12), Arange(12)

	b.ResetTimer()
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		a.Subtr(n)
	}
	b.StopTimer()
	runtime.GC()
}

func BenchmarkMult(b *testing.B) {
	a, n := NewArray64(nil, 10, 10, 12), Arange(1, 13)

	b.ResetTimer()
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		a.Mult(n)
	}
	b.StopTimer()
	runtime.GC()
}

func BenchmarkDiv(b *testing.B) {
	a, n := NewArray64(nil, 10, 10, 12), Arange(1, 13)

	b.ResetTimer()
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		a.Div(n)
	}
	b.StopTimer()
	runtime.GC()
}

func BenchmarkFMA12_FMA(b *testing.B) {
	a := Arange(1, 1000000, .5)
	if len(a.data) != (1000000-1)/.5 {
		b.Log("Expected:", (1000000-1)/.5, "Got:", len(a.data))
		b.FailNow()
	}

	b.ResetTimer()
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		a.FMA12(2, a)
	}
	b.StopTimer()
	runtime.GC()
}

func BenchmarkFMA12_noFMA(b *testing.B) {
	if !fmaSupt {
		b.Skip()
	}
	tmp := fmaSupt
	fmaSupt = false
	a := Arange(1, 1000000, .5)
	if len(a.data) != (1000000-1)/.5 {
		b.Log("Expected:", (1000000-1)/.5, "Got:", len(a.data))
		b.FailNow()
	}

	b.ResetTimer()
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		a.FMA12(2, a)
	}
	b.StopTimer()
	fmaSupt = tmp
	runtime.GC()
}
<|endoftext|>


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

package signer // import "go.mozilla.org/autograph/signer"

import (
	"crypto"
	"crypto/dsa"
	"crypto/ecdsa"
	"crypto/rsa"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/asn1"
	"encoding/pem"
	"fmt"
	"math/big"
	"regexp"
	"strings"
	"time"

	"github.com/ThalesIgnite/crypto11"
	"github.com/pkg/errors"
	log "github.com/sirupsen/logrus"
	"github.com/DataDog/datadog-go/statsd"
)

// RSACacheConfig is a config for the RSAKeyCache
type RSACacheConfig struct {
	// NumKeys is the number of RSA keys matching the issuer size
	// to cache
	NumKeys uint64

	// NumGenerators is the number of key generator workers to run
	// that populate the RSA key cache
	NumGenerators uint8

	// GeneratorSleepDuration is how frequently each cache key
	// generator tries to add a key to the cache chan
	GeneratorSleepDuration time.Duration

	// FetchTimeout is how long a consumer waits for the cache
	// before generating its own key
	FetchTimeout time.Duration

	// StatsSampleRate is how frequently the monitor reports the
	// cache size and capacity
	StatsSampleRate time.Duration
}

// Configuration defines the parameters of a signer
type Configuration struct {
	ID             string         `json:"id"`
	Type           string         `json:"type"`
	Mode           string         `json:"mode"`
	PrivateKey     string         `json:"privatekey,omitempty"`
	PublicKey      string         `json:"publickey,omitempty"`
	Certificate    string         `json:"certificate,omitempty"`
	X5U            string         `json:"x5u,omitempty"`
	RSACacheConfig RSACacheConfig `json:"rsacacheconfig,omitempty"`

	isHsmAvailable bool
}

// HSMIsAvailable indicates that an HSM has been initialized
func (cfg *Configuration) HSMIsAvailable() {
	cfg.isHsmAvailable = true
}

// Signer is an interface to a configurable issuer of digital signatures
type Signer interface {
	Config() Configuration
}

// HashSigner is an interface to a signer able to sign hashes
type HashSigner interface {
	SignHash(data []byte, options interface{}) (Signature, error)
	GetDefaultOptions() interface{}
}

// DataSigner is an interface to a signer able to sign raw data
type DataSigner interface {
	SignData(data []byte, options interface{}) (Signature, error)
	GetDefaultOptions() interface{}
}

// FileSigner is an interface to a signer able to sign files
type FileSigner interface {
	SignFile(file []byte, options interface{}) (SignedFile, error)
	GetDefaultOptions() interface{}
}

// Signature is an interface to a digital signature
type Signature interface {
	Marshal() (signature string, err error)
}

// SignedFile is an []bytes that contains file data
type SignedFile []byte

// GetPrivateKey uses a signer configuration to determine where a private
// key should be accessed from. If it is in local configuration, it will
// be parsed and loaded in the signer. If it is in an HSM, it will be
// used via a PKCS11 interface. This is completely transparent to the
// caller, who should simply assume that the privatekey implements a
// crypto.Sign interface
//
// Note that we assume the PKCS11 library has been previously initialized
func (cfg *Configuration) GetPrivateKey() (crypto.PrivateKey, error) {
	// make sure heading newlines are removed
	removeNewlines := regexp.MustCompile(`^(\r?\n)`)
	cfg.PrivateKey = removeNewlines.ReplaceAllString(cfg.PrivateKey, "")
	// if a private key in the config starts with a PEM header, it is
	// defined locally and is parsed and returned
	if strings.HasPrefix(cfg.PrivateKey, "-----BEGIN") {
		return ParsePrivateKey([]byte(cfg.PrivateKey))
	}
	// otherwise, we assume the privatekey represents a label in the HSM
	if cfg.isHsmAvailable {
		key, err := crypto11.FindKeyPair(nil, []byte(cfg.PrivateKey))
		if err != nil {
			return nil, err
		}
		return key, nil
	}
	return nil, fmt.Errorf("no suitable key found")
}

// ParsePrivateKey takes a PEM blocks are returns a crypto.PrivateKey
// It tries to parse as many known key types as possible before failing and
// returning all the errors it encountered.
func ParsePrivateKey(keyPEMBlock []byte) (key crypto.PrivateKey, err error) {
	var (
		keyDERBlock       *pem.Block
		skippedBlockTypes []string
	)
	for {
		keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock)
		if keyDERBlock == nil {
			if len(skippedBlockTypes) == 1 && skippedBlockTypes[0] == "CERTIFICATE" {
				return nil, errors.New("signer: found a certificate rather than a key in the PEM for the private key")
			}
			return nil, fmt.Errorf("signer: failed to find PEM block with type ending in \"PRIVATE KEY\" in key input after skipping PEM blocks of the following types: %v", skippedBlockTypes)

		}
		if strings.HasSuffix(keyDERBlock.Type, "PRIVATE KEY") {
			break
		}
		skippedBlockTypes = append(skippedBlockTypes, keyDERBlock.Type)
	}
	// Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates
	// PKCS#1 private keys by default, while OpenSSL 1.0.0 generates PKCS#8 keys.
	// OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three.
	// Code taken from the crypto/tls standard library.
	if key, err = x509.ParsePKCS1PrivateKey(keyDERBlock.Bytes); err == nil {
		return key, nil
	}
	var savedErr []string
	savedErr = append(savedErr, "pkcs1: "+err.Error())
	if key, err = x509.ParsePKCS8PrivateKey(keyDERBlock.Bytes); err == nil {
		switch key := key.(type) {
		case *rsa.PrivateKey, *ecdsa.PrivateKey:
			return key, nil
		}
	}
	savedErr = append(savedErr, "pkcs8: "+err.Error())

	if key, err = x509.ParseECPrivateKey(keyDERBlock.Bytes); err == nil {
		return key, nil
	}
	savedErr = append(savedErr, "ecdsa: "+err.Error())

	if key, err = parseDSAPKCS8PrivateKey(keyDERBlock.Bytes); err == nil {
		return key, nil
	}
	savedErr = append(savedErr, "dsa: "+err.Error())

	return nil, errors.New("failed to parse private key, make sure to use PKCS1 for RSA and PKCS8 for (EC)DSA. errors: " + strings.Join(savedErr, ";;; "))
}

// parseDSAPKCS8PrivateKey returns a DSA private key from its ASN.1 DER encoding
func parseDSAPKCS8PrivateKey(der []byte) (*dsa.PrivateKey, error) {
	var k struct {
		Version int
		Algo    pkix.AlgorithmIdentifier
		Priv    []byte
	}
	rest, err := asn1.Unmarshal(der, &k)
	if err != nil {
		return nil, err
	}
	if len(rest) > 0 {
		return nil, errors.New("garbage after DSA key")
	}
	var params dsa.Parameters
	_, err = asn1.Unmarshal(k.Algo.Parameters.FullBytes, &params)
	if err != nil {
		return nil, err
	}
	// FIXME: couldn't get asn1.Unmarshal to properly parse the OCTET STRING
	// tag in front of the X value of the DSA key, but doing it manually by
	// stripping off the first two bytes and loading it as a bigint works
	if len(k.Priv) < 22 {
		return nil, errors.New("DSA key is too short")
	}
	x := new(big.Int).SetBytes(k.Priv[2:])
	return &dsa.PrivateKey{
		PublicKey: dsa.PublicKey{
			Parameters: dsa.Parameters{
				P: params.P,
				Q: params.Q,
				G: params.G,
			},
		},
		X: x,
	}, nil
}

// StatsClient is a helper for sending statsd stats with the relevant
// tags for the signer and error handling
type StatsClient struct {
	// signerTags is the
	signerTags []string

	// stats is the statsd client for reporting metrics
	stats *statsd.Client
}

func NewStatsClient(signerConfig Configuration, stats *statsd.Client) (*StatsClient, error) {
	if stats == nil {
		return nil, errors.Errorf("xpi: statsd client is nil. Could not create StatsClient for signer %s", signerConfig.ID)
	}
	return &StatsClient{
		stats: stats,
		signerTags: []string{signerConfig.ID, signerConfig.Type, signerConfig.Mode},
	}, nil
}

// SendGauge checks for a statsd client and when one is present sends
// a statsd gauge with the given name, int value cast to float64, tags
// for the signer, and sampling rate of 1
func (s *StatsClient) SendGauge(name string, value int) {
	if s.stats == nil {
		log.Warnf("xpi: statsd client is nil. Could not send gauge %s with value %v", name, value)
		return
	}
	err := s.stats.Gauge(name, float64(value), s.signerTags, 1)
	if err != nil {
		log.Warnf("Error sending gauge %s: %s", name, err)
	}
}

// SendHistogram checks for a statsd client and when one is present
// sends a statsd histogram with the given name, time.Duration value
// cast to float64, tags for the signer, and sampling rate of 1
func (s *StatsClient) SendHistogram(name string, value time.Duration) {
	if s.stats == nil {
		log.Warnf("xpi: statsd client is nil. Could not send histogram %s with value %s", name, value)
		return
	}
	err := s.stats.Histogram(name, float64(value), s.signerTags, 1)
	if err != nil {
		log.Warnf("Error sending histogram %s: %s", name, err)
	}
}
<commit_msg>signer: use key:value fmt for signer stats tags<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Contributor: Julien Vehent jvehent@mozilla.com [:ulfr]

package signer // import "go.mozilla.org/autograph/signer"

import (
	"crypto"
	"crypto/dsa"
	"crypto/ecdsa"
	"crypto/rsa"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/asn1"
	"encoding/pem"
	"fmt"
	"math/big"
	"regexp"
	"strings"
	"time"

	"github.com/ThalesIgnite/crypto11"
	"github.com/pkg/errors"
	log "github.com/sirupsen/logrus"
	"github.com/DataDog/datadog-go/statsd"
)

// RSACacheConfig is a config for the RSAKeyCache
type RSACacheConfig struct {
	// NumKeys is the number of RSA keys matching the issuer size
	// to cache
	NumKeys uint64

	// NumGenerators is the number of key generator workers to run
	// that populate the RSA key cache
	NumGenerators uint8

	// GeneratorSleepDuration is how frequently each cache key
	// generator tries to add a key to the cache chan
	GeneratorSleepDuration time.Duration

	// FetchTimeout is how long a consumer waits for the cache
	// before generating its own key
	FetchTimeout time.Duration

	// StatsSampleRate is how frequently the monitor reports the
	// cache size and capacity
	StatsSampleRate time.Duration
}

// Configuration defines the parameters of a signer
type Configuration struct {
	ID             string         `json:"id"`
	Type           string         `json:"type"`
	Mode           string         `json:"mode"`
	PrivateKey     string         `json:"privatekey,omitempty"`
	PublicKey      string         `json:"publickey,omitempty"`
	Certificate    string         `json:"certificate,omitempty"`
	X5U            string         `json:"x5u,omitempty"`
	RSACacheConfig RSACacheConfig `json:"rsacacheconfig,omitempty"`

	isHsmAvailable bool
}

// HSMIsAvailable indicates that an HSM has been initialized
func (cfg *Configuration) HSMIsAvailable() {
	cfg.isHsmAvailable = true
}

// Signer is an interface to a configurable issuer of digital signatures
type Signer interface {
	Config() Configuration
}

// HashSigner is an interface to a signer able to sign hashes
type HashSigner interface {
	SignHash(data []byte, options interface{}) (Signature, error)
	GetDefaultOptions() interface{}
}

// DataSigner is an interface to a signer able to sign raw data
type DataSigner interface {
	SignData(data []byte, options interface{}) (Signature, error)
	GetDefaultOptions() interface{}
}

// FileSigner is an interface to a signer able to sign files
type FileSigner interface {
	SignFile(file []byte, options interface{}) (SignedFile, error)
	GetDefaultOptions() interface{}
}

// Signature is an interface to a digital signature
type Signature interface {
	Marshal() (signature string, err error)
}

// SignedFile is an []bytes that contains file data
type SignedFile []byte

// GetPrivateKey uses a signer configuration to determine where a private
// key should be accessed from. If it is in local configuration, it will
// be parsed and loaded in the signer. If it is in an HSM, it will be
// used via a PKCS11 interface. This is completely transparent to the
// caller, who should simply assume that the privatekey implements a
// crypto.Sign interface
//
// Note that we assume the PKCS11 library has been previously initialized
func (cfg *Configuration) GetPrivateKey() (crypto.PrivateKey, error) {
	// make sure heading newlines are removed
	removeNewlines := regexp.MustCompile(`^(\r?\n)`)
	cfg.PrivateKey = removeNewlines.ReplaceAllString(cfg.PrivateKey, "")
	// if a private key in the config starts with a PEM header, it is
	// defined locally and is parsed and returned
	if strings.HasPrefix(cfg.PrivateKey, "-----BEGIN") {
		return ParsePrivateKey([]byte(cfg.PrivateKey))
	}
	// otherwise, we assume the privatekey represents a label in the HSM
	if cfg.isHsmAvailable {
		key, err := crypto11.FindKeyPair(nil, []byte(cfg.PrivateKey))
		if err != nil {
			return nil, err
		}
		return key, nil
	}
	return nil, fmt.Errorf("no suitable key found")
}

// ParsePrivateKey takes a PEM blocks are returns a crypto.PrivateKey
// It tries to parse as many known key types as possible before failing and
// returning all the errors it encountered.
func ParsePrivateKey(keyPEMBlock []byte) (key crypto.PrivateKey, err error) {
	var (
		keyDERBlock       *pem.Block
		skippedBlockTypes []string
	)
	for {
		keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock)
		if keyDERBlock == nil {
			if len(skippedBlockTypes) == 1 && skippedBlockTypes[0] == "CERTIFICATE" {
				return nil, errors.New("signer: found a certificate rather than a key in the PEM for the private key")
			}
			return nil, fmt.Errorf("signer: failed to find PEM block with type ending in \"PRIVATE KEY\" in key input after skipping PEM blocks of the following types: %v", skippedBlockTypes)

		}
		if strings.HasSuffix(keyDERBlock.Type, "PRIVATE KEY") {
			break
		}
		skippedBlockTypes = append(skippedBlockTypes, keyDERBlock.Type)
	}
	// Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates
	// PKCS#1 private keys by default, while OpenSSL 1.0.0 generates PKCS#8 keys.
	// OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three.
	// Code taken from the crypto/tls standard library.
	if key, err = x509.ParsePKCS1PrivateKey(keyDERBlock.Bytes); err == nil {
		return key, nil
	}
	var savedErr []string
	savedErr = append(savedErr, "pkcs1: "+err.Error())
	if key, err = x509.ParsePKCS8PrivateKey(keyDERBlock.Bytes); err == nil {
		switch key := key.(type) {
		case *rsa.PrivateKey, *ecdsa.PrivateKey:
			return key, nil
		}
	}
	savedErr = append(savedErr, "pkcs8: "+err.Error())

	if key, err = x509.ParseECPrivateKey(keyDERBlock.Bytes); err == nil {
		return key, nil
	}
	savedErr = append(savedErr, "ecdsa: "+err.Error())

	if key, err = parseDSAPKCS8PrivateKey(keyDERBlock.Bytes); err == nil {
		return key, nil
	}
	savedErr = append(savedErr, "dsa: "+err.Error())

	return nil, errors.New("failed to parse private key, make sure to use PKCS1 for RSA and PKCS8 for (EC)DSA. errors: " + strings.Join(savedErr, ";;; "))
}

// parseDSAPKCS8PrivateKey returns a DSA private key from its ASN.1 DER encoding
func parseDSAPKCS8PrivateKey(der []byte) (*dsa.PrivateKey, error) {
	var k struct {
		Version int
		Algo    pkix.AlgorithmIdentifier
		Priv    []byte
	}
	rest, err := asn1.Unmarshal(der, &k)
	if err != nil {
		return nil, err
	}
	if len(rest) > 0 {
		return nil, errors.New("garbage after DSA key")
	}
	var params dsa.Parameters
	_, err = asn1.Unmarshal(k.Algo.Parameters.FullBytes, &params)
	if err != nil {
		return nil, err
	}
	// FIXME: couldn't get asn1.Unmarshal to properly parse the OCTET STRING
	// tag in front of the X value of the DSA key, but doing it manually by
	// stripping off the first two bytes and loading it as a bigint works
	if len(k.Priv) < 22 {
		return nil, errors.New("DSA key is too short")
	}
	x := new(big.Int).SetBytes(k.Priv[2:])
	return &dsa.PrivateKey{
		PublicKey: dsa.PublicKey{
			Parameters: dsa.Parameters{
				P: params.P,
				Q: params.Q,
				G: params.G,
			},
		},
		X: x,
	}, nil
}

// StatsClient is a helper for sending statsd stats with the relevant
// tags for the signer and error handling
type StatsClient struct {
	// signerTags is the
	signerTags []string

	// stats is the statsd client for reporting metrics
	stats *statsd.Client
}

func NewStatsClient(signerConfig Configuration, stats *statsd.Client) (*StatsClient, error) {
	if stats == nil {
		return nil, errors.Errorf("xpi: statsd client is nil. Could not create StatsClient for signer %s", signerConfig.ID)
	}
	return &StatsClient{
		stats: stats,
		signerTags: []string{
			fmt.Sprintf("autograph-signer-id:%s", signerConfig.ID),
			fmt.Sprintf("autograph-signer-type:%s", signerConfig.Type),
			fmt.Sprintf("autograph-signer-mode:%s", signerConfig.Mode),
		},
	}, nil
}

// SendGauge checks for a statsd client and when one is present sends
// a statsd gauge with the given name, int value cast to float64, tags
// for the signer, and sampling rate of 1
func (s *StatsClient) SendGauge(name string, value int) {
	if s.stats == nil {
		log.Warnf("xpi: statsd client is nil. Could not send gauge %s with value %v", name, value)
		return
	}
	err := s.stats.Gauge(name, float64(value), s.signerTags, 1)
	if err != nil {
		log.Warnf("Error sending gauge %s: %s", name, err)
	}
}

// SendHistogram checks for a statsd client and when one is present
// sends a statsd histogram with the given name, time.Duration value
// cast to float64, tags for the signer, and sampling rate of 1
func (s *StatsClient) SendHistogram(name string, value time.Duration) {
	if s.stats == nil {
		log.Warnf("xpi: statsd client is nil. Could not send histogram %s with value %s", name, value)
		return
	}
	err := s.stats.Histogram(name, float64(value), s.signerTags, 1)
	if err != nil {
		log.Warnf("Error sending histogram %s: %s", name, err)
	}
}
<|endoftext|>


<commit_before>// logger
//
// @author darryl.west <darryl.west@raincitysoftware.com>
// @created 2017-03-11 10:57:53

package spotcache

import (
	"fmt"
	"path"

	"github.com/darrylwest/cassava-logger/logger"
)

var log *logger.Logger

// CreateLogger create a new logger based on config
func CreateLogger(cfg *Config) *logger.Logger {
	if log == nil {
		filename := path.Join(cfg.Logpath, cfg.Logname)
		handler, err := logger.NewRotatingDayHandler(filename)

		if err != nil {
			fmt.Printf("%s\n", err)
			panic("logger could not be created...")
		}

		fmt.Printf("created rolling log file: %s\n", filename)
		log = logger.NewLogger(handler)
	}

	return log
}
<commit_msg>added create log path<commit_after>// logger
//
// @author darryl.west <darryl.west@raincitysoftware.com>
// @created 2017-03-11 10:57:53

package spotcache

import (
	"fmt"
	"os"
	"path"

	"github.com/darrylwest/cassava-logger/logger"
)

var log *logger.Logger

// CreateLogger create a new logger based on config
func CreateLogger(cfg *Config) *logger.Logger {
	if log == nil {
		if err := CreateLogFolder(cfg.Logpath); err != nil {
			panic(err)
		}

		filename := path.Join(cfg.Logpath, cfg.Logname)
		handler, err := logger.NewRotatingDayHandler(filename)

		if err != nil {
			fmt.Printf("%s\n", err)
			panic("logger could not be created...")
		}

		fmt.Printf("created rolling log file: %s\n", filename)
		log = logger.NewLogger(handler)
	}

	return log
}

// CreateLogFolder - create the log folder if it doesn't already exist
func CreateLogFolder(logpath string) error {
	if _, err := os.Stat(logpath); err == nil {
		return nil
	}

	fmt.Printf("create log folder %s\n", logpath)
	return os.MkdirAll(logpath, 0755)
}
<|endoftext|>


<commit_before>package main

import (
	"net"
	"testing"
)

var app = "test"
var tags = []string{"tag1", "tag2"}
var prefix = "prefix."

var statsdTests = []struct {
	cnt      int
	m        logMetrics
	Expected []string
}{
	{
		cnt: 2,
		m: logMetrics{
			routerMsg,
			&app,
			&tags,
			&prefix,
			map[string]logValue{
				"at":      {"info", ""},
				"path":    {"/foo", ""},
				"connect": {"1", "ms"},
				"service": {"37", "ms"},
				"garbage": {"bar", ""},
			},
		},
		Expected: []string{
			"prefix.heroku.router.request.connect:1.000000|h|#tag1,tag2,at:info",
			"prefix.heroku.router.request.service:37.000000|h|#tag1,tag2,at:info",
		},
	},
	{
		cnt: 1,
		m: logMetrics{
			sampleMsg,
			&app,
			&tags,
			&prefix,
			map[string]logValue{
				"source":             {"web1", ""},
				"sample#load_avg_1m": {"0.01", ""},
			},
		},
		Expected: []string{
			"prefix.heroku.dyno.load.avg.1m:0.010000|g|#tag1,tag2,source:web1",
		},
	},
	{
		cnt: 2,
		m: logMetrics{
			scalingMsg,
			&app,
			&tags,
			&prefix,
			map[string]logValue{
				"mailer": {"1", ""},
				"web":    {"3", ""},
			},
		},
		Expected: []string{
			"prefix.heroku.dyno.mailer:1.000000|g|#tag1,tag2",
			"prefix.heroku.dyno.web:3.000000|g|#tag1,tag2",
		},
	},
}

func TestStatsdClient(t *testing.T) {

	addr := "localhost:1201"
	udpAddr, err := net.ResolveUDPAddr("udp", addr)
	if err != nil {
		t.Fatal(err)
	}

	server, err := net.ListenUDP("udp", udpAddr)
	if err != nil {
		t.Fatal(err)
	}
	defer server.Close()

	c, err := statsdClient(addr)
	if err != nil {
		t.Fatal(err)
	}

	// c.ExcludedTags = map[string]bool{"path": true}
	c.ExcludedTags["path"] = true

	out := make(chan *logMetrics)
	defer close(out)
	go c.sendToStatsd(out)

	bytes := make([]byte, 1024)
	for _, tt := range statsdTests {
		out <- &tt.m
		for i := 0; i < tt.cnt; i++ {
			n, err := server.Read(bytes)
			if err != nil {
				t.Fatal(err)
			}
			message := bytes[:n]
			if string(message) != tt.Expected[i] {
				t.Errorf("Expected: %s. Actual: %s", tt.Expected[i], string(message))
			}
		}
	}
}
<commit_msg>Leftover comment 😳<commit_after>package main

import (
	"net"
	"testing"
)

var app = "test"
var tags = []string{"tag1", "tag2"}
var prefix = "prefix."

var statsdTests = []struct {
	cnt      int
	m        logMetrics
	Expected []string
}{
	{
		cnt: 2,
		m: logMetrics{
			routerMsg,
			&app,
			&tags,
			&prefix,
			map[string]logValue{
				"at":      {"info", ""},
				"path":    {"/foo", ""},
				"connect": {"1", "ms"},
				"service": {"37", "ms"},
				"garbage": {"bar", ""},
			},
		},
		Expected: []string{
			"prefix.heroku.router.request.connect:1.000000|h|#tag1,tag2,at:info",
			"prefix.heroku.router.request.service:37.000000|h|#tag1,tag2,at:info",
		},
	},
	{
		cnt: 1,
		m: logMetrics{
			sampleMsg,
			&app,
			&tags,
			&prefix,
			map[string]logValue{
				"source":             {"web1", ""},
				"sample#load_avg_1m": {"0.01", ""},
			},
		},
		Expected: []string{
			"prefix.heroku.dyno.load.avg.1m:0.010000|g|#tag1,tag2,source:web1",
		},
	},
	{
		cnt: 2,
		m: logMetrics{
			scalingMsg,
			&app,
			&tags,
			&prefix,
			map[string]logValue{
				"mailer": {"1", ""},
				"web":    {"3", ""},
			},
		},
		Expected: []string{
			"prefix.heroku.dyno.mailer:1.000000|g|#tag1,tag2",
			"prefix.heroku.dyno.web:3.000000|g|#tag1,tag2",
		},
	},
}

func TestStatsdClient(t *testing.T) {

	addr := "localhost:1201"
	udpAddr, err := net.ResolveUDPAddr("udp", addr)
	if err != nil {
		t.Fatal(err)
	}

	server, err := net.ListenUDP("udp", udpAddr)
	if err != nil {
		t.Fatal(err)
	}
	defer server.Close()

	c, err := statsdClient(addr)
	if err != nil {
		t.Fatal(err)
	}

	c.ExcludedTags["path"] = true

	out := make(chan *logMetrics)
	defer close(out)
	go c.sendToStatsd(out)

	bytes := make([]byte, 1024)
	for _, tt := range statsdTests {
		out <- &tt.m
		for i := 0; i < tt.cnt; i++ {
			n, err := server.Read(bytes)
			if err != nil {
				t.Fatal(err)
			}
			message := bytes[:n]
			if string(message) != tt.Expected[i] {
				t.Errorf("Expected: %s. Actual: %s", tt.Expected[i], string(message))
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/russmack/cloudsigma"
	"github.com/russmack/statemachiner"
)

type CommandCloudStatus struct {
	responseChan chan string
	promptChan   chan string
	userChan     chan string
}

func NewCloudStatus() *CommandCloudStatus {
	return &CommandCloudStatus{}
}

func (m *CommandCloudStatus) Start(respChan chan string, promptChan chan string, userChan chan string) {
	m.responseChan = respChan
	m.promptChan = promptChan
	m.userChan = userChan
	stateMachine := &statemachiner.StateMachine{}
	stateMachine.StartState = m.getCloudStatus
	cargo := CommandCloudStatus{}
	stateMachine.Start(cargo)
}

func (m *CommandCloudStatus) getCloudStatus(cargo interface{}) statemachiner.StateFn {
	o := cloudsigma.NewCloudStatus()
	args := o.NewGet()
	client := &cloudsigma.Client{}
	resp, err := client.Call(args)
	if err != nil {
		fmt.Println("Error calling client.", err)
	}
	m.responseChan <- string(resp)
	return nil
}
<commit_msg>Hardcoded location until implemented.<commit_after>package main

import (
	"fmt"
	"github.com/russmack/cloudsigma"
	"github.com/russmack/statemachiner"
)

type CommandCloudStatus struct {
	responseChan chan string
	promptChan   chan string
	userChan     chan string
}

func NewCloudStatus() *CommandCloudStatus {
	return &CommandCloudStatus{}
}

func (m *CommandCloudStatus) Start(respChan chan string, promptChan chan string, userChan chan string) {
	m.responseChan = respChan
	m.promptChan = promptChan
	m.userChan = userChan
	stateMachine := &statemachiner.StateMachine{}
	stateMachine.StartState = m.getCloudStatus
	cargo := CommandCloudStatus{}
	stateMachine.Start(cargo)
}

func (m *CommandCloudStatus) getCloudStatus(cargo interface{}) statemachiner.StateFn {
	o := cloudsigma.NewCloudStatus()
	args := o.NewGet()
	// TODO: this must be entered by repl user.
	args.Location = "zrh"
	client := &cloudsigma.Client{}
	resp, err := client.Call(args)
	if err != nil {
		fmt.Println("Error calling client.", err)
	}
	m.responseChan <- string(resp)
	return nil
}
<|endoftext|>


<commit_before>package cmd

import (
	"html/template"
	"os"
	"path/filepath"
	"strings"
	"sync"

	"github.com/pkg/errors"
)

const exePath = ".grifter/main.go"

var once = &sync.Once{}

type grifter struct {
	GriftsPackagePath  string
	CommandName        string
	Verbose            bool
	GriftsAbsolutePath string
}

func hasGriftDir(path string) bool {
	stat, err := os.Stat(filepath.Join(path, "grifts"))
	if err != nil {
		if os.IsNotExist(err) {
			return false
		}
		return false
	}

	if !stat.IsDir() {
		return false
	}

	return true

}

func newGrifter(name string) (*grifter, error) {
	g := &grifter{
		CommandName: name,
	}

	path, err := os.Getwd()
	if err != nil {
		return g, errors.WithStack(err)
	}

	for !strings.HasSuffix(path, "/src") && path != "/" {
		if hasGriftDir(path) {
			break
		}

		path = filepath.Dir(path)
	}

	p := strings.SplitN(path, "/src/", 2)
	if len(p) == 1 {
		return g, errors.Errorf("There is no directory named 'grifts'. Run '%s init' or switch to the appropriate directory", name)
	}
	g.GriftsAbsolutePath = filepath.ToSlash(filepath.Join(path, "grifts"))
	g.GriftsPackagePath = filepath.ToSlash(filepath.Join(p[1], "grifts"))
	return g, nil
}

func (g *grifter) Setup() error {
	t, err := template.New("main").Parse(mainTmpl)
	if err != nil {
		return errors.WithStack(err)
	}

	err = os.MkdirAll(filepath.Dir(exePath), 0755)
	if err != nil {
		return errors.WithStack(err)
	}
	f, err := os.Create(exePath)
	if err != nil {
		return errors.WithStack(err)
	}

	err = t.Execute(f, g)
	if err != nil {
		return errors.WithStack(err)
	}

	return nil
}

func (g *grifter) TearDown() error {
	return os.RemoveAll(filepath.Dir(exePath))
}
<commit_msg>minor task issue caused by path resolution.<commit_after>package cmd

import (
	"html/template"
	"os"
	"path/filepath"
	"strings"
	"sync"

	"github.com/pkg/errors"
)

const exePath = ".grifter/main.go"

var once = &sync.Once{}

type grifter struct {
	GriftsPackagePath  string
	CommandName        string
	Verbose            bool
	GriftsAbsolutePath string
}

func hasGriftDir(path string) bool {
	stat, err := os.Stat(filepath.Join(path, "grifts"))
	if err != nil {
		if os.IsNotExist(err) {
			return false
		}
		return false
	}

	if !stat.IsDir() {
		return false
	}

	return true

}

func newGrifter(name string) (*grifter, error) {
	g := &grifter{
		CommandName: name,
	}

	path, err := os.Getwd()
	if err != nil {
		return g, errors.WithStack(err)
	}

	for !strings.HasSuffix(path, "/src") && path != "/" {
		if hasGriftDir(path) {
			break
		}

		path = filepath.Dir(path)
	}

	p := strings.SplitN(path, filepath.FromSlash("/src/"), 2)
	if len(p) == 1 {
		return g, errors.Errorf("There is no directory named 'grifts'. Run '%s init' or switch to the appropriate directory", name)
	}
	g.GriftsAbsolutePath = filepath.ToSlash(filepath.Join(path, "grifts"))
	g.GriftsPackagePath = filepath.ToSlash(filepath.Join(p[1], "grifts"))
	return g, nil
}

func (g *grifter) Setup() error {
	t, err := template.New("main").Parse(mainTmpl)
	if err != nil {
		return errors.WithStack(err)
	}

	err = os.MkdirAll(filepath.Dir(exePath), 0755)
	if err != nil {
		return errors.WithStack(err)
	}
	f, err := os.Create(exePath)
	if err != nil {
		return errors.WithStack(err)
	}

	err = t.Execute(f, g)
	if err != nil {
		return errors.WithStack(err)
	}

	return nil
}

func (g *grifter) TearDown() error {
	return os.RemoveAll(filepath.Dir(exePath))
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/simeji/jid"
)

func main() {
	content := os.Stdin

	var qm bool
	qs := "."

	flag.BoolVar(&qm, "q", false, "Output query mode")
	flag.Parse()

	args := flag.Args()
	if len(args) > 0 {
		qs = args[0]
	}

	e, err := jid.NewEngine(content, qs)

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	os.Exit(run(e, qm))
}

func run(e jid.EngineInterface, qm bool) int {

	result := e.Run()
	if result.GetError() != nil {
		return 2
	}
	if qm {
		fmt.Printf("%s", result.GetQueryString())
	} else {
		fmt.Printf("%s", result.GetContent())
	}
	return 0
}
<commit_msg>Add --version flag for homebrew test<commit_after>package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/simeji/jid"
)

const VERSION = "0.6.2"

func main() {
	content := os.Stdin

	var qm bool
	var version bool
	qs := "."

	flag.BoolVar(&qm, "q", false, "Output query mode")
	flag.BoolVar(&version, "version", false, "print the version and exit")
	flag.Parse()

	if version {
		fmt.Println(fmt.Sprintf("jid version v%s", VERSION))
		os.Exit(0)
	}
	args := flag.Args()
	if len(args) > 0 {
		qs = args[0]
	}

	e, err := jid.NewEngine(content, qs)

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	os.Exit(run(e, qm))
}

func run(e jid.EngineInterface, qm bool) int {

	result := e.Run()
	if result.GetError() != nil {
		return 2
	}
	if qm {
		fmt.Printf("%s", result.GetQueryString())
	} else {
		fmt.Printf("%s", result.GetContent())
	}
	return 0
}
<|endoftext|>