<commit_before>// Copyright 2015 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"encoding/hex"
	"encoding/json"
	"flag"
	"fmt"
	fct "github.com/FactomProject/factoid"
	"github.com/FactomProject/factom"
	"io/ioutil"
	"net/http"
	"os"
	"regexp"
	"strconv"
)

var _ = hex.EncodeToString
var serverFct = "localhost:8089"

var badChar, _ = regexp.Compile("[^A-Za-z0-9_-]")

type Response struct {
	Response string
	Success  bool
}

func ValidateKey(key string) (msg string, valid bool) {
	if len(key) > fct.ADDRESS_LENGTH {
		return "Key is too long.  Keys must be less than 32 characters", false
	}
	if badChar.FindStringIndex(key) != nil {
		str := fmt.Sprintf("The key or name '%s' contains invalid characters.\n"+
			"Keys and names are restricted to alphanumeric characters,\n"+
			"minuses (dashes), and underscores", key)
		return str, false
	}
	return "", true
}

func getCmd(cmd string, cmderror string) {
	resp, err := http.Get(cmd)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	body, err := ioutil.ReadAll(resp.Body)

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	resp.Body.Close()

	b := new(Response)
	if err := json.Unmarshal(body, b); err != nil || !b.Success {
		fmt.Println(cmderror)
		fmt.Println("Command Failed: ", string(body))
		os.Exit(1)
	}
	fmt.Println(b.Response)
	return
}

func postCmd(cmd string) {
	resp, err := http.PostForm(cmd, nil)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	resp.Body.Close()

	b := new(Response)
	if err := json.Unmarshal(body, b); err != nil {
		fmt.Printf("Failed to parse the response from factomd: %s\n", body)
		os.Exit(1)
	}

	fmt.Println(b.Response)

	if !b.Success {
		os.Exit(1)
	}

	return
}

// Generates a new Address
func generateaddress(args []string) {

	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 2 {
		man("generatefactoidaddress")
		os.Exit(1)
	}

	var err error
	var Addr string
	switch args[0] {
	case "ec":
		Addr, err = factom.GenerateEntryCreditAddress(args[1])
	case "fct":
		Addr, err = factom.GenerateFactoidAddress(args[1])
	default:
		panic("Expected ec|fct name")
	}

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	fmt.Println(args[0], " = ", Addr)
	return

}

func getaddresses(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) > 0 {
		man("getaddresses")
		os.Exit(1)
	}

	str := fmt.Sprintf("http://%s/v1/factoid-get-addresses/", serverFct)
	getCmd(str, "Error printing addresses")

	return
}

func gettransactions(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) > 0 {
		man("transactions")
		os.Exit(1)
	}

	str := fmt.Sprintf("http://%s/v1/factoid-get-transactions/", serverFct)
	getCmd(str, "Error Getting Transactions")

	return
}

func fctnewtrans(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		fmt.Println("Missing Key")
		man("newtransaction")
		os.Exit(1)
	}
	msg, valid := ValidateKey(args[0])
	if !valid {
		fmt.Println(msg)
		os.Exit(1)
	}
	str := fmt.Sprintf("http://%s/v1/factoid-new-transaction/%s", serverFct, args[0])
	postCmd(str)

	return

}

func fctdeletetrans(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		fmt.Println("Missing Key")
		man("deletetransaction")
		os.Exit(1)
	}
	msg, valid := ValidateKey(args[0])
	if !valid {
		fmt.Println(msg)
		os.Exit(1)
	}
	str := fmt.Sprintf("http://%s/v1/factoid-delete-transaction/%s", serverFct, args[0])
	postCmd(str)

	return

}

func fctaddfee(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 2 {
		fmt.Println("Was expecting a transaction key, and an address used as an input to that transaction.")
		os.Exit(1)
	}

	msg, valid := ValidateKey(args[0])
	if !valid {
		fmt.Println(msg)
		os.Exit(1)
	}

	str := fmt.Sprintf("http://%s/v1/factoid-add-fee/?key=%s&name=%s",
		serverFct, args[0], args[1])
	postCmd(str)

	return
}

func fctaddinput(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 3 {
		fmt.Println("Expecting a 1) transaction key, 2) an Address or Address name, and 3) an amount.")
		os.Exit(1)
	}

	msg, valid := ValidateKey(args[0])
	if !valid {
		fmt.Println(msg)
		os.Exit(1)
	}

	amt, err := fct.ConvertFixedPoint(args[2])
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	ramt, err := strconv.ParseInt(amt, 10, 64)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	_, err = fct.ValidateAmounts(uint64(ramt))
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	str := fmt.Sprintf("http://%s/v1/factoid-add-input/?key=%s&name=%s&amount=%s",
		serverFct, args[0], args[1], amt)
	postCmd(str)

	return
}

func fctaddoutput(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 3 {
		fmt.Println("Expecting a 1) transaction key, 2) an Address or Address name, and 3) an amount.")
		os.Exit(1)
	}
	// localhost:8089/v1/factoid-add-input/?key=<key>&name=<name or address>&amount=<amount>

	msg, valid := ValidateKey(args[0])
	if !valid {
		fmt.Println(msg)
		os.Exit(1)
	}

	amt, err := fct.ConvertFixedPoint(args[2])
	if err != nil {
		fmt.Println("Invalid format for a number: ", args[2])
		man("addoutput")
		os.Exit(1)
	}

	ramt, err := strconv.ParseInt(amt, 10, 64)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	_, err = fct.ValidateAmounts(uint64(ramt))
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	str := fmt.Sprintf("http://%s/v1/factoid-add-output/?key=%s&name=%s&amount=%s",
		serverFct, args[0], args[1], amt)
	postCmd(str)

	return
}

func fctaddecoutput(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 3 {
		fmt.Println("Expecting a 1) transaction key, 2) an Address or Address name, and 3) an amount.")
		os.Exit(1)
	}
	// localhost:8089/v1/factoid-add-input/?key=<key>&name=<name or address>&amount=<amount>

	msg, valid := ValidateKey(args[0])
	if !valid {
		fmt.Println(msg)
		os.Exit(1)
	}

	amt, err := fct.ConvertFixedPoint(args[2])
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	ramt, err := strconv.ParseInt(amt, 10, 64)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	_, err = fct.ValidateAmounts(uint64(ramt))
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	str := fmt.Sprintf("http://%s/v1/factoid-add-ecoutput/?key=%s&name=%s&amount=%s",
		serverFct, args[0], args[1], amt)
	postCmd(str)

	return
}

func fctgetfee(args []string) {
	var getfeereq string
	if len(args)>1 {
		getfeereq = fmt.Sprintf("http://%s/v1/factoid-get-fee/?key=%s", serverFct,args[1])
	}else{
		getfeereq = fmt.Sprintf("http://%s/v1/factoid-get-fee/", serverFct)
	}

	resp, err := http.Get(getfeereq)

	if err != nil {
		fmt.Println("Command Failed Get")
		os.Exit(1)
	}
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("Failed to understand response from fctwallet")
		os.Exit(1)
	}
	resp.Body.Close()

	// We pull the fee.  If the fee isn't positive, or if we fail to marshal, then there is a failure
	type x struct{
		Response string
		Success  bool
	}

	b := new(x)
	if err := json.Unmarshal(body, b); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}else if !b.Success {
		fmt.Println(b.Response)
		os.Exit(1)
	}
	if len(args)<2 {
		fmt.Printf("Currently, Entry Credits are %s Factoids each\n",b.Response)
	}else{
		fmt.Printf("The fee due for this transaction is %s Factoids\n", b.Response)
	}
}

func fctsign(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		fmt.Println("Missing Key")
		os.Exit(1)
	}

	msg, valid := ValidateKey(args[0])
	if !valid {
		fmt.Println(msg)
		os.Exit(1)
	}

	str := fmt.Sprintf("http://%s/v1/factoid-sign-transaction/%s", serverFct, args[0])
	postCmd(str)

}

func fctsubmit(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		fmt.Println("Missing Key")
		os.Exit(1)
	}

	msg, valid := ValidateKey(args[0])
	if !valid {
		fmt.Println(msg)
		os.Exit(1)
	}

	s := struct{ Transaction string }{args[0]}

	jdata, err := json.Marshal(s)
	if err != nil {
		fmt.Println("Submitt failed")
		os.Exit(1)
	}

	str := fmt.Sprintf("http://%s/v1/factoid-submit/%s", serverFct, bytes.NewBuffer(jdata))
	postCmd(str)
}

func fctsetup(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		msg := "You must supply some random seed. For example (don't use this!)\n" +
			"  factom-cli setup 'woe!#in31!%234ng)%^&$%oeg%^&*^jp45694a;gmr@#t4 q34y'\n" +
			"would make a nice seed.  The more random the better.\n\n" +
			"Note that if you create an address before you call Setup, you must\n" +
			"use those address(s) as you access the fountians."

		fmt.Println(msg)
		os.Exit(1)
	}

	s := struct{ Transaction string }{args[0]}

	jdata, err := json.Marshal(s)
	if err != nil {
		fmt.Println("Submitt failed")
		os.Exit(1)
	}

	str := fmt.Sprintf("http://%s/v1/factoid-setup/%s", serverFct, bytes.NewBuffer(jdata))
	postCmd(str)
}
<commit_msg>Added address generation from private key. Go fmt.<commit_after>// Copyright 2015 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"encoding/hex"
	"encoding/json"
	"flag"
	"fmt"
	fct "github.com/FactomProject/factoid"
	"github.com/FactomProject/factom"
	"io/ioutil"
	"net/http"
	"os"
	"regexp"
	"strconv"
)

var _ = hex.EncodeToString
var serverFct = "localhost:8089"

var badChar, _ = regexp.Compile("[^A-Za-z0-9_-]")

type Response struct {
	Response string
	Success  bool
}

func ValidateKey(key string) (msg string, valid bool) {
	if len(key) > fct.ADDRESS_LENGTH {
		return "Key is too long.  Keys must be less than 32 characters", false
	}
	if badChar.FindStringIndex(key) != nil {
		str := fmt.Sprintf("The key or name '%s' contains invalid characters.\n"+
			"Keys and names are restricted to alphanumeric characters,\n"+
			"minuses (dashes), and underscores", key)
		return str, false
	}
	return "", true
}

func getCmd(cmd string, cmderror string) {
	resp, err := http.Get(cmd)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	body, err := ioutil.ReadAll(resp.Body)

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	resp.Body.Close()

	b := new(Response)
	if err := json.Unmarshal(body, b); err != nil || !b.Success {
		fmt.Println(cmderror)
		fmt.Println("Command Failed: ", string(body))
		os.Exit(1)
	}
	fmt.Println(b.Response)
	return
}

func postCmd(cmd string) {
	resp, err := http.PostForm(cmd, nil)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	resp.Body.Close()

	b := new(Response)
	if err := json.Unmarshal(body, b); err != nil {
		fmt.Printf("Failed to parse the response from factomd: %s\n", body)
		os.Exit(1)
	}

	fmt.Println(b.Response)

	if !b.Success {
		os.Exit(1)
	}

	return
}

// Generates a new Address
func generateaddress(args []string) {

	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 2 {
		man("generatefactoidaddress")
		os.Exit(1)
	}

	var err error
	var Addr string
	if len(args) == 2 {
		switch args[0] {
		case "ec":
			Addr, err = factom.GenerateEntryCreditAddress(args[1])
		case "fct":
			Addr, err = factom.GenerateFactoidAddress(args[1])
		default:
			panic("Expected ec|fct name")
		}
	} else {
		switch args[0] {
		case "ec":
			Addr, err = factom.GenerateEntryCreditAddressFromPrivateKey(args[1], args[2])
		case "fct":
			Addr, err = factom.GenerateFactoidAddressFromPrivateKey(args[1], args[2])
		default:
			panic("Expected ec|fct name")
		}
	}

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	fmt.Println(args[0], " = ", Addr)
	return

}

func getaddresses(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) > 0 {
		man("getaddresses")
		os.Exit(1)
	}

	str := fmt.Sprintf("http://%s/v1/factoid-get-addresses/", serverFct)
	getCmd(str, "Error printing addresses")

	return
}

func gettransactions(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) > 0 {
		man("transactions")
		os.Exit(1)
	}

	str := fmt.Sprintf("http://%s/v1/factoid-get-transactions/", serverFct)
	getCmd(str, "Error Getting Transactions")

	return
}

func fctnewtrans(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		fmt.Println("Missing Key")
		man("newtransaction")
		os.Exit(1)
	}
	msg, valid := ValidateKey(args[0])
	if !valid {
		fmt.Println(msg)
		os.Exit(1)
	}
	str := fmt.Sprintf("http://%s/v1/factoid-new-transaction/%s", serverFct, args[0])
	postCmd(str)

	return

}

func fctdeletetrans(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		fmt.Println("Missing Key")
		man("deletetransaction")
		os.Exit(1)
	}
	msg, valid := ValidateKey(args[0])
	if !valid {
		fmt.Println(msg)
		os.Exit(1)
	}
	str := fmt.Sprintf("http://%s/v1/factoid-delete-transaction/%s", serverFct, args[0])
	postCmd(str)

	return

}

func fctaddfee(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 2 {
		fmt.Println("Was expecting a transaction key, and an address used as an input to that transaction.")
		os.Exit(1)
	}

	msg, valid := ValidateKey(args[0])
	if !valid {
		fmt.Println(msg)
		os.Exit(1)
	}

	str := fmt.Sprintf("http://%s/v1/factoid-add-fee/?key=%s&name=%s",
		serverFct, args[0], args[1])
	postCmd(str)

	return
}

func fctaddinput(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 3 {
		fmt.Println("Expecting a 1) transaction key, 2) an Address or Address name, and 3) an amount.")
		os.Exit(1)
	}

	msg, valid := ValidateKey(args[0])
	if !valid {
		fmt.Println(msg)
		os.Exit(1)
	}

	amt, err := fct.ConvertFixedPoint(args[2])
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	ramt, err := strconv.ParseInt(amt, 10, 64)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	_, err = fct.ValidateAmounts(uint64(ramt))
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	str := fmt.Sprintf("http://%s/v1/factoid-add-input/?key=%s&name=%s&amount=%s",
		serverFct, args[0], args[1], amt)
	postCmd(str)

	return
}

func fctaddoutput(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 3 {
		fmt.Println("Expecting a 1) transaction key, 2) an Address or Address name, and 3) an amount.")
		os.Exit(1)
	}
	// localhost:8089/v1/factoid-add-input/?key=<key>&name=<name or address>&amount=<amount>

	msg, valid := ValidateKey(args[0])
	if !valid {
		fmt.Println(msg)
		os.Exit(1)
	}

	amt, err := fct.ConvertFixedPoint(args[2])
	if err != nil {
		fmt.Println("Invalid format for a number: ", args[2])
		man("addoutput")
		os.Exit(1)
	}

	ramt, err := strconv.ParseInt(amt, 10, 64)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	_, err = fct.ValidateAmounts(uint64(ramt))
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	str := fmt.Sprintf("http://%s/v1/factoid-add-output/?key=%s&name=%s&amount=%s",
		serverFct, args[0], args[1], amt)
	postCmd(str)

	return
}

func fctaddecoutput(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 3 {
		fmt.Println("Expecting a 1) transaction key, 2) an Address or Address name, and 3) an amount.")
		os.Exit(1)
	}
	// localhost:8089/v1/factoid-add-input/?key=<key>&name=<name or address>&amount=<amount>

	msg, valid := ValidateKey(args[0])
	if !valid {
		fmt.Println(msg)
		os.Exit(1)
	}

	amt, err := fct.ConvertFixedPoint(args[2])
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	ramt, err := strconv.ParseInt(amt, 10, 64)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	_, err = fct.ValidateAmounts(uint64(ramt))
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	str := fmt.Sprintf("http://%s/v1/factoid-add-ecoutput/?key=%s&name=%s&amount=%s",
		serverFct, args[0], args[1], amt)
	postCmd(str)

	return
}

func fctgetfee(args []string) {
	var getfeereq string
	if len(args) > 1 {
		getfeereq = fmt.Sprintf("http://%s/v1/factoid-get-fee/?key=%s", serverFct, args[1])
	} else {
		getfeereq = fmt.Sprintf("http://%s/v1/factoid-get-fee/", serverFct)
	}

	resp, err := http.Get(getfeereq)

	if err != nil {
		fmt.Println("Command Failed Get")
		os.Exit(1)
	}
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("Failed to understand response from fctwallet")
		os.Exit(1)
	}
	resp.Body.Close()

	// We pull the fee.  If the fee isn't positive, or if we fail to marshal, then there is a failure
	type x struct {
		Response string
		Success  bool
	}

	b := new(x)
	if err := json.Unmarshal(body, b); err != nil {
		fmt.Println(err)
		os.Exit(1)
	} else if !b.Success {
		fmt.Println(b.Response)
		os.Exit(1)
	}
	if len(args) < 2 {
		fmt.Printf("Currently, Entry Credits are %s Factoids each\n", b.Response)
	} else {
		fmt.Printf("The fee due for this transaction is %s Factoids\n", b.Response)
	}
}

func fctsign(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		fmt.Println("Missing Key")
		os.Exit(1)
	}

	msg, valid := ValidateKey(args[0])
	if !valid {
		fmt.Println(msg)
		os.Exit(1)
	}

	str := fmt.Sprintf("http://%s/v1/factoid-sign-transaction/%s", serverFct, args[0])
	postCmd(str)

}

func fctsubmit(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		fmt.Println("Missing Key")
		os.Exit(1)
	}

	msg, valid := ValidateKey(args[0])
	if !valid {
		fmt.Println(msg)
		os.Exit(1)
	}

	s := struct{ Transaction string }{args[0]}

	jdata, err := json.Marshal(s)
	if err != nil {
		fmt.Println("Submitt failed")
		os.Exit(1)
	}

	str := fmt.Sprintf("http://%s/v1/factoid-submit/%s", serverFct, bytes.NewBuffer(jdata))
	postCmd(str)
}

func fctsetup(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		msg := "You must supply some random seed. For example (don't use this!)\n" +
			"  factom-cli setup 'woe!#in31!%234ng)%^&$%oeg%^&*^jp45694a;gmr@#t4 q34y'\n" +
			"would make a nice seed.  The more random the better.\n\n" +
			"Note that if you create an address before you call Setup, you must\n" +
			"use those address(s) as you access the fountians."

		fmt.Println(msg)
		os.Exit(1)
	}

	s := struct{ Transaction string }{args[0]}

	jdata, err := json.Marshal(s)
	if err != nil {
		fmt.Println("Submitt failed")
		os.Exit(1)
	}

	str := fmt.Sprintf("http://%s/v1/factoid-setup/%s", serverFct, bytes.NewBuffer(jdata))
	postCmd(str)
}
<|endoftext|>


<commit_before>// package patree implements a simple http request multiplexer.
package patree

import (
	"net/http"
)

// params is a map of matched request parameters. For example, a request with
// url "/posts/2345" will have "post_id" key and "2345" value with pattern
// "/posts/<int:post_id>".
type params map[string]string

// contexts stores params for http requests.
var contexts = make(map[*http.Request]params)

// Param returns a mathced request parameter with the given key.
func Param(r *http.Request, key string) string {
	return contexts[r][key]
}

func createParams(p params, paramArray []string) params {
	if p == nil {
		p = make(params)
	}
	for i := len(paramArray) - 1; i >= 1; i -= 2 {
		p[paramArray[i-1]] = paramArray[i]
	}
	return p
}

// PatternTreeServeMux is an HTTP request multiplexer that does pattern matching.
type PatternTreeServeMux struct {
	rootEntry *Entry
	notfound  http.Handler
}

// New creates a new muxer
func New() *PatternTreeServeMux {
	entry := newStaticEntry("")
	entry.exec = entry.traverse
	return &PatternTreeServeMux{
		rootEntry: entry,
		notfound:  http.NotFoundHandler(),
	}
}

// NewWithPrefix create a new muxer with the given prefix pattern string.
func NewWithPrefix(pat string) *PatternTreeServeMux {
	entry := newStaticEntry(pat)
	return &PatternTreeServeMux{
		rootEntry: entry,
		notfound:  http.NotFoundHandler(),
	}
}

// ServeHTTP execute matched handler or execute notfound handler.
func (m *PatternTreeServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	h, paramArray := m.rootEntry.exec(r.Method, r.URL.Path)
	if h != nil {
		p := createParams(contexts[r], paramArray)
		contexts[r] = p
		defer delete(contexts, r)
		h.ServeHTTP(w, r)
	} else {
		m.notfound.ServeHTTP(w, r)
	}
}

// Handle a http.Handler with the given url pattern. panic with duplicate
// handler registration for a pattern.
func (m *PatternTreeServeMux) Handle(pat string, h http.Handler) {
	patterns, err := SplitPath(pat)
	if err != nil {
		panic(err)
	}
	leafEntry := m.rootEntry.MergePatterns(patterns)
	err = leafEntry.SetHandler(h)
	if err != nil {
		panic(err)
	}
}

// Handle the handler with the given http method and pattern. Panic with
// duplicate handler registration.
func (m *PatternTreeServeMux) HandleMethod(method, pat string, h http.Handler) {
	patterns, err := SplitPath(pat)
	if err != nil {
		panic(err)
	}
	leafEntry := m.rootEntry.MergePatterns(patterns)
	err = leafEntry.SetMethodHandler(method, h)
	if err != nil {
		panic(err)
	}
}

// Get registers the handler with the given pattern for "GET" and "HEAD" method.
func (m *PatternTreeServeMux) Get(pat string, h http.Handler) {
	m.HandleMethod("GET", pat, h)
	m.HandleMethod("HEAD", pat, h)
}

// Post registers the handler with the given pattern for "POST" method.
func (m *PatternTreeServeMux) Post(pat string, h http.Handler) {
	m.HandleMethod("POST", pat, h)
}

// Put registers the handler with the given pattern for "PUT" method.
func (m *PatternTreeServeMux) Put(pat string, h http.Handler) {
	m.HandleMethod("PUT", pat, h)
}

// Patch registers the handler with the given pattern for "PATCH" method.
func (m *PatternTreeServeMux) Patch(pat string, h http.Handler) {
	m.HandleMethod("PATCH", pat, h)
}

// Delete registers the handler with the give pattern for "DELETE" method.
func (m *PatternTreeServeMux) Delete(pat string, h http.Handler) {
	m.HandleMethod("DELETE", pat, h)
}

// Options registers the handler with the given pattern for "OPTIONS" method.
func (m *PatternTreeServeMux) Options(pat string, h http.Handler) {
	m.HandleMethod("OPTIONS", pat, h)
}

// NotFoundFunc registers fallback HandlerFunc in case no pattern matches.
func (m *PatternTreeServeMux) NotFoundFunc(f http.HandlerFunc) {
	m.NotFound(http.HandlerFunc(f))
}

// NotFound reigsters fallback Handler in case no pattern matches.
func (m *PatternTreeServeMux) NotFound(h http.Handler) {
	m.notfound = h
}
<commit_msg>add HandleFunc<commit_after>// package patree implements a simple http request multiplexer.
package patree

import (
	"net/http"
)

// params is a map of matched request parameters. For example, a request with
// url "/posts/2345" will have "post_id" key and "2345" value with pattern
// "/posts/<int:post_id>".
type params map[string]string

// contexts stores params for http requests.
var contexts = make(map[*http.Request]params)

// Param returns a mathced request parameter with the given key.
func Param(r *http.Request, key string) string {
	return contexts[r][key]
}

func createParams(p params, paramArray []string) params {
	if p == nil {
		p = make(params)
	}
	for i := len(paramArray) - 1; i >= 1; i -= 2 {
		p[paramArray[i-1]] = paramArray[i]
	}
	return p
}

// PatternTreeServeMux is an HTTP request multiplexer that does pattern matching.
type PatternTreeServeMux struct {
	rootEntry *Entry
	notfound  http.Handler
}

// New creates a new muxer
func New() *PatternTreeServeMux {
	entry := newStaticEntry("")
	entry.exec = entry.traverse
	return &PatternTreeServeMux{
		rootEntry: entry,
		notfound:  http.NotFoundHandler(),
	}
}

// NewWithPrefix create a new muxer with the given prefix pattern string.
func NewWithPrefix(pat string) *PatternTreeServeMux {
	entry := newStaticEntry(pat)
	return &PatternTreeServeMux{
		rootEntry: entry,
		notfound:  http.NotFoundHandler(),
	}
}

// ServeHTTP execute matched handler or execute notfound handler.
func (m *PatternTreeServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	h, paramArray := m.rootEntry.exec(r.Method, r.URL.Path)
	if h != nil {
		p := createParams(contexts[r], paramArray)
		contexts[r] = p
		defer delete(contexts, r)
		h.ServeHTTP(w, r)
	} else {
		m.notfound.ServeHTTP(w, r)
	}

// HandleFunc add a Handler
func (m *PatternTreeServeMux) HandleFunc(pat string, h http.HandlerFunc) {
	m.Handle(pat, h)
}

// Handle a http.Handler with the given url pattern. panic with duplicate
// handler registration for a pattern.
func (m *PatternTreeServeMux) Handle(pat string, h http.Handler) {
	patterns, err := SplitPath(pat)
	if err != nil {
		panic(err)
	}
	leafEntry := m.rootEntry.MergePatterns(patterns)
	err = leafEntry.SetHandler(h)
	if err != nil {
		panic(err)
	}
}

// Handle the handler with the given http method and pattern. Panic with
// duplicate handler registration.
func (m *PatternTreeServeMux) HandleMethod(method, pat string, h http.Handler) {
	patterns, err := SplitPath(pat)
	if err != nil {
		panic(err)
	}
	leafEntry := m.rootEntry.MergePatterns(patterns)
	err = leafEntry.SetMethodHandler(method, h)
	if err != nil {
		panic(err)
	}
}

// Get registers the handler with the given pattern for "GET" and "HEAD" method.
func (m *PatternTreeServeMux) Get(pat string, h http.Handler) {
	m.HandleMethod("GET", pat, h)
	m.HandleMethod("HEAD", pat, h)
}

// Post registers the handler with the given pattern for "POST" method.
func (m *PatternTreeServeMux) Post(pat string, h http.Handler) {
	m.HandleMethod("POST", pat, h)
}

// Put registers the handler with the given pattern for "PUT" method.
func (m *PatternTreeServeMux) Put(pat string, h http.Handler) {
	m.HandleMethod("PUT", pat, h)
}

// Patch registers the handler with the given pattern for "PATCH" method.
func (m *PatternTreeServeMux) Patch(pat string, h http.Handler) {
	m.HandleMethod("PATCH", pat, h)
}

// Delete registers the handler with the give pattern for "DELETE" method.
func (m *PatternTreeServeMux) Delete(pat string, h http.Handler) {
	m.HandleMethod("DELETE", pat, h)
}

// Options registers the handler with the given pattern for "OPTIONS" method.
func (m *PatternTreeServeMux) Options(pat string, h http.Handler) {
	m.HandleMethod("OPTIONS", pat, h)
}

// NotFoundFunc registers fallback HandlerFunc in case no pattern matches.
func (m *PatternTreeServeMux) NotFoundFunc(f http.HandlerFunc) {
	m.NotFound(http.HandlerFunc(f))
}

// NotFound reigsters fallback Handler in case no pattern matches.
func (m *PatternTreeServeMux) NotFound(h http.Handler) {
	m.notfound = h
}
<|endoftext|>


<commit_before>package sdl

import (
	"testing"
)

func TestGetBasePath(t *testing.T) {
	Do(func() {
		Init(INIT_EVERYTHING)
		path := GetBasePath()
		// pathetic, but a comparison to runtime.Caller() does not help here,
		// since this would return go's testing package
		if path == "" {
			t.Error("GetBasePath() did not return anything")
		}
		Quit()
	})
}

// Do not test GetPrefPath(), since SDL_GetPrefPath() also
// *creates* the necessary directories, polluting the user's
// system with unnecessary stuff.
// func TestGetPrefPath(t *testing.T) {
// 	path := GetPrefPath("go-sdl2", "test")
// 	t.Error(path)
// }
<commit_msg>sdl: filesystem_test.go: Run TestGetBasePath only on SDL >= 2.0.1<commit_after>package sdl

import (
	"testing"
)

func TestGetBasePath(t *testing.T) {
	if !VERSION_ATLEAST(2,0,1) {
		return
	}

	Do(func() {
		Init(INIT_EVERYTHING)
		path := GetBasePath()
		// pathetic, but a comparison to runtime.Caller() does not help here,
		// since this would return go's testing package
		if path == "" {
			t.Error("GetBasePath() did not return anything")
		}
		Quit()
	})
}

// Do not test GetPrefPath(), since SDL_GetPrefPath() also
// *creates* the necessary directories, polluting the user's
// system with unnecessary stuff.
// func TestGetPrefPath(t *testing.T) {
// 	path := GetPrefPath("go-sdl2", "test")
// 	t.Error(path)
// }
<|endoftext|>


<commit_before>package rel

import (
	"fmt"
	"testing"
)

func TestSelectManagerJoinSources(t *testing.T) {
	t.Skip("TestSelectManagerJoinSources not implemented")
}

func TestSelectManagerSkip(t *testing.T) {
	table := NewTable("users")
	manager := table.From(table)
	sql := manager.Skip(10).ToSql()
	if sql != "SELECT FROM \"users\" OFFSET 10" {
		t.Fail()
	}
}

func TestSelectManagerClone(t *testing.T) {
	t.Skip("TestSelectManagerClone not implemented")
}

func TestSelectManagerExists(t *testing.T) {
	table := NewTable("users")
	manager := table.From(table)
	manager.Project(Sql("*"))
	m2 := NewSelectManager(TableEngine, nil)
	m2.Project(manager.Exists())
	sql := m2.ToSql()
	expected := fmt.Sprintf("SELECT EXISTS (%s)", manager.ToSql())
	if sql != expected {
		t.Logf("TestSelectManagerExists sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerExistsAs(t *testing.T) {
	table := NewTable("users")
	manager := table.From(table)
	manager.Project(Sql("*"))
	m2 := NewSelectManager(TableEngine, nil)
	m2.Project(manager.Exists().As(Sql("foo")))
	sql := m2.ToSql()
	expected := fmt.Sprintf("SELECT EXISTS (%s) AS foo", manager.ToSql())
	if sql != expected {
		t.Logf("TestSelectManagerExists sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerOffset(t *testing.T) {
	table := NewTable("users")
	manager := table.From(table)
	sql := manager.Offset(10).ToSql()
	expected := "SELECT FROM \"users\" OFFSET 10"
	if sql != expected {
		t.Fail()
	}
}

func TestSelectManagerUnion(t *testing.T) {
	table := NewTable("users")
	m1 := NewSelectManager(TableEngine, table)
	m1.Project(Star())
	m1.Where(table.Attr("age").Lt(18))
	m2 := NewSelectManager(TableEngine, table)
	m2.Project(Star())
	m2.Where(table.Attr("age").Gt(99))
	mgr := m1.Union(m1.Ast, m2.Ast)
	sql := mgr.ToSql()
	expected := "( SELECT * FROM \"users\" WHERE \"users\".\"age\" < 18 UNION SELECT * FROM \"users\" WHERE \"users\".\"age\" > 99 )"
	if sql != expected {
		t.Logf("TestSelectManagerUnion sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerUnionAll(t *testing.T) {
	table := NewTable("users")
	m1 := NewSelectManager(TableEngine, table)
	m1.Project(Star())
	m1.Where(table.Attr("age").Lt(18))
	m2 := NewSelectManager(TableEngine, table)
	m2.Project(Star())
	m2.Where(table.Attr("age").Gt(99))
	mgr := m1.UnionAll(m1.Ast, m2.Ast)
	sql := mgr.ToSql()
	expected := "( SELECT * FROM \"users\" WHERE \"users\".\"age\" < 18 UNION ALL SELECT * FROM \"users\" WHERE \"users\".\"age\" > 99 )"
	if sql != expected {
		t.Logf("TestSelectManagerUnionAll sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerIntersect(t *testing.T) {
	table := NewTable("users")
	m1 := NewSelectManager(TableEngine, table)
	m1.Project(Star())
	m1.Where(table.Attr("age").Lt(18))
	m2 := NewSelectManager(TableEngine, table)
	m2.Project(Star())
	m2.Where(table.Attr("age").Gt(99))
	mgr := m1.Intersect(m1.Ast, m2.Ast)
	sql := mgr.ToSql()
	expected := "( SELECT * FROM \"users\" WHERE \"users\".\"age\" < 18 INTERSECT SELECT * FROM \"users\" WHERE \"users\".\"age\" > 99 )"
	if sql != expected {
		t.Logf("TestSelectManagerUnionAll sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerExcept(t *testing.T) {
	table := NewTable("users")
	m1 := NewSelectManager(TableEngine, table)
	m1.Project(Star())
	m1.Where(table.Attr("age").Lt(99))
	m2 := NewSelectManager(TableEngine, table)
	m2.Project(Star())
	m2.Where(table.Attr("age").Lt(50))
	mgr := m1.Except(m1.Ast, m2.Ast)
	sql := mgr.ToSql()
	expected := "( SELECT * FROM \"users\" WHERE \"users\".\"age\" < 99 EXCEPT SELECT * FROM \"users\" WHERE \"users\".\"age\" < 50 )"
	if sql != expected {
		t.Logf("TestSelectManagerExcept sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerJoin(t *testing.T) {
	left := NewTable("users")
	right := left.Alias()
	predicate := left.Attr("id").Eq(right.Attr("id"))
	mgr := left.Select(Star()).Join(right).On(predicate)
	sql := mgr.ToSql()
	expected := "SELECT * FROM \"users\" INNER JOIN \"users\" \"users_2\" ON \"users\".\"id\" = \"users_2\".\"id\""
	if sql != expected {
		t.Logf("TestSelectManagerJoin sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerOrder(t *testing.T) {
	table := NewTable("users")
	mgr := table.Select(Star())
	mgr.Order(table.Attr("id"))
	sql := mgr.ToSql()
	expected := "SELECT * FROM \"users\" ORDER BY \"users\".\"id\""
	if sql != expected {
		t.Logf("TestSelectManagerOrder sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerOrderWithDirection(t *testing.T) {
	table := NewTable("users")
	mgr := table.Select(Star())
	mgr.Order(table.Attr("id").Desc())
	sql := mgr.ToSql()
	expected := "SELECT * FROM \"users\" ORDER BY \"users\".\"id\" DESC"
	if sql != expected {
		t.Logf("TestSelectManagerOrderWithDirection sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerOnWithMultipleArguments(t *testing.T) {
	left := NewTable("users")
	right := left.Alias()
	predicate := left.Attr("id").Eq(right.Attr("id"))
	mgr := left.From(left)
	mgr.Join(right).On(predicate, predicate)
	sql := mgr.ToSql()
	expected := "SELECT FROM \"users\" INNER JOIN \"users\" \"users_2\" ON \"users\".\"id\" = \"users_2\".\"id\" AND \"users\".\"id\" = \"users_2\".\"id\""
	if sql != expected {
		t.Logf("TestSelectManagerOnWithMultipleArguments sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerOrderWithAttributesForExpressions(t *testing.T) {
	table := NewTable("users")
	mgr := table.Select(Star())
	mgr.Order(table.Attr("id").Count().Desc())
	sql := mgr.ToSql()
	expected := "SELECT * FROM \"users\" ORDER BY COUNT(\"users\".\"id\") DESC"
	if sql != expected {
		t.Logf("TestSelectManagerOrderWithAttributesForExpressions sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerLock(t *testing.T) {
	table := NewTable("users")
	mgr := table.From(table)
	sql := mgr.Lock().ToSql()
	expected := "SELECT FROM \"users\" FOR UPDATE"
	if sql != expected {
		t.Logf("TestSelectManagerLock sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerGroup(t *testing.T) {
	users := NewTable("users")
	mgr := users.Group(users.Attr("id"))
	sql := mgr.ToSql()
	expected := "SELECT FROM \"users\" GROUP BY \"users\".\"id\""
	if sql != expected {
		t.Logf("TestSelectManagerGroup sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerWindowEmpty(t *testing.T) {
	users := NewTable("users")
	mgr := users.From(users)
	mgr.Window(Sql("a_window"))
	sql := mgr.ToSql()
	expected := "SELECT FROM \"users\" WINDOW \"a_window\" AS ()"
	if sql != expected {
		t.Logf("TestSelectManagerWindowEmpty sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerWindowWithOrders(t *testing.T) {
	users := NewTable("users")
	mgr := users.From(users)
	mgr.Window(Sql("a_window")).Order(users.Attr("foo").Asc())
	sql := mgr.ToSql()
	expected := "SELECT FROM \"users\" WINDOW \"a_window\" AS (ORDER BY \"users\".\"foo\" ASC)"
	if sql != expected {
		t.Logf("TestSelectManagerWindowWithOrders sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerWindowWithUnboundedPreceding(t *testing.T) {
	users := NewTable("users")
	mgr := users.From(users)
	mgr.Window(Sql("a_window")).Rows(&PrecedingNode{})
	sql := mgr.ToSql()
	expected := "SELECT FROM \"users\" WINDOW \"a_window\" AS (ROWS UNBOUNDED PRECEDING)"
	if sql != expected {
		t.Logf("TestSelectManagerWindowWithUnboundedPreceding sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerWindowWithBoundedPreceding(t *testing.T) {
	users := NewTable("users")
	mgr := users.From(users)
	mgr.Window(Sql("a_window")).Rows(&PrecedingNode{Expr: Sql(5)})
	sql := mgr.ToSql()
	expected := "SELECT FROM \"users\" WINDOW \"a_window\" AS (ROWS 5 PRECEDING)"
	if sql != expected {
		t.Logf("TestSelectManagerWindowWithBoundedPreceding sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerJoinMultipleTables(t *testing.T) {
	users := NewTable("users")
	comments := NewTable("comments")
	counts := comments.From(comments).Group(comments.Attr("user_id")).Project(
		comments.Attr("user_id").As(Sql("user_id")),
		comments.Attr("user_id").Count().As(Sql("count")),
	).As(Sql("counts"))
	mgr := users.Join(counts).On(counts.Attr("user_id").Eq(Sql(10)))
	sql := mgr.ToSql()
	expected := "SELECT FROM \"users\" INNER JOIN (SELECT \"comments\".\"user_id\" AS user_id, COUNT(\"comments\".\"user_id\") AS count FROM \"comments\" GROUP BY \"comments\".\"user_id\") counts ON counts.\"user_id\" = 10"
	if sql != expected {
		t.Logf("TestSelectManagerJoinMultipleTables sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}
<commit_msg>Create test for window with unbounded following<commit_after>package rel

import (
	"fmt"
	"testing"
)

func TestSelectManagerJoinSources(t *testing.T) {
	t.Skip("TestSelectManagerJoinSources not implemented")
}

func TestSelectManagerSkip(t *testing.T) {
	table := NewTable("users")
	manager := table.From(table)
	sql := manager.Skip(10).ToSql()
	if sql != "SELECT FROM \"users\" OFFSET 10" {
		t.Fail()
	}
}

func TestSelectManagerClone(t *testing.T) {
	t.Skip("TestSelectManagerClone not implemented")
}

func TestSelectManagerExists(t *testing.T) {
	table := NewTable("users")
	manager := table.From(table)
	manager.Project(Sql("*"))
	m2 := NewSelectManager(TableEngine, nil)
	m2.Project(manager.Exists())
	sql := m2.ToSql()
	expected := fmt.Sprintf("SELECT EXISTS (%s)", manager.ToSql())
	if sql != expected {
		t.Logf("TestSelectManagerExists sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerExistsAs(t *testing.T) {
	table := NewTable("users")
	manager := table.From(table)
	manager.Project(Sql("*"))
	m2 := NewSelectManager(TableEngine, nil)
	m2.Project(manager.Exists().As(Sql("foo")))
	sql := m2.ToSql()
	expected := fmt.Sprintf("SELECT EXISTS (%s) AS foo", manager.ToSql())
	if sql != expected {
		t.Logf("TestSelectManagerExists sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerOffset(t *testing.T) {
	table := NewTable("users")
	manager := table.From(table)
	sql := manager.Offset(10).ToSql()
	expected := "SELECT FROM \"users\" OFFSET 10"
	if sql != expected {
		t.Fail()
	}
}

func TestSelectManagerUnion(t *testing.T) {
	table := NewTable("users")
	m1 := NewSelectManager(TableEngine, table)
	m1.Project(Star())
	m1.Where(table.Attr("age").Lt(18))
	m2 := NewSelectManager(TableEngine, table)
	m2.Project(Star())
	m2.Where(table.Attr("age").Gt(99))
	mgr := m1.Union(m1.Ast, m2.Ast)
	sql := mgr.ToSql()
	expected := "( SELECT * FROM \"users\" WHERE \"users\".\"age\" < 18 UNION SELECT * FROM \"users\" WHERE \"users\".\"age\" > 99 )"
	if sql != expected {
		t.Logf("TestSelectManagerUnion sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerUnionAll(t *testing.T) {
	table := NewTable("users")
	m1 := NewSelectManager(TableEngine, table)
	m1.Project(Star())
	m1.Where(table.Attr("age").Lt(18))
	m2 := NewSelectManager(TableEngine, table)
	m2.Project(Star())
	m2.Where(table.Attr("age").Gt(99))
	mgr := m1.UnionAll(m1.Ast, m2.Ast)
	sql := mgr.ToSql()
	expected := "( SELECT * FROM \"users\" WHERE \"users\".\"age\" < 18 UNION ALL SELECT * FROM \"users\" WHERE \"users\".\"age\" > 99 )"
	if sql != expected {
		t.Logf("TestSelectManagerUnionAll sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerIntersect(t *testing.T) {
	table := NewTable("users")
	m1 := NewSelectManager(TableEngine, table)
	m1.Project(Star())
	m1.Where(table.Attr("age").Lt(18))
	m2 := NewSelectManager(TableEngine, table)
	m2.Project(Star())
	m2.Where(table.Attr("age").Gt(99))
	mgr := m1.Intersect(m1.Ast, m2.Ast)
	sql := mgr.ToSql()
	expected := "( SELECT * FROM \"users\" WHERE \"users\".\"age\" < 18 INTERSECT SELECT * FROM \"users\" WHERE \"users\".\"age\" > 99 )"
	if sql != expected {
		t.Logf("TestSelectManagerUnionAll sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerExcept(t *testing.T) {
	table := NewTable("users")
	m1 := NewSelectManager(TableEngine, table)
	m1.Project(Star())
	m1.Where(table.Attr("age").Lt(99))
	m2 := NewSelectManager(TableEngine, table)
	m2.Project(Star())
	m2.Where(table.Attr("age").Lt(50))
	mgr := m1.Except(m1.Ast, m2.Ast)
	sql := mgr.ToSql()
	expected := "( SELECT * FROM \"users\" WHERE \"users\".\"age\" < 99 EXCEPT SELECT * FROM \"users\" WHERE \"users\".\"age\" < 50 )"
	if sql != expected {
		t.Logf("TestSelectManagerExcept sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerJoin(t *testing.T) {
	left := NewTable("users")
	right := left.Alias()
	predicate := left.Attr("id").Eq(right.Attr("id"))
	mgr := left.Select(Star()).Join(right).On(predicate)
	sql := mgr.ToSql()
	expected := "SELECT * FROM \"users\" INNER JOIN \"users\" \"users_2\" ON \"users\".\"id\" = \"users_2\".\"id\""
	if sql != expected {
		t.Logf("TestSelectManagerJoin sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerOrder(t *testing.T) {
	table := NewTable("users")
	mgr := table.Select(Star())
	mgr.Order(table.Attr("id"))
	sql := mgr.ToSql()
	expected := "SELECT * FROM \"users\" ORDER BY \"users\".\"id\""
	if sql != expected {
		t.Logf("TestSelectManagerOrder sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerOrderWithDirection(t *testing.T) {
	table := NewTable("users")
	mgr := table.Select(Star())
	mgr.Order(table.Attr("id").Desc())
	sql := mgr.ToSql()
	expected := "SELECT * FROM \"users\" ORDER BY \"users\".\"id\" DESC"
	if sql != expected {
		t.Logf("TestSelectManagerOrderWithDirection sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerOnWithMultipleArguments(t *testing.T) {
	left := NewTable("users")
	right := left.Alias()
	predicate := left.Attr("id").Eq(right.Attr("id"))
	mgr := left.From(left)
	mgr.Join(right).On(predicate, predicate)
	sql := mgr.ToSql()
	expected := "SELECT FROM \"users\" INNER JOIN \"users\" \"users_2\" ON \"users\".\"id\" = \"users_2\".\"id\" AND \"users\".\"id\" = \"users_2\".\"id\""
	if sql != expected {
		t.Logf("TestSelectManagerOnWithMultipleArguments sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerOrderWithAttributesForExpressions(t *testing.T) {
	table := NewTable("users")
	mgr := table.Select(Star())
	mgr.Order(table.Attr("id").Count().Desc())
	sql := mgr.ToSql()
	expected := "SELECT * FROM \"users\" ORDER BY COUNT(\"users\".\"id\") DESC"
	if sql != expected {
		t.Logf("TestSelectManagerOrderWithAttributesForExpressions sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerLock(t *testing.T) {
	table := NewTable("users")
	mgr := table.From(table)
	sql := mgr.Lock().ToSql()
	expected := "SELECT FROM \"users\" FOR UPDATE"
	if sql != expected {
		t.Logf("TestSelectManagerLock sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerGroup(t *testing.T) {
	users := NewTable("users")
	mgr := users.Group(users.Attr("id"))
	sql := mgr.ToSql()
	expected := "SELECT FROM \"users\" GROUP BY \"users\".\"id\""
	if sql != expected {
		t.Logf("TestSelectManagerGroup sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerWindowEmpty(t *testing.T) {
	users := NewTable("users")
	mgr := users.From(users)
	mgr.Window(Sql("a_window"))
	sql := mgr.ToSql()
	expected := "SELECT FROM \"users\" WINDOW \"a_window\" AS ()"
	if sql != expected {
		t.Logf("TestSelectManagerWindowEmpty sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerWindowWithOrders(t *testing.T) {
	users := NewTable("users")
	mgr := users.From(users)
	mgr.Window(Sql("a_window")).Order(users.Attr("foo").Asc())
	sql := mgr.ToSql()
	expected := "SELECT FROM \"users\" WINDOW \"a_window\" AS (ORDER BY \"users\".\"foo\" ASC)"
	if sql != expected {
		t.Logf("TestSelectManagerWindowWithOrders sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerWindowWithUnboundedPreceding(t *testing.T) {
	users := NewTable("users")
	mgr := users.From(users)
	mgr.Window(Sql("a_window")).Rows(&PrecedingNode{})
	sql := mgr.ToSql()
	expected := "SELECT FROM \"users\" WINDOW \"a_window\" AS (ROWS UNBOUNDED PRECEDING)"
	if sql != expected {
		t.Logf("TestSelectManagerWindowWithUnboundedPreceding sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerWindowWithBoundedPreceding(t *testing.T) {
	users := NewTable("users")
	mgr := users.From(users)
	mgr.Window(Sql("a_window")).Rows(&PrecedingNode{Expr: Sql(5)})
	sql := mgr.ToSql()
	expected := "SELECT FROM \"users\" WINDOW \"a_window\" AS (ROWS 5 PRECEDING)"
	if sql != expected {
		t.Logf("TestSelectManagerWindowWithBoundedPreceding sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerWindowWithUnboundedFollowing(t *testing.T) {
	users := NewTable("users")
	mgr := users.From(users)
	mgr.Window(Sql("a_window")).Rows(&FollowingNode{})
	sql := mgr.ToSql()
	expected := "SELECT FROM \"users\" WINDOW \"a_window\" AS (ROWS UNBOUNDED FOLLOWING)"
	if sql != expected {
		t.Logf("TestSelectManagerWindowWithUnboundedPreceding sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}

func TestSelectManagerJoinMultipleTables(t *testing.T) {
	users := NewTable("users")
	comments := NewTable("comments")
	counts := comments.From(comments).Group(comments.Attr("user_id")).Project(
		comments.Attr("user_id").As(Sql("user_id")),
		comments.Attr("user_id").Count().As(Sql("count")),
	).As(Sql("counts"))
	mgr := users.Join(counts).On(counts.Attr("user_id").Eq(Sql(10)))
	sql := mgr.ToSql()
	expected := "SELECT FROM \"users\" INNER JOIN (SELECT \"comments\".\"user_id\" AS user_id, COUNT(\"comments\".\"user_id\") AS count FROM \"comments\" GROUP BY \"comments\".\"user_id\") counts ON counts.\"user_id\" = 10"
	if sql != expected {
		t.Logf("TestSelectManagerJoinMultipleTables sql: \n%s != \n%s", sql, expected)
		t.Fail()
	}
}
<|endoftext|>


<commit_before>package types

import (
	"os"
	"time"

	"github.com/docker/engine-api/types/container"
	"github.com/docker/engine-api/types/network"
	"github.com/docker/engine-api/types/registry"
	"github.com/docker/go-connections/nat"
)

// ContainerCreateResponse contains the information returned to a client on the
// creation of a new container.
type ContainerCreateResponse struct {
	// ID is the ID of the created container.
	ID string `json:"Id"`

	// Warnings are any warnings encountered during the creation of the container.
	Warnings []string `json:"Warnings"`
}

// ContainerExecCreateResponse contains response of Remote API:
// POST "/containers/{name:.*}/exec"
type ContainerExecCreateResponse struct {
	// ID is the exec ID.
	ID string `json:"Id"`
}

// ContainerUpdateResponse contains response of Remote API:
// POST /containers/{name:.*}/update
type ContainerUpdateResponse struct {
	// Warnings are any warnings encountered during the updating of the container.
	Warnings []string `json:"Warnings"`
}

// AuthResponse contains response of Remote API:
// POST "/auth"
type AuthResponse struct {
	// Status is the authentication status
	Status string `json:"Status"`

	// IdentityToken is an opaque token used for authenticating
	// a user after a successful login.
	IdentityToken string `json:"IdentityToken,omitempty"`
}

// ContainerWaitResponse contains response of Remote API:
// POST "/containers/"+containerID+"/wait"
type ContainerWaitResponse struct {
	// StatusCode is the status code of the wait job
	StatusCode int `json:"StatusCode"`
}

// ContainerCommitResponse contains response of Remote API:
// POST "/commit?container="+containerID
type ContainerCommitResponse struct {
	ID string `json:"Id"`
}

// ContainerChange contains response of Remote API:
// GET "/containers/{name:.*}/changes"
type ContainerChange struct {
	Kind int
	Path string
}

// ImageHistory contains response of Remote API:
// GET "/images/{name:.*}/history"
type ImageHistory struct {
	ID        string `json:"Id"`
	Created   int64
	CreatedBy string
	Tags      []string
	Size      int64
	Comment   string
}

// ImageDelete contains response of Remote API:
// DELETE "/images/{name:.*}"
type ImageDelete struct {
	Untagged string `json:",omitempty"`
	Deleted  string `json:",omitempty"`
}

// Image contains response of Remote API:
// GET "/images/json"
type Image struct {
	ID          string `json:"Id"`
	ParentID    string `json:"ParentId"`
	RepoTags    []string
	RepoDigests []string
	Created     int64
	Size        int64
	VirtualSize int64
	Labels      map[string]string
}

// GraphDriverData returns Image's graph driver config info
// when calling inspect command
type GraphDriverData struct {
	Name string
	Data map[string]string
}

// ImageInspect contains response of Remote API:
// GET "/images/{name:.*}/json"
type ImageInspect struct {
	ID              string `json:"Id"`
	RepoTags        []string
	RepoDigests     []string
	Parent          string
	Comment         string
	Created         string
	Container       string
	ContainerConfig *container.Config
	DockerVersion   string
	Author          string
	Config          *container.Config
	Architecture    string
	Os              string
	Size            int64
	VirtualSize     int64
	GraphDriver     GraphDriverData
}

// Port stores open ports info of container
// e.g. {"PrivatePort": 8080, "PublicPort": 80, "Type": "tcp"}
type Port struct {
	IP          string `json:",omitempty"`
	PrivatePort int
	PublicPort  int `json:",omitempty"`
	Type        string
}

// Container contains response of Remote API:
// GET  "/containers/json"
type Container struct {
	ID         string `json:"Id"`
	Names      []string
	Image      string
	ImageID    string
	Command    string
	Created    int64
	Ports      []Port
	SizeRw     int64 `json:",omitempty"`
	SizeRootFs int64 `json:",omitempty"`
	Labels     map[string]string
	State      string
	Status     string
	HostConfig struct {
		NetworkMode string `json:",omitempty"`
	}
	NetworkSettings *SummaryNetworkSettings
	Mounts          []MountPoint
}

// CopyConfig contains request body of Remote API:
// POST "/containers/"+containerID+"/copy"
type CopyConfig struct {
	Resource string
}

// ContainerPathStat is used to encode the header from
// GET "/containers/{name:.*}/archive"
// "Name" is the file or directory name.
type ContainerPathStat struct {
	Name       string      `json:"name"`
	Size       int64       `json:"size"`
	Mode       os.FileMode `json:"mode"`
	Mtime      time.Time   `json:"mtime"`
	LinkTarget string      `json:"linkTarget"`
}

// ContainerProcessList contains response of Remote API:
// GET "/containers/{name:.*}/top"
type ContainerProcessList struct {
	Processes [][]string
	Titles    []string
}

// Version contains response of Remote API:
// GET "/version"
type Version struct {
	Version       string
	APIVersion    string `json:"ApiVersion"`
	GitCommit     string
	GoVersion     string
	Os            string
	Arch          string
	KernelVersion string `json:",omitempty"`
	Experimental  bool   `json:",omitempty"`
	BuildTime     string `json:",omitempty"`
}

// Info contains response of Remote API:
// GET "/info"
type Info struct {
	ID                 string
	Containers         int
	ContainersRunning  int
	ContainersPaused   int
	ContainersStopped  int
	Images             int
	Driver             string
	DriverStatus       [][2]string
	SystemStatus       [][2]string
	Plugins            PluginsInfo
	MemoryLimit        bool
	SwapLimit          bool
	KernelMemory       bool
	CPUCfsPeriod       bool `json:"CpuCfsPeriod"`
	CPUCfsQuota        bool `json:"CpuCfsQuota"`
	CPUShares          bool
	CPUSet             bool
	IPv4Forwarding     bool
	BridgeNfIptables   bool
	BridgeNfIP6tables  bool `json:"BridgeNfIp6tables"`
	Debug              bool
	NFd                int
	OomKillDisable     bool
	NGoroutines        int
	SystemTime         string
	ExecutionDriver    string
	LoggingDriver      string
	CgroupDriver       string
	NEventsListener    int
	KernelVersion      string
	OperatingSystem    string
	OSType             string
	Architecture       string
	IndexServerAddress string
	RegistryConfig     *registry.ServiceConfig
	NCPU               int
	MemTotal           int64
	DockerRootDir      string
	HTTPProxy          string `json:"HttpProxy"`
	HTTPSProxy         string `json:"HttpsProxy"`
	NoProxy            string
	Name               string
	Labels             []string
	ExperimentalBuild  bool
	ServerVersion      string
	ClusterStore       string
	ClusterAdvertise   string
}

// PluginsInfo is a temp struct holding Plugins name
// registered with docker daemon. It is used by Info struct
type PluginsInfo struct {
	// List of Volume plugins registered
	Volume []string
	// List of Network plugins registered
	Network []string
	// List of Authorization plugins registered
	Authorization []string
}

// ExecStartCheck is a temp struct used by execStart
// Config fields is part of ExecConfig in runconfig package
type ExecStartCheck struct {
	// ExecStart will first check if it's detached
	Detach bool
	// Check if there's a tty
	Tty bool
}

// ContainerState stores container's running state
// it's part of ContainerJSONBase and will return by "inspect" command
type ContainerState struct {
	Status     string
	Running    bool
	Paused     bool
	Restarting bool
	OOMKilled  bool
	Dead       bool
	Pid        int
	ExitCode   int
	Error      string
	StartedAt  string
	FinishedAt string
}

// ContainerJSONBase contains response of Remote API:
// GET "/containers/{name:.*}/json"
type ContainerJSONBase struct {
	ID              string `json:"Id"`
	Created         string
	Path            string
	Args            []string
	State           *ContainerState
	Image           string
	ResolvConfPath  string
	HostnamePath    string
	HostsPath       string
	LogPath         string
	Name            string
	RestartCount    int
	Driver          string
	MountLabel      string
	ProcessLabel    string
	AppArmorProfile string
	ExecIDs         []string
	HostConfig      *container.HostConfig
	GraphDriver     GraphDriverData
	SizeRw          *int64 `json:",omitempty"`
	SizeRootFs      *int64 `json:",omitempty"`
}

// ContainerJSON is newly used struct along with MountPoint
type ContainerJSON struct {
	*ContainerJSONBase
	Mounts          []MountPoint
	Config          *container.Config
	NetworkSettings *NetworkSettings
}

// NetworkSettings exposes the network settings in the api
type NetworkSettings struct {
	NetworkSettingsBase
	DefaultNetworkSettings
	Networks map[string]*network.EndpointSettings
}

// SummaryNetworkSettings provides a summary of container's networks
// in /containers/json
type SummaryNetworkSettings struct {
	Networks map[string]*network.EndpointSettings
}

// NetworkSettingsBase holds basic information about networks
type NetworkSettingsBase struct {
	Bridge                 string
	SandboxID              string
	HairpinMode            bool
	LinkLocalIPv6Address   string
	LinkLocalIPv6PrefixLen int
	Ports                  nat.PortMap
	SandboxKey             string
	SecondaryIPAddresses   []network.Address
	SecondaryIPv6Addresses []network.Address
}

// DefaultNetworkSettings holds network information
// during the 2 release deprecation period.
// It will be removed in Docker 1.11.
type DefaultNetworkSettings struct {
	EndpointID          string
	Gateway             string
	GlobalIPv6Address   string
	GlobalIPv6PrefixLen int
	IPAddress           string
	IPPrefixLen         int
	IPv6Gateway         string
	MacAddress          string
}

// MountPoint represents a mount point configuration inside the container.
type MountPoint struct {
	Name        string `json:",omitempty"`
	Source      string
	Destination string
	Driver      string `json:",omitempty"`
	Mode        string
	RW          bool
	Propagation string
}

// Volume represents the configuration of a volume for the remote API
type Volume struct {
	Name       string // Name is the name of the volume
	Driver     string // Driver is the Driver name used to create the volume
	Mountpoint string // Mountpoint is the location on disk of the volume
}

// VolumesListResponse contains the response for the remote API:
// GET "/volumes"
type VolumesListResponse struct {
	Volumes  []*Volume // Volumes is the list of volumes being returned
	Warnings []string  // Warnings is a list of warnings that occurred when getting the list from the volume drivers
}

// VolumeCreateRequest contains the response for the remote API:
// POST "/volumes/create"
type VolumeCreateRequest struct {
	Name       string            // Name is the requested name of the volume
	Driver     string            // Driver is the name of the driver that should be used to create the volume
	DriverOpts map[string]string // DriverOpts holds the driver specific options to use for when creating the volume.
}

// NetworkResource is the body of the "get network" http response message
type NetworkResource struct {
	Name       string
	ID         string `json:"Id"`
	Scope      string
	Driver     string
	EnableIPv6 bool
	IPAM       network.IPAM
	Internal   bool
	Containers map[string]EndpointResource
	Options    map[string]string
}

// EndpointResource contains network resources allocated and used for a container in a network
type EndpointResource struct {
	Name        string
	EndpointID  string
	MacAddress  string
	IPv4Address string
	IPv6Address string
}

// NetworkCreate is the expected body of the "create network" http request message
type NetworkCreate struct {
	Name           string
	CheckDuplicate bool
	Driver         string
	EnableIPv6     bool
	IPAM           network.IPAM
	Internal       bool
	Options        map[string]string
}

// NetworkCreateResponse is the response message sent by the server for network create call
type NetworkCreateResponse struct {
	ID      string `json:"Id"`
	Warning string
}

// NetworkConnect represents the data to be used to connect a container to the network
type NetworkConnect struct {
	Container      string
	EndpointConfig *network.EndpointSettings `json:",omitempty"`
}

// NetworkDisconnect represents the data to be used to disconnect a container from the network
type NetworkDisconnect struct {
	Container string
	Force     bool
}
<commit_msg>Add `Status` field to Volume type<commit_after>package types

import (
	"os"
	"time"

	"github.com/docker/engine-api/types/container"
	"github.com/docker/engine-api/types/network"
	"github.com/docker/engine-api/types/registry"
	"github.com/docker/go-connections/nat"
)

// ContainerCreateResponse contains the information returned to a client on the
// creation of a new container.
type ContainerCreateResponse struct {
	// ID is the ID of the created container.
	ID string `json:"Id"`

	// Warnings are any warnings encountered during the creation of the container.
	Warnings []string `json:"Warnings"`
}

// ContainerExecCreateResponse contains response of Remote API:
// POST "/containers/{name:.*}/exec"
type ContainerExecCreateResponse struct {
	// ID is the exec ID.
	ID string `json:"Id"`
}

// ContainerUpdateResponse contains response of Remote API:
// POST /containers/{name:.*}/update
type ContainerUpdateResponse struct {
	// Warnings are any warnings encountered during the updating of the container.
	Warnings []string `json:"Warnings"`
}

// AuthResponse contains response of Remote API:
// POST "/auth"
type AuthResponse struct {
	// Status is the authentication status
	Status string `json:"Status"`

	// IdentityToken is an opaque token used for authenticating
	// a user after a successful login.
	IdentityToken string `json:"IdentityToken,omitempty"`
}

// ContainerWaitResponse contains response of Remote API:
// POST "/containers/"+containerID+"/wait"
type ContainerWaitResponse struct {
	// StatusCode is the status code of the wait job
	StatusCode int `json:"StatusCode"`
}

// ContainerCommitResponse contains response of Remote API:
// POST "/commit?container="+containerID
type ContainerCommitResponse struct {
	ID string `json:"Id"`
}

// ContainerChange contains response of Remote API:
// GET "/containers/{name:.*}/changes"
type ContainerChange struct {
	Kind int
	Path string
}

// ImageHistory contains response of Remote API:
// GET "/images/{name:.*}/history"
type ImageHistory struct {
	ID        string `json:"Id"`
	Created   int64
	CreatedBy string
	Tags      []string
	Size      int64
	Comment   string
}

// ImageDelete contains response of Remote API:
// DELETE "/images/{name:.*}"
type ImageDelete struct {
	Untagged string `json:",omitempty"`
	Deleted  string `json:",omitempty"`
}

// Image contains response of Remote API:
// GET "/images/json"
type Image struct {
	ID          string `json:"Id"`
	ParentID    string `json:"ParentId"`
	RepoTags    []string
	RepoDigests []string
	Created     int64
	Size        int64
	VirtualSize int64
	Labels      map[string]string
}

// GraphDriverData returns Image's graph driver config info
// when calling inspect command
type GraphDriverData struct {
	Name string
	Data map[string]string
}

// ImageInspect contains response of Remote API:
// GET "/images/{name:.*}/json"
type ImageInspect struct {
	ID              string `json:"Id"`
	RepoTags        []string
	RepoDigests     []string
	Parent          string
	Comment         string
	Created         string
	Container       string
	ContainerConfig *container.Config
	DockerVersion   string
	Author          string
	Config          *container.Config
	Architecture    string
	Os              string
	Size            int64
	VirtualSize     int64
	GraphDriver     GraphDriverData
}

// Port stores open ports info of container
// e.g. {"PrivatePort": 8080, "PublicPort": 80, "Type": "tcp"}
type Port struct {
	IP          string `json:",omitempty"`
	PrivatePort int
	PublicPort  int `json:",omitempty"`
	Type        string
}

// Container contains response of Remote API:
// GET  "/containers/json"
type Container struct {
	ID         string `json:"Id"`
	Names      []string
	Image      string
	ImageID    string
	Command    string
	Created    int64
	Ports      []Port
	SizeRw     int64 `json:",omitempty"`
	SizeRootFs int64 `json:",omitempty"`
	Labels     map[string]string
	State      string
	Status     string
	HostConfig struct {
		NetworkMode string `json:",omitempty"`
	}
	NetworkSettings *SummaryNetworkSettings
	Mounts          []MountPoint
}

// CopyConfig contains request body of Remote API:
// POST "/containers/"+containerID+"/copy"
type CopyConfig struct {
	Resource string
}

// ContainerPathStat is used to encode the header from
// GET "/containers/{name:.*}/archive"
// "Name" is the file or directory name.
type ContainerPathStat struct {
	Name       string      `json:"name"`
	Size       int64       `json:"size"`
	Mode       os.FileMode `json:"mode"`
	Mtime      time.Time   `json:"mtime"`
	LinkTarget string      `json:"linkTarget"`
}

// ContainerProcessList contains response of Remote API:
// GET "/containers/{name:.*}/top"
type ContainerProcessList struct {
	Processes [][]string
	Titles    []string
}

// Version contains response of Remote API:
// GET "/version"
type Version struct {
	Version       string
	APIVersion    string `json:"ApiVersion"`
	GitCommit     string
	GoVersion     string
	Os            string
	Arch          string
	KernelVersion string `json:",omitempty"`
	Experimental  bool   `json:",omitempty"`
	BuildTime     string `json:",omitempty"`
}

// Info contains response of Remote API:
// GET "/info"
type Info struct {
	ID                 string
	Containers         int
	ContainersRunning  int
	ContainersPaused   int
	ContainersStopped  int
	Images             int
	Driver             string
	DriverStatus       [][2]string
	SystemStatus       [][2]string
	Plugins            PluginsInfo
	MemoryLimit        bool
	SwapLimit          bool
	KernelMemory       bool
	CPUCfsPeriod       bool `json:"CpuCfsPeriod"`
	CPUCfsQuota        bool `json:"CpuCfsQuota"`
	CPUShares          bool
	CPUSet             bool
	IPv4Forwarding     bool
	BridgeNfIptables   bool
	BridgeNfIP6tables  bool `json:"BridgeNfIp6tables"`
	Debug              bool
	NFd                int
	OomKillDisable     bool
	NGoroutines        int
	SystemTime         string
	ExecutionDriver    string
	LoggingDriver      string
	CgroupDriver       string
	NEventsListener    int
	KernelVersion      string
	OperatingSystem    string
	OSType             string
	Architecture       string
	IndexServerAddress string
	RegistryConfig     *registry.ServiceConfig
	NCPU               int
	MemTotal           int64
	DockerRootDir      string
	HTTPProxy          string `json:"HttpProxy"`
	HTTPSProxy         string `json:"HttpsProxy"`
	NoProxy            string
	Name               string
	Labels             []string
	ExperimentalBuild  bool
	ServerVersion      string
	ClusterStore       string
	ClusterAdvertise   string
}

// PluginsInfo is a temp struct holding Plugins name
// registered with docker daemon. It is used by Info struct
type PluginsInfo struct {
	// List of Volume plugins registered
	Volume []string
	// List of Network plugins registered
	Network []string
	// List of Authorization plugins registered
	Authorization []string
}

// ExecStartCheck is a temp struct used by execStart
// Config fields is part of ExecConfig in runconfig package
type ExecStartCheck struct {
	// ExecStart will first check if it's detached
	Detach bool
	// Check if there's a tty
	Tty bool
}

// ContainerState stores container's running state
// it's part of ContainerJSONBase and will return by "inspect" command
type ContainerState struct {
	Status     string
	Running    bool
	Paused     bool
	Restarting bool
	OOMKilled  bool
	Dead       bool
	Pid        int
	ExitCode   int
	Error      string
	StartedAt  string
	FinishedAt string
}

// ContainerJSONBase contains response of Remote API:
// GET "/containers/{name:.*}/json"
type ContainerJSONBase struct {
	ID              string `json:"Id"`
	Created         string
	Path            string
	Args            []string
	State           *ContainerState
	Image           string
	ResolvConfPath  string
	HostnamePath    string
	HostsPath       string
	LogPath         string
	Name            string
	RestartCount    int
	Driver          string
	MountLabel      string
	ProcessLabel    string
	AppArmorProfile string
	ExecIDs         []string
	HostConfig      *container.HostConfig
	GraphDriver     GraphDriverData
	SizeRw          *int64 `json:",omitempty"`
	SizeRootFs      *int64 `json:",omitempty"`
}

// ContainerJSON is newly used struct along with MountPoint
type ContainerJSON struct {
	*ContainerJSONBase
	Mounts          []MountPoint
	Config          *container.Config
	NetworkSettings *NetworkSettings
}

// NetworkSettings exposes the network settings in the api
type NetworkSettings struct {
	NetworkSettingsBase
	DefaultNetworkSettings
	Networks map[string]*network.EndpointSettings
}

// SummaryNetworkSettings provides a summary of container's networks
// in /containers/json
type SummaryNetworkSettings struct {
	Networks map[string]*network.EndpointSettings
}

// NetworkSettingsBase holds basic information about networks
type NetworkSettingsBase struct {
	Bridge                 string
	SandboxID              string
	HairpinMode            bool
	LinkLocalIPv6Address   string
	LinkLocalIPv6PrefixLen int
	Ports                  nat.PortMap
	SandboxKey             string
	SecondaryIPAddresses   []network.Address
	SecondaryIPv6Addresses []network.Address
}

// DefaultNetworkSettings holds network information
// during the 2 release deprecation period.
// It will be removed in Docker 1.11.
type DefaultNetworkSettings struct {
	EndpointID          string
	Gateway             string
	GlobalIPv6Address   string
	GlobalIPv6PrefixLen int
	IPAddress           string
	IPPrefixLen         int
	IPv6Gateway         string
	MacAddress          string
}

// MountPoint represents a mount point configuration inside the container.
type MountPoint struct {
	Name        string `json:",omitempty"`
	Source      string
	Destination string
	Driver      string `json:",omitempty"`
	Mode        string
	RW          bool
	Propagation string
}

// Volume represents the configuration of a volume for the remote API
type Volume struct {
	Name       string                 // Name is the name of the volume
	Driver     string                 // Driver is the Driver name used to create the volume
	Mountpoint string                 // Mountpoint is the location on disk of the volume
	Status     map[string]interface{} `json:",omitempty"` // Status provides low-level status information about the volume
}

// VolumesListResponse contains the response for the remote API:
// GET "/volumes"
type VolumesListResponse struct {
	Volumes  []*Volume // Volumes is the list of volumes being returned
	Warnings []string  // Warnings is a list of warnings that occurred when getting the list from the volume drivers
}

// VolumeCreateRequest contains the response for the remote API:
// POST "/volumes/create"
type VolumeCreateRequest struct {
	Name       string            // Name is the requested name of the volume
	Driver     string            // Driver is the name of the driver that should be used to create the volume
	DriverOpts map[string]string // DriverOpts holds the driver specific options to use for when creating the volume.
}

// NetworkResource is the body of the "get network" http response message
type NetworkResource struct {
	Name       string
	ID         string `json:"Id"`
	Scope      string
	Driver     string
	EnableIPv6 bool
	IPAM       network.IPAM
	Internal   bool
	Containers map[string]EndpointResource
	Options    map[string]string
}

// EndpointResource contains network resources allocated and used for a container in a network
type EndpointResource struct {
	Name        string
	EndpointID  string
	MacAddress  string
	IPv4Address string
	IPv6Address string
}

// NetworkCreate is the expected body of the "create network" http request message
type NetworkCreate struct {
	Name           string
	CheckDuplicate bool
	Driver         string
	EnableIPv6     bool
	IPAM           network.IPAM
	Internal       bool
	Options        map[string]string
}

// NetworkCreateResponse is the response message sent by the server for network create call
type NetworkCreateResponse struct {
	ID      string `json:"Id"`
	Warning string
}

// NetworkConnect represents the data to be used to connect a container to the network
type NetworkConnect struct {
	Container      string
	EndpointConfig *network.EndpointSettings `json:",omitempty"`
}

// NetworkDisconnect represents the data to be used to disconnect a container from the network
type NetworkDisconnect struct {
	Container string
	Force     bool
}
<|endoftext|>


<commit_before>package users

import (
	"fmt"
	"net/http"

	"github.com/howeyc/gopass"
	"github.com/julienschmidt/httprouter"
	"github.com/octavore/naga/service"
	"github.com/octavore/nagax/logger"
	"github.com/octavore/nagax/router"
	"github.com/octavore/nagax/users"
	"github.com/octavore/nagax/users/databaseauth"
	"github.com/octavore/nagax/users/session"

	"github.com/octavore/press/db"
)

// Module users is a largely a wrapper around nagax/users/databaseauth
// to enable user logins.
type Module struct {
	Auth     *users.Module
	DBAuth   *databaseauth.Module // todo: make this pluggable?
	Sessions *session.Module
	Router   *router.Module
	DB       *db.Module
	Logger   *logger.Module
}

// Handle is similar to httprouter.Handle, except it returns an error which can be
// handled separately.
type Handle func(rw http.ResponseWriter, req *http.Request, par httprouter.Params) error

// Init implements service.Init
func (m *Module) Init(c *service.Config) {
	c.AddCommand(&service.Command{
		Keyword:    "users:add <email>",
		Usage:      "Add a new user.",
		ShortUsage: "Add a new user",
		Run: func(ctx *service.CommandContext) {
			ctx.RequireExactlyNArgs(1)
			email := ctx.Args[0]
			fmt.Println("enter a password:")
			pass, err := gopass.GetPasswdMasked()
			if err != nil {
				panic(err)
			}
			_, err = m.DBAuth.Create(email, string(pass))
			if err != nil {
				panic(err)
			}

		},
	})
	c.Setup = func() error {
		m.DBAuth.UserStore = m
		m.DBAuth.LoginPath = "/api/v1/login"
		m.DBAuth.ErrorHandler = m.ErrorHandler
		m.Auth.ErrorHandler = m.ErrorHandler
		m.Auth.RegisterAuthenticator(m.Sessions)
		// todo: allow to be set in a config file
		m.Sessions.CookieDomain = ""
		return nil
	}
}

// ErrorHandler to handle auth errors.
// todo: return more fine-grained error codes.
func (m *Module) ErrorHandler(rw http.ResponseWriter, req *http.Request, err error) {
	m.Router.SimpleError(rw, http.StatusInternalServerError, err)
}

// MustWithAuth wraps a http
func (m *Module) MustWithAuth(delegate Handle) Handle {
	return func(rw http.ResponseWriter, req *http.Request, par httprouter.Params) (err error) {
		// authenticate with the auth module, with a wrapper for the delegate to
		// make it compatible with http.HandlerFunc (while ensuring it closes over httprouter.Params).
		h := func(x http.ResponseWriter, y *http.Request) {
			err = delegate(x, y, par)
		}
		m.Auth.MustWithAuth(h)(rw, req)
		return
	}
}
<commit_msg>server: Use new dbauth config.<commit_after>package users

import (
	"fmt"
	"net/http"

	"github.com/howeyc/gopass"
	"github.com/julienschmidt/httprouter"
	"github.com/octavore/naga/service"
	"github.com/octavore/nagax/logger"
	"github.com/octavore/nagax/router"
	"github.com/octavore/nagax/users"
	"github.com/octavore/nagax/users/databaseauth"
	"github.com/octavore/nagax/users/session"

	"github.com/octavore/press/db"
)

// Module users is a largely a wrapper around nagax/users/databaseauth
// to enable user logins.
type Module struct {
	Auth     *users.Module
	DBAuth   *databaseauth.Module // todo: make this pluggable?
	Sessions *session.Module
	Router   *router.Module
	DB       *db.Module
	Logger   *logger.Module
}

// Handle is similar to httprouter.Handle, except it returns an error which can be
// handled separately.
type Handle func(rw http.ResponseWriter, req *http.Request, par httprouter.Params) error

// Init implements service.Init
func (m *Module) Init(c *service.Config) {
	c.AddCommand(&service.Command{
		Keyword:    "users:add <email>",
		Usage:      "Add a new user.",
		ShortUsage: "Add a new user",
		Run: func(ctx *service.CommandContext) {
			ctx.RequireExactlyNArgs(1)
			email := ctx.Args[0]
			fmt.Println("enter a password:")
			pass, err := gopass.GetPasswdMasked()
			if err != nil {
				panic(err)
			}
			_, err = m.DBAuth.Create(email, string(pass))
			if err != nil {
				panic(err)
			}

		},
	})
	c.Setup = func() error {
		m.DBAuth.Configure(
			databaseauth.WithUserStore(m),
			databaseauth.WithLoginPath("/api/v1/login"),
			databaseauth.WithErrorHandler(m.ErrorHandler),
		)
		m.Auth.ErrorHandler = m.ErrorHandler
		m.Auth.RegisterAuthenticator(m.Sessions)
		// todo: allow to be set in a config file
		m.Sessions.CookieDomain = ""
		return nil
	}
}

// ErrorHandler to handle auth errors.
// todo: return more fine-grained error codes.
func (m *Module) ErrorHandler(rw http.ResponseWriter, req *http.Request, err error) {
	m.Router.SimpleError(rw, http.StatusInternalServerError, err)
}

// MustWithAuth wraps a http
func (m *Module) MustWithAuth(delegate Handle) Handle {
	return func(rw http.ResponseWriter, req *http.Request, par httprouter.Params) (err error) {
		// authenticate with the auth module, with a wrapper for the delegate to
		// make it compatible with http.HandlerFunc (while ensuring it closes over httprouter.Params).
		h := func(x http.ResponseWriter, y *http.Request) {
			err = delegate(x, y, par)
		}
		m.Auth.MustWithAuth(h)(rw, req)
		return
	}
}
<|endoftext|>


<commit_before>package version

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

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


<commit_before>package seq

import (
	"fmt"
	"sync"
	"testing"
	"time"

	"github.com/facebookgo/ensure"
)

// -----------------------------------------------------------------------------

// NOTE: run these tests with `go test -race -cpu 1,8,32`

func TestSimpleBufSeq_New_BufSize(t *testing.T) {
	ensure.DeepEqual(t, cap(NewSimpleBufSeq(-42).ids), 0)
	ensure.DeepEqual(t, cap(NewSimpleBufSeq(0).ids), 0)
	ensure.DeepEqual(t, cap(NewSimpleBufSeq(1).ids), 1)
	ensure.DeepEqual(t, cap(NewSimpleBufSeq(1e6).ids), int(1e6))
}

func TestSimpleBufSeq_FirstID(t *testing.T) {
	ensure.DeepEqual(t, <-NewSimpleBufSeq(1e2).GetStream(), ID(1))
}

func TestSimpleBufSeq_SingleClient(t *testing.T) {
	seq := NewSimpleBufSeq(1024)
	lastID := ID(0)

	go func() {
		<-time.After(time.Millisecond * 250)
		_ = seq.Close()
	}()

	for id := range seq.GetStream() {
		ensure.DeepEqual(t, id, lastID+1)
		lastID = id
	}
}

func TestSimpleBufSeq_MultiClient(t *testing.T) {
	seq := NewSimpleBufSeq(1024)
	lastID := ID(0)

	go func() {
		<-time.After(time.Millisecond * 250)
		_ = seq.Close()
	}()

	s1, s2, s3 := seq.GetStream(), seq.GetStream(), seq.GetStream()
	for {
		id1 := s1.Next()
		if id1 == 0 {
			break
		}
		ensure.DeepEqual(t, id1, lastID+1)
		lastID++
		id2 := s2.Next()
		if id2 == 0 {
			break
		}
		ensure.DeepEqual(t, id2, id1+1)
		lastID++
		id3 := s3.Next()
		if id3 == 0 {
			break
		}
		ensure.DeepEqual(t, id3, id2+1)
		lastID++
	}
}

func TestSimpleBufSeq_ConcurrentClients256(t *testing.T) {
	seq := NewSimpleBufSeq(1024)

	go func() {
		<-time.After(time.Millisecond * 250)
		_ = seq.Close()
	}()

	wg := &sync.WaitGroup{}
	for i := 0; i < 256; i++ {
		wg.Add(1)
		go func() {
			for id := range seq.GetStream() {
				_ = id
			}
			wg.Done()
		}()
	}
	wg.Wait()
}

// -----------------------------------------------------------------------------

// NOTE: run these benchmarks with `go test -run=none -bench=. -cpu 1,8,32`

func BenchmarkSimpleBufSeq_BufSize1024_SingleClient(b *testing.B) {
	s := NewSimpleBufSeq(1024).GetStream()
	for i := 0; i < b.N; i++ {
		_ = s.Next()
	}
}

func BenchmarkSimpleBufSeq_BufSize1024_MultiClient(b *testing.B) {
	s := NewSimpleBufSeq(1024)
	b.RunParallel(func(pb *testing.PB) {
		ids := s.GetStream()
		for pb.Next() {
			_ = ids.Next()
		}
	})
}

// -----------------------------------------------------------------------------

func ExampleSimpleBufSeq() {
	seq := NewSimpleBufSeq(2)

	ids := make([]ID, 0)
	for id := range seq.GetStream() {
		ids = append(ids, id)
		if id == 10 { // won't stop until 12: 11 & 12 are already buffered
			seq.Close()
		}
	}
	fmt.Println(ids)

	// Output: [1 2 3 4 5 6 7 8 9 10 11 12]
}
<commit_msg>SimpleBufSeq: 0/1/1024 bufsize tests<commit_after>package seq

import (
	"fmt"
	"sync"
	"testing"
	"time"

	"github.com/facebookgo/ensure"
)

// -----------------------------------------------------------------------------

// NOTE: run these tests with `go test -race -cpu 1,8,32`

func TestSimpleBufSeq_New_BufSize(t *testing.T) {
	ensure.DeepEqual(t, cap(NewSimpleBufSeq(-42).ids), 0)
	ensure.DeepEqual(t, cap(NewSimpleBufSeq(0).ids), 0)
	ensure.DeepEqual(t, cap(NewSimpleBufSeq(1).ids), 1)
	ensure.DeepEqual(t, cap(NewSimpleBufSeq(1e6).ids), int(1e6))
}

func TestSimpleBufSeq_FirstID(t *testing.T) {
	ensure.DeepEqual(t, <-NewSimpleBufSeq(1e2).GetStream(), ID(1))
}

// -----------------------------------------------------------------------------

func testSimpleBufSeq_SingleClient(bufSize int, t *testing.T) {
	seq := NewSimpleBufSeq(bufSize)
	lastID := ID(0)

	go func() {
		<-time.After(time.Millisecond * 250)
		_ = seq.Close()
	}()

	for id := range seq.GetStream() {
		ensure.DeepEqual(t, id, lastID+1)
		lastID = id
	}
}

func TestSimpleBufSeq_BufSize0_SingleClient(t *testing.T) {
	testSimpleBufSeq_SingleClient(0, t)
}

func TestSimpleBufSeq_BufSize1_SingleClient(t *testing.T) {
	testSimpleBufSeq_SingleClient(1, t)
}

func TestSimpleBufSeq_BufSize1024_SingleClient(t *testing.T) {
	testSimpleBufSeq_SingleClient(1024, t)
}

// -----------------------------------------------------------------------------

func testSimpleBufSeq_MultiClient(bufSize int, t *testing.T) {
	seq := NewSimpleBufSeq(bufSize)
	lastID := ID(0)

	go func() {
		<-time.After(time.Millisecond * 250)
		_ = seq.Close()
	}()

	s1, s2, s3 := seq.GetStream(), seq.GetStream(), seq.GetStream()
	for {
		id1 := s1.Next()
		if id1 == 0 {
			break
		}
		ensure.DeepEqual(t, id1, lastID+1)
		lastID++
		id2 := s2.Next()
		if id2 == 0 {
			break
		}
		ensure.DeepEqual(t, id2, id1+1)
		lastID++
		id3 := s3.Next()
		if id3 == 0 {
			break
		}
		ensure.DeepEqual(t, id3, id2+1)
		lastID++
	}
}

func TestSimpleBufSeq_BufSize0_MultiClient(t *testing.T) {
	testSimpleBufSeq_MultiClient(0, t)
}

func TestSimpleBufSeq_BufSize1_MultiClient(t *testing.T) {
	testSimpleBufSeq_MultiClient(1, t)
}

func TestSimpleBufSeq_BufSize1024_MultiClient(t *testing.T) {
	testSimpleBufSeq_MultiClient(1024, t)
}

// -----------------------------------------------------------------------------

func testSimpleBufSeq_ConcurrentClients256(bufSize int, t *testing.T) {
	seq := NewSimpleBufSeq(bufSize)

	go func() {
		<-time.After(time.Millisecond * 250)
		_ = seq.Close()
	}()

	wg := &sync.WaitGroup{}
	for i := 0; i < 256; i++ {
		wg.Add(1)
		go func() {
			for id := range seq.GetStream() {
				_ = id
			}
			wg.Done()
		}()
	}
	wg.Wait()
}

func TestSimpleBufSeq_BufSize0_ConcurrentClients256(t *testing.T) {
	testSimpleBufSeq_ConcurrentClients256(0, t)
}

func TestSimpleBufSeq_BufSize1_ConcurrentClients256(t *testing.T) {
	testSimpleBufSeq_ConcurrentClients256(1, t)
}

func TestSimpleBufSeq_BufSize1024_ConcurrentClients256(t *testing.T) {
	testSimpleBufSeq_ConcurrentClients256(1024, t)
}

// -----------------------------------------------------------------------------

// NOTE: run these benchmarks with `go test -run=none -bench=. -cpu 1,8,32`

func BenchmarkSimpleBufSeq_BufSize1024_SingleClient(b *testing.B) {
	s := NewSimpleBufSeq(1024).GetStream()
	for i := 0; i < b.N; i++ {
		_ = s.Next()
	}
}

func BenchmarkSimpleBufSeq_BufSize1024_MultiClient(b *testing.B) {
	s := NewSimpleBufSeq(1024)
	b.RunParallel(func(pb *testing.PB) {
		ids := s.GetStream()
		for pb.Next() {
			_ = ids.Next()
		}
	})
}

// -----------------------------------------------------------------------------

func ExampleSimpleBufSeq() {
	seq := NewSimpleBufSeq(2)

	ids := make([]ID, 0)
	for id := range seq.GetStream() {
		ids = append(ids, id)
		if id == 10 { // won't stop until 12: 11 & 12 are already buffered
			seq.Close()
		}
	}
	fmt.Println(ids)

	// Output: [1 2 3 4 5 6 7 8 9 10 11 12]
}
<|endoftext|>


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

// Package simulator provides a go interface to the Microsoft TPM2 simulator.
package simulator

import (
	"bytes"
	"fmt"
	"math/rand"
	"sync"

	"github.com/google/go-tpm-tools/simulator/internal"
	"github.com/google/go-tpm/tpm2"
)

// Simulator represents a go-tpm compatible interface to the IBM TPM2 simulator.
// Similar to the file-based (for linux) or syscall-based (for Windows) TPM
// handles, no synchronization is provided; the same simulator handle should not
// be used from multiple threads.
type Simulator struct {
	buf    bytes.Buffer
	closed bool
}

// The simulator is a global resource, so we use the variables below to make
// sure we only ever have one open reference to the Simulator at a time.
var lock sync.Mutex

// Get the pointer to an initialized, powered on, and started simulator. As only
// one simulator may be running at a time, a second call to Get() block until
// the first Simulator is Closed.
func Get() (*Simulator, error) {
	lock.Lock()

	simulator := &Simulator{}
	internal.Reset(true)
	if err := simulator.on(true); err != nil {
		lock.Unlock()
		return nil, err
	}
	simulator.closed = false
	return simulator, nil
}

// GetWithFixedSeedInsecure behaves like Get() expect that all of the internal
// hierarchy seeds are derived from the input seed. Note that this function
// compromises the security of the keys/seeds and should only be used for tests.
func GetWithFixedSeedInsecure(seed int64) (*Simulator, error) {
	s, err := Get()
	if err != nil {
		return nil, err
	}

	internal.SetSeeds(rand.New(rand.NewSource(seed)))
	return s, nil
}

// Reset the TPM as if the host computer had rebooted.
func (s *Simulator) Reset() error {
	if err := s.off(); err != nil {
		return err
	}
	internal.Reset(false)
	return s.on(false)
}

// ManufactureReset behaves like Reset() except that the TPM is complete wiped.
// All data (NVData, Hierarchy seeds, etc...) is cleared or reset.
func (s *Simulator) ManufactureReset() error {
	if err := s.off(); err != nil {
		return err
	}
	internal.Reset(true)
	return s.on(true)
}

// Write executes the command specified by commandBuffer. The command response
// can be retrieved with a subsequent call to Read().
func (s *Simulator) Write(commandBuffer []byte) (int, error) {
	resp, err := internal.RunCommand(commandBuffer)
	if err != nil {
		return 0, err
	}
	return s.buf.Write(resp)
}

// Read gets the response of a command previously issued by calling Write().
func (s *Simulator) Read(responseBuffer []byte) (int, error) {
	return s.buf.Read(responseBuffer)
}

// Close cleans up and stops the simulator, Close() should always be called when
// the Simulator is no longer needed, freeing up other callers to use Get().
func (s *Simulator) Close() error {
	s.closed = true
	defer lock.Unlock()
	return s.off()
}

// IsClosed returns true if the simulator has been Closed()
func (s *Simulator) IsClosed() bool {
	return s.closed
}

func (s *Simulator) on(manufactureReset bool) error {
	// TPM2_Startup must be the first command the TPM receives.
	if err := tpm2.Startup(s, tpm2.StartupClear); err != nil {
		return fmt.Errorf("startup: %w", err)
	}
	return nil
}

func (s *Simulator) off() error {
	// TPM2_Shutdown must be the last command the TPM receives. We call
	// Shutdown with StartupClear to simulate a full reboot.
	if err := tpm2.Shutdown(s, tpm2.StartupClear); err != nil {
		return fmt.Errorf("shutdown: %w", err)
	}
	return nil
}
<commit_msg>make simulator double close a no-op, as a temp fix<commit_after>/*
 * Copyright 2018 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

// Package simulator provides a go interface to the Microsoft TPM2 simulator.
package simulator

import (
	"bytes"
	"fmt"
	"math/rand"
	"sync"

	"github.com/google/go-tpm-tools/simulator/internal"
	"github.com/google/go-tpm/tpm2"
)

// Simulator represents a go-tpm compatible interface to the IBM TPM2 simulator.
// Similar to the file-based (for linux) or syscall-based (for Windows) TPM
// handles, no synchronization is provided; the same simulator handle should not
// be used from multiple threads.
type Simulator struct {
	buf    bytes.Buffer
	closed bool
}

// The simulator is a global resource, so we use the variables below to make
// sure we only ever have one open reference to the Simulator at a time.
var lock sync.Mutex

// Get the pointer to an initialized, powered on, and started simulator. As only
// one simulator may be running at a time, a second call to Get() block until
// the first Simulator is Closed.
func Get() (*Simulator, error) {
	lock.Lock()

	simulator := &Simulator{}
	internal.Reset(true)
	if err := simulator.on(true); err != nil {
		lock.Unlock()
		return nil, err
	}
	simulator.closed = false
	return simulator, nil
}

// GetWithFixedSeedInsecure behaves like Get() expect that all of the internal
// hierarchy seeds are derived from the input seed. Note that this function
// compromises the security of the keys/seeds and should only be used for tests.
func GetWithFixedSeedInsecure(seed int64) (*Simulator, error) {
	s, err := Get()
	if err != nil {
		return nil, err
	}

	internal.SetSeeds(rand.New(rand.NewSource(seed)))
	return s, nil
}

// Reset the TPM as if the host computer had rebooted.
func (s *Simulator) Reset() error {
	if err := s.off(); err != nil {
		return err
	}
	internal.Reset(false)
	return s.on(false)
}

// ManufactureReset behaves like Reset() except that the TPM is complete wiped.
// All data (NVData, Hierarchy seeds, etc...) is cleared or reset.
func (s *Simulator) ManufactureReset() error {
	if err := s.off(); err != nil {
		return err
	}
	internal.Reset(true)
	return s.on(true)
}

// Write executes the command specified by commandBuffer. The command response
// can be retrieved with a subsequent call to Read().
func (s *Simulator) Write(commandBuffer []byte) (int, error) {
	resp, err := internal.RunCommand(commandBuffer)
	if err != nil {
		return 0, err
	}
	return s.buf.Write(resp)
}

// Read gets the response of a command previously issued by calling Write().
func (s *Simulator) Read(responseBuffer []byte) (int, error) {
	return s.buf.Read(responseBuffer)
}

// Close cleans up and stops the simulator, Close() should always be called when
// the Simulator is no longer needed, freeing up other callers to use Get().
func (s *Simulator) Close() error {
	if s.closed {
		fmt.Println("The Simulator has already been closed!")
		return nil
	}
	s.closed = true
	defer lock.Unlock()
	return s.off()
}

// IsClosed returns true if the simulator has been Closed()
func (s *Simulator) IsClosed() bool {
	return s.closed
}

func (s *Simulator) on(manufactureReset bool) error {
	// TPM2_Startup must be the first command the TPM receives.
	if err := tpm2.Startup(s, tpm2.StartupClear); err != nil {
		return fmt.Errorf("startup: %w", err)
	}
	return nil
}

func (s *Simulator) off() error {
	// TPM2_Shutdown must be the last command the TPM receives. We call
	// Shutdown with StartupClear to simulate a full reboot.
	if err := tpm2.Shutdown(s, tpm2.StartupClear); err != nil {
		return fmt.Errorf("shutdown: %w", err)
	}
	return nil
}
<|endoftext|>


<commit_before>package middleware

import (
	"bufio"
	"errors"
	"fmt"
	"github.com/DeedleFake/Go-PhysicsFS/physfs"
	"github.com/fzzy/radix/redis"
	"github.com/gin-gonic/gin"
	"github.com/pmylund/go-cache"
	"github.com/vifino/carbon/modules/glue"
	"github.com/vifino/carbon/modules/helpers"
	"github.com/vifino/carbon/modules/scheduler"
	"github.com/vifino/carbon/modules/static"
	"github.com/vifino/contrib/gzip"
	"github.com/vifino/golua/lua"
	"github.com/vifino/luar"
	"net"
	"time"
)

func Bind(L *lua.State) {
	BindMiddleware(L)
	BindRedis(L)
	BindPhysFS(L)
	BindThread(L)
	BindOther(L)
	BindNet(L)
	BindConversions(L)
	BindComs(L)
}

func BindEngine(L *lua.State) {
	luar.Register(L, "engine", luar.Map{
		"new": gin.New,
	})
}

func BindMiddleware(L *lua.State) {
	luar.Register(L, "mw", luar.Map{
		"Lua": Lua,
		"ExtRoute": (func(plan map[string]interface{}) func(*gin.Context) {
			newplan := make(Plan, len(plan))
			for k, v := range plan {
				newplan[k] = v.(func(*gin.Context))
			}
			return ExtRoute(newplan)
		}),
		"VHOST": (func(plan map[string]interface{}) func(*gin.Context) {
			newplan := make(Plan, len(plan))
			for k, v := range plan {
				newplan[k] = v.(func(*gin.Context))
			}
			return VHOST(newplan)
		}),
		"Logger":   gin.Logger,
		"Recovery": gin.Recovery,
		"GZip": func() func(*gin.Context) {
			return gzip.Gzip(gzip.DefaultCompression)
		},
		"DLR_NS":    DLR_NS,
		"DLR_RUS":   DLR_RUS,
		"DLRWS_RUS": DLRWS_RUS,
		"Echo":      EchoHTML,
		"EchoText":  Echo,
	})
	L.DoString(glue.RouteGlue())
}

func BindPhysFS(L *lua.State) {
	luar.Register(L, "fs", luar.Map{ // PhysFS
		"mount":       physfs.Mount,
		"exits":       physfs.Exists,
		"getFS":       physfs.FileSystem,
		"mkdir":       physfs.Mkdir,
		"umount":      physfs.RemoveFromSearchPath,
		"delete":      physfs.Delete,
		"setWriteDir": physfs.SetWriteDir,
		"getWriteDir": physfs.GetWriteDir,
	})
}

func BindRedis(L *lua.State) {
	luar.Register(L, "redis", luar.Map{
		"connectTimeout": (func(host string, timeout int) (*redis.Client, error) {
			return redis.DialTimeout("tcp", host, time.Duration(timeout)*time.Second)
		}),
		"connect": (func(host string) (*redis.Client, error) {
			return redis.Dial("tcp", host)
		}),
	})
}

func BindThread(L *lua.State) {
	luar.Register(L, "thread", luar.Map{
		"_spawn": (func(bcode string, instances int, dobind bool, vals map[string]interface{}) error {
			L := luar.Init()
			Bind(L)
			err := L.DoString(glue.MainGlue())
			if err != nil {
				panic(err)
			}

			if dobind {
				luar.Register(L, "", vals)
			}

			if L.LoadBuffer(bcode, len(bcode), "thread") != 0 {
				return errors.New(L.ToString(-1))
			}

			scheduler.Add(func() {
				if L.Pcall(0, 0, 0) != 0 { // != 0 means error in execution
					// Silently error because reasons. ._.
				}
			})
			return nil
		}),
	})
}

func BindOther(L *lua.State) {
	luar.Register(L, "", luar.Map{
		"unixtime": (func() int {
			return int(time.Now().UnixNano())
		}),
		"_syntaxhlfunc": helpers.SyntaxHL,
	})
}

func BindComs(L *lua.State) {
	luar.Register(L, "com", luar.Map{
		"create": (func() chan interface{} {
			return make(chan interface{})
		}),
		"createBuffered": (func(buffer int) chan interface{} {
			return make(chan interface{}, buffer)
		}),
		"receive": (func(c chan interface{}) interface{} {
			return <-c
		}),
		"send": (func(c chan interface{}, val interface{}) {
			c <- val
		}),
	})
}

func BindNet(L *lua.State) {
	luar.Register(L, "net", luar.Map{
		"dial": net.Dial,
		"write": (func(con net.Conn, str string) {
			fmt.Fprintf(con, str)
		}),
		"readline": (func(con net.Conn) (string, error) {
			return bufio.NewReader(con).ReadString('\n')
		}),
	})
}

func BindConversions(L *lua.State) {
	luar.Register(L, "convert", luar.Map{
		"stringtocharslice": (func(x string) []byte {
			return []byte(x)
		}),
		"charslicetostring": (func(x []byte) string {
			return string(x)
		}),
	})
}

func BindContext(L *lua.State, context *gin.Context) {
	luar.Register(L, "", luar.Map{
		"context":    context,
		"req":        context.Request,
		"_paramfunc": context.Param,
		"_formfunc":  context.PostForm,
		"_queryfunc": context.Query,
	})
}
func BindStatic(L *lua.State, cfe *cache.Cache) {
	luar.Register(L, "static", luar.Map{
		"serve": (func(prefix string) func(*gin.Context) {
			return staticServe.ServeCached(prefix, staticServe.PhysFS("", true, true), cfe)
		}),
	})
}
<commit_msg>Something something ctrl-z is evil something something.<commit_after>package middleware

import (
	"bufio"
	"errors"
	"fmt"
	"github.com/DeedleFake/Go-PhysicsFS/physfs"
	"github.com/fzzy/radix/redis"
	"github.com/gin-gonic/gin"
	"github.com/pmylund/go-cache"
	"github.com/vifino/carbon/modules/glue"
	"github.com/vifino/carbon/modules/helpers"
	"github.com/vifino/carbon/modules/scheduler"
	"github.com/vifino/carbon/modules/static"
	"github.com/vifino/contrib/gzip"
	"github.com/vifino/golua/lua"
	"github.com/vifino/luar"
	"net"
	"time"
)

func Bind(L *lua.State) {
	BindMiddleware(L)
	BindRedis(L)
	BindPhysFS(L)
	BindThread(L)
	BindOther(L)
	BindNet(L)
	BindConversions(L)
	BindComs(L)
}

func BindEngine(L *lua.State) {
	luar.Register(L, "engine", luar.Map{
		"new": gin.New,
	})
}

func BindMiddleware(L *lua.State) {
	luar.Register(L, "mw", luar.Map{
		"Lua": Lua,
		"ExtRoute": (func(plan map[string]interface{}) func(*gin.Context) {
			newplan := make(Plan, len(plan))
			for k, v := range plan {
				newplan[k] = v.(func(*gin.Context))
			}
			return ExtRoute(newplan)
		}),
		"VHOST": (func(plan map[string]interface{}) func(*gin.Context) {
			newplan := make(Plan, len(plan))
			for k, v := range plan {
				newplan[k] = v.(func(*gin.Context))
			}
			return VHOST(newplan)
		}),
		"Logger":   gin.Logger,
		"Recovery": gin.Recovery,
		"GZip": func() func(*gin.Context) {
			return gzip.Gzip(gzip.DefaultCompression)
		},
		"DLR_NS":    DLR_NS,
		"DLR_RUS":   DLR_RUS,
		"DLRWS_RUS": DLRWS_RUS,
		"Echo":      EchoHTML,
		"EchoText":  Echo,
	})
	L.DoString(glue.RouteGlue())
}

func BindPhysFS(L *lua.State) {
	luar.Register(L, "fs", luar.Map{ // PhysFS
		"mount":       physfs.Mount,
		"exits":       physfs.Exists,
		"getFS":       physfs.FileSystem,
		"mkdir":       physfs.Mkdir,
		"umount":      physfs.RemoveFromSearchPath,
		"delete":      physfs.Delete,
		"setWriteDir": physfs.SetWriteDir,
		"getWriteDir": physfs.GetWriteDir,
	})
}

func BindRedis(L *lua.State) {
	luar.Register(L, "redis", luar.Map{
		"connectTimeout": (func(host string, timeout int) (*redis.Client, error) {
			return redis.DialTimeout("tcp", host, time.Duration(timeout)*time.Second)
		}),
		"connect": (func(host string) (*redis.Client, error) {
			return redis.Dial("tcp", host)
		}),
	})
}

func BindThread(L *lua.State) {
	luar.Register(L, "thread", luar.Map{
		"_spawn": (func(bcode string, dobind bool, vals map[string]interface{}) error {
			L := luar.Init()
			Bind(L)
			err := L.DoString(glue.MainGlue())
			if err != nil {
				panic(err)
			}

			if dobind {
				luar.Register(L, "", vals)
			}

			if L.LoadBuffer(bcode, len(bcode), "thread") != 0 {
				return errors.New(L.ToString(-1))
			}

			scheduler.Add(func() {
				if L.Pcall(0, 0, 0) != 0 { // != 0 means error in execution
					// Silently error because reasons. ._.
				}
			})
			return nil
		}),
	})
}

func BindOther(L *lua.State) {
	luar.Register(L, "", luar.Map{
		"unixtime": (func() int {
			return int(time.Now().UnixNano())
		}),
		"_syntaxhlfunc": helpers.SyntaxHL,
	})
}

func BindComs(L *lua.State) {
	luar.Register(L, "com", luar.Map{
		"create": (func() chan interface{} {
			return make(chan interface{})
		}),
		"createBuffered": (func(buffer int) chan interface{} {
			return make(chan interface{}, buffer)
		}),
		"receive": (func(c chan interface{}) interface{} {
			return <-c
		}),
		"send": (func(c chan interface{}, val interface{}) {
			c <- val
		}),
	})
}

func BindNet(L *lua.State) {
	luar.Register(L, "net", luar.Map{
		"dial": net.Dial,
		"write": (func(con net.Conn, str string) {
			fmt.Fprintf(con, str)
		}),
		"readline": (func(con net.Conn) (string, error) {
			return bufio.NewReader(con).ReadString('\n')
		}),
	})
}

func BindConversions(L *lua.State) {
	luar.Register(L, "convert", luar.Map{
		"stringtocharslice": (func(x string) []byte {
			return []byte(x)
		}),
		"charslicetostring": (func(x []byte) string {
			return string(x)
		}),
	})
}

func BindContext(L *lua.State, context *gin.Context) {
	luar.Register(L, "", luar.Map{
		"context":    context,
		"req":        context.Request,
		"_paramfunc": context.Param,
		"_formfunc":  context.PostForm,
		"_queryfunc": context.Query,
	})
}
func BindStatic(L *lua.State, cfe *cache.Cache) {
	luar.Register(L, "static", luar.Map{
		"serve": (func(prefix string) func(*gin.Context) {
			return staticServe.ServeCached(prefix, staticServe.PhysFS("", true, true), cfe)
		}),
	})
}
<|endoftext|>