<commit_before>package parser

import (
	"fmt"
	"goposm/element"
	"goposm/parser/osmpbf"
	"log"
	"os"
)

type PBF struct {
	file     *os.File
	filename string
	offset   int64
}

type BlockPosition struct {
	Filename string
	Offset   int64
	Size     int32
}

func Open(filename string) (f *PBF, err error) {
	file, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	f = &PBF{filename: filename, file: file}
	return f, nil
}

func (pbf *PBF) Close() error {
	return pbf.file.Close()
}

func (pbf *PBF) NextDataPosition() (offset int64, size int32) {
	header := pbf.nextBlobHeader()
	size = header.GetDatasize()
	offset = pbf.offset

	pbf.offset += int64(size)
	pbf.file.Seek(pbf.offset, 0)

	if header.GetType() == "OSMHeader" {
		return pbf.NextDataPosition()
	}
	return
}

const COORD_FACTOR float64 = 11930464.7083 // ((2<<31)-1)/360.0

func coordToInt(coord float64) uint32 {
	return uint32((coord + 180.0) * COORD_FACTOR)
}

func intToCoord(coord uint32) float64 {
	return float64((float64(coord) / COORD_FACTOR) - 180.0)
}

func ReadDenseNodes(
	dense *osmpbf.DenseNodes,
	block *osmpbf.PrimitiveBlock,
	stringtable StringTable) (nodes []element.Node) {

	var lastId int64
	var lastLon, lastLat int64
	nodes = make([]element.Node, len(dense.Id))
	granularity := int64(block.GetGranularity())
	latOffset := block.GetLatOffset()
	lonOffset := block.GetLonOffset()
	coordScale := 0.000000001
	lastKeyValPos := 0

	for i := range nodes {
		lastId += dense.Id[i]
		lastLon += dense.Lon[i]
		lastLat += dense.Lat[i]
		nodes[i].Id = lastId
		nodes[i].Long = (coordScale * float64(lonOffset+(granularity*lastLon)))
		nodes[i].Lat = (coordScale * float64(latOffset+(granularity*lastLat)))
		if stringtable != nil && len(dense.KeysVals) > 0 {
			if dense.KeysVals[lastKeyValPos] != 0 {
				nodes[i].Tags = ParseDenseNodeTags(stringtable, &dense.KeysVals, &lastKeyValPos)
			} else {
				lastKeyValPos += 1
			}
		}
	}
	return nodes
}

func ParseDenseNodeTags(stringtable StringTable, keysVals *[]int32, pos *int) map[string]string {
	result := make(map[string]string)
	for {
		if *pos >= len(*keysVals) {
			return result
		}
		key := (*keysVals)[*pos]
		*pos += 1
		if key == 0 {
			return result
		}
		val := (*keysVals)[*pos]
		*pos += 1
		result[stringtable[key]] = stringtable[val]
	}
}

func ParseTags(stringtable StringTable, keys []uint32, vals []uint32) map[string]string {
	tags := make(map[string]string)
	for i := 0; i < len(keys); i++ {
		key := stringtable[keys[i]]
		val := stringtable[vals[i]]
		tags[key] = val
	}
	return tags
}

func ReadNodes(
	nodes []*osmpbf.Node,
	block *osmpbf.PrimitiveBlock,
	stringtable StringTable) []element.Node {

	result := make([]element.Node, len(nodes))
	granularity := int64(block.GetGranularity())
	latOffset := block.GetLatOffset()
	lonOffset := block.GetLonOffset()
	coordScale := 0.000000001

	for i := range nodes {
		id := *nodes[i].Id
		lon := *nodes[i].Lon
		lat := *nodes[i].Lat
		result[i].Id = id
		result[i].Long = (coordScale * float64(lonOffset+(granularity*lon)))
		result[i].Lat = (coordScale * float64(latOffset+(granularity*lat)))
		if stringtable != nil {
			result[i].Tags = ParseTags(stringtable, nodes[i].Keys, nodes[i].Vals)
		}
	}
	return result
}

func ParseDeltaRefs(refs []int64) []int64 {
	result := make([]int64, len(refs))
	var lastRef int64

	for i, refDelta := range refs {
		lastRef += refDelta
		result[i] = lastRef
	}
	return result
}

func ReadWays(
	ways []*osmpbf.Way,
	block *osmpbf.PrimitiveBlock,
	stringtable StringTable) []element.Way {

	result := make([]element.Way, len(ways))

	for i := range ways {
		id := *ways[i].Id
		result[i].Id = id
		result[i].Tags = ParseTags(stringtable, ways[i].Keys, ways[i].Vals)
		result[i].Refs = ParseDeltaRefs(ways[i].Refs)
	}
	return result
}

func ParseRelationMembers(rel *osmpbf.Relation, stringtable StringTable) []element.Member {
	result := make([]element.Member, len(rel.Memids))

	var lastId int64
	for i := range rel.Memids {
		lastId += rel.Memids[i]
		result[i].Id = lastId
		result[i].Role = stringtable[rel.RolesSid[i]]
		result[i].Type = element.MemberType(rel.Types[i])
	}
	return result
}

func ReadRelations(
	relations []*osmpbf.Relation,
	block *osmpbf.PrimitiveBlock,
	stringtable StringTable) []element.Relation {

	result := make([]element.Relation, len(relations))

	for i := range relations {
		id := *relations[i].Id
		result[i].Id = id
		result[i].Tags = ParseTags(stringtable, relations[i].Keys, relations[i].Vals)
		result[i].Members = ParseRelationMembers(relations[i], stringtable)
	}
	return result
}

type StringTable []string

func NewStringTable(source *osmpbf.StringTable) StringTable {
	result := make(StringTable, len(source.S))
	for i, bytes := range source.S {
		result[i] = string(bytes)
	}
	return result
}

func PBFBlockPositions(filename string) chan BlockPosition {
	pbf, err := Open(filename)
	if err != nil {
		log.Fatal(err)
	}

	return pbf.BlockPositions()
}

func ParseBlock(pos BlockPosition, coords chan []element.Node, nodes chan []element.Node, ways chan []element.Way, relations chan []element.Relation) {
	block := ReadPrimitiveBlock(pos)
	stringtable := NewStringTable(block.GetStringtable())

	for _, group := range block.Primitivegroup {
		dense := group.GetDense()
		if dense != nil {
			parsedNodes := ReadDenseNodes(dense, block, stringtable)
			if len(parsedNodes) > 0 {
				nodes <- parsedNodes
				coords <- parsedNodes
			}
		}
		parsedNodes := ReadNodes(group.Nodes, block, stringtable)
		if len(parsedNodes) > 0 {
			nodes <- parsedNodes
			coords <- parsedNodes
		}
		parsedWays := ReadWays(group.Ways, block, stringtable)
		if len(parsedWays) > 0 {
			ways <- parsedWays
		}
		parsedRelations := ReadRelations(group.Relations, block, stringtable)
		if len(parsedRelations) > 0 {
			relations <- parsedRelations
		}
	}

}

func PBFStats(filename string) {
	pbf, err := Open(filename)
	if err != nil {
		log.Fatal(err)
	}

	var nodesCounter, relationsCounter, waysCounter int

	for pos := range pbf.BlockPositions() {
		block := ReadPrimitiveBlock(pos)
		stringtable := NewStringTable(block.GetStringtable())

		for _, group := range block.Primitivegroup {
			dense := group.GetDense()
			if dense != nil {
				_ = ReadDenseNodes(dense, block, stringtable)
				nodesCounter += len(dense.Id)
			}
			_ = ReadNodes(group.Nodes, block, stringtable)
			nodesCounter += len(group.Nodes)
			waysCounter += len(group.Ways)
			_ = ReadWays(group.Ways, block, stringtable)
			relationsCounter += len(group.Relations)
			_ = ReadRelations(group.Relations, block, stringtable)

		}
	}
	fmt.Printf("nodes: %v\tways: %v\trelations:%v\n", nodesCounter, waysCounter, relationsCounter)
}
<commit_msg>use seprarate slice for nodes and coords in parser<commit_after>package parser

import (
	"fmt"
	"goposm/element"
	"goposm/parser/osmpbf"
	"log"
	"os"
)

type PBF struct {
	file     *os.File
	filename string
	offset   int64
}

type BlockPosition struct {
	Filename string
	Offset   int64
	Size     int32
}

func Open(filename string) (f *PBF, err error) {
	file, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	f = &PBF{filename: filename, file: file}
	return f, nil
}

func (pbf *PBF) Close() error {
	return pbf.file.Close()
}

func (pbf *PBF) NextDataPosition() (offset int64, size int32) {
	header := pbf.nextBlobHeader()
	size = header.GetDatasize()
	offset = pbf.offset

	pbf.offset += int64(size)
	pbf.file.Seek(pbf.offset, 0)

	if header.GetType() == "OSMHeader" {
		return pbf.NextDataPosition()
	}
	return
}

const COORD_FACTOR float64 = 11930464.7083 // ((2<<31)-1)/360.0

func coordToInt(coord float64) uint32 {
	return uint32((coord + 180.0) * COORD_FACTOR)
}

func intToCoord(coord uint32) float64 {
	return float64((float64(coord) / COORD_FACTOR) - 180.0)
}

func ReadDenseNodes(
	dense *osmpbf.DenseNodes,
	block *osmpbf.PrimitiveBlock,
	stringtable StringTable) (coords []element.Node, nodes []element.Node) {

	var lastId int64
	var lastLon, lastLat int64
	coords = make([]element.Node, len(dense.Id))
	nodes = make([]element.Node, 0, len(dense.Id)/8)
	granularity := int64(block.GetGranularity())
	latOffset := block.GetLatOffset()
	lonOffset := block.GetLonOffset()
	coordScale := 0.000000001
	lastKeyValPos := 0

	for i := range coords {
		lastId += dense.Id[i]
		lastLon += dense.Lon[i]
		lastLat += dense.Lat[i]
		coords[i].Id = lastId
		coords[i].Long = (coordScale * float64(lonOffset+(granularity*lastLon)))
		coords[i].Lat = (coordScale * float64(latOffset+(granularity*lastLat)))
		if stringtable != nil && len(dense.KeysVals) > 0 {
			if dense.KeysVals[lastKeyValPos] != 0 {
				tags := ParseDenseNodeTags(stringtable, &dense.KeysVals, &lastKeyValPos)
				if tags != nil {
					if _, ok := tags["created_by"]; ok && len(tags) == 1 {
						// don't add nodes with only created_by tag to nodes cache
					} else {
						nd := coords[i]
						nd.Tags = tags
						nodes = append(nodes, nd)
					}
				}
			} else {
				lastKeyValPos += 1
			}
		}
	}

	return coords, nodes
}

func ParseDenseNodeTags(stringtable StringTable, keysVals *[]int32, pos *int) map[string]string {
	result := make(map[string]string)
	for {
		if *pos >= len(*keysVals) {
			return result
		}
		key := (*keysVals)[*pos]
		*pos += 1
		if key == 0 {
			return result
		}
		val := (*keysVals)[*pos]
		*pos += 1
		result[stringtable[key]] = stringtable[val]
	}
}

func ParseTags(stringtable StringTable, keys []uint32, vals []uint32) map[string]string {
	tags := make(map[string]string)
	for i := 0; i < len(keys); i++ {
		key := stringtable[keys[i]]
		val := stringtable[vals[i]]
		tags[key] = val
	}
	return tags
}

func ReadNodes(
	nodes []*osmpbf.Node,
	block *osmpbf.PrimitiveBlock,
	stringtable StringTable) ([]element.Node, []element.Node) {

	coords := make([]element.Node, len(nodes))
	nds := make([]element.Node, 0, len(nodes)/8)
	granularity := int64(block.GetGranularity())
	latOffset := block.GetLatOffset()
	lonOffset := block.GetLonOffset()
	coordScale := 0.000000001

	for i := range nodes {
		id := *nodes[i].Id
		lon := *nodes[i].Lon
		lat := *nodes[i].Lat
		coords[i].Id = id
		coords[i].Long = (coordScale * float64(lonOffset+(granularity*lon)))
		coords[i].Lat = (coordScale * float64(latOffset+(granularity*lat)))
		if stringtable != nil {
			tags := ParseTags(stringtable, nodes[i].Keys, nodes[i].Vals)
			if tags != nil {
				if _, ok := tags["created_by"]; ok && len(tags) == 1 {
					// don't add nodes with only created_by tag to nodes cache
				} else {
					nd := coords[i]
					nd.Tags = tags
					nds = append(nds, nd)
				}
			}
		}
	}
	return coords, nds
}

func ParseDeltaRefs(refs []int64) []int64 {
	result := make([]int64, len(refs))
	var lastRef int64

	for i, refDelta := range refs {
		lastRef += refDelta
		result[i] = lastRef
	}
	return result
}

func ReadWays(
	ways []*osmpbf.Way,
	block *osmpbf.PrimitiveBlock,
	stringtable StringTable) []element.Way {

	result := make([]element.Way, len(ways))

	for i := range ways {
		id := *ways[i].Id
		result[i].Id = id
		result[i].Tags = ParseTags(stringtable, ways[i].Keys, ways[i].Vals)
		result[i].Refs = ParseDeltaRefs(ways[i].Refs)
	}
	return result
}

func ParseRelationMembers(rel *osmpbf.Relation, stringtable StringTable) []element.Member {
	result := make([]element.Member, len(rel.Memids))

	var lastId int64
	for i := range rel.Memids {
		lastId += rel.Memids[i]
		result[i].Id = lastId
		result[i].Role = stringtable[rel.RolesSid[i]]
		result[i].Type = element.MemberType(rel.Types[i])
	}
	return result
}

func ReadRelations(
	relations []*osmpbf.Relation,
	block *osmpbf.PrimitiveBlock,
	stringtable StringTable) []element.Relation {

	result := make([]element.Relation, len(relations))

	for i := range relations {
		id := *relations[i].Id
		result[i].Id = id
		result[i].Tags = ParseTags(stringtable, relations[i].Keys, relations[i].Vals)
		result[i].Members = ParseRelationMembers(relations[i], stringtable)
	}
	return result
}

type StringTable []string

func NewStringTable(source *osmpbf.StringTable) StringTable {
	result := make(StringTable, len(source.S))
	for i, bytes := range source.S {
		result[i] = string(bytes)
	}
	return result
}

func PBFBlockPositions(filename string) chan BlockPosition {
	pbf, err := Open(filename)
	if err != nil {
		log.Fatal(err)
	}

	return pbf.BlockPositions()
}

func ParseBlock(pos BlockPosition, coords chan []element.Node, nodes chan []element.Node, ways chan []element.Way, relations chan []element.Relation) {
	block := ReadPrimitiveBlock(pos)
	stringtable := NewStringTable(block.GetStringtable())

	for _, group := range block.Primitivegroup {
		dense := group.GetDense()
		if dense != nil {
			parsedCoords, parsedNodes := ReadDenseNodes(dense, block, stringtable)
			if len(parsedCoords) > 0 {
				coords <- parsedCoords
			}
			if len(parsedNodes) > 0 {
				nodes <- parsedNodes
			}
		}
		parsedCoords, parsedNodes := ReadNodes(group.Nodes, block, stringtable)
		if len(parsedCoords) > 0 {
			coords <- parsedCoords
		}
		if len(parsedNodes) > 0 {
			nodes <- parsedNodes
		}
		parsedWays := ReadWays(group.Ways, block, stringtable)
		if len(parsedWays) > 0 {
			ways <- parsedWays
		}
		parsedRelations := ReadRelations(group.Relations, block, stringtable)
		if len(parsedRelations) > 0 {
			relations <- parsedRelations
		}
	}

}

func PBFStats(filename string) {
	pbf, err := Open(filename)
	if err != nil {
		log.Fatal(err)
	}

	var nodesCounter, relationsCounter, waysCounter int

	for pos := range pbf.BlockPositions() {
		block := ReadPrimitiveBlock(pos)
		stringtable := NewStringTable(block.GetStringtable())

		for _, group := range block.Primitivegroup {
			dense := group.GetDense()
			if dense != nil {
				_, _ = ReadDenseNodes(dense, block, stringtable)
				nodesCounter += len(dense.Id)
			}
			_, _ = ReadNodes(group.Nodes, block, stringtable)
			nodesCounter += len(group.Nodes)
			waysCounter += len(group.Ways)
			_ = ReadWays(group.Ways, block, stringtable)
			relationsCounter += len(group.Relations)
			_ = ReadRelations(group.Relations, block, stringtable)

		}
	}
	fmt.Printf("nodes: %v\tways: %v\trelations:%v\n", nodesCounter, waysCounter, relationsCounter)
}
<|endoftext|>


<commit_before>package jsonpatch

import (
	"bytes"
	"encoding/json"
	"fmt"
	"testing"
)

func reformatJSON(j string) string {
	buf := new(bytes.Buffer)

	json.Indent(buf, []byte(j), "", "  ")

	return buf.String()
}

func compareJSON(a, b string) bool {
	return Equal([]byte(a), []byte(b))
}

func applyPatch(doc, patch string) (string, error) {
	obj, err := DecodePatch([]byte(patch))

	if err != nil {
		panic(err)
	}

	out, err := obj.Apply([]byte(doc))

	if err != nil {
		return "", err
	}

	return string(out), nil
}

type Case struct {
	doc, patch, result string
}

var Cases = []Case{
	{
		`{ "foo": "bar"}`,
		`[
         { "op": "add", "path": "/baz", "value": "qux" }
     ]`,
		`{
       "baz": "qux",
       "foo": "bar"
     }`,
	},
	{
		`{ "foo": [ "bar", "baz" ] }`,
		`[
     { "op": "add", "path": "/foo/1", "value": "qux" }
    ]`,
		`{ "foo": [ "bar", "qux", "baz" ] }`,
	},
	{
		`{ "baz": "qux", "foo": "bar" }`,
		`[ { "op": "remove", "path": "/baz" } ]`,
		`{ "foo": "bar" }`,
	},
	{
		`{ "foo": [ "bar", "qux", "baz" ] }`,
		`[ { "op": "remove", "path": "/foo/1" } ]`,
		`{ "foo": [ "bar", "baz" ] }`,
	},
	{
		`{ "baz": "qux", "foo": "bar" }`,
		`[ { "op": "replace", "path": "/baz", "value": "boo" } ]`,
		`{ "baz": "boo", "foo": "bar" }`,
	},
	{
		`{
     "foo": {
       "bar": "baz",
       "waldo": "fred"
     },
     "qux": {
       "corge": "grault"
     }
   }`,
		`[ { "op": "move", "from": "/foo/waldo", "path": "/qux/thud" } ]`,
		`{
     "foo": {
       "bar": "baz"
     },
     "qux": {
       "corge": "grault",
       "thud": "fred"
     }
   }`,
	},
	{
		`{ "foo": [ "all", "grass", "cows", "eat" ] }`,
		`[ { "op": "move", "from": "/foo/1", "path": "/foo/3" } ]`,
		`{ "foo": [ "all", "cows", "eat", "grass" ] }`,
	},
	{
		`{ "foo": "bar" }`,
		`[ { "op": "add", "path": "/child", "value": { "grandchild": { } } } ]`,
		`{ "foo": "bar", "child": { "grandchild": { } } }`,
	},
	{
		`{ "foo": ["bar"] }`,
		`[ { "op": "add", "path": "/foo/-", "value": ["abc", "def"] } ]`,
		`{ "foo": ["bar", ["abc", "def"]] }`,
	},
}

type BadCase struct {
	doc, patch string
}

var BadCases = []BadCase{
	{
		`{ "foo": "bar" }`,
		`[ { "op": "add", "path": "/baz/bat", "value": "qux" } ]`,
	},
}

func TestAllCases(t *testing.T) {
	for _, c := range Cases {
		out, err := applyPatch(c.doc, c.patch)

		if err != nil {
			t.Errorf("Unable to apply patch: %s", err)
		}

		if !compareJSON(out, c.result) {
			t.Errorf("Patch did not apply. Expected:\n%s\n\nActual:\n%s",
				reformatJSON(c.result), reformatJSON(out))
		}
	}

	for _, c := range BadCases {
		_, err := applyPatch(c.doc, c.patch)

		if err == nil {
			t.Errorf("Patch should have failed to apply but it did not")
		}
	}
}

type TestCase struct {
	doc, patch string
	result     bool
	failedPath string
}

var TestCases = []TestCase{
	{
		`{
       "baz": "qux",
       "foo": [ "a", 2, "c" ]
     }`,
		`[
       { "op": "test", "path": "/baz", "value": "qux" },
       { "op": "test", "path": "/foo/1", "value": 2 }
     ]`,
		true,
		"",
	},
	{
		`{ "baz": "qux" }`,
		`[ { "op": "test", "path": "/baz", "value": "bar" } ]`,
		false,
		"/baz",
	},
	{
		`{
       "baz": "qux",
       "foo": ["a", 2, "c"]
     }`,
		`[
       { "op": "test", "path": "/baz", "value": "qux" },
       { "op": "test", "path": "/foo/1", "value": "c" }
     ]`,
		false,
		"/foo/1",
	},
}

func TestAllTest(t *testing.T) {
	for _, c := range TestCases {
		_, err := applyPatch(c.doc, c.patch)

		if c.result && err != nil {
			t.Errorf("Testing failed when it should have passed: %s", err)
		} else if !c.result && err == nil {
			t.Errorf("Testing passed when it should have faild", err)
		} else if !c.result {
			expected := fmt.Sprintf("Testing value %s failed", c.failedPath)
			if err.Error() != expected {
				t.Errorf("Testing failed as expected but invalid message: expected [%s], got [%s]", expected, err)
			}
		}
	}
}
<commit_msg>Align with tabs, even the multiline strings<commit_after>package jsonpatch

import (
	"bytes"
	"encoding/json"
	"fmt"
	"testing"
)

func reformatJSON(j string) string {
	buf := new(bytes.Buffer)

	json.Indent(buf, []byte(j), "", "  ")

	return buf.String()
}

func compareJSON(a, b string) bool {
	return Equal([]byte(a), []byte(b))
}

func applyPatch(doc, patch string) (string, error) {
	obj, err := DecodePatch([]byte(patch))

	if err != nil {
		panic(err)
	}

	out, err := obj.Apply([]byte(doc))

	if err != nil {
		return "", err
	}

	return string(out), nil
}

type Case struct {
	doc, patch, result string
}

var Cases = []Case{
	{
		`{ "foo": "bar"}`,
		`[
         { "op": "add", "path": "/baz", "value": "qux" }
     ]`,
		`{
       "baz": "qux",
       "foo": "bar"
     }`,
	},
	{
		`{ "foo": [ "bar", "baz" ] }`,
		`[
     { "op": "add", "path": "/foo/1", "value": "qux" }
    ]`,
		`{ "foo": [ "bar", "qux", "baz" ] }`,
	},
	{
		`{ "baz": "qux", "foo": "bar" }`,
		`[ { "op": "remove", "path": "/baz" } ]`,
		`{ "foo": "bar" }`,
	},
	{
		`{ "foo": [ "bar", "qux", "baz" ] }`,
		`[ { "op": "remove", "path": "/foo/1" } ]`,
		`{ "foo": [ "bar", "baz" ] }`,
	},
	{
		`{ "baz": "qux", "foo": "bar" }`,
		`[ { "op": "replace", "path": "/baz", "value": "boo" } ]`,
		`{ "baz": "boo", "foo": "bar" }`,
	},
	{
		`{
     "foo": {
       "bar": "baz",
       "waldo": "fred"
     },
     "qux": {
       "corge": "grault"
     }
   }`,
		`[ { "op": "move", "from": "/foo/waldo", "path": "/qux/thud" } ]`,
		`{
     "foo": {
       "bar": "baz"
     },
     "qux": {
       "corge": "grault",
       "thud": "fred"
     }
   }`,
	},
	{
		`{ "foo": [ "all", "grass", "cows", "eat" ] }`,
		`[ { "op": "move", "from": "/foo/1", "path": "/foo/3" } ]`,
		`{ "foo": [ "all", "cows", "eat", "grass" ] }`,
	},
	{
		`{ "foo": "bar" }`,
		`[ { "op": "add", "path": "/child", "value": { "grandchild": { } } } ]`,
		`{ "foo": "bar", "child": { "grandchild": { } } }`,
	},
	{
		`{ "foo": ["bar"] }`,
		`[ { "op": "add", "path": "/foo/-", "value": ["abc", "def"] } ]`,
		`{ "foo": ["bar", ["abc", "def"]] }`,
	},
}

type BadCase struct {
	doc, patch string
}

var BadCases = []BadCase{
	{
		`{ "foo": "bar" }`,
		`[ { "op": "add", "path": "/baz/bat", "value": "qux" } ]`,
	},
}

func TestAllCases(t *testing.T) {
	for _, c := range Cases {
		out, err := applyPatch(c.doc, c.patch)

		if err != nil {
			t.Errorf("Unable to apply patch: %s", err)
		}

		if !compareJSON(out, c.result) {
			t.Errorf("Patch did not apply. Expected:\n%s\n\nActual:\n%s",
				reformatJSON(c.result), reformatJSON(out))
		}
	}

	for _, c := range BadCases {
		_, err := applyPatch(c.doc, c.patch)

		if err == nil {
			t.Errorf("Patch should have failed to apply but it did not")
		}
	}
}

type TestCase struct {
	doc, patch string
	result     bool
	failedPath string
}

var TestCases = []TestCase{
	{
		`{
			"baz": "qux",
			"foo": [ "a", 2, "c" ]
		}`,
		`[
			{ "op": "test", "path": "/baz", "value": "qux" },
			{ "op": "test", "path": "/foo/1", "value": 2 }
		]`,
		true,
		"",
	},
	{
		`{ "baz": "qux" }`,
		`[ { "op": "test", "path": "/baz", "value": "bar" } ]`,
		false,
		"/baz",
	},
	{
		`{
			"baz": "qux",
			"foo": ["a", 2, "c"]
		}`,
		`[
			{ "op": "test", "path": "/baz", "value": "qux" },
			{ "op": "test", "path": "/foo/1", "value": "c" }
		]`,
		false,
		"/foo/1",
	},
}

func TestAllTest(t *testing.T) {
	for _, c := range TestCases {
		_, err := applyPatch(c.doc, c.patch)

		if c.result && err != nil {
			t.Errorf("Testing failed when it should have passed: %s", err)
		} else if !c.result && err == nil {
			t.Errorf("Testing passed when it should have faild", err)
		} else if !c.result {
			expected := fmt.Sprintf("Testing value %s failed", c.failedPath)
			if err.Error() != expected {
				t.Errorf("Testing failed as expected but invalid message: expected [%s], got [%s]", expected, err)
			}
		}
	}
}
<|endoftext|>


<commit_before>package skill

import (
	"github.com/fudanchii/sifr/irc"
)

func canPermit(msg *irc.Message) bool {
    // Stub...
    return true
}

func addAuthorizedIdent(c *irc.Client, m *irc.Message) {
    // w.i.p.
}
<commit_msg>Stub for command authorization<commit_after>package skill

import (
	"github.com/fudanchii/sifr/irc"
)

func canPermit(msg *irc.Message) bool {
	// Stub...
	return true
}

func addAuthorizedIdent(c *irc.Client, m *irc.Message) {
	// w.i.p.
}
<|endoftext|>


<commit_before>package digitalocean

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

	"github.com/JamesClonk/easy-vpn/config"
	"github.com/stretchr/testify/assert"
)

var testConfig *config.Config

func init() {
	var err error
	testConfig, err = config.LoadConfiguration("../../fixtures/config_test.toml")
	if err != nil {
		log.Println(err)
	}
}

func getTestServer(code int, body string) *httptest.Server {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(code)
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprint(w, body)
	}))
	baseUrl = ts.URL
	return ts
}

func Test_Provider_Digitalocean_GetProviderName(t *testing.T) {
	d := DO{Config: testConfig}
	if assert.NotNil(t, d) {
		assert.Equal(t, "digitalocean", d.GetProviderName())
	}
}

func Test_Provider_Digitalocean_GetConfig(t *testing.T) {
	d := DO{Config: testConfig}
	cfg := d.GetConfig()
	if assert.NotNil(t, cfg) {
		assert.Equal(t, testConfig, cfg)
	}
}

func Test_Provider_Digitalocean_GetInstalledSshKeys_Error(t *testing.T) {
	server := getTestServer(http.StatusNotAcceptable, `{error-message}`)
	defer server.Close()

	d := DO{Config: testConfig}

	keys, err := d.GetInstalledSshKeys()
	assert.Nil(t, keys)
	if assert.NotNil(t, err) {
		assert.Equal(t, `{error-message}`, err.Error())
	}
}

func Test_Provider_Digitalocean_GetInstalledSshKeys_NoKeys(t *testing.T) {
	server := getTestServer(http.StatusOK,
		`{"ssh_keys": [], "links": {}, "meta": {"total": 0}}`)
	defer server.Close()

	d := DO{Config: testConfig}

	keys, err := d.GetInstalledSshKeys()
	if err != nil {
		t.Error(err)
	}
	assert.Nil(t, keys)
}

func Test_Provider_Digitalocean_GetInstalledSshKeys_Keys(t *testing.T) {
	server := getTestServer(http.StatusOK,
		`{"ssh_keys": [
			{"id": 1, "fingerprint": "who cares", "public_key": "aaaa", "name": "alpha"},
			{"id": 2, "fingerprint": "who cares", "public_key": "bbbb", "name": "beta"},
			{"id": 3, "fingerprint": "who cares", "public_key": "cccc", "name": "charlie"}
			], "links": {}, "meta": {"total": 3}
		}`)
	defer server.Close()

	d := DO{Config: testConfig}

	keys, err := d.GetInstalledSshKeys()
	if err != nil {
		t.Error(err)
	}
	if assert.NotNil(t, keys) {
		assert.Equal(t, 3, len(keys))
		// keys can be in random order
		for _, key := range keys {
			switch key.Id {
			case "1":
				assert.Equal(t, "aaaa", key.Key)
			case "2":
				assert.Equal(t, "bbbb", key.Key)
			case "3":
				assert.Equal(t, "charlie", key.Name)
			default:
				t.Error("Unknown Key Id")
			}
		}
	}
}

func Test_Provider_Digitalocean_InstallNewSshKey_Error(t *testing.T) {
	server := getTestServer(http.StatusNotAcceptable, `{error-message}`)
	defer server.Close()

	d := DO{Config: testConfig}

	keyId, err := d.InstallNewSshKey("delta", "ddddd")
	assert.Equal(t, "", keyId)
	if assert.NotNil(t, err) {
		assert.Equal(t, `{error-message}`, err.Error())
	}
}

func Test_Provider_Digitalocean_InstallNewSshKey_NoKeyId(t *testing.T) {
	server := getTestServer(http.StatusCreated, `{error-message}`)
	defer server.Close()

	d := DO{Config: testConfig}

	keyId, err := d.InstallNewSshKey("delta", "ddddd")
	assert.Equal(t, "", keyId)
	if assert.NotNil(t, err) {
		assert.Equal(t, `{error-message}`, err.Error())
	}
}

func Test_Provider_Digitalocean_InstallNewSshKey_KeyId(t *testing.T) {
	server := getTestServer(http.StatusCreated,
		`{"ssh_key":{"id":4,"public_key":"ddddd","name":"My SSH Public Key"}}`)
	defer server.Close()

	d := DO{Config: testConfig}

	keyId, err := d.InstallNewSshKey("delta", "ddddd")
	if err != nil {
		t.Error(err)
	}
	if assert.NotNil(t, keyId) {
		assert.Equal(t, "4", keyId)
	}
}

func Test_Provider_Digitalocean_DeleteSshKey_Error(t *testing.T) {
	server := getTestServer(http.StatusNotAcceptable, `{error-message}`)
	defer server.Close()

	d := DO{Config: testConfig}

	err := d.deleteSshKey("123")
	if assert.NotNil(t, err) {
		assert.Equal(t, `{error-message}`, err.Error())
	}
}

func Test_Provider_Digitalocean_DeleteSshKey_Deleted(t *testing.T) {
	server := getTestServer(http.StatusNoContent, `{no-response?!}`)
	defer server.Close()

	d := DO{Config: testConfig}

	err := d.deleteSshKey("123")
	if err != nil {
		t.Error(err)
	}
}

func Test_Provider_Digitalocean_GetAllVMs_Error(t *testing.T) {
	server := getTestServer(http.StatusNotAcceptable, `{error-message}`)
	defer server.Close()

	d := DO{Config: testConfig}

	machines, err := d.GetAllVMs()
	assert.Nil(t, machines)
	if assert.NotNil(t, err) {
		assert.Equal(t, `{error-message}`, err.Error())
	}
}

func Test_Provider_Digitalocean_GetAllVMs_NoVMs(t *testing.T) {
	server := getTestServer(http.StatusOK, `{"droplets": [],"links": {},"meta": {"total": 0}}`)
	defer server.Close()

	d := DO{Config: testConfig}

	machines, err := d.GetAllVMs()
	if err != nil {
		t.Error(err)
	}
	assert.Nil(t, machines)
}

func Test_Provider_Digitalocean_GetAllVMs_VMs(t *testing.T) {
	server := getTestServer(http.StatusOK, `{"droplets": [{
    "id": 1111,
    "name": "example.com",
    "memory": 512,
    "disk": 20,
    "status": "active",
    "image": {
        "id": 6918990,
        "name": "14.04 x64",
        "distribution": "Ubuntu",
        "slug": "ubuntu-14-04-x64"
    },
    "size_slug": "512mb",
    "networks": {
        "v4": [{
            "ip_address": "104.236.32.111",
            "netmask": "255.255.192.0",
            "gateway": "104.236.0.1",
            "type": "public"
        }],
        "v6": [{}]
    },
    "region": {
        "name": "New York 3",
        "slug": "nyc3"
    }
},{
    "id": 7777,
    "name": "example.com",
    "memory": 512,
    "status": "active",
    "image": {
        "id": 123,
        "distribution": "CentOS",
        "slug": "centos-x64"
    },
    "size_slug": "512mb",
    "networks": {
        "v4": [{
            "ip_address": "104.236.32.999",
            "netmask": "255.255.192.0",
            "gateway": "104.236.0.1",
            "type": "public"
        }]
    },
    "region": {
        "name": "New York 2",
        "slug": "nyc2"
    }
},{
    "id": 9999,
    "name": "test.com",
    "memory": 1024,
    "status": "stopped",
    "image": {
        "slug": "ubuntu-14-10-x64"
    },
    "networks": {"v4": [{"ip_address": "104.236.32.777"}]},
    "region": {
        "name": "New York 1",
        "slug": "nyc1"
    }
}],"links": {},"meta": {"total": 3}}`)
	defer server.Close()

	d := DO{Config: testConfig}

	machines, err := d.GetAllVMs()
	if err != nil {
		t.Error(err)
	}
	if assert.NotNil(t, machines) {
		assert.Equal(t, 3, len(machines))
		// machines can be in random order
		for _, vm := range machines {
			switch vm.Id {
			case "1111":
				assert.Equal(t, "example.com", vm.Name)
				assert.Equal(t, "ubuntu-14-04-x64", vm.OS)
				assert.Equal(t, "nyc3", vm.Region)
				assert.Equal(t, "active", vm.Status)
			case "7777":
				assert.Equal(t, "nyc2", vm.Region)
				assert.Equal(t, "104.236.32.999", vm.IP)
				assert.Equal(t, "centos-x64", vm.OS)
			case "9999":
				assert.Equal(t, "test.com", vm.Name)
				assert.Equal(t, "stopped", vm.Status)
				assert.Equal(t, "104.236.32.777", vm.IP)
			default:
				t.Error("Unknown VM Id")
			}
		}
	}
}
<commit_msg>add tests for DO droplet actions<commit_after>package digitalocean

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

	"github.com/JamesClonk/easy-vpn/config"
	"github.com/stretchr/testify/assert"
)

var testConfig *config.Config

func init() {
	var err error
	testConfig, err = config.LoadConfiguration("../../fixtures/config_test.toml")
	if err != nil {
		log.Println(err)
	}
}

func getTestServer(code int, body string) *httptest.Server {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(code)
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprint(w, body)
	}))
	baseUrl = ts.URL
	return ts
}

func Test_Provider_Digitalocean_GetProviderName(t *testing.T) {
	d := DO{Config: testConfig}
	if assert.NotNil(t, d) {
		assert.Equal(t, "digitalocean", d.GetProviderName())
	}
}

func Test_Provider_Digitalocean_GetConfig(t *testing.T) {
	d := DO{Config: testConfig}
	cfg := d.GetConfig()
	if assert.NotNil(t, cfg) {
		assert.Equal(t, testConfig, cfg)
	}
}

func Test_Provider_Digitalocean_GetInstalledSshKeys_Error(t *testing.T) {
	server := getTestServer(http.StatusNotAcceptable, `{error-message}`)
	defer server.Close()

	d := DO{Config: testConfig}

	keys, err := d.GetInstalledSshKeys()
	assert.Nil(t, keys)
	if assert.NotNil(t, err) {
		assert.Equal(t, `{error-message}`, err.Error())
	}
}

func Test_Provider_Digitalocean_GetInstalledSshKeys_NoKeys(t *testing.T) {
	server := getTestServer(http.StatusOK,
		`{"ssh_keys": [], "links": {}, "meta": {"total": 0}}`)
	defer server.Close()

	d := DO{Config: testConfig}

	keys, err := d.GetInstalledSshKeys()
	if err != nil {
		t.Error(err)
	}
	assert.Nil(t, keys)
}

func Test_Provider_Digitalocean_GetInstalledSshKeys_Keys(t *testing.T) {
	server := getTestServer(http.StatusOK,
		`{"ssh_keys": [
			{"id": 1, "fingerprint": "who cares", "public_key": "aaaa", "name": "alpha"},
			{"id": 2, "fingerprint": "who cares", "public_key": "bbbb", "name": "beta"},
			{"id": 3, "fingerprint": "who cares", "public_key": "cccc", "name": "charlie"}
			], "links": {}, "meta": {"total": 3}
		}`)
	defer server.Close()

	d := DO{Config: testConfig}

	keys, err := d.GetInstalledSshKeys()
	if err != nil {
		t.Error(err)
	}
	if assert.NotNil(t, keys) {
		assert.Equal(t, 3, len(keys))
		// keys can be in random order
		for _, key := range keys {
			switch key.Id {
			case "1":
				assert.Equal(t, "aaaa", key.Key)
			case "2":
				assert.Equal(t, "bbbb", key.Key)
			case "3":
				assert.Equal(t, "charlie", key.Name)
			default:
				t.Error("Unknown Key Id")
			}
		}
	}
}

func Test_Provider_Digitalocean_InstallNewSshKey_Error(t *testing.T) {
	server := getTestServer(http.StatusNotAcceptable, `{error-message}`)
	defer server.Close()

	d := DO{Config: testConfig}

	keyId, err := d.InstallNewSshKey("delta", "ddddd")
	assert.Equal(t, "", keyId)
	if assert.NotNil(t, err) {
		assert.Equal(t, `{error-message}`, err.Error())
	}
}

func Test_Provider_Digitalocean_InstallNewSshKey_NoKeyId(t *testing.T) {
	server := getTestServer(http.StatusCreated, `{error-message}`)
	defer server.Close()

	d := DO{Config: testConfig}

	keyId, err := d.InstallNewSshKey("delta", "ddddd")
	assert.Equal(t, "", keyId)
	if assert.NotNil(t, err) {
		assert.Equal(t, `{error-message}`, err.Error())
	}
}

func Test_Provider_Digitalocean_InstallNewSshKey_KeyId(t *testing.T) {
	server := getTestServer(http.StatusCreated,
		`{"ssh_key":{"id":4,"public_key":"ddddd","name":"My SSH Public Key"}}`)
	defer server.Close()

	d := DO{Config: testConfig}

	keyId, err := d.InstallNewSshKey("delta", "ddddd")
	if err != nil {
		t.Error(err)
	}
	if assert.NotNil(t, keyId) {
		assert.Equal(t, "4", keyId)
	}
}

func Test_Provider_Digitalocean_DeleteSshKey_Error(t *testing.T) {
	server := getTestServer(http.StatusNotAcceptable, `{error-message}`)
	defer server.Close()

	d := DO{Config: testConfig}

	err := d.deleteSshKey("123")
	if assert.NotNil(t, err) {
		assert.Equal(t, `{error-message}`, err.Error())
	}
}

func Test_Provider_Digitalocean_DeleteSshKey_Deleted(t *testing.T) {
	server := getTestServer(http.StatusNoContent, `{no-response?!}`)
	defer server.Close()

	d := DO{Config: testConfig}

	err := d.deleteSshKey("123")
	if err != nil {
		t.Error(err)
	}
}

func Test_Provider_Digitalocean_GetAllVMs_Error(t *testing.T) {
	server := getTestServer(http.StatusNotAcceptable, `{error-message}`)
	defer server.Close()

	d := DO{Config: testConfig}

	machines, err := d.GetAllVMs()
	assert.Nil(t, machines)
	if assert.NotNil(t, err) {
		assert.Equal(t, `{error-message}`, err.Error())
	}
}

func Test_Provider_Digitalocean_GetAllVMs_NoVMs(t *testing.T) {
	server := getTestServer(http.StatusOK, `{"droplets": [],"links": {},"meta": {"total": 0}}`)
	defer server.Close()

	d := DO{Config: testConfig}

	machines, err := d.GetAllVMs()
	if err != nil {
		t.Error(err)
	}
	assert.Nil(t, machines)
}

func Test_Provider_Digitalocean_GetAllVMs_VMs(t *testing.T) {
	server := getTestServer(http.StatusOK, `{"droplets": [{
    "id": 1111,
    "name": "example.com",
    "memory": 512,
    "disk": 20,
    "status": "active",
    "image": {
        "id": 6918990,
        "name": "14.04 x64",
        "distribution": "Ubuntu",
        "slug": "ubuntu-14-04-x64"
    },
    "size_slug": "512mb",
    "networks": {
        "v4": [{
            "ip_address": "104.236.32.111",
            "netmask": "255.255.192.0",
            "gateway": "104.236.0.1",
            "type": "public"
        }],
        "v6": [{}]
    },
    "region": {
        "name": "New York 3",
        "slug": "nyc3"
    }
},{
    "id": 7777,
    "name": "example.com",
    "memory": 512,
    "status": "active",
    "image": {
        "id": 123,
        "distribution": "CentOS",
        "slug": "centos-x64"
    },
    "size_slug": "512mb",
    "networks": {
        "v4": [{
            "ip_address": "104.236.32.999",
            "netmask": "255.255.192.0",
            "gateway": "104.236.0.1",
            "type": "public"
        }]
    },
    "region": {
        "name": "New York 2",
        "slug": "nyc2"
    }
},{
    "id": 9999,
    "name": "test.com",
    "memory": 1024,
    "status": "stopped",
    "image": {
        "slug": "ubuntu-14-10-x64"
    },
    "networks": {"v4": [{"ip_address": "104.236.32.777"}]},
    "region": {
        "name": "New York 1",
        "slug": "nyc1"
    }
}],"links": {},"meta": {"total": 3}}`)
	defer server.Close()

	d := DO{Config: testConfig}

	machines, err := d.GetAllVMs()
	if err != nil {
		t.Error(err)
	}
	if assert.NotNil(t, machines) {
		assert.Equal(t, 3, len(machines))
		// machines can be in random order
		for _, vm := range machines {
			switch vm.Id {
			case "1111":
				assert.Equal(t, "example.com", vm.Name)
				assert.Equal(t, "ubuntu-14-04-x64", vm.OS)
				assert.Equal(t, "nyc3", vm.Region)
				assert.Equal(t, "active", vm.Status)
			case "7777":
				assert.Equal(t, "nyc2", vm.Region)
				assert.Equal(t, "104.236.32.999", vm.IP)
				assert.Equal(t, "centos-x64", vm.OS)
			case "9999":
				assert.Equal(t, "test.com", vm.Name)
				assert.Equal(t, "stopped", vm.Status)
				assert.Equal(t, "104.236.32.777", vm.IP)
			default:
				t.Error("Unknown VM Id")
			}
		}
	}
}

func Test_Provider_Digitalocean_CreateVM_Error(t *testing.T) {
	server := getTestServer(http.StatusNotAcceptable, `{error-message}`)
	defer server.Close()

	d := DO{Config: testConfig}

	vmId, err := d.CreateVM("test-vm", "test-os", "test-size", "test-region", "test-key-id")
	assert.Equal(t, "", vmId)
	if assert.NotNil(t, err) {
		assert.Equal(t, `{error-message}`, err.Error())
	}
}

func Test_Provider_Digitalocean_CreateVM_NoVMId(t *testing.T) {
	server := getTestServer(http.StatusOK, `{error-message}`)
	defer server.Close()

	d := DO{Config: testConfig}

	vmId, err := d.CreateVM("test-vm", "test-os", "test-size", "test-region", "test-key-id")
	assert.Equal(t, "", vmId)
	if assert.NotNil(t, err) {
		assert.Equal(t, `{error-message}`, err.Error())
	}
}

func Test_Provider_Digitalocean_CreateVM_VMId(t *testing.T) {
	server := getTestServer(http.StatusOK, `{"droplet":{"id":3333,"name":"example.com","status":"new"}}`)
	defer server.Close()

	d := DO{Config: testConfig}

	vmId, err := d.CreateVM("test-vm", "test-os", "test-size", "test-region", "test-key-id")
	if err != nil {
		t.Error(err)
	}
	if assert.NotNil(t, vmId) {
		assert.Equal(t, "3333", vmId)
	}
}

func Test_Provider_Digitalocean_StartVM_Error(t *testing.T) {
	server := getTestServer(http.StatusNotAcceptable, `{error-message}`)
	defer server.Close()

	d := DO{Config: testConfig}

	err := d.StartVM("1111")
	if assert.NotNil(t, err) {
		assert.Equal(t, `{error-message}`, err.Error())
	}
}

func Test_Provider_Digitalocean_StartVM_VMId(t *testing.T) {
	server := getTestServer(http.StatusOK, `{"action":{"id":36804758,"status":"in-progress","type":"power_on"}}`)
	defer server.Close()

	d := DO{Config: testConfig}

	err := d.StartVM("1111")
	if err != nil {
		t.Error(err)
	}
}

func Test_Provider_Digitalocean_DestroyVM_Error(t *testing.T) {
	server := getTestServer(http.StatusNotAcceptable, `{error-message}`)
	defer server.Close()

	d := DO{Config: testConfig}

	err := d.DestroyVM("1111")
	if assert.NotNil(t, err) {
		assert.Equal(t, `{error-message}`, err.Error())
	}
}

func Test_Provider_Digitalocean_DestroyVM_VMId(t *testing.T) {
	server := getTestServer(http.StatusNoContent, `{no-response?!}`)
	defer server.Close()

	d := DO{Config: testConfig}

	err := d.DestroyVM("1111")
	if err != nil {
		t.Error(err)
	}
}
<|endoftext|>


<commit_before>package static

import (
	"bytes"
	"net/http"
	"reflect"
	"testing"
)

func TestResponseWriterHeader(t *testing.T) {
	writtenBuffer := bytes.Buffer{}
	responseWriter := newResponseWriter(&writtenBuffer)

	t.Log("Setting the Content-Type to text/html.")
	header := responseWriter.Header()
	header["Content-Type"] = []string{"text/html"}
	t.Logf("Header => %#v", header)

	t.Log("Expect Content-Type to be persisted.")
	header_expected := http.Header{"Content-Type": []string{"text/html"}}
	header = responseWriter.Header()
	t.Logf("Header => %#v", header)
	if !reflect.DeepEqual(header, header_expected) {
		t.Errorf("Header => %#v, want %#v", header, header_expected)
	}
}

func TestResponseWriterStatus(t *testing.T) {
	writtenBuffer := bytes.Buffer{}
	responseWriter := newResponseWriter(&writtenBuffer)

	t.Log("Expect default Status to be 0.")
	expectedStatus := 0
	status := responseWriter.Status()
	t.Logf("Status => %d", status)
	if status != expectedStatus {
		t.Logf("Status => %d, want %d", status, expectedStatus)
	}
}

func TestResponseWriterStatusAfterWriteHeader(t *testing.T) {
	writtenBuffer := bytes.Buffer{}
	responseWriter := newResponseWriter(&writtenBuffer)

	t.Log("When WriteHeader has been called with a status code.")
	t.Log("Expect Status to be the status code.")
	{
		expectedStatus := 404
		responseWriter.WriteHeader(404)
		t.Logf("WriteHeader(404)")
		status := responseWriter.Status()
		t.Logf("Status => %d", status)
		if status != expectedStatus {
			t.Logf("Status => %d, want %d", status, expectedStatus)
		}
	}

	t.Log("When WriteHeader has been called multiple times.")
	t.Log("Expect Status to be the last status code.")
	{
		expectedStatus := 403
		responseWriter.WriteHeader(403)
		t.Logf("WriteHeader(403)")
		status := responseWriter.Status()
		t.Logf("Status => %d", status)
		if status != expectedStatus {
			t.Logf("Status => %d, want %d", status, expectedStatus)
		}
	}
}

func TestResponseWriterStatusAfterWrite(t *testing.T) {
	writtenBuffer := bytes.Buffer{}
	responseWriter := newResponseWriter(&writtenBuffer)

	t.Log("When Write has been called.")
	t.Log("Expect Status to be 200 OK.")
	expectedStatus := 200
	responseWriter.Write([]byte{})
	t.Logf("Write([]byte{})")
	status := responseWriter.Status()
	t.Logf("Status => %d", status)
	if status != expectedStatus {
		t.Logf("Status => %d, want %d", status, expectedStatus)
	}
}

func TestResponseWriterStatusAfterWriteHeaderAndWrite(t *testing.T) {
	writtenBuffer := bytes.Buffer{}
	responseWriter := newResponseWriter(&writtenBuffer)

	t.Log("When WriteHeader and Write have been called.")
	t.Log("Expect Status to be the WriteHeader input.")
	expectedStatus := 404
	responseWriter.WriteHeader(404)
	t.Logf("WriteHeader(404)")
	responseWriter.Write([]byte{})
	t.Logf("Write([]byte{})")
	status := responseWriter.Status()
	t.Logf("Status => %d", status)
	if status != expectedStatus {
		t.Logf("Status => %d, want %d", status, expectedStatus)
	}
}

func TestResponseWriterStatusAfterWriteAndWriteHeader(t *testing.T) {
	writtenBuffer := bytes.Buffer{}
	responseWriter := newResponseWriter(&writtenBuffer)

	t.Log("When Write and WriteHeader have been called.")
	t.Log("Expect Status to be the WriteHeader input.")
	expectedStatus := 404
	responseWriter.Write([]byte{})
	t.Logf("Write([]byte{})")
	responseWriter.WriteHeader(404)
	t.Logf("WriteHeader(404)")
	status := responseWriter.Status()
	t.Logf("Status => %d", status)
	if status != expectedStatus {
		t.Logf("Status => %d, want %d", status, expectedStatus)
	}
}

func TestResponseWriterWrite(t *testing.T) {
	writtenBuffer := bytes.Buffer{}
	responseWriter := newResponseWriter(&writtenBuffer)

	t.Log("When nothing has been written to the responseWriter.")
	t.Log("Expect nothing will be written to the Writer.")
	{
		expected := []byte{}
		written := writtenBuffer.Bytes()
		t.Logf("written => %#v", written)
		if !bytes.Equal(written, expected) {
			t.Errorf("written => %#v, want %#v", written, expected)
		}
	}

	t.Log("When bytes are written to the responseWriter.")
	t.Log("The bytes will be written to the Writer.")
	{
		responseWriter.Write([]byte{0x01, 0x02, 0x03, 0x04})

		written := writtenBuffer.Bytes()
		t.Logf("written => %#v", written)

		expected := []byte{0x01, 0x02, 0x03, 0x04}
		if !bytes.Equal(written, expected) {
			t.Errorf("written => %#v, want %#v", written, expected)
		}
	}

	t.Log("When additional bytes are written to the responseWriter.")
	t.Log("The additional bytes will be written to the Writer.")
	{
		responseWriter.Write([]byte{0x05, 0x06})
		t.Logf("Write(%#v)", []byte{0x05, 0x06})
		responseWriter.Write([]byte{0x07, 0x08})
		t.Logf("Write(%#v)", []byte{0x07, 0x08})

		written := writtenBuffer.Bytes()
		t.Logf("written => %#v", written)

		expected := []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}
		if !bytes.Equal(written, expected) {
			t.Errorf("written => %#v, want %#v", written, expected)
		}
	}
}
<commit_msg>Changed underscore variables to camelcase.<commit_after>package static

import (
	"bytes"
	"net/http"
	"reflect"
	"testing"
)

func TestResponseWriterHeader(t *testing.T) {
	writtenBuffer := bytes.Buffer{}
	responseWriter := newResponseWriter(&writtenBuffer)

	t.Log("Setting the Content-Type to text/html.")
	header := responseWriter.Header()
	header["Content-Type"] = []string{"text/html"}
	t.Logf("Header => %#v", header)

	t.Log("Expect Content-Type to be persisted.")
	headerExpected := http.Header{"Content-Type": []string{"text/html"}}
	header = responseWriter.Header()
	t.Logf("Header => %#v", header)
	if !reflect.DeepEqual(header, headerExpected) {
		t.Errorf("Header => %#v, want %#v", header, headerExpected)
	}
}

func TestResponseWriterStatus(t *testing.T) {
	writtenBuffer := bytes.Buffer{}
	responseWriter := newResponseWriter(&writtenBuffer)

	t.Log("Expect default Status to be 0.")
	expectedStatus := 0
	status := responseWriter.Status()
	t.Logf("Status => %d", status)
	if status != expectedStatus {
		t.Logf("Status => %d, want %d", status, expectedStatus)
	}
}

func TestResponseWriterStatusAfterWriteHeader(t *testing.T) {
	writtenBuffer := bytes.Buffer{}
	responseWriter := newResponseWriter(&writtenBuffer)

	t.Log("When WriteHeader has been called with a status code.")
	t.Log("Expect Status to be the status code.")
	{
		expectedStatus := 404
		responseWriter.WriteHeader(404)
		t.Logf("WriteHeader(404)")
		status := responseWriter.Status()
		t.Logf("Status => %d", status)
		if status != expectedStatus {
			t.Logf("Status => %d, want %d", status, expectedStatus)
		}
	}

	t.Log("When WriteHeader has been called multiple times.")
	t.Log("Expect Status to be the last status code.")
	{
		expectedStatus := 403
		responseWriter.WriteHeader(403)
		t.Logf("WriteHeader(403)")
		status := responseWriter.Status()
		t.Logf("Status => %d", status)
		if status != expectedStatus {
			t.Logf("Status => %d, want %d", status, expectedStatus)
		}
	}
}

func TestResponseWriterStatusAfterWrite(t *testing.T) {
	writtenBuffer := bytes.Buffer{}
	responseWriter := newResponseWriter(&writtenBuffer)

	t.Log("When Write has been called.")
	t.Log("Expect Status to be 200 OK.")
	expectedStatus := 200
	responseWriter.Write([]byte{})
	t.Logf("Write([]byte{})")
	status := responseWriter.Status()
	t.Logf("Status => %d", status)
	if status != expectedStatus {
		t.Logf("Status => %d, want %d", status, expectedStatus)
	}
}

func TestResponseWriterStatusAfterWriteHeaderAndWrite(t *testing.T) {
	writtenBuffer := bytes.Buffer{}
	responseWriter := newResponseWriter(&writtenBuffer)

	t.Log("When WriteHeader and Write have been called.")
	t.Log("Expect Status to be the WriteHeader input.")
	expectedStatus := 404
	responseWriter.WriteHeader(404)
	t.Logf("WriteHeader(404)")
	responseWriter.Write([]byte{})
	t.Logf("Write([]byte{})")
	status := responseWriter.Status()
	t.Logf("Status => %d", status)
	if status != expectedStatus {
		t.Logf("Status => %d, want %d", status, expectedStatus)
	}
}

func TestResponseWriterStatusAfterWriteAndWriteHeader(t *testing.T) {
	writtenBuffer := bytes.Buffer{}
	responseWriter := newResponseWriter(&writtenBuffer)

	t.Log("When Write and WriteHeader have been called.")
	t.Log("Expect Status to be the WriteHeader input.")
	expectedStatus := 404
	responseWriter.Write([]byte{})
	t.Logf("Write([]byte{})")
	responseWriter.WriteHeader(404)
	t.Logf("WriteHeader(404)")
	status := responseWriter.Status()
	t.Logf("Status => %d", status)
	if status != expectedStatus {
		t.Logf("Status => %d, want %d", status, expectedStatus)
	}
}

func TestResponseWriterWrite(t *testing.T) {
	writtenBuffer := bytes.Buffer{}
	responseWriter := newResponseWriter(&writtenBuffer)

	t.Log("When nothing has been written to the responseWriter.")
	t.Log("Expect nothing will be written to the Writer.")
	{
		expected := []byte{}
		written := writtenBuffer.Bytes()
		t.Logf("written => %#v", written)
		if !bytes.Equal(written, expected) {
			t.Errorf("written => %#v, want %#v", written, expected)
		}
	}

	t.Log("When bytes are written to the responseWriter.")
	t.Log("The bytes will be written to the Writer.")
	{
		responseWriter.Write([]byte{0x01, 0x02, 0x03, 0x04})

		written := writtenBuffer.Bytes()
		t.Logf("written => %#v", written)

		expected := []byte{0x01, 0x02, 0x03, 0x04}
		if !bytes.Equal(written, expected) {
			t.Errorf("written => %#v, want %#v", written, expected)
		}
	}

	t.Log("When additional bytes are written to the responseWriter.")
	t.Log("The additional bytes will be written to the Writer.")
	{
		responseWriter.Write([]byte{0x05, 0x06})
		t.Logf("Write(%#v)", []byte{0x05, 0x06})
		responseWriter.Write([]byte{0x07, 0x08})
		t.Logf("Write(%#v)", []byte{0x07, 0x08})

		written := writtenBuffer.Bytes()
		t.Logf("written => %#v", written)

		expected := []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}
		if !bytes.Equal(written, expected) {
			t.Errorf("written => %#v, want %#v", written, expected)
		}
	}
}
<|endoftext|>


<commit_before>//  Copyright (c) 2014 Couchbase, 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 main

import (
	"os"

	"github.com/blevesearch/bleve"

	log "github.com/couchbaselabs/clog"
)

// Wraps an error, but allows Run() implementation to signal that
// we should keep any files in the PIndex.Path.
type PIndexKeepError struct {
	err error
}

func (e *PIndexKeepError) Error() string {
	return e.err.Error()
}

func (pindex *PIndex) Run(mgr PIndexManager) {
	var err error = nil

	if pindex.IndexType == "bleve" {
		err = RunBleveStream(mgr, pindex, pindex.Stream, pindex.Impl.(bleve.Index))
		if err != nil {
			log.Printf("error: RunBleveStream, err: %v", err)
			return
		}
	} else {
		log.Printf("error: PIndex.Run() saw unknown IndexType: %s", pindex.IndexType)
	}

	// NOTE: We expect the PIndexImpl to handle any inflight, concurrent
	// queries, access and Close() correctly with its own locking.
	pindex.Impl.Close()

	// Remove files, unless we see a PIndexKeepError.
	if _, ok := err.(*PIndexKeepError); !ok {
		os.RemoveAll(pindex.Path)
	}
}

func RunBleveStream(mgr PIndexManager, pindex *PIndex, stream Stream, bindex bleve.Index) error {
	for m := range stream {
		// TODO: probably need things like stream reset/rollback
		// and snapshot kinds of ops here, too.

		// TODO: maybe need a more batchy API?  Perhaps, yet another
		// goroutine that clumps up up updates into bigger batches?

		switch m := m.(type) {
		case *StreamUpdate:
			bindex.Index(string(m.Id()), m.Body())
		case *StreamDelete:
			bindex.Delete(string(m.Id()))
		}
	}

	return nil
}
<commit_msg>replace PIndexKeepError with simple bool return flag<commit_after>//  Copyright (c) 2014 Couchbase, 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 main

import (
	"os"

	"github.com/blevesearch/bleve"

	log "github.com/couchbaselabs/clog"
)

func (pindex *PIndex) Run(mgr PIndexManager) {
	var keepFiles bool = false
	var err error = nil

	if pindex.IndexType == "bleve" {
		keepFiles, err = RunBleveStream(mgr, pindex, pindex.Stream, pindex.Impl.(bleve.Index))
		if err != nil {
			log.Printf("error: RunBleveStream, keepFiles: %b, err: %v", keepFiles, err)
		} else {
			log.Printf("done: RunBleveStream, keepFiles: %b", keepFiles)
		}
	} else {
		log.Printf("error: PIndex.Run() saw unknown IndexType: %s", pindex.IndexType)
	}

	// NOTE: We expect the PIndexImpl to handle any inflight, concurrent
	// queries, access and Close() correctly with its own locking.
	pindex.Impl.Close()

	// Remove files, unless we see a PIndexKeepError.
	if !keepFiles {
		os.RemoveAll(pindex.Path)
	}
}

func RunBleveStream(mgr PIndexManager, pindex *PIndex, stream Stream,
	bindex bleve.Index) (bool, error) {
	for m := range stream {
		// TODO: probably need things like stream reset/rollback
		// and snapshot kinds of ops here, too.

		// TODO: maybe need a more batchy API?  Perhaps, yet another
		// goroutine that clumps up up updates into bigger batches?

		switch m := m.(type) {
		case *StreamUpdate:
			bindex.Index(string(m.Id()), m.Body())
		case *StreamDelete:
			bindex.Delete(string(m.Id()))
		}
	}

	return false, nil
}
<|endoftext|>


<commit_before>package stripe

import "encoding/json"

// InvoiceLineType is the list of allowed values for the invoice line's type.
// Allowed values are "invoiceitem", "subscription".
type InvoiceLineType string

// InvoiceParams is the set of parameters that can be used when creating or updating an invoice.
// For more details see https://stripe.com/docs/api#create_invoice, https://stripe.com/docs/api#update_invoice.
type InvoiceParams struct {
	Params
	Customer             string
	Desc, Statement, Sub string
	Fee                  uint64
	Closed, Forgive      bool
	TaxPercent           float64
}

// InvoiceListParams is the set of parameters that can be used when listing invoices.
// For more details see https://stripe.com/docs/api#list_customer_invoices.
type InvoiceListParams struct {
	ListParams
	Date     int64
	Customer string
}

// InvoiceLineListParams is the set of parameters that can be used when listing invoice line items.
// For more details see https://stripe.com/docs/api#invoice_lines.
type InvoiceLineListParams struct {
	ListParams
	ID            string
	Customer, Sub string
}

// Invoice is the resource representing a Stripe invoice.
// For more details see https://stripe.com/docs/api#invoice_object.
type Invoice struct {
	ID           string            `json:"id"`
	Live         bool              `json:"livemode"`
	Amount       int64             `json:"amount_due"`
	Attempts     uint64            `json:"attempt_count"`
	Attempted    bool              `json:"attempted"`
	Closed       bool              `json:"closed"`
	Currency     Currency          `json:"currency"`
	Customer     *Customer         `json:"customer"`
	Date         int64             `json:"date"`
	Forgive      bool              `json:"forgiven"`
	Lines        *InvoiceLineList  `json:"lines"`
	Paid         bool              `json:"paid"`
	End          int64             `json:"period_end"`
	Start        int64             `json:"period_start"`
	StartBalance int64             `json:"starting_balance"`
	Subtotal     int64             `json:"subtotal"`
	Total        int64             `json:"total"`
	Tax          int64             `json:"tax"`
	TaxPercent   float64           `json:"tax_percent"`
	Fee          uint64            `json:"application_fee"`
	Charge       *Charge           `json:"charge"`
	Desc         string            `json:"description"`
	Discount     *Discount         `json:"discount"`
	EndBalance   int64             `json:"ending_balance"`
	NextAttempt  int64             `json:"next_payment_attempt"`
	Statement    string            `json:"statement_descriptor"`
	Sub          string            `json:"subscription"`
	Webhook      int64             `json:"webhooks_delivered_at"`
	Meta         map[string]string `json:"metadata"`
}

// InvoiceLine is the resource representing a Stripe invoice line item.
// For more details see https://stripe.com/docs/api#invoice_line_item_object.
type InvoiceLine struct {
	ID        string            `json:"id"`
	Live      bool              `json:"live_mode"`
	Amount    int64             `json:"amount"`
	Currency  Currency          `json:"currency"`
	Period    *Period           `json:"period"`
	Proration bool              `json:"proration"`
	Type      InvoiceLineType   `json:"type"`
	Desc      string            `json:"description"`
	Meta      map[string]string `json:"metadata"`
	Plan      *Plan             `json:"plan"`
	Quantity  int64             `json:"quantity"`
}

// Period is a structure representing a start and end dates.
type Period struct {
	Start int64 `json:"start"`
	End   int64 `json:"end"`
}

// InvoiceLineList is a list object for invoice line items.
type InvoiceLineList struct {
	ListMeta
	Values []*InvoiceLine `json:"data"`
}

// UnmarshalJSON handles deserialization of an Invoice.
// This custom unmarshaling is needed because the resulting
// property may be an id or the full struct if it was expanded.
func (i *Invoice) UnmarshalJSON(data []byte) error {
	type invoice Invoice
	var ii invoice
	err := json.Unmarshal(data, &ii)
	if err == nil {
		*i = Invoice(ii)
	} else {
		// the id is surrounded by "\" characters, so strip them
		i.ID = string(data[1 : len(data)-1])
	}

	return nil
}
<commit_msg>Add missing fields to invoice line<commit_after>package stripe

import "encoding/json"

// InvoiceLineType is the list of allowed values for the invoice line's type.
// Allowed values are "invoiceitem", "subscription".
type InvoiceLineType string

// InvoiceParams is the set of parameters that can be used when creating or updating an invoice.
// For more details see https://stripe.com/docs/api#create_invoice, https://stripe.com/docs/api#update_invoice.
type InvoiceParams struct {
	Params
	Customer             string
	Desc, Statement, Sub string
	Fee                  uint64
	Closed, Forgive      bool
	TaxPercent           float64
}

// InvoiceListParams is the set of parameters that can be used when listing invoices.
// For more details see https://stripe.com/docs/api#list_customer_invoices.
type InvoiceListParams struct {
	ListParams
	Date     int64
	Customer string
}

// InvoiceLineListParams is the set of parameters that can be used when listing invoice line items.
// For more details see https://stripe.com/docs/api#invoice_lines.
type InvoiceLineListParams struct {
	ListParams
	ID            string
	Customer, Sub string
}

// Invoice is the resource representing a Stripe invoice.
// For more details see https://stripe.com/docs/api#invoice_object.
type Invoice struct {
	ID           string            `json:"id"`
	Live         bool              `json:"livemode"`
	Amount       int64             `json:"amount_due"`
	Attempts     uint64            `json:"attempt_count"`
	Attempted    bool              `json:"attempted"`
	Closed       bool              `json:"closed"`
	Currency     Currency          `json:"currency"`
	Customer     *Customer         `json:"customer"`
	Date         int64             `json:"date"`
	Forgive      bool              `json:"forgiven"`
	Lines        *InvoiceLineList  `json:"lines"`
	Paid         bool              `json:"paid"`
	End          int64             `json:"period_end"`
	Start        int64             `json:"period_start"`
	StartBalance int64             `json:"starting_balance"`
	Subtotal     int64             `json:"subtotal"`
	Total        int64             `json:"total"`
	Tax          int64             `json:"tax"`
	TaxPercent   float64           `json:"tax_percent"`
	Fee          uint64            `json:"application_fee"`
	Charge       *Charge           `json:"charge"`
	Desc         string            `json:"description"`
	Discount     *Discount         `json:"discount"`
	EndBalance   int64             `json:"ending_balance"`
	NextAttempt  int64             `json:"next_payment_attempt"`
	Statement    string            `json:"statement_descriptor"`
	Sub          string            `json:"subscription"`
	Webhook      int64             `json:"webhooks_delivered_at"`
	Meta         map[string]string `json:"metadata"`
}

// InvoiceLine is the resource representing a Stripe invoice line item.
// For more details see https://stripe.com/docs/api#invoice_line_item_object.
type InvoiceLine struct {
	ID           string            `json:"id"`
	Live         bool              `json:"live_mode"`
	Amount       int64             `json:"amount"`
	Currency     Currency          `json:"currency"`
	Period       *Period           `json:"period"`
	Proration    bool              `json:"proration"`
	Type         InvoiceLineType   `json:"type"`
	Desc         string            `json:"description"`
	Meta         map[string]string `json:"metadata"`
	Plan         *Plan             `json:"plan"`
	Quantity     int64             `json:"quantity"`
	Sub          string            `json:"subscription"`
	Discountable bool              `json:"discountable"`
}

// Period is a structure representing a start and end dates.
type Period struct {
	Start int64 `json:"start"`
	End   int64 `json:"end"`
}

// InvoiceLineList is a list object for invoice line items.
type InvoiceLineList struct {
	ListMeta
	Values []*InvoiceLine `json:"data"`
}

// UnmarshalJSON handles deserialization of an Invoice.
// This custom unmarshaling is needed because the resulting
// property may be an id or the full struct if it was expanded.
func (i *Invoice) UnmarshalJSON(data []byte) error {
	type invoice Invoice
	var ii invoice
	err := json.Unmarshal(data, &ii)
	if err == nil {
		*i = Invoice(ii)
	} else {
		// the id is surrounded by "\" characters, so strip them
		i.ID = string(data[1 : len(data)-1])
	}

	return nil
}
<|endoftext|>


<commit_before>package io

import (
	"os"
	"path/filepath"
)

//	写文件
func WriteLines(filePath string, lines []string) error {

	//	打开文件
	file, err := openFile(filePath)
	if err != nil {
		return err
	}
	defer file.Close()

	for _, line := range lines {

		//	将股价写入文件
		_, err = file.WriteString(line)
		if err != nil {
			return err
		}
	}

	return nil
}

//	写入字符串
func WriteString(filePath, content string) error {

	//	打开文件
	file, err := openFile(filePath)
	if err != nil {
		return err
	}
	defer file.Close()

	file.WriteString(content)

	return nil
}

//	打开文件
func openFile(filePath string) (*os.File, error) {
	//	检查文件所处目录是否存在
	fileDir := filepath.Dir(filePath)
	_, err := os.Stat(fileDir)
	if os.IsNotExist(err) {
		//	如果不存在就先创建目录
		err = os.Mkdir(fileDir, 0x644)
		if err != nil {
			return nil, err
		}
	}

	//	打开文件
	return os.OpenFile(filePath, os.O_CREATE, 0x644)
}
<commit_msg>修改数据文件权限<commit_after>package io

import (
	"os"
	"path/filepath"
)

//	写文件
func WriteLines(filePath string, lines []string) error {

	//	打开文件
	file, err := openFile(filePath)
	if err != nil {
		return err
	}
	defer file.Close()

	for _, line := range lines {

		//	将股价写入文件
		_, err = file.WriteString(line)
		if err != nil {
			return err
		}
	}

	return nil
}

//	写入字符串
func WriteString(filePath, content string) error {

	//	打开文件
	file, err := openFile(filePath)
	if err != nil {
		return err
	}
	defer file.Close()

	file.WriteString(content)

	return nil
}

//	打开文件
func openFile(filePath string) (*os.File, error) {
	//	检查文件所处目录是否存在
	fileDir := filepath.Dir(filePath)
	_, err := os.Stat(fileDir)
	if os.IsNotExist(err) {
		//	如果不存在就先创建目录
		err = os.Mkdir(fileDir, 0660)
		if err != nil {
			return nil, err
		}
	}

	//	打开文件
	return os.OpenFile(filePath, os.O_CREATE|os.O_WRONLY, 0660)
}
<|endoftext|>


<commit_before>package steno

import (
	"bufio"
	"os"
)

type IO struct {
	writer *bufio.Writer
	codec Codec
}

func NewIOSink(file *os.File) *IO {
	writer := bufio.NewWriter(file)

	io := new(IO)
	io.writer = writer

	return io
}

func NewFileSink(path string) *IO {
	file, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
	if err != nil {
		panic(err)
	}

	return NewIOSink(file)
}

func (io *IO) AddRecord(record *Record) {
	msg := io.codec.EncodeRecord(record)
	io.writer.WriteString(msg)
}

func (io *IO) Flush() {
	io.writer.Flush()
}

func (io *IO) SetCodec(codec Codec) {
	io.codec = codec
}

func (io *IO) GetCodec() Codec {
	return io.codec
}
<commit_msg>Rename struct IO to IOSink<commit_after>package steno

import (
	"bufio"
	"os"
)

type IOSink struct {
	writer *bufio.Writer
	codec Codec
}

func NewIOSink(file *os.File) *IOSink {
	writer := bufio.NewWriter(file)

	ioSink := new(IOSink)
	ioSink.writer = writer

	return ioSink
}

func NewFileSink(path string) *IOSink {
	file, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
	if err != nil {
		panic(err)
	}

	return NewIOSink(file)
}

func (ioSink *IOSink) AddRecord(record *Record) {
	msg := ioSink.codec.EncodeRecord(record)
	ioSink.writer.WriteString(msg)
}

func (ioSink *IOSink) Flush() {
	ioSink.writer.Flush()
}

func (ioSink *IOSink) SetCodec(codec Codec) {
	ioSink.codec = codec
}

func (ioSink *IOSink) GetCodec() Codec {
	return ioSink.codec
}
<|endoftext|>


<commit_before>package daemon

import (
	"fmt"
	"io"
	"io/ioutil"
	"strings"
	"sync"

	log "github.com/Sirupsen/logrus"
	"github.com/docker/docker/daemon/execdriver"
	"github.com/docker/docker/daemon/execdriver/lxc"
	"github.com/docker/docker/engine"
	"github.com/docker/docker/pkg/broadcastwriter"
	"github.com/docker/docker/pkg/common"
	"github.com/docker/docker/pkg/ioutils"
	"github.com/docker/docker/pkg/promise"
	"github.com/docker/docker/runconfig"
)

type execConfig struct {
	sync.Mutex
	ID            string
	Running       bool
	ExitCode      int
	ProcessConfig execdriver.ProcessConfig
	StreamConfig
	OpenStdin  bool
	OpenStderr bool
	OpenStdout bool
	Container  *Container
}

type execStore struct {
	s map[string]*execConfig
	sync.RWMutex
}

func newExecStore() *execStore {
	return &execStore{s: make(map[string]*execConfig, 0)}
}

func (e *execStore) Add(id string, execConfig *execConfig) {
	e.Lock()
	e.s[id] = execConfig
	e.Unlock()
}

func (e *execStore) Get(id string) *execConfig {
	e.RLock()
	res := e.s[id]
	e.RUnlock()
	return res
}

func (e *execStore) Delete(id string) {
	e.Lock()
	delete(e.s, id)
	e.Unlock()
}

func (e *execStore) List() []string {
	var IDs []string
	e.RLock()
	for id := range e.s {
		IDs = append(IDs, id)
	}
	e.RUnlock()
	return IDs
}

func (execConfig *execConfig) Resize(h, w int) error {
	return execConfig.ProcessConfig.Terminal.Resize(h, w)
}

func (d *Daemon) registerExecCommand(execConfig *execConfig) {
	// Storing execs in container inorder to kill them gracefully whenever the container is stopped or removed.
	execConfig.Container.execCommands.Add(execConfig.ID, execConfig)
	// Storing execs in daemon for easy access via remote API.
	d.execCommands.Add(execConfig.ID, execConfig)
}

func (d *Daemon) getExecConfig(name string) (*execConfig, error) {
	if execConfig := d.execCommands.Get(name); execConfig != nil {
		if !execConfig.Container.IsRunning() {
			return nil, fmt.Errorf("Container %s is not running", execConfig.Container.ID)
		}
		return execConfig, nil
	}

	return nil, fmt.Errorf("No such exec instance '%s' found in daemon", name)
}

func (d *Daemon) unregisterExecCommand(execConfig *execConfig) {
	execConfig.Container.execCommands.Delete(execConfig.ID)
	d.execCommands.Delete(execConfig.ID)
}

func (d *Daemon) getActiveContainer(name string) (*Container, error) {
	container, err := d.Get(name)
	if err != nil {
		return nil, err
	}

	if !container.IsRunning() {
		return nil, fmt.Errorf("Container %s is not running", name)
	}
	if container.IsPaused() {
		return nil, fmt.Errorf("Container %s is paused, unpause the container before exec", name)
	}
	return container, nil
}

func (d *Daemon) ContainerExecCreate(job *engine.Job) engine.Status {
	if len(job.Args) != 1 {
		return job.Errorf("Usage: %s [options] container command [args]", job.Name)
	}

	if strings.HasPrefix(d.execDriver.Name(), lxc.DriverName) {
		return job.Error(lxc.ErrExec)
	}

	var name = job.Args[0]

	container, err := d.getActiveContainer(name)
	if err != nil {
		return job.Error(err)
	}

	config, err := runconfig.ExecConfigFromJob(job)
	if err != nil {
		return job.Error(err)
	}

	entrypoint, args := d.getEntrypointAndArgs(nil, config.Cmd)

	processConfig := execdriver.ProcessConfig{
		Tty:        config.Tty,
		Entrypoint: entrypoint,
		Arguments:  args,
	}

	execConfig := &execConfig{
		ID:            common.GenerateRandomID(),
		OpenStdin:     config.AttachStdin,
		OpenStdout:    config.AttachStdout,
		OpenStderr:    config.AttachStderr,
		StreamConfig:  StreamConfig{},
		ProcessConfig: processConfig,
		Container:     container,
		Running:       false,
	}

	container.LogEvent("exec_create: " + execConfig.ProcessConfig.Entrypoint + " " + strings.Join(execConfig.ProcessConfig.Arguments, " "))

	d.registerExecCommand(execConfig)

	job.Printf("%s\n", execConfig.ID)

	return engine.StatusOK
}

func (d *Daemon) ContainerExecStart(job *engine.Job) engine.Status {
	if len(job.Args) != 1 {
		return job.Errorf("Usage: %s [options] exec", job.Name)
	}

	var (
		cStdin           io.ReadCloser
		cStdout, cStderr io.Writer
		execName         = job.Args[0]
	)

	execConfig, err := d.getExecConfig(execName)
	if err != nil {
		return job.Error(err)
	}

	func() {
		execConfig.Lock()
		defer execConfig.Unlock()
		if execConfig.Running {
			err = fmt.Errorf("Error: Exec command %s is already running", execName)
		}
		execConfig.Running = true
	}()
	if err != nil {
		return job.Error(err)
	}

	log.Debugf("starting exec command %s in container %s", execConfig.ID, execConfig.Container.ID)
	container := execConfig.Container

	container.LogEvent("exec_start: " + execConfig.ProcessConfig.Entrypoint + " " + strings.Join(execConfig.ProcessConfig.Arguments, " "))

	if execConfig.OpenStdin {
		r, w := io.Pipe()
		go func() {
			defer w.Close()
			defer log.Debugf("Closing buffered stdin pipe")
			io.Copy(w, job.Stdin)
		}()
		cStdin = r
	}
	if execConfig.OpenStdout {
		cStdout = job.Stdout
	}
	if execConfig.OpenStderr {
		cStderr = job.Stderr
	}

	execConfig.StreamConfig.stderr = broadcastwriter.New()
	execConfig.StreamConfig.stdout = broadcastwriter.New()
	// Attach to stdin
	if execConfig.OpenStdin {
		execConfig.StreamConfig.stdin, execConfig.StreamConfig.stdinPipe = io.Pipe()
	} else {
		execConfig.StreamConfig.stdinPipe = ioutils.NopWriteCloser(ioutil.Discard) // Silently drop stdin
	}

	attachErr := d.Attach(&execConfig.StreamConfig, execConfig.OpenStdin, true, execConfig.ProcessConfig.Tty, cStdin, cStdout, cStderr)

	execErr := make(chan error)

	// Note, the execConfig data will be removed when the container
	// itself is deleted.  This allows us to query it (for things like
	// the exitStatus) even after the cmd is done running.

	go func() {
		err := container.Exec(execConfig)
		if err != nil {
			execErr <- fmt.Errorf("Cannot run exec command %s in container %s: %s", execName, container.ID, err)
		}
	}()

	select {
	case err := <-attachErr:
		if err != nil {
			return job.Errorf("attach failed with error: %s", err)
		}
		break
	case err := <-execErr:
		return job.Error(err)
	}

	return engine.StatusOK
}

func (d *Daemon) Exec(c *Container, execConfig *execConfig, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (int, error) {
	exitStatus, err := d.execDriver.Exec(c.command, &execConfig.ProcessConfig, pipes, startCallback)

	// On err, make sure we don't leave ExitCode at zero
	if err != nil && exitStatus == 0 {
		exitStatus = 128
	}

	execConfig.ExitCode = exitStatus
	execConfig.Running = false

	return exitStatus, err
}

func (container *Container) GetExecIDs() []string {
	return container.execCommands.List()
}

func (container *Container) Exec(execConfig *execConfig) error {
	container.Lock()
	defer container.Unlock()

	waitStart := make(chan struct{})

	callback := func(processConfig *execdriver.ProcessConfig, pid int) {
		if processConfig.Tty {
			// The callback is called after the process Start()
			// so we are in the parent process. In TTY mode, stdin/out/err is the PtySlave
			// which we close here.
			if c, ok := processConfig.Stdout.(io.Closer); ok {
				c.Close()
			}
		}
		close(waitStart)
	}

	// We use a callback here instead of a goroutine and an chan for
	// syncronization purposes
	cErr := promise.Go(func() error { return container.monitorExec(execConfig, callback) })

	// Exec should not return until the process is actually running
	select {
	case <-waitStart:
	case err := <-cErr:
		return err
	}

	return nil
}

func (container *Container) monitorExec(execConfig *execConfig, callback execdriver.StartCallback) error {
	var (
		err      error
		exitCode int
	)

	pipes := execdriver.NewPipes(execConfig.StreamConfig.stdin, execConfig.StreamConfig.stdout, execConfig.StreamConfig.stderr, execConfig.OpenStdin)
	exitCode, err = container.daemon.Exec(container, execConfig, pipes, callback)
	if err != nil {
		log.Errorf("Error running command in existing container %s: %s", container.ID, err)
	}

	log.Debugf("Exec task in container %s exited with code %d", container.ID, exitCode)
	if execConfig.OpenStdin {
		if err := execConfig.StreamConfig.stdin.Close(); err != nil {
			log.Errorf("Error closing stdin while running in %s: %s", container.ID, err)
		}
	}
	if err := execConfig.StreamConfig.stdout.Clean(); err != nil {
		log.Errorf("Error closing stdout while running in %s: %s", container.ID, err)
	}
	if err := execConfig.StreamConfig.stderr.Clean(); err != nil {
		log.Errorf("Error closing stderr while running in %s: %s", container.ID, err)
	}
	if execConfig.ProcessConfig.Terminal != nil {
		if err := execConfig.ProcessConfig.Terminal.Close(); err != nil {
			log.Errorf("Error closing terminal while running in container %s: %s", container.ID, err)
		}
	}

	return err
}
<commit_msg>fix a minor typo in daemon/exec.go<commit_after>package daemon

import (
	"fmt"
	"io"
	"io/ioutil"
	"strings"
	"sync"

	log "github.com/Sirupsen/logrus"
	"github.com/docker/docker/daemon/execdriver"
	"github.com/docker/docker/daemon/execdriver/lxc"
	"github.com/docker/docker/engine"
	"github.com/docker/docker/pkg/broadcastwriter"
	"github.com/docker/docker/pkg/common"
	"github.com/docker/docker/pkg/ioutils"
	"github.com/docker/docker/pkg/promise"
	"github.com/docker/docker/runconfig"
)

type execConfig struct {
	sync.Mutex
	ID            string
	Running       bool
	ExitCode      int
	ProcessConfig execdriver.ProcessConfig
	StreamConfig
	OpenStdin  bool
	OpenStderr bool
	OpenStdout bool
	Container  *Container
}

type execStore struct {
	s map[string]*execConfig
	sync.RWMutex
}

func newExecStore() *execStore {
	return &execStore{s: make(map[string]*execConfig, 0)}
}

func (e *execStore) Add(id string, execConfig *execConfig) {
	e.Lock()
	e.s[id] = execConfig
	e.Unlock()
}

func (e *execStore) Get(id string) *execConfig {
	e.RLock()
	res := e.s[id]
	e.RUnlock()
	return res
}

func (e *execStore) Delete(id string) {
	e.Lock()
	delete(e.s, id)
	e.Unlock()
}

func (e *execStore) List() []string {
	var IDs []string
	e.RLock()
	for id := range e.s {
		IDs = append(IDs, id)
	}
	e.RUnlock()
	return IDs
}

func (execConfig *execConfig) Resize(h, w int) error {
	return execConfig.ProcessConfig.Terminal.Resize(h, w)
}

func (d *Daemon) registerExecCommand(execConfig *execConfig) {
	// Storing execs in container in order to kill them gracefully whenever the container is stopped or removed.
	execConfig.Container.execCommands.Add(execConfig.ID, execConfig)
	// Storing execs in daemon for easy access via remote API.
	d.execCommands.Add(execConfig.ID, execConfig)
}

func (d *Daemon) getExecConfig(name string) (*execConfig, error) {
	if execConfig := d.execCommands.Get(name); execConfig != nil {
		if !execConfig.Container.IsRunning() {
			return nil, fmt.Errorf("Container %s is not running", execConfig.Container.ID)
		}
		return execConfig, nil
	}

	return nil, fmt.Errorf("No such exec instance '%s' found in daemon", name)
}

func (d *Daemon) unregisterExecCommand(execConfig *execConfig) {
	execConfig.Container.execCommands.Delete(execConfig.ID)
	d.execCommands.Delete(execConfig.ID)
}

func (d *Daemon) getActiveContainer(name string) (*Container, error) {
	container, err := d.Get(name)
	if err != nil {
		return nil, err
	}

	if !container.IsRunning() {
		return nil, fmt.Errorf("Container %s is not running", name)
	}
	if container.IsPaused() {
		return nil, fmt.Errorf("Container %s is paused, unpause the container before exec", name)
	}
	return container, nil
}

func (d *Daemon) ContainerExecCreate(job *engine.Job) engine.Status {
	if len(job.Args) != 1 {
		return job.Errorf("Usage: %s [options] container command [args]", job.Name)
	}

	if strings.HasPrefix(d.execDriver.Name(), lxc.DriverName) {
		return job.Error(lxc.ErrExec)
	}

	var name = job.Args[0]

	container, err := d.getActiveContainer(name)
	if err != nil {
		return job.Error(err)
	}

	config, err := runconfig.ExecConfigFromJob(job)
	if err != nil {
		return job.Error(err)
	}

	entrypoint, args := d.getEntrypointAndArgs(nil, config.Cmd)

	processConfig := execdriver.ProcessConfig{
		Tty:        config.Tty,
		Entrypoint: entrypoint,
		Arguments:  args,
	}

	execConfig := &execConfig{
		ID:            common.GenerateRandomID(),
		OpenStdin:     config.AttachStdin,
		OpenStdout:    config.AttachStdout,
		OpenStderr:    config.AttachStderr,
		StreamConfig:  StreamConfig{},
		ProcessConfig: processConfig,
		Container:     container,
		Running:       false,
	}

	container.LogEvent("exec_create: " + execConfig.ProcessConfig.Entrypoint + " " + strings.Join(execConfig.ProcessConfig.Arguments, " "))

	d.registerExecCommand(execConfig)

	job.Printf("%s\n", execConfig.ID)

	return engine.StatusOK
}

func (d *Daemon) ContainerExecStart(job *engine.Job) engine.Status {
	if len(job.Args) != 1 {
		return job.Errorf("Usage: %s [options] exec", job.Name)
	}

	var (
		cStdin           io.ReadCloser
		cStdout, cStderr io.Writer
		execName         = job.Args[0]
	)

	execConfig, err := d.getExecConfig(execName)
	if err != nil {
		return job.Error(err)
	}

	func() {
		execConfig.Lock()
		defer execConfig.Unlock()
		if execConfig.Running {
			err = fmt.Errorf("Error: Exec command %s is already running", execName)
		}
		execConfig.Running = true
	}()
	if err != nil {
		return job.Error(err)
	}

	log.Debugf("starting exec command %s in container %s", execConfig.ID, execConfig.Container.ID)
	container := execConfig.Container

	container.LogEvent("exec_start: " + execConfig.ProcessConfig.Entrypoint + " " + strings.Join(execConfig.ProcessConfig.Arguments, " "))

	if execConfig.OpenStdin {
		r, w := io.Pipe()
		go func() {
			defer w.Close()
			defer log.Debugf("Closing buffered stdin pipe")
			io.Copy(w, job.Stdin)
		}()
		cStdin = r
	}
	if execConfig.OpenStdout {
		cStdout = job.Stdout
	}
	if execConfig.OpenStderr {
		cStderr = job.Stderr
	}

	execConfig.StreamConfig.stderr = broadcastwriter.New()
	execConfig.StreamConfig.stdout = broadcastwriter.New()
	// Attach to stdin
	if execConfig.OpenStdin {
		execConfig.StreamConfig.stdin, execConfig.StreamConfig.stdinPipe = io.Pipe()
	} else {
		execConfig.StreamConfig.stdinPipe = ioutils.NopWriteCloser(ioutil.Discard) // Silently drop stdin
	}

	attachErr := d.Attach(&execConfig.StreamConfig, execConfig.OpenStdin, true, execConfig.ProcessConfig.Tty, cStdin, cStdout, cStderr)

	execErr := make(chan error)

	// Note, the execConfig data will be removed when the container
	// itself is deleted.  This allows us to query it (for things like
	// the exitStatus) even after the cmd is done running.

	go func() {
		err := container.Exec(execConfig)
		if err != nil {
			execErr <- fmt.Errorf("Cannot run exec command %s in container %s: %s", execName, container.ID, err)
		}
	}()

	select {
	case err := <-attachErr:
		if err != nil {
			return job.Errorf("attach failed with error: %s", err)
		}
		break
	case err := <-execErr:
		return job.Error(err)
	}

	return engine.StatusOK
}

func (d *Daemon) Exec(c *Container, execConfig *execConfig, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (int, error) {
	exitStatus, err := d.execDriver.Exec(c.command, &execConfig.ProcessConfig, pipes, startCallback)

	// On err, make sure we don't leave ExitCode at zero
	if err != nil && exitStatus == 0 {
		exitStatus = 128
	}

	execConfig.ExitCode = exitStatus
	execConfig.Running = false

	return exitStatus, err
}

func (container *Container) GetExecIDs() []string {
	return container.execCommands.List()
}

func (container *Container) Exec(execConfig *execConfig) error {
	container.Lock()
	defer container.Unlock()

	waitStart := make(chan struct{})

	callback := func(processConfig *execdriver.ProcessConfig, pid int) {
		if processConfig.Tty {
			// The callback is called after the process Start()
			// so we are in the parent process. In TTY mode, stdin/out/err is the PtySlave
			// which we close here.
			if c, ok := processConfig.Stdout.(io.Closer); ok {
				c.Close()
			}
		}
		close(waitStart)
	}

	// We use a callback here instead of a goroutine and an chan for
	// syncronization purposes
	cErr := promise.Go(func() error { return container.monitorExec(execConfig, callback) })

	// Exec should not return until the process is actually running
	select {
	case <-waitStart:
	case err := <-cErr:
		return err
	}

	return nil
}

func (container *Container) monitorExec(execConfig *execConfig, callback execdriver.StartCallback) error {
	var (
		err      error
		exitCode int
	)

	pipes := execdriver.NewPipes(execConfig.StreamConfig.stdin, execConfig.StreamConfig.stdout, execConfig.StreamConfig.stderr, execConfig.OpenStdin)
	exitCode, err = container.daemon.Exec(container, execConfig, pipes, callback)
	if err != nil {
		log.Errorf("Error running command in existing container %s: %s", container.ID, err)
	}

	log.Debugf("Exec task in container %s exited with code %d", container.ID, exitCode)
	if execConfig.OpenStdin {
		if err := execConfig.StreamConfig.stdin.Close(); err != nil {
			log.Errorf("Error closing stdin while running in %s: %s", container.ID, err)
		}
	}
	if err := execConfig.StreamConfig.stdout.Clean(); err != nil {
		log.Errorf("Error closing stdout while running in %s: %s", container.ID, err)
	}
	if err := execConfig.StreamConfig.stderr.Clean(); err != nil {
		log.Errorf("Error closing stderr while running in %s: %s", container.ID, err)
	}
	if execConfig.ProcessConfig.Terminal != nil {
		if err := execConfig.ProcessConfig.Terminal.Close(); err != nil {
			log.Errorf("Error closing terminal while running in container %s: %s", container.ID, err)
		}
	}

	return err
}
<|endoftext|>


<commit_before>package models

import (
	"reflect"
	"time"

	"github.com/jinzhu/gorm"
)

type Brand struct {
	ID   uint   `gorm:"primary_key"`
	Name string `gorm:"size:30;not null"`

	CreatedAt time.Time `gorm:"not null"`
}

// GetBrand gets a brand by name
func GetBrand(name string, db *gorm.DB) *gorm.DB {
	var result Brand
	var query string

	if isPostgres(db) {
		query = "SELECT id FROM brands WHERE name ILIKE ?"
	} else {
		query = "SELECT id FROM brands WHERE name ILIKE ?"
	}

	return db.Raw(query, name).Scan(&result)
}

// CreateBrand creates a new brand
func CreateBrand(brand *Brand, db *gorm.DB) *gorm.DB {
	return db.Create(brand)
}

func isPostgres(db *gorm.DB) bool {
	driver := reflect.ValueOf(db.DB().Driver())

	if driver.Type().String() == "*pq.Driver" {
		return true
	}

	return false
}
<commit_msg>Fixed SQL statement<commit_after>package models

import (
	"reflect"
	"time"

	"github.com/jinzhu/gorm"
)

type Brand struct {
	ID   uint   `gorm:"primary_key"`
	Name string `gorm:"size:30;not null"`

	CreatedAt time.Time `gorm:"not null"`
}

// GetBrand gets a brand by name
func GetBrand(name string, db *gorm.DB) *gorm.DB {
	var result Brand
	var query string

	if isPostgres(db) {
		query = "SELECT id FROM brands WHERE name ILIKE ?"
	} else {
		query = "SELECT id FROM brands WHERE name LIKE ?"
	}

	return db.Raw(query, name).Scan(&result)
}

// CreateBrand creates a new brand
func CreateBrand(brand *Brand, db *gorm.DB) *gorm.DB {
	return db.Create(brand)
}

func isPostgres(db *gorm.DB) bool {
	driver := reflect.ValueOf(db.DB().Driver())

	if driver.Type().String() == "*pq.Driver" {
		return true
	}

	return false
}
<|endoftext|>


<commit_before>package gpool_test

import (
	"errors"
	"testing"
	"time"

	"github.com/gogf/gf/g/container/gpool"
	"github.com/gogf/gf/g/test/gtest"
)

var nf gpool.NewFunc = func() (i interface{}, e error) {
	return "hello", nil
}

var assertIndex int = 0
var ef gpool.ExpireFunc = func(i interface{}) {
	assertIndex++
	gtest.Assert(i, assertIndex)
}

func Test_Gpool(t *testing.T) {
	gtest.Case(t, func() {
		//
		//expire = 0
		p1 := gpool.New(0, nf)
		p1.Put(1)
		p1.Put(2)
		time.Sleep(1 * time.Second)
		//test won't be timeout
		v1, err1 := p1.Get()
		gtest.Assert(err1, nil)
		gtest.Assert(v1, 1)
		//test clear
		p1.Clear()
		gtest.Assert(p1.Size(), 0)
		//test newFunc
		v1, err1 = p1.Get()
		gtest.Assert(err1, nil)
		gtest.Assert(v1, "hello")
		//put data again
		p1.Put(3)
		p1.Put(4)
		v1, err1 = p1.Get()
		gtest.Assert(err1, nil)
		gtest.Assert(v1, 3)
		//test close
		p1.Close()
		v1, err1 = p1.Get()
		gtest.Assert(err1, nil)
		gtest.Assert(v1, "hello")

	})

	gtest.Case(t, func() {
		//
		//expire > 0
		p2 := gpool.New(2000, nil, ef)
		for index := 0; index < 10; index++ {
			p2.Put(index)
		}
		gtest.Assert(p2.Size(), 10)
		v2, err2 := p2.Get()
		gtest.Assert(err2, nil)
		gtest.Assert(v2, 0)
		//test timeout expireFunc
		time.Sleep(3 * time.Second)
		v2, err2 = p2.Get()
		gtest.Assert(err2, errors.New("pool is empty"))
		gtest.Assert(v2, nil)
		//test close expireFunc
		for index := 0; index < 10; index++ {
			p2.Put(index)
		}
		gtest.Assert(p2.Size(), 10)
		v2, err2 = p2.Get()
		gtest.Assert(err2, nil)
		gtest.Assert(v2, 0)
		assertIndex = 0
		p2.Close()
		time.Sleep(3 * time.Second)
	})

	gtest.Case(t, func() {
		//
		//expire < 0
		p3 := gpool.New(-1, nil)
		v3, err3 := p3.Get()
		gtest.Assert(err3, errors.New("pool is empty"))
		gtest.Assert(v3, nil)
	})
}
<commit_msg>improve unit test cases for gpool<commit_after>// Copyright 2019 gf Author(https://github.com/gogf/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.

package gpool_test

import (
	"errors"
	"github.com/gogf/gf/g"
	"testing"
	"time"

	"github.com/gogf/gf/g/container/gpool"
	"github.com/gogf/gf/g/test/gtest"
)

var nf gpool.NewFunc = func() (i interface{}, e error) {
	return "hello", nil
}

var assertIndex int = 0
var ef gpool.ExpireFunc = func(i interface{}) {
	assertIndex++
	gtest.Assert(i, assertIndex)
}

func Test_Gpool(t *testing.T) {
	gtest.Case(t, func() {
		//
		//expire = 0
		p1 := gpool.New(0, nf)
		p1.Put(1)
		p1.Put(2)
		time.Sleep(1 * time.Second)
		//test won't be timeout
		v1, err1 := p1.Get()
		gtest.Assert(err1, nil)
		gtest.AssertIN(v1, g.Slice{1, 2})
		//test clear
		p1.Clear()
		gtest.Assert(p1.Size(), 0)
		//test newFunc
		v1, err1 = p1.Get()
		gtest.Assert(err1, nil)
		gtest.Assert(v1, "hello")
		//put data again
		p1.Put(3)
		p1.Put(4)
		v1, err1 = p1.Get()
		gtest.Assert(err1, nil)
		gtest.AssertIN(v1, g.Slice{3, 4})
		//test close
		p1.Close()
		v1, err1 = p1.Get()
		gtest.Assert(err1, nil)
		gtest.Assert(v1, "hello")
	})

	gtest.Case(t, func() {
		//
		//expire > 0
		p2 := gpool.New(2000, nil, ef)
		for index := 0; index < 10; index++ {
			p2.Put(index)
		}
		gtest.Assert(p2.Size(), 10)
		v2, err2 := p2.Get()
		gtest.Assert(err2, nil)
		gtest.Assert(v2, 0)
		//test timeout expireFunc
		time.Sleep(3 * time.Second)
		v2, err2 = p2.Get()
		gtest.Assert(err2, errors.New("pool is empty"))
		gtest.Assert(v2, nil)
		//test close expireFunc
		for index := 0; index < 10; index++ {
			p2.Put(index)
		}
		gtest.Assert(p2.Size(), 10)
		v2, err2 = p2.Get()
		gtest.Assert(err2, nil)
		gtest.Assert(v2, 0)
		assertIndex = 0
		p2.Close()
		time.Sleep(3 * time.Second)
	})

	gtest.Case(t, func() {
		//
		//expire < 0
		p3 := gpool.New(-1, nil)
		v3, err3 := p3.Get()
		gtest.Assert(err3, errors.New("pool is empty"))
		gtest.Assert(v3, nil)
	})
}
<|endoftext|>


<commit_before>package timeout

import (
	"net"
	"time"
)

var lastBandwidthUpdate time.Time
var bytesSinceLastUpdate float64
var maxBucketDuration = 1 * time.Second
var bps float64

type BytesReadFunc func(bytesRead int64)

var bytesReadCallback BytesReadFunc

type monitoringConn struct {
	Conn net.Conn
}

var _ net.Conn = (*monitoringConn)(nil)

func (mc *monitoringConn) Close() error {
	return mc.Conn.Close()
}

func (mc *monitoringConn) LocalAddr() net.Addr {
	return mc.Conn.LocalAddr()
}

func (mc *monitoringConn) RemoteAddr() net.Addr {
	return mc.Conn.RemoteAddr()
}

func (mc *monitoringConn) SetDeadline(t time.Time) error {
	return mc.Conn.SetDeadline(t)
}

func (mc *monitoringConn) SetReadDeadline(t time.Time) error {
	return mc.Conn.SetReadDeadline(t)
}

func (mc *monitoringConn) SetWriteDeadline(t time.Time) error {
	return mc.Conn.SetWriteDeadline(t)
}

func (mc *monitoringConn) Read(buf []byte) (int, error) {
	readBytes, err := mc.Conn.Read(buf)
	recordBytesRead(int64(readBytes))
	return readBytes, err
}

func (mc *monitoringConn) Write(buf []byte) (int, error) {
	return mc.Conn.Write(buf)
}

func recordBytesRead(bytesRead int64) {
	if bytesRead == 0 {
		return
	}

	bytesSinceLastUpdate += float64(bytesRead)
	if lastBandwidthUpdate.IsZero() {
		lastBandwidthUpdate = time.Now()
	}

	bucketDuration := time.Since(lastBandwidthUpdate)

	if bucketDuration > maxBucketDuration {
		bps = bytesSinceLastUpdate / bucketDuration.Seconds()
		lastBandwidthUpdate = time.Now()
		bytesSinceLastUpdate = 0.0
	}
}

func GetBPS() float64 {
	return bps
}
<commit_msg>return 0 bps if there hasn't been any network activity in a while<commit_after>package timeout

import (
	"net"
	"time"
)

var lastBandwidthUpdate time.Time
var bytesSinceLastUpdate float64
var maxBucketDuration = 1 * time.Second
var bps float64

type BytesReadFunc func(bytesRead int64)

var bytesReadCallback BytesReadFunc

type monitoringConn struct {
	Conn net.Conn
}

var _ net.Conn = (*monitoringConn)(nil)

func (mc *monitoringConn) Close() error {
	return mc.Conn.Close()
}

func (mc *monitoringConn) LocalAddr() net.Addr {
	return mc.Conn.LocalAddr()
}

func (mc *monitoringConn) RemoteAddr() net.Addr {
	return mc.Conn.RemoteAddr()
}

func (mc *monitoringConn) SetDeadline(t time.Time) error {
	return mc.Conn.SetDeadline(t)
}

func (mc *monitoringConn) SetReadDeadline(t time.Time) error {
	return mc.Conn.SetReadDeadline(t)
}

func (mc *monitoringConn) SetWriteDeadline(t time.Time) error {
	return mc.Conn.SetWriteDeadline(t)
}

func (mc *monitoringConn) Read(buf []byte) (int, error) {
	readBytes, err := mc.Conn.Read(buf)
	recordBytesRead(int64(readBytes))
	return readBytes, err
}

func (mc *monitoringConn) Write(buf []byte) (int, error) {
	return mc.Conn.Write(buf)
}

func recordBytesRead(bytesRead int64) {
	if bytesRead == 0 {
		return
	}

	bytesSinceLastUpdate += float64(bytesRead)
	if lastBandwidthUpdate.IsZero() {
		lastBandwidthUpdate = time.Now()
	}

	bucketDuration := time.Since(lastBandwidthUpdate)

	if bucketDuration > maxBucketDuration {
		bps = bytesSinceLastUpdate / bucketDuration.Seconds()
		lastBandwidthUpdate = time.Now()
		bytesSinceLastUpdate = 0.0
	}
}

func GetBPS() float64 {
	bucketDuration := time.Since(lastBandwidthUpdate)

	if bucketDuration > maxBucketDuration*2 {
		// if we don't read anything from the network in a while,
		// bps won't update, but it should be 0
		return 0.0
	}

	return bps
}
<|endoftext|>