<commit_before>package validator

import (
	"fmt"
	"math/big"

	"github.com/hyperledger/burrow/crypto"
	"github.com/tendermint/tendermint/types"
)

// Safety margin determined by Tendermint (see comment on source constant)
var maxTotalPower = big.NewInt(types.MaxTotalVotingPower)
var minTotalPower = big.NewInt(4)

type Bucket struct {
	// Delta tracks the changes to validator power made since the previous rotation
	Delta *Set
	// Previous the value for all validator powers at the point of the last rotation
	// (the sum of all the deltas over all rotations) - these are the history of the complete validator sets at each rotation
	Previous *Set
	// Tracks the current working version of the next set; Previous + Delta
	Next *Set
	// Flow tracks the absolute value of all flows (difference between previous cum bucket and current delta) towards and away from each validator (tracking each validator separately to avoid double counting flows made against the same validator
	Flow *Set
}

func NewBucket(initialSets ...Iterable) *Bucket {
	bucket := &Bucket{
		Previous: NewTrimSet(),
		Next:     NewTrimSet(),
		Delta:    NewSet(),
		Flow:     NewSet(),
	}
	for _, vs := range initialSets {
		vs.IterateValidators(func(id crypto.Addressable, power *big.Int) error {
			bucket.Previous.ChangePower(id.GetPublicKey(), power)
			bucket.Next.ChangePower(id.GetPublicKey(), power)
			return nil
		})
	}
	return bucket
}

// Implement Reader
func (vc *Bucket) Power(id crypto.Address) (*big.Int, error) {
	return vc.Previous.Power(id)
}

// SetPower ensures that validator power would not change too quickly in a single block
func (vc *Bucket) SetPower(id crypto.PublicKey, power *big.Int) (*big.Int, error) {
	const errHeader = "Bucket.SetPower():"
	err := checkPower(power)
	if err != nil {
		return nil, fmt.Errorf("%s %v", errHeader, err)
	}

	nextTotalPower := vc.Next.TotalPower()
	nextTotalPower.Add(nextTotalPower, vc.Next.Flow(id, power))
	// We must not have lower validator power than 4 because this would prevent any flow from occurring
	// min > nextTotalPower
	if minTotalPower.Cmp(nextTotalPower) == 1 {
		return nil, fmt.Errorf("%s cannot change validator power of %v from %v to %v because that would result "+
			"in a total power less than the permitted minimum of 4: would make next total power: %v",
			errHeader, id.GetAddress(), vc.Previous.GetPower(id.GetAddress()), power, nextTotalPower)
	}

	// nextTotalPower > max
	if nextTotalPower.Cmp(maxTotalPower) == 1 {
		return nil, fmt.Errorf("%s cannot change validator power of %v from %v to %v because that would result "+
			"in a total power greater than that allowed by tendermint (%v): would make next total power: %v",
			errHeader, id.GetAddress(), vc.Previous.GetPower(id.GetAddress()), power, maxTotalPower, nextTotalPower)
	}

	// The new absolute flow caused by this AlterPower
	flow := vc.Previous.Flow(id, power)
	absFlow := new(big.Int).Abs(flow)

	// Check flow except in the special case when previous Set was empty
	if vc.Previous.TotalPower().Sign() == 0 {
		// The max flow we are permitted to allow across all validators
		maxFlow := vc.Previous.MaxFlow()
		// The remaining flow we have to play with
		allowableFlow := new(big.Int).Sub(maxFlow, vc.Flow.totalPower)

		// If we call vc.flow.ChangePower(id, absFlow) (below) will we induce a change in flow greater than the allowable
		// flow we have left to spend?
		if vc.Flow.Flow(id, absFlow).Cmp(allowableFlow) == 1 {
			return nil, fmt.Errorf("%s cannot change validator power of %v from %v to %v because that would result "+
				"in a flow greater than or equal to 1/3 of total power for the next commit: flow induced by change: %v, "+
				"current total flow: %v/%v (cumulative/max), remaining allowable flow: %v",
				errHeader, id.GetAddress(), vc.Previous.GetPower(id.GetAddress()), power, absFlow, vc.Flow.totalPower,
				maxFlow, allowableFlow)
		}
	}
	// Set flow for this id to update flow.totalPower (total flow) for comparison below, keep track of flow for each id
	// so that we only count flow once for each id
	vc.Flow.ChangePower(id, absFlow)
	// Update Delta and Next
	vc.Delta.ChangePower(id, power)
	vc.Next.ChangePower(id, power)
	return absFlow, nil
}

func (vc *Bucket) CurrentSet() *Set {
	return vc.Previous
}

func (vc *Bucket) String() string {
	return fmt.Sprintf("Bucket{Previous: %v; Next: %v; Delta: %v}", vc.Previous, vc.Next, vc.Delta)
}

func (vc *Bucket) Equal(vwOther *Bucket) error {
	err := vc.Delta.Equal(vwOther.Delta)
	if err != nil {
		return fmt.Errorf("bucket delta != other bucket delta: %v", err)
	}
	err = vc.Previous.Equal(vwOther.Previous)
	if err != nil {
		return fmt.Errorf("bucket cum != other bucket cum: %v", err)
	}
	return nil
}

func checkPower(power *big.Int) error {
	if power.Sign() == -1 {
		return fmt.Errorf("cannot set negative validator power: %v", power)
	}
	if !power.IsInt64() {
		return fmt.Errorf("for tendermint compatibility validator power must fit within an int but %v "+
			"does not", power)
	}
	return nil
}
<commit_msg>only check flow if totalpower > 0<commit_after>package validator

import (
	"fmt"
	"math/big"

	"github.com/hyperledger/burrow/crypto"
	"github.com/tendermint/tendermint/types"
)

// Safety margin determined by Tendermint (see comment on source constant)
var maxTotalPower = big.NewInt(types.MaxTotalVotingPower)
var minTotalPower = big.NewInt(4)

type Bucket struct {
	// Delta tracks the changes to validator power made since the previous rotation
	Delta *Set
	// Previous the value for all validator powers at the point of the last rotation
	// (the sum of all the deltas over all rotations) - these are the history of the complete validator sets at each rotation
	Previous *Set
	// Tracks the current working version of the next set; Previous + Delta
	Next *Set
	// Flow tracks the absolute value of all flows (difference between previous cum bucket and current delta) towards and away from each validator (tracking each validator separately to avoid double counting flows made against the same validator
	Flow *Set
}

func NewBucket(initialSets ...Iterable) *Bucket {
	bucket := &Bucket{
		Previous: NewTrimSet(),
		Next:     NewTrimSet(),
		Delta:    NewSet(),
		Flow:     NewSet(),
	}
	for _, vs := range initialSets {
		vs.IterateValidators(func(id crypto.Addressable, power *big.Int) error {
			bucket.Previous.ChangePower(id.GetPublicKey(), power)
			bucket.Next.ChangePower(id.GetPublicKey(), power)
			return nil
		})
	}
	return bucket
}

// Implement Reader
func (vc *Bucket) Power(id crypto.Address) (*big.Int, error) {
	return vc.Previous.Power(id)
}

// SetPower ensures that validator power would not change too quickly in a single block
func (vc *Bucket) SetPower(id crypto.PublicKey, power *big.Int) (*big.Int, error) {
	const errHeader = "Bucket.SetPower():"
	err := checkPower(power)
	if err != nil {
		return nil, fmt.Errorf("%s %v", errHeader, err)
	}

	nextTotalPower := vc.Next.TotalPower()
	nextTotalPower.Add(nextTotalPower, vc.Next.Flow(id, power))
	// We must not have lower validator power than 4 because this would prevent any flow from occurring
	// min > nextTotalPower
	if minTotalPower.Cmp(nextTotalPower) == 1 {
		return nil, fmt.Errorf("%s cannot change validator power of %v from %v to %v because that would result "+
			"in a total power less than the permitted minimum of 4: would make next total power: %v",
			errHeader, id.GetAddress(), vc.Previous.GetPower(id.GetAddress()), power, nextTotalPower)
	}

	// nextTotalPower > max
	if nextTotalPower.Cmp(maxTotalPower) == 1 {
		return nil, fmt.Errorf("%s cannot change validator power of %v from %v to %v because that would result "+
			"in a total power greater than that allowed by tendermint (%v): would make next total power: %v",
			errHeader, id.GetAddress(), vc.Previous.GetPower(id.GetAddress()), power, maxTotalPower, nextTotalPower)
	}

	// The new absolute flow caused by this AlterPower
	flow := vc.Previous.Flow(id, power)
	absFlow := new(big.Int).Abs(flow)

	// Only check flow if power exists, this allows us to
	// bootstrap the set from an empty state
	if vc.Previous.TotalPower().Sign() > 0 {
		// The max flow we are permitted to allow across all validators
		maxFlow := vc.Previous.MaxFlow()
		// The remaining flow we have to play with
		allowableFlow := new(big.Int).Sub(maxFlow, vc.Flow.totalPower)

		// If we call vc.flow.ChangePower(id, absFlow) (below) will we induce a change in flow greater than the allowable
		// flow we have left to spend?
		if vc.Flow.Flow(id, absFlow).Cmp(allowableFlow) == 1 {
			return nil, fmt.Errorf("%s cannot change validator power of %v from %v to %v because that would result "+
				"in a flow greater than or equal to 1/3 of total power for the next commit: flow induced by change: %v, "+
				"current total flow: %v/%v (cumulative/max), remaining allowable flow: %v",
				errHeader, id.GetAddress(), vc.Previous.GetPower(id.GetAddress()), power, absFlow, vc.Flow.totalPower,
				maxFlow, allowableFlow)
		}
	}
	// Set flow for this id to update flow.totalPower (total flow) for comparison below, keep track of flow for each id
	// so that we only count flow once for each id
	vc.Flow.ChangePower(id, absFlow)
	// Update Delta and Next
	vc.Delta.ChangePower(id, power)
	vc.Next.ChangePower(id, power)
	return absFlow, nil
}

func (vc *Bucket) CurrentSet() *Set {
	return vc.Previous
}

func (vc *Bucket) String() string {
	return fmt.Sprintf("Bucket{Previous: %v; Next: %v; Delta: %v}", vc.Previous, vc.Next, vc.Delta)
}

func (vc *Bucket) Equal(vwOther *Bucket) error {
	err := vc.Delta.Equal(vwOther.Delta)
	if err != nil {
		return fmt.Errorf("bucket delta != other bucket delta: %v", err)
	}
	err = vc.Previous.Equal(vwOther.Previous)
	if err != nil {
		return fmt.Errorf("bucket cum != other bucket cum: %v", err)
	}
	return nil
}

func checkPower(power *big.Int) error {
	if power.Sign() == -1 {
		return fmt.Errorf("cannot set negative validator power: %v", power)
	}
	if !power.IsInt64() {
		return fmt.Errorf("for tendermint compatibility validator power must fit within an int but %v "+
			"does not", power)
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"path/filepath"
	"testing"
)

func TestBuildWillCreateBlogFolder(t *testing.T) {
	dir := createTmpFolder(t)
	output := filepath.Join(dir, "blog")

	NewBlogBuilder(dir).Build(output)

	assertFilePathExist(t, output)
}

func TestBlogFolderWillBeDeletedBeforeBuild(t *testing.T) {
	dir := createTmpFolder(t)
	output := filepath.Join(dir, "blog")
	deleteme := filepath.Join(output, "delete_me")
	os.Mkdir(output, os.ModePerm)
	os.Create(deleteme)

	NewBlogBuilder(dir).Build(output)

	if _, err := os.Stat(deleteme); !os.IsNotExist(err) {
		t.Fatalf("Should delete exist blog folder before build")
	}
}
<commit_msg>rename test<commit_after>package main

import (
	"os"
	"path/filepath"
	"testing"
)

func TestBuildWillCreateBlogFolder(t *testing.T) {
	dir := createTmpFolder(t)
	output := filepath.Join(dir, "blog")

	NewBlogBuilder(dir).Build(output)

	assertFilePathExist(t, output)
}

func TestCleanUpBeforeBuild(t *testing.T) {
	dir := createTmpFolder(t)
	output := filepath.Join(dir, "blog")
	deleteme := filepath.Join(output, "delete_me")
	os.Mkdir(output, os.ModePerm)
	os.Create(deleteme)

	NewBlogBuilder(dir).Build(output)

	if _, err := os.Stat(deleteme); !os.IsNotExist(err) {
		t.Fatalf("Should delete exist blog folder before build")
	}
}

func TestBuild(t *testing.T) {

}
<|endoftext|>


<commit_before>package gitinfo_test

import (
	"testing"

	"github.com/denormal/go-gitinfo"
)

const _NONSENSE = "my.nonsense.field"

func TestBuild(t *testing.T) {
	// create a GitInfo instance
	_map := map[string]string{
		gitinfo.BRANCH:     "branch",
		gitinfo.COMMIT:     "commit",
		gitinfo.EDITOR:     "editor",
		gitinfo.GIT:        "git",
		gitinfo.MODIFIED:   "true",
		gitinfo.PATH:       "path",
		gitinfo.ROOT:       "root",
		gitinfo.USER_NAME:  "user.name",
		gitinfo.USER_EMAIL: "user.email",
		_NONSENSE:          "nonsense",
	}

	// ensure Build creates the requisite model
	_git := gitinfo.Build(_map)
	//		- branch
	_branch, _err := _git.Branch()
	if _err != nil {
		t.Fatalf("unexpected error in Branch(): %s", _err.Error())
	} else if _branch != _map[gitinfo.BRANCH] {
		t.Fatalf("unexpected Branch(); expected %q, got %q",
			_map[gitinfo.BRANCH], _branch,
		)
	}
	//		- config
	_config := _git.Config()
	if _config != nil {
		t.Fatalf(
			"unexpected Config(); expected %v, got %v", nil, _config,
		)
	}
	//		- commit
	_commit, _err := _git.Commit()
	if _err != nil {
		t.Fatalf("unexpected error in Commit(): %s", _err.Error())
	} else if _commit == nil {
		t.Fatalf("unexpected nil from Commit()")
	} else if _commit.String() != _map[gitinfo.COMMIT] {
		t.Fatalf(
			"unexpected Commit(); expected %q, got %q",
			_map[gitinfo.COMMIT], _commit.String(),
		)
	}
	//		- editor
	_editor := _git.Editor()
	if _editor != _map[gitinfo.EDITOR] {
		t.Fatalf(
			"unexpected Editor(); expected %q, got %q",
			_map[gitinfo.EDITOR], _editor,
		)
	}
	//		- modified
	_modified, _err := _git.Modified()
	if _err != nil {
		t.Fatalf("unexpected error in Modified(): %s", _err.Error())
	} else if !_modified { // the test set above uses "true"
		t.Fatalf(
			"unexpected Modified(); expected %s, got %v",
			_map[gitinfo.MODIFIED], _modified,
		)
	}
	//		- path
	_path := _git.Path()
	if _path != _map[gitinfo.PATH] {
		t.Fatalf(
			"unexpected Path(); expected %q, got %q",
			_map[gitinfo.PATH], _path,
		)
	}
	//		- root
	_root := _git.Root()
	if _root != _map[gitinfo.ROOT] {
		t.Fatalf(
			"unexpected Root(); expected %q, got %q",
			_map[gitinfo.ROOT], _root,
		)
	}
	//		- user
	_user := _git.User()
	if _user == nil {
		t.Fatalf("unexpected nil from User()")
	} else if _user.Name() != _map[gitinfo.USER_NAME] {
		t.Fatalf(
			"unexpected User() name; expected %q, got %q",
			_map[gitinfo.USER_NAME], _user.Name(),
		)
	} else if _user.Email() != _map[gitinfo.USER_EMAIL] {
		t.Fatalf(
			"unexpected User() name; expected %q, got %q",
			_map[gitinfo.USER_EMAIL], _user.Email(),
		)
	}
	//		- git version
	_gitversion, _err := _git.Git()
	if _err != nil {
		t.Fatalf("unexpected error in Git(): %s", _err.Error())
	} else if _gitversion != _map[gitinfo.GIT] {
		t.Fatalf(
			"unexpected Git(); expected %q, got %q",
			_map[gitinfo.GIT], _gitversion,
		)
	}

	// Map()
	_got := _git.Map()
	for _k, _v := range _got {
		_value, _ok := _map[_k]
		if !_ok {
			t.Fatalf("expected map value for %q, none found", _k)
		} else if _value != _v {
			t.Fatalf(
				"unexpected value for %q; expected %q, got %q",
				_k, _v, _value,
			)
		}
	}
	//		- ensure the "nonsense" key is not returned
	_nonsense, _ok := _got[_NONSENSE]
	if _ok {
		t.Fatal(
			"unexpected result from Map(); expected no entry for %q, got %q",
			_NONSENSE, _nonsense,
		)
	}
} // TestBuild()
<commit_msg>Corrections to fix "go vet" warnings.<commit_after>package gitinfo_test

import (
	"testing"

	"github.com/denormal/go-gitinfo"
)

const _NONSENSE = "my.nonsense.field"

func TestBuild(t *testing.T) {
	// create a GitInfo instance
	_map := map[string]string{
		gitinfo.BRANCH:     "branch",
		gitinfo.COMMIT:     "commit",
		gitinfo.EDITOR:     "editor",
		gitinfo.GIT:        "git",
		gitinfo.MODIFIED:   "true",
		gitinfo.PATH:       "path",
		gitinfo.ROOT:       "root",
		gitinfo.USER_NAME:  "user.name",
		gitinfo.USER_EMAIL: "user.email",
		_NONSENSE:          "nonsense",
	}

	// ensure Build creates the requisite model
	_git := gitinfo.Build(_map)
	//		- branch
	_branch, _err := _git.Branch()
	if _err != nil {
		t.Fatalf("unexpected error in Branch(): %s", _err.Error())
	} else if _branch != _map[gitinfo.BRANCH] {
		t.Fatalf("unexpected Branch(); expected %q, got %q",
			_map[gitinfo.BRANCH], _branch,
		)
	}
	//		- config
	_config := _git.Config()
	if _config != nil {
		t.Fatalf(
			"unexpected Config(); expected %v, got %v", nil, _config,
		)
	}
	//		- commit
	_commit, _err := _git.Commit()
	if _err != nil {
		t.Fatalf("unexpected error in Commit(): %s", _err.Error())
	} else if _commit == nil {
		t.Fatalf("unexpected nil from Commit()")
	} else if _commit.String() != _map[gitinfo.COMMIT] {
		t.Fatalf(
			"unexpected Commit(); expected %q, got %q",
			_map[gitinfo.COMMIT], _commit.String(),
		)
	}
	//		- editor
	_editor := _git.Editor()
	if _editor != _map[gitinfo.EDITOR] {
		t.Fatalf(
			"unexpected Editor(); expected %q, got %q",
			_map[gitinfo.EDITOR], _editor,
		)
	}
	//		- modified
	_modified, _err := _git.Modified()
	if _err != nil {
		t.Fatalf("unexpected error in Modified(): %s", _err.Error())
	} else if !_modified { // the test set above uses "true"
		t.Fatalf(
			"unexpected Modified(); expected %s, got %v",
			_map[gitinfo.MODIFIED], _modified,
		)
	}
	//		- path
	_path := _git.Path()
	if _path != _map[gitinfo.PATH] {
		t.Fatalf(
			"unexpected Path(); expected %q, got %q",
			_map[gitinfo.PATH], _path,
		)
	}
	//		- root
	_root := _git.Root()
	if _root != _map[gitinfo.ROOT] {
		t.Fatalf(
			"unexpected Root(); expected %q, got %q",
			_map[gitinfo.ROOT], _root,
		)
	}
	//		- user
	_user := _git.User()
	if _user == nil {
		t.Fatalf("unexpected nil from User()")
	} else if _user.Name() != _map[gitinfo.USER_NAME] {
		t.Fatalf(
			"unexpected User() name; expected %q, got %q",
			_map[gitinfo.USER_NAME], _user.Name(),
		)
	} else if _user.Email() != _map[gitinfo.USER_EMAIL] {
		t.Fatalf(
			"unexpected User() name; expected %q, got %q",
			_map[gitinfo.USER_EMAIL], _user.Email(),
		)
	}
	//		- git version
	_gitversion, _err := _git.Git()
	if _err != nil {
		t.Fatalf("unexpected error in Git(): %s", _err.Error())
	} else if _gitversion != _map[gitinfo.GIT] {
		t.Fatalf(
			"unexpected Git(); expected %q, got %q",
			_map[gitinfo.GIT], _gitversion,
		)
	}

	// Map()
	_got := _git.Map()
	for _k, _v := range _got {
		_value, _ok := _map[_k]
		if !_ok {
			t.Fatalf("expected map value for %q, none found", _k)
		} else if _value != _v {
			t.Fatalf(
				"unexpected value for %q; expected %q, got %q",
				_k, _v, _value,
			)
		}
	}
	//		- ensure the "nonsense" key is not returned
	_nonsense, _ok := _got[_NONSENSE]
	if _ok {
		t.Fatalf(
			"unexpected result from Map(); expected no entry for %q, got %q",
			_NONSENSE, _nonsense,
		)
	}
} // TestBuild()
<|endoftext|>


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

package astutil

import (
	"bytes"
	"go/ast"
	"go/format"
	"go/parser"
	"go/token"
	"reflect"
	"strconv"
	"testing"
)

var fset = token.NewFileSet()

func parse(t *testing.T, name, in string) *ast.File {
	file, err := parser.ParseFile(fset, name, in, parser.ParseComments)
	if err != nil {
		t.Fatalf("%s parse: %v", name, err)
	}
	return file
}

func print(t *testing.T, name string, f *ast.File) string {
	var buf bytes.Buffer
	if err := format.Node(&buf, fset, f); err != nil {
		t.Fatalf("%s gofmt: %v", name, err)
	}
	return string(buf.Bytes())
}

type test struct {
	name       string
	renamedPkg string
	pkg        string
	in         string
	out        string
	broken     bool // known broken
}

var addTests = []test{
	{
		name: "leave os alone",
		pkg:  "os",
		in: `package main

import (
	"os"
)
`,
		out: `package main

import (
	"os"
)
`,
	},
	{
		name: "import.1",
		pkg:  "os",
		in: `package main
`,
		out: `package main

import "os"
`,
	},
	{
		name: "import.2",
		pkg:  "os",
		in: `package main

// Comment
import "C"
`,
		out: `package main

// Comment
import "C"
import "os"
`,
	},
	{
		name: "import.3",
		pkg:  "os",
		in: `package main

// Comment
import "C"

import (
	"io"
	"utf8"
)
`,
		out: `package main

// Comment
import "C"

import (
	"io"
	"os"
	"utf8"
)
`,
	},
	{
		name: "import.17",
		pkg:  "x/y/z",
		in: `package main

// Comment
import "C"

import (
	"a"
	"b"

	"x/w"

	"d/f"
)
`,
		out: `package main

// Comment
import "C"

import (
	"a"
	"b"

	"x/w"
	"x/y/z"

	"d/f"
)
`,
	},
	{
		name: "import into singular block",
		pkg:  "bytes",
		in: `package main

import "os"

`,
		out: `package main

import (
	"bytes"
	"os"
)
`,
	},
	{
		name:       "",
		renamedPkg: "fmtpkg",
		pkg:        "fmt",
		in: `package main

import "os"

`,
		out: `package main

import (
	fmtpkg "fmt"
	"os"
)
`,
	},
	{
		broken: true,
		name:   "struct comment",
		pkg:    "time",
		in: `package main

// This is a comment before a struct.
type T struct {
	t  time.Time
}
`,
		out: `package main

import "time"

// This is a comment before a struct.
type T struct {
	t time.Time
}
`,
	},
}

func TestAddImport(t *testing.T) {
	for _, test := range addTests {
		file := parse(t, test.name, test.in)
		AddNamedImport(file, test.renamedPkg, test.pkg)
		if got := print(t, test.name, file); got != test.out {
			if test.broken {
				t.Logf("%s is known broken:\ngot: %s\nwant: %s", test.name, got, test.out)
			} else {
				t.Errorf("%s:\ngot: %s\nwant: %s", test.name, got, test.out)
			}
		}
	}
}

func TestDoubleAddImport(t *testing.T) {
	file := parse(t, "doubleimport", "package main\n")
	AddImport(file, "os")
	AddImport(file, "bytes")
	want := `package main

import (
	"bytes"
	"os"
)
`
	if got := print(t, "doubleimport", file); got != want {
		t.Errorf("got: %s\nwant: %s", got, want)
	}
}

var deleteTests = []test{
	{
		name: "import.4",
		pkg:  "os",
		in: `package main

import (
	"os"
)
`,
		out: `package main
`,
	},
	{
		name: "import.5",
		pkg:  "os",
		in: `package main

// Comment
import "C"
import "os"
`,
		out: `package main

// Comment
import "C"
`,
	},
	{
		name: "import.6",
		pkg:  "os",
		in: `package main

// Comment
import "C"

import (
	"io"
	"os"
	"utf8"
)
`,
		out: `package main

// Comment
import "C"

import (
	"io"
	"utf8"
)
`,
	},
	{
		name: "import.7",
		pkg:  "io",
		in: `package main

import (
	"io"   // a
	"os"   // b
	"utf8" // c
)
`,
		out: `package main

import (
	// a
	"os"   // b
	"utf8" // c
)
`,
	},
	{
		name: "import.8",
		pkg:  "os",
		in: `package main

import (
	"io"   // a
	"os"   // b
	"utf8" // c
)
`,
		out: `package main

import (
	"io" // a
	// b
	"utf8" // c
)
`,
	},
	{
		name: "import.9",
		pkg:  "utf8",
		in: `package main

import (
	"io"   // a
	"os"   // b
	"utf8" // c
)
`,
		out: `package main

import (
	"io" // a
	"os" // b
	// c
)
`,
	},
	{
		name: "import.10",
		pkg:  "io",
		in: `package main

import (
	"io"
	"os"
	"utf8"
)
`,
		out: `package main

import (
	"os"
	"utf8"
)
`,
	},
	{
		name: "import.11",
		pkg:  "os",
		in: `package main

import (
	"io"
	"os"
	"utf8"
)
`,
		out: `package main

import (
	"io"
	"utf8"
)
`,
	},
	{
		name: "import.12",
		pkg:  "utf8",
		in: `package main

import (
	"io"
	"os"
	"utf8"
)
`,
		out: `package main

import (
	"io"
	"os"
)
`,
	},
	{
		name: "handle.raw.quote.imports",
		pkg:  "os",
		in:   "package main\n\nimport `os`",
		out: `package main
`,
	},
}

func TestDeleteImport(t *testing.T) {
	for _, test := range deleteTests {
		file := parse(t, test.name, test.in)
		DeleteImport(file, test.pkg)
		if got := print(t, test.name, file); got != test.out {
			t.Errorf("%s:\ngot: %s\nwant: %s", test.name, got, test.out)
		}
	}
}

type rewriteTest struct {
	name   string
	srcPkg string
	dstPkg string
	in     string
	out    string
}

var rewriteTests = []rewriteTest{
	{
		name:   "import.13",
		srcPkg: "utf8",
		dstPkg: "encoding/utf8",
		in: `package main

import (
	"io"
	"os"
	"utf8" // thanks ken
)
`,
		out: `package main

import (
	"encoding/utf8" // thanks ken
	"io"
	"os"
)
`,
	},
	{
		name:   "import.14",
		srcPkg: "asn1",
		dstPkg: "encoding/asn1",
		in: `package main

import (
	"asn1"
	"crypto"
	"crypto/rsa"
	_ "crypto/sha1"
	"crypto/x509"
	"crypto/x509/pkix"
	"time"
)

var x = 1
`,
		out: `package main

import (
	"crypto"
	"crypto/rsa"
	_ "crypto/sha1"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/asn1"
	"time"
)

var x = 1
`,
	},
	{
		name:   "import.15",
		srcPkg: "url",
		dstPkg: "net/url",
		in: `package main

import (
	"bufio"
	"net"
	"path"
	"url"
)

var x = 1 // comment on x, not on url
`,
		out: `package main

import (
	"bufio"
	"net"
	"net/url"
	"path"
)

var x = 1 // comment on x, not on url
`,
	},
	{
		name:   "import.16",
		srcPkg: "http",
		dstPkg: "net/http",
		in: `package main

import (
	"flag"
	"http"
	"log"
	"text/template"
)

var addr = flag.String("addr", ":1718", "http service address") // Q=17, R=18
`,
		out: `package main

import (
	"flag"
	"log"
	"net/http"
	"text/template"
)

var addr = flag.String("addr", ":1718", "http service address") // Q=17, R=18
`,
	},
}

func TestRewriteImport(t *testing.T) {
	for _, test := range rewriteTests {
		file := parse(t, test.name, test.in)
		RewriteImport(file, test.srcPkg, test.dstPkg)
		if got := print(t, test.name, file); got != test.out {
			t.Errorf("%s:\ngot: %s\nwant: %s", test.name, got, test.out)
		}
	}
}

var renameTests = []rewriteTest{
	{
		name:   "rename pkg use",
		srcPkg: "bytes",
		dstPkg: "bytes_",
		in: `package main

func f() []byte {
	buf := new(bytes.Buffer)
	return buf.Bytes()
}
`,
		out: `package main

func f() []byte {
	buf := new(bytes_.Buffer)
	return buf.Bytes()
}
`,
	},
}

func TestRenameTop(t *testing.T) {
	for _, test := range renameTests {
		file := parse(t, test.name, test.in)
		RenameTop(file, test.srcPkg, test.dstPkg)
		if got := print(t, test.name, file); got != test.out {
			t.Errorf("%s:\ngot: %s\nwant: %s", test.name, got, test.out)
		}
	}
}

var importsTests = []struct {
	name string
	in   string
	want [][]string
}{
	{
		name: "no packages",
		in: `package foo
`,
		want: nil,
	},
	{
		name: "one group",
		in: `package foo

import (
	"fmt"
	"testing"
)
`,
		want: [][]string{{"fmt", "testing"}},
	},
	{
		name: "four groups",
		in: `package foo

import "C"
import (
	"fmt"
	"testing"

	"appengine"

	"myproject/mylib1"
	"myproject/mylib2"
)
`,
		want: [][]string{
			{"C"},
			{"fmt", "testing"},
			{"appengine"},
			{"myproject/mylib1", "myproject/mylib2"},
		},
	},
	{
		name: "multiple factored groups",
		in: `package foo

import (
	"fmt"
	"testing"

	"appengine"
)
import (
	"reflect"

	"bytes"
)
`,
		want: [][]string{
			{"fmt", "testing"},
			{"appengine"},
			{"reflect"},
			{"bytes"},
		},
	},
}

func unquote(s string) string {
	res, err := strconv.Unquote(s)
	if err != nil {
		return "could_not_unquote"
	}
	return res
}

func TestImports(t *testing.T) {
	fset := token.NewFileSet()
	for _, test := range importsTests {
		f, err := parser.ParseFile(fset, "test.go", test.in, 0)
		if err != nil {
			t.Errorf("%s: %v", test.name, err)
			continue
		}
		var got [][]string
		for _, block := range Imports(fset, f) {
			var b []string
			for _, spec := range block {
				b = append(b, unquote(spec.Path.Value))
			}
			got = append(got, b)
		}
		if !reflect.DeepEqual(got, test.want) {
			t.Errorf("Imports(%s)=%v, want %v", test.name, got, test.want)
		}
	}
}
<commit_msg>astutil: in test, dump AST before and after on failure<commit_after>// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package astutil

import (
	"bytes"
	"go/ast"
	"go/format"
	"go/parser"
	"go/token"
	"reflect"
	"strconv"
	"testing"
)

var fset = token.NewFileSet()

func parse(t *testing.T, name, in string) *ast.File {
	file, err := parser.ParseFile(fset, name, in, parser.ParseComments)
	if err != nil {
		t.Fatalf("%s parse: %v", name, err)
	}
	return file
}

func print(t *testing.T, name string, f *ast.File) string {
	var buf bytes.Buffer
	if err := format.Node(&buf, fset, f); err != nil {
		t.Fatalf("%s gofmt: %v", name, err)
	}
	return string(buf.Bytes())
}

type test struct {
	name       string
	renamedPkg string
	pkg        string
	in         string
	out        string
	broken     bool // known broken
}

var addTests = []test{
	{
		name: "leave os alone",
		pkg:  "os",
		in: `package main

import (
	"os"
)
`,
		out: `package main

import (
	"os"
)
`,
	},
	{
		name: "import.1",
		pkg:  "os",
		in: `package main
`,
		out: `package main

import "os"
`,
	},
	{
		name: "import.2",
		pkg:  "os",
		in: `package main

// Comment
import "C"
`,
		out: `package main

// Comment
import "C"
import "os"
`,
	},
	{
		name: "import.3",
		pkg:  "os",
		in: `package main

// Comment
import "C"

import (
	"io"
	"utf8"
)
`,
		out: `package main

// Comment
import "C"

import (
	"io"
	"os"
	"utf8"
)
`,
	},
	{
		name: "import.17",
		pkg:  "x/y/z",
		in: `package main

// Comment
import "C"

import (
	"a"
	"b"

	"x/w"

	"d/f"
)
`,
		out: `package main

// Comment
import "C"

import (
	"a"
	"b"

	"x/w"
	"x/y/z"

	"d/f"
)
`,
	},
	{
		name: "import into singular block",
		pkg:  "bytes",
		in: `package main

import "os"

`,
		out: `package main

import (
	"bytes"
	"os"
)
`,
	},
	{
		name:       "",
		renamedPkg: "fmtpkg",
		pkg:        "fmt",
		in: `package main

import "os"

`,
		out: `package main

import (
	fmtpkg "fmt"
	"os"
)
`,
	},
	{
		broken: true,
		name:   "struct comment",
		pkg:    "time",
		in: `package main

// This is a comment before a struct.
type T struct {
	t  time.Time
}
`,
		out: `package main

import "time"

// This is a comment before a struct.
type T struct {
	t time.Time
}
`,
	},
}

func TestAddImport(t *testing.T) {
	for _, test := range addTests {
		file := parse(t, test.name, test.in)
		var before bytes.Buffer
		ast.Fprint(&before, fset, file, nil)
		AddNamedImport(file, test.renamedPkg, test.pkg)
		if got := print(t, test.name, file); got != test.out {
			if test.broken {
				t.Logf("%s is known broken:\ngot: %s\nwant: %s", test.name, got, test.out)
			} else {
				t.Errorf("%s:\ngot: %s\nwant: %s", test.name, got, test.out)
			}
			var after bytes.Buffer
			ast.Fprint(&after, fset, file, nil)

			t.Logf("AST before:\n%s\nAST after:\n%s\n", before.String(), after.String())
		}
	}
}

func TestDoubleAddImport(t *testing.T) {
	file := parse(t, "doubleimport", "package main\n")
	AddImport(file, "os")
	AddImport(file, "bytes")
	want := `package main

import (
	"bytes"
	"os"
)
`
	if got := print(t, "doubleimport", file); got != want {
		t.Errorf("got: %s\nwant: %s", got, want)
	}
}

var deleteTests = []test{
	{
		name: "import.4",
		pkg:  "os",
		in: `package main

import (
	"os"
)
`,
		out: `package main
`,
	},
	{
		name: "import.5",
		pkg:  "os",
		in: `package main

// Comment
import "C"
import "os"
`,
		out: `package main

// Comment
import "C"
`,
	},
	{
		name: "import.6",
		pkg:  "os",
		in: `package main

// Comment
import "C"

import (
	"io"
	"os"
	"utf8"
)
`,
		out: `package main

// Comment
import "C"

import (
	"io"
	"utf8"
)
`,
	},
	{
		name: "import.7",
		pkg:  "io",
		in: `package main

import (
	"io"   // a
	"os"   // b
	"utf8" // c
)
`,
		out: `package main

import (
	// a
	"os"   // b
	"utf8" // c
)
`,
	},
	{
		name: "import.8",
		pkg:  "os",
		in: `package main

import (
	"io"   // a
	"os"   // b
	"utf8" // c
)
`,
		out: `package main

import (
	"io" // a
	// b
	"utf8" // c
)
`,
	},
	{
		name: "import.9",
		pkg:  "utf8",
		in: `package main

import (
	"io"   // a
	"os"   // b
	"utf8" // c
)
`,
		out: `package main

import (
	"io" // a
	"os" // b
	// c
)
`,
	},
	{
		name: "import.10",
		pkg:  "io",
		in: `package main

import (
	"io"
	"os"
	"utf8"
)
`,
		out: `package main

import (
	"os"
	"utf8"
)
`,
	},
	{
		name: "import.11",
		pkg:  "os",
		in: `package main

import (
	"io"
	"os"
	"utf8"
)
`,
		out: `package main

import (
	"io"
	"utf8"
)
`,
	},
	{
		name: "import.12",
		pkg:  "utf8",
		in: `package main

import (
	"io"
	"os"
	"utf8"
)
`,
		out: `package main

import (
	"io"
	"os"
)
`,
	},
	{
		name: "handle.raw.quote.imports",
		pkg:  "os",
		in:   "package main\n\nimport `os`",
		out: `package main
`,
	},
}

func TestDeleteImport(t *testing.T) {
	for _, test := range deleteTests {
		file := parse(t, test.name, test.in)
		DeleteImport(file, test.pkg)
		if got := print(t, test.name, file); got != test.out {
			t.Errorf("%s:\ngot: %s\nwant: %s", test.name, got, test.out)
		}
	}
}

type rewriteTest struct {
	name   string
	srcPkg string
	dstPkg string
	in     string
	out    string
}

var rewriteTests = []rewriteTest{
	{
		name:   "import.13",
		srcPkg: "utf8",
		dstPkg: "encoding/utf8",
		in: `package main

import (
	"io"
	"os"
	"utf8" // thanks ken
)
`,
		out: `package main

import (
	"encoding/utf8" // thanks ken
	"io"
	"os"
)
`,
	},
	{
		name:   "import.14",
		srcPkg: "asn1",
		dstPkg: "encoding/asn1",
		in: `package main

import (
	"asn1"
	"crypto"
	"crypto/rsa"
	_ "crypto/sha1"
	"crypto/x509"
	"crypto/x509/pkix"
	"time"
)

var x = 1
`,
		out: `package main

import (
	"crypto"
	"crypto/rsa"
	_ "crypto/sha1"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/asn1"
	"time"
)

var x = 1
`,
	},
	{
		name:   "import.15",
		srcPkg: "url",
		dstPkg: "net/url",
		in: `package main

import (
	"bufio"
	"net"
	"path"
	"url"
)

var x = 1 // comment on x, not on url
`,
		out: `package main

import (
	"bufio"
	"net"
	"net/url"
	"path"
)

var x = 1 // comment on x, not on url
`,
	},
	{
		name:   "import.16",
		srcPkg: "http",
		dstPkg: "net/http",
		in: `package main

import (
	"flag"
	"http"
	"log"
	"text/template"
)

var addr = flag.String("addr", ":1718", "http service address") // Q=17, R=18
`,
		out: `package main

import (
	"flag"
	"log"
	"net/http"
	"text/template"
)

var addr = flag.String("addr", ":1718", "http service address") // Q=17, R=18
`,
	},
}

func TestRewriteImport(t *testing.T) {
	for _, test := range rewriteTests {
		file := parse(t, test.name, test.in)
		RewriteImport(file, test.srcPkg, test.dstPkg)
		if got := print(t, test.name, file); got != test.out {
			t.Errorf("%s:\ngot: %s\nwant: %s", test.name, got, test.out)
		}
	}
}

var renameTests = []rewriteTest{
	{
		name:   "rename pkg use",
		srcPkg: "bytes",
		dstPkg: "bytes_",
		in: `package main

func f() []byte {
	buf := new(bytes.Buffer)
	return buf.Bytes()
}
`,
		out: `package main

func f() []byte {
	buf := new(bytes_.Buffer)
	return buf.Bytes()
}
`,
	},
}

func TestRenameTop(t *testing.T) {
	for _, test := range renameTests {
		file := parse(t, test.name, test.in)
		RenameTop(file, test.srcPkg, test.dstPkg)
		if got := print(t, test.name, file); got != test.out {
			t.Errorf("%s:\ngot: %s\nwant: %s", test.name, got, test.out)
		}
	}
}

var importsTests = []struct {
	name string
	in   string
	want [][]string
}{
	{
		name: "no packages",
		in: `package foo
`,
		want: nil,
	},
	{
		name: "one group",
		in: `package foo

import (
	"fmt"
	"testing"
)
`,
		want: [][]string{{"fmt", "testing"}},
	},
	{
		name: "four groups",
		in: `package foo

import "C"
import (
	"fmt"
	"testing"

	"appengine"

	"myproject/mylib1"
	"myproject/mylib2"
)
`,
		want: [][]string{
			{"C"},
			{"fmt", "testing"},
			{"appengine"},
			{"myproject/mylib1", "myproject/mylib2"},
		},
	},
	{
		name: "multiple factored groups",
		in: `package foo

import (
	"fmt"
	"testing"

	"appengine"
)
import (
	"reflect"

	"bytes"
)
`,
		want: [][]string{
			{"fmt", "testing"},
			{"appengine"},
			{"reflect"},
			{"bytes"},
		},
	},
}

func unquote(s string) string {
	res, err := strconv.Unquote(s)
	if err != nil {
		return "could_not_unquote"
	}
	return res
}

func TestImports(t *testing.T) {
	fset := token.NewFileSet()
	for _, test := range importsTests {
		f, err := parser.ParseFile(fset, "test.go", test.in, 0)
		if err != nil {
			t.Errorf("%s: %v", test.name, err)
			continue
		}
		var got [][]string
		for _, block := range Imports(fset, f) {
			var b []string
			for _, spec := range block {
				b = append(b, unquote(spec.Path.Value))
			}
			got = append(got, b)
		}
		if !reflect.DeepEqual(got, test.want) {
			t.Errorf("Imports(%s)=%v, want %v", test.name, got, test.want)
		}
	}
}
<|endoftext|>


<commit_before>package assert

import (
	_ "github.com/ToQoz/gopwt/translatedassert" // for go get github.com/ToQoz/gopwt/assert
	"io/ioutil"
	"runtime"
	"strings"
	"testing"
)

type testingInterface interface {
	Error(args ...interface{})
	Skip(args ...interface{})
}

// OK assert given bool is true.
// This will be translate to `translatedassert.OK` by gopwt.
func OK(t *testing.T, ok bool, messages ...string) {
	_ok(t, ok, callerLine(1), messages...)
}

func _ok(t testingInterface, ok bool, callerLine string, messages ...string) {
	if ok {
		return
	}

	t.Error(`[FAIL Assersion] ` + callerLine + `

Please run tests by command "gopwt". It give you power.
If you need more information, see http://github.com/ToQoz/gopwt
`)
}

// Require assert given bool is true.
// The difference from OK is Require calls t.Skip after t.Error on fail.
// This will be translate to `translatedassert.Require` by gopwt.
func Require(t *testing.T, ok bool, messages ...string) {
	_require(t, ok, callerLine(1), messages...)
}

func _require(t testingInterface, ok bool, callerLine string, messages ...string) {
	if ok {
		return
	}

	t.Error(`[FAIL Assersion] ` + callerLine + `

Please run tests by command "gopwt". It give you power.
If you need more information, see http://github.com/ToQoz/gopwt
`)
	t.Skip("skip by gopwt/assert.Require")
}

func callerLine(skip int) string {
	_, file, lnum, ok := runtime.Caller(skip + 1)

	if !ok {
		return ""
	}

	b, err := ioutil.ReadFile(file)
	if err != nil {
		return ""
	}

	s := strings.Split(string(b), "\n")
	if len(s) <= lnum-1 {
		return ""
	}

	return strings.Trim(s[lnum-1], " \n\t")
}
<commit_msg>feat(gopwt): show assertion messages in plain assert(that is not translated)<commit_after>package assert

import (
	_ "github.com/ToQoz/gopwt/translatedassert" // for go get github.com/ToQoz/gopwt/assert
	"io/ioutil"
	"runtime"
	"strings"
	"testing"
)

type testingInterface interface {
	Error(args ...interface{})
	Skip(args ...interface{})
}

// OK assert given bool is true.
// This will be translate to `translatedassert.OK` by gopwt.
func OK(t *testing.T, ok bool, messages ...string) {
	_ok(t, ok, callerLine(1), messages...)
}

func _ok(t testingInterface, ok bool, callerLine string, messages ...string) {
	if ok {
		return
	}

	msg := `[FAIL Assersion] ` + callerLine + `

Please run tests by command "gopwt". It give you power.
If you need more information, see http://github.com/ToQoz/gopwt
`

	if len(messages) > 0 {
		msg += "\nAssersionMessage:\n"
		for _, m := range messages {
			msg += "\t- " + m
		}
	}

	t.Error(msg)
}

// Require assert given bool is true.
// The difference from OK is Require calls t.Skip after t.Error on fail.
// This will be translate to `translatedassert.Require` by gopwt.
func Require(t *testing.T, ok bool, messages ...string) {
	_require(t, ok, callerLine(1), messages...)
}

func _require(t testingInterface, ok bool, callerLine string, messages ...string) {
	if ok {
		return
	}

	msg := `[FAIL Assersion] ` + callerLine + `

Please run tests by command "gopwt". It give you power.
If you need more information, see http://github.com/ToQoz/gopwt
`

	if len(messages) > 0 {
		msg += "\nAssersionMessage:\n"
		for _, m := range messages {
			msg += "\t- " + m
		}
	}

	t.Error(msg)
	t.Skip("skip by gopwt/assert.Require")
}

func callerLine(skip int) string {
	_, file, lnum, ok := runtime.Caller(skip + 1)

	if !ok {
		return ""
	}

	b, err := ioutil.ReadFile(file)
	if err != nil {
		return ""
	}

	s := strings.Split(string(b), "\n")
	if len(s) <= lnum-1 {
		return ""
	}

	return strings.Trim(s[lnum-1], " \n\t")
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"strconv"
	"strings"
	"unicode"
)

/*
WARNING: HACK APPROACHING!

The suggested way to store squares is with bit fiddling. So a square is a
byte, with the following structure:

000XCPPP

Where 0 is junk, X is validity, C is colour, and PPP is piece data.
*/

const (
	EMPTY byte = iota
	PAWN
	KNIGHT
	BISHOP
	ROOK
	QUEEN
	KING
)

const (
	WHITE byte = 0x00
	BLACK byte = 0x08
)

const (
	ONBOARD  byte = 0x00
	OFFBOARD byte = 0x10
)

const (
	CASTLEWK byte = 0x01
	CASTLEWQ byte = 0x02
	CASTLEBK byte = 0x04
	CASTLEBQ byte = 0x08
)

type Board struct {
	/* Mailbox style, 10x12 board. */
	Data      [120]byte
	ToMove    byte
	Castle    byte
	EnPassant int
}

const (
	A1 int = 21
	H8 int = 98
)

const START string = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"

func ClearBoard(b *Board) {
	for i := 0; i < 120; i++ {
		if i < A1 || i > H8 {
			b.Data[i] = OFFBOARD
		} else if i%10 == 0 || i%10 == 9 {
			b.Data[i] = OFFBOARD
		} else {
			b.Data[i] = ONBOARD
		}
	}
}

func Parse(fen string) (*Board, error) {
	b := new(Board)
	ClearBoard(b)
	rank := 7
	file := 0
	eprank := -1
	epfile := -1
	stage := 0
	for _, runeValue := range fen {
		switch stage {
		case 0:
			/* Fill the data */
			if runeValue >= '1' && runeValue <= '8' {
				inc, _ := strconv.Atoi(string(runeValue))
				file += inc
			} else if runeValue == '/' {
				rank -= 1
				file = 0
			} else if runeValue == ' ' {
				stage++
			} else {
				switch unicode.ToUpper(runeValue) {
				case 'P':
					b.Data[CartesianToIndex(file, rank)] |= PAWN
				case 'N':
					b.Data[CartesianToIndex(file, rank)] |= KNIGHT
				case 'B':
					b.Data[CartesianToIndex(file, rank)] |= BISHOP
				case 'R':
					b.Data[CartesianToIndex(file, rank)] |= ROOK
				case 'Q':
					b.Data[CartesianToIndex(file, rank)] |= QUEEN
				case 'K':
					b.Data[CartesianToIndex(file, rank)] |= KING
				default:
					return nil, errors.New("Unexpected character in board data")
				}
				if unicode.IsLower(runeValue) {
					b.Data[CartesianToIndex(file, rank)] |= BLACK
				}
				file += 1
			}
		case 1:
			/* Get who's to play next */
			switch runeValue {
			case 'w':
				b.ToMove = WHITE
			case 'b':
				b.ToMove = BLACK
			case ' ':
				stage++
			default:
				return nil, errors.New("Unexpected character for active colour")
			}
		case 2:
			/* Castling */
			switch runeValue {
			case 'K':
				b.Castle |= CASTLEWK
			case 'Q':
				b.Castle |= CASTLEWQ
			case 'k':
				b.Castle |= CASTLEBK
			case 'q':
				b.Castle |= CASTLEBQ
			case ' ':
				stage++
			default:
				return nil, errors.New("Unexpected character for castling")
			}
		case 3:
			/* En-passant */
			if runeValue >= '1' && runeValue <= '8' {
				eprank, _ = strconv.Atoi(string(runeValue))
				eprank--
			} else if runeValue >= 'a' && runeValue <= 'h' {
				epfile = int(runeValue - 'a')
			} else if runeValue == ' ' {
				b.EnPassant = CartesianToIndex(epfile, eprank)
				stage++
			} else if runeValue != '-' {
				return nil, errors.New("Unexpected character for en passant")
			}
		}
	}
	return b, nil
}

func PrintBoard(b *Board) string {
	retval := ""
	for rank := 7; rank >= 0; rank-- {
		for file := 0; file < 8; file++ {
			retval +=
				ByteToString(b.Data[CartesianToIndex(file, rank)])
		}
		retval += "\n"
	}
	return retval
}

func CartesianToIndex(file, rank int) int {
	return 21 + (10 * rank) + file
}

func ByteToString(b byte) string {
	if ByteIsOffboard(b) {
		return ""
	}
	retval := ""
	switch GetPiece(b) {
	case EMPTY:
		return "."
	case PAWN:
		retval = "P"
	case KNIGHT:
		retval = "N"
	case BISHOP:
		retval = "B"
	case ROOK:
		retval = "R"
	case QUEEN:
		retval = "Q"
	case KING:
		retval = "K"
	default:
		return "?"
	}
	if IsBlack(b) {
		return strings.ToLower(retval)
	}
	return retval
}

func ByteIsOffboard(b byte) bool {
	return b&OFFBOARD == OFFBOARD
}

func GetPiece(b byte) byte {
	return b & 0x07
}

func IsBlack(b byte) bool {
	return b&BLACK == BLACK
}

func OnBoard(i int) bool {
	return i >= A1 && i <= H8
}
<commit_msg>add rank checks to OnBoard; refactor ClearBoard<commit_after>package main

import (
	"errors"
	"strconv"
	"strings"
	"unicode"
)

/*
WARNING: HACK APPROACHING!

The suggested way to store squares is with bit fiddling. So a square is a
byte, with the following structure:

000XCPPP

Where 0 is junk, X is validity, C is colour, and PPP is piece data.
*/

const (
	EMPTY byte = iota
	PAWN
	KNIGHT
	BISHOP
	ROOK
	QUEEN
	KING
)

const (
	WHITE byte = 0x00
	BLACK byte = 0x08
)

const (
	ONBOARD  byte = 0x00
	OFFBOARD byte = 0x10
)

const (
	CASTLEWK byte = 0x01
	CASTLEWQ byte = 0x02
	CASTLEBK byte = 0x04
	CASTLEBQ byte = 0x08
)

type Board struct {
	/* Mailbox style, 10x12 board. */
	Data      [120]byte
	ToMove    byte
	Castle    byte
	EnPassant int
}

const (
	A1 int = 21
	H8 int = 98
)

const START string = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"

func ClearBoard(b *Board) {
	for i := 0; i < 120; i++ {
		if OnBoard(i) {
			b.Data[i] = ONBOARD
		} else {
			b.Data[i] = OFFBOARD
		}
	}
}

func Parse(fen string) (*Board, error) {
	b := new(Board)
	ClearBoard(b)
	rank := 7
	file := 0
	eprank := -1
	epfile := -1
	stage := 0
	for _, runeValue := range fen {
		switch stage {
		case 0:
			/* Fill the data */
			if runeValue >= '1' && runeValue <= '8' {
				inc, _ := strconv.Atoi(string(runeValue))
				file += inc
			} else if runeValue == '/' {
				rank -= 1
				file = 0
			} else if runeValue == ' ' {
				stage++
			} else {
				switch unicode.ToUpper(runeValue) {
				case 'P':
					b.Data[CartesianToIndex(file, rank)] |= PAWN
				case 'N':
					b.Data[CartesianToIndex(file, rank)] |= KNIGHT
				case 'B':
					b.Data[CartesianToIndex(file, rank)] |= BISHOP
				case 'R':
					b.Data[CartesianToIndex(file, rank)] |= ROOK
				case 'Q':
					b.Data[CartesianToIndex(file, rank)] |= QUEEN
				case 'K':
					b.Data[CartesianToIndex(file, rank)] |= KING
				default:
					return nil, errors.New("Unexpected character in board data")
				}
				if unicode.IsLower(runeValue) {
					b.Data[CartesianToIndex(file, rank)] |= BLACK
				}
				file += 1
			}
		case 1:
			/* Get who's to play next */
			switch runeValue {
			case 'w':
				b.ToMove = WHITE
			case 'b':
				b.ToMove = BLACK
			case ' ':
				stage++
			default:
				return nil, errors.New("Unexpected character for active colour")
			}
		case 2:
			/* Castling */
			switch runeValue {
			case 'K':
				b.Castle |= CASTLEWK
			case 'Q':
				b.Castle |= CASTLEWQ
			case 'k':
				b.Castle |= CASTLEBK
			case 'q':
				b.Castle |= CASTLEBQ
			case ' ':
				stage++
			default:
				return nil, errors.New("Unexpected character for castling")
			}
		case 3:
			/* En-passant */
			if runeValue >= '1' && runeValue <= '8' {
				eprank, _ = strconv.Atoi(string(runeValue))
				eprank--
			} else if runeValue >= 'a' && runeValue <= 'h' {
				epfile = int(runeValue - 'a')
			} else if runeValue == ' ' {
				b.EnPassant = CartesianToIndex(epfile, eprank)
				stage++
			} else if runeValue != '-' {
				return nil, errors.New("Unexpected character for en passant")
			}
		}
	}
	return b, nil
}

func PrintBoard(b *Board) string {
	retval := ""
	for rank := 7; rank >= 0; rank-- {
		for file := 0; file < 8; file++ {
			retval +=
				ByteToString(b.Data[CartesianToIndex(file, rank)])
		}
		retval += "\n"
	}
	return retval
}

func CartesianToIndex(file, rank int) int {
	return 21 + (10 * rank) + file
}

func ByteToString(b byte) string {
	if ByteIsOffboard(b) {
		return ""
	}
	retval := ""
	switch GetPiece(b) {
	case EMPTY:
		return "."
	case PAWN:
		retval = "P"
	case KNIGHT:
		retval = "N"
	case BISHOP:
		retval = "B"
	case ROOK:
		retval = "R"
	case QUEEN:
		retval = "Q"
	case KING:
		retval = "K"
	default:
		return "?"
	}
	if IsBlack(b) {
		return strings.ToLower(retval)
	}
	return retval
}

func ByteIsOffboard(b byte) bool {
	return b&OFFBOARD == OFFBOARD
}

func GetPiece(b byte) byte {
	return b & 0x07
}

func IsBlack(b byte) bool {
	return b&BLACK == BLACK
}

func OnBoard(i int) bool {
	return i >= A1 && i <= H8 && !(i%10 == 0 || i%10 == 9)
}
<|endoftext|>


<commit_before>// Copyright 2015 Square 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 (
	"testing"
	"time"

	"github.com/square/keywhiz-fs/log"
	"github.com/stretchr/testify/assert"
)

var logConfig = log.Config{Debug: false, Mountpoint: "/tmp/mnt"}

// FailingBackend always returns ok==false
type FailingBackend struct {
}

func (b FailingBackend) Secret(name string) (*Secret, bool) {
	return nil, false
}

func (b FailingBackend) SecretList() ([]Secret, bool) {
	return nil, false
}

// ChannelBackend reads values from channels to return or blocks.
type ChannelBackend struct {
	secretc     chan *Secret
	secretListc chan []Secret
}

func (b ChannelBackend) Secret(name string) (*Secret, bool) {
	secret := <-b.secretc
	return secret, true
}

func (b ChannelBackend) SecretList() ([]Secret, bool) {
	secretList := <-b.secretListc
	return secretList, true
}

var timeouts = Timeouts{0, 10 * time.Millisecond, 20 * time.Millisecond}

func TestCacheSecretUsesValuesFromClient(t *testing.T) {
	assert := assert.New(t)

	secretFixture, _ := ParseSecret(fixture("secret.json"))

	secretc := make(chan *Secret, 1)
	backend := ChannelBackend{secretc: secretc}
	secretc <- secretFixture

	cache := NewCache(backend, timeouts, logConfig)
	secret, ok := cache.Secret("password-file")
	assert.True(ok)
	assert.Equal(secretFixture, secret)
}

func TestCachePassesThroughSecretNotFound(t *testing.T) {
	assert := assert.New(t)

	secretFixture, _ := ParseSecret(fixture("secret.json"))

	cache := NewCache(FailingBackend{}, timeouts, logConfig)
	secret, ok := cache.Secret(secretFixture.Name)
	assert.False(ok)
	assert.Nil(secret)

	cache.Add(*secretFixture)
	secret, ok = cache.Secret(secretFixture.Name)
	assert.True(ok)
	assert.Equal(secretFixture, secret)
}

func TestCacheSecretWhenClientTimesOut(t *testing.T) {
	assert := assert.New(t)

	secretFixture, _ := ParseSecret(fixture("secret.json"))
	backend := ChannelBackend{} // channels are nil and will block
	cache := NewCache(backend, timeouts, logConfig)

	// empty cache
	secret, ok := cache.Secret(secretFixture.Name)
	assert.False(ok)
	assert.Nil(secret)

	// cache with entry
	cache.Add(*secretFixture)
	secret, ok = cache.Secret(secretFixture.Name)
	assert.True(ok)
	assert.Equal(secretFixture, secret)
}

func TestCacheSecretUsesClientOverCache(t *testing.T) {
	assert := assert.New(t)

	fixture1, _ := ParseSecret(fixture("secret.json"))
	fixture2, _ := ParseSecret(fixture("secretNormalOwner.json"))
	fixture2.Name = fixture1.Name

	secretc := make(chan *Secret, 1)
	backend := ChannelBackend{secretc: secretc}
	secretc <- fixture1

	cache := NewCache(backend, timeouts, logConfig)
	cache.Add(*fixture2)

	// Although fixture2 is in the cache, the client returns fixture1.
	secret, ok := cache.Secret(fixture2.Name)
	assert.True(ok)
	assert.Equal(fixture1, secret)

	assert.Equal(1, cache.Len())
}

func TestCacheSecretAvoidsBackendWhenResultFresh(t *testing.T) {
	assert := assert.New(t)

	fixture1, _ := ParseSecret(fixture("secret.json"))
	fixture2, _ := ParseSecret(fixture("secretNormalOwner.json"))
	fixture2.Name = fixture1.Name

	// Backend has fixture1, cache has fixture2
	secretc := make(chan *Secret, 1)
	backend := ChannelBackend{secretc: secretc}
	secretc <- fixture1

	// 1 Hour fresh threshold is sure to be fresh
	timeouts := Timeouts{1 * time.Hour, 10 * time.Millisecond, 20 * time.Millisecond}
	cache := NewCache(backend, timeouts, logConfig)
	cache.Add(*fixture2)

	secret, ok := cache.Secret(fixture2.Name)
	assert.True(ok)
	assert.Equal(fixture2, secret)
	secret, ok = cache.Secret(fixture2.Name)
	assert.True(ok)
	assert.Equal(fixture2, secret)

	// 1 Nanosecond fresh threshold is sure to make a server request
	timeouts = Timeouts{1 * time.Nanosecond, 10 * time.Millisecond, 20 * time.Millisecond}
	cache = NewCache(backend, timeouts, logConfig)
	cache.Add(*fixture2)
	time.Sleep(2 * time.Nanosecond)

	secret, ok = cache.Secret(fixture2.Name)
	assert.True(ok)
	assert.Equal(fixture1, secret) // fixture1 comes form the backend
}

func TestCacheSecretListUsesValuesFromCacheIfClientFails(t *testing.T) {
	assert := assert.New(t)

	secretFixture, _ := ParseSecret(fixture("secret.json"))

	cache := NewCache(FailingBackend{}, timeouts, logConfig)
	cache.Add(*secretFixture)
	list := cache.SecretList()
	assert.Len(list, 1)
	assert.Contains(list, *secretFixture)
}

func TestCacheSecretListWhenClientTimesOut(t *testing.T) {
	assert := assert.New(t)

	secretFixture, _ := ParseSecret(fixture("secret.json"))
	backend := ChannelBackend{} // channels are nil and will block
	cache := NewCache(backend, timeouts, logConfig)

	// cache empty
	list := cache.SecretList()
	assert.Empty(list)

	// cache with entry
	cache.Add(*secretFixture)
	list = cache.SecretList()
	assert.Len(list, 1)
	assert.Contains(list, *secretFixture)
}

func TestCacheSecretListUsesValuesFromClient(t *testing.T) {
	assert := assert.New(t)

	secretFixture, _ := ParseSecret(fixture("secret.json"))

	secretListc := make(chan []Secret, 1)
	backend := ChannelBackend{secretListc: secretListc}
	secretListc <- []Secret{*secretFixture}

	cache := NewCache(backend, timeouts, logConfig)
	list := cache.SecretList()
	assert.Len(list, 1)
	assert.Contains(list, *secretFixture)

	assert.Equal(1, cache.Len())
}

func TestCacheSecretListUsesClientOverCache(t *testing.T) {
	assert := assert.New(t)

	fixture1, _ := ParseSecret(fixture("secret.json"))
	fixture2, _ := ParseSecret(fixture("secretNormalOwner.json"))

	secretListc := make(chan []Secret, 1)
	backend := ChannelBackend{secretListc: secretListc}
	secretListc <- []Secret{*fixture1}

	cache := NewCache(backend, timeouts, logConfig)
	cache.Add(*fixture2)

	// Although fixture2 is in the cache, the client says only fixture1 available.
	list := cache.SecretList()
	assert.Len(list, 1)
	assert.Contains(list, *fixture1)

	assert.Equal(1, cache.Len())
}

func TestCacheClears(t *testing.T) {
	assert := assert.New(t)

	cache := NewCache(nil, timeouts, logConfig)

	secretFixture, _ := ParseSecret(fixture("secret.json"))
	cache.Add(*secretFixture)
	assert.NotEqual(0, cache.Len())

	cache.Clear()
	assert.Equal(0, cache.Len())
}
<commit_msg>Add test for max wait<commit_after>// Copyright 2015 Square 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 (
	"testing"
	"time"

	"github.com/square/keywhiz-fs/log"
	"github.com/stretchr/testify/assert"
)

var logConfig = log.Config{Debug: false, Mountpoint: "/tmp/mnt"}

// FailingBackend always returns ok==false
type FailingBackend struct {
}

func (b FailingBackend) Secret(name string) (*Secret, bool) {
	return nil, false
}

func (b FailingBackend) SecretList() ([]Secret, bool) {
	return nil, false
}

// ChannelBackend reads values from channels to return or blocks.
type ChannelBackend struct {
	secretc     chan *Secret
	secretListc chan []Secret
}

func (b ChannelBackend) Secret(name string) (*Secret, bool) {
	secret := <-b.secretc
	return secret, true
}

func (b ChannelBackend) SecretList() ([]Secret, bool) {
	secretList := <-b.secretListc
	return secretList, true
}

var timeouts = Timeouts{0, 10 * time.Millisecond, 20 * time.Millisecond}

func TestCacheSecretUsesValuesFromClient(t *testing.T) {
	assert := assert.New(t)

	secretFixture, _ := ParseSecret(fixture("secret.json"))

	secretc := make(chan *Secret, 1)
	backend := ChannelBackend{secretc: secretc}
	secretc <- secretFixture

	cache := NewCache(backend, timeouts, logConfig)
	secret, ok := cache.Secret("password-file")
	assert.True(ok)
	assert.Equal(secretFixture, secret)
}

func TestCachePassesThroughSecretNotFound(t *testing.T) {
	assert := assert.New(t)

	secretFixture, _ := ParseSecret(fixture("secret.json"))

	cache := NewCache(FailingBackend{}, timeouts, logConfig)
	secret, ok := cache.Secret(secretFixture.Name)
	assert.False(ok)
	assert.Nil(secret)

	cache.Add(*secretFixture)
	secret, ok = cache.Secret(secretFixture.Name)
	assert.True(ok)
	assert.Equal(secretFixture, secret)
}

func TestCacheSecretWhenClientTimesOut(t *testing.T) {
	assert := assert.New(t)

	secretFixture, _ := ParseSecret(fixture("secret.json"))
	backend := ChannelBackend{} // channels are nil and will block
	cache := NewCache(backend, timeouts, logConfig)

	// empty cache
	secret, ok := cache.Secret(secretFixture.Name)
	assert.False(ok)
	assert.Nil(secret)

	// cache with entry
	cache.Add(*secretFixture)
	secret, ok = cache.Secret(secretFixture.Name)
	assert.True(ok)
	assert.Equal(secretFixture, secret)
}

func TestCacheAndBackendTimeout(t *testing.T) {
	assert := assert.New(t)
	timeouts := Timeouts{0, 1 * time.Hour, 0}

	backend := ChannelBackend{} // channels are nil and will block
	cache := NewCache(backend, timeouts, logConfig)

	// everything times out, should get empty list
	list := cache.SecretList()
	assert.Empty(list)
}

func TestCacheSecretUsesClientOverCache(t *testing.T) {
	assert := assert.New(t)

	fixture1, _ := ParseSecret(fixture("secret.json"))
	fixture2, _ := ParseSecret(fixture("secretNormalOwner.json"))
	fixture2.Name = fixture1.Name

	secretc := make(chan *Secret, 1)
	backend := ChannelBackend{secretc: secretc}
	secretc <- fixture1

	cache := NewCache(backend, timeouts, logConfig)
	cache.Add(*fixture2)

	// Although fixture2 is in the cache, the client returns fixture1.
	secret, ok := cache.Secret(fixture2.Name)
	assert.True(ok)
	assert.Equal(fixture1, secret)

	assert.Equal(1, cache.Len())
}

func TestCacheSecretAvoidsBackendWhenResultFresh(t *testing.T) {
	assert := assert.New(t)

	fixture1, _ := ParseSecret(fixture("secret.json"))
	fixture2, _ := ParseSecret(fixture("secretNormalOwner.json"))
	fixture2.Name = fixture1.Name

	// Backend has fixture1, cache has fixture2
	secretc := make(chan *Secret, 1)
	backend := ChannelBackend{secretc: secretc}
	secretc <- fixture1

	// 1 Hour fresh threshold is sure to be fresh
	timeouts := Timeouts{1 * time.Hour, 10 * time.Millisecond, 20 * time.Millisecond}
	cache := NewCache(backend, timeouts, logConfig)
	cache.Add(*fixture2)

	secret, ok := cache.Secret(fixture2.Name)
	assert.True(ok)
	assert.Equal(fixture2, secret)
	secret, ok = cache.Secret(fixture2.Name)
	assert.True(ok)
	assert.Equal(fixture2, secret)

	// 1 Nanosecond fresh threshold is sure to make a server request
	timeouts = Timeouts{1 * time.Nanosecond, 10 * time.Millisecond, 20 * time.Millisecond}
	cache = NewCache(backend, timeouts, logConfig)
	cache.Add(*fixture2)
	time.Sleep(2 * time.Nanosecond)

	secret, ok = cache.Secret(fixture2.Name)
	assert.True(ok)
	assert.Equal(fixture1, secret) // fixture1 comes form the backend
}

func TestCacheSecretListUsesValuesFromCacheIfClientFails(t *testing.T) {
	assert := assert.New(t)

	secretFixture, _ := ParseSecret(fixture("secret.json"))

	cache := NewCache(FailingBackend{}, timeouts, logConfig)
	cache.Add(*secretFixture)
	list := cache.SecretList()
	assert.Len(list, 1)
	assert.Contains(list, *secretFixture)
}

func TestCacheSecretListWhenClientTimesOut(t *testing.T) {
	assert := assert.New(t)

	secretFixture, _ := ParseSecret(fixture("secret.json"))
	backend := ChannelBackend{} // channels are nil and will block
	cache := NewCache(backend, timeouts, logConfig)

	// cache empty
	list := cache.SecretList()
	assert.Empty(list)

	// cache with entry
	cache.Add(*secretFixture)
	list = cache.SecretList()
	assert.Len(list, 1)
	assert.Contains(list, *secretFixture)
}

func TestCacheSecretListUsesValuesFromClient(t *testing.T) {
	assert := assert.New(t)

	secretFixture, _ := ParseSecret(fixture("secret.json"))

	secretListc := make(chan []Secret, 1)
	backend := ChannelBackend{secretListc: secretListc}
	secretListc <- []Secret{*secretFixture}

	cache := NewCache(backend, timeouts, logConfig)
	list := cache.SecretList()
	assert.Len(list, 1)
	assert.Contains(list, *secretFixture)

	assert.Equal(1, cache.Len())
}

func TestCacheSecretListUsesClientOverCache(t *testing.T) {
	assert := assert.New(t)

	fixture1, _ := ParseSecret(fixture("secret.json"))
	fixture2, _ := ParseSecret(fixture("secretNormalOwner.json"))

	secretListc := make(chan []Secret, 1)
	backend := ChannelBackend{secretListc: secretListc}
	secretListc <- []Secret{*fixture1}

	cache := NewCache(backend, timeouts, logConfig)
	cache.Add(*fixture2)

	// Although fixture2 is in the cache, the client says only fixture1 available.
	list := cache.SecretList()
	assert.Len(list, 1)
	assert.Contains(list, *fixture1)

	assert.Equal(1, cache.Len())
}

func TestCacheClears(t *testing.T) {
	assert := assert.New(t)

	cache := NewCache(nil, timeouts, logConfig)

	secretFixture, _ := ParseSecret(fixture("secret.json"))
	cache.Add(*secretFixture)
	assert.NotEqual(0, cache.Len())

	cache.Clear()
	assert.Equal(0, cache.Len())
}
<|endoftext|>


<commit_before>// Copyright 2017 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.

/*
Binary cloudprober is a tool for running a set of probes and metric surfacers
on a GCE VM. Cloudprober takes in a config proto which dictates what probes
and surfacers should be created with what configuration, and then manages the
asynchronous fan-in/fan-out of the data between the probes and the surfacers.
*/
package main

import (
	"context"
	"io/ioutil"
	_ "net/http/pprof"
	"os"
	"os/signal"
	"runtime/pprof"

	"cloud.google.com/go/compute/metadata"
	"flag"
	"github.com/golang/glog"
	"github.com/google/cloudprober"
	"github.com/google/cloudprober/config"
	"github.com/google/cloudprober/sysvars"
)

var (
	configFile = flag.String("config_file", "", "Config file")
	cpuprofile = flag.String("cpuprof", "", "Write cpu profile to file")
	memprofile = flag.String("memprof", "", "Write heap profile to file")
	configTest = flag.Bool("configtest", false, "Dry run to test config file")

	// configTestVars provides a sane set of sysvars for config testing.
	configTestVars = map[string]string{
		"zone":              "us-central1-a",
		"project":           "fake-domain.com:fake-project",
		"project_id":        "12345678",
		"instance":          "ig-us-central1-a-01-0000",
		"internal_ip":       "192.168.0.10",
		"external_ip":       "10.10.10.10",
		"instance_template": "ig-us-central1-a-01",
	}
)

const (
	configMetadataKeyName = "cloudprober_config"
	defaultConfigFile     = "/etc/cloudprober.cfg"
)

func setupProfiling() {
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, os.Interrupt)
	var f *os.File
	if *cpuprofile != "" {
		var err error
		f, err = os.Create(*cpuprofile)
		if err != nil {
			glog.Exit(err)
		}
		if err = pprof.StartCPUProfile(f); err != nil {
			glog.Errorf("Could not start CPU profiling: %v", err)
		}
	}
	go func(file *os.File) {
		<-sigChan
		pprof.StopCPUProfile()
		if *cpuprofile != "" {
			if err := file.Close(); err != nil {
				glog.Exit(err)
			}
		}
		if *memprofile != "" {
			f, err := os.Create(*memprofile)
			if err != nil {
				glog.Exit(err)
			}
			if err = pprof.WriteHeapProfile(f); err != nil {
				glog.Exit(err)
			}
			if err := f.Close(); err != nil {
				glog.Exit(err)
			}
		}
		os.Exit(1)
	}(f)
}

func configFileToString(fileName string) string {
	b, err := ioutil.ReadFile(fileName)
	if err != nil {
		glog.Exitf("Failed to read the config file: %v", err)
	}
	return string(b)
}

func getConfig() string {
	if *configFile != "" {
		return configFileToString(*configFile)
	}
	// On GCE first check if there is a config in custom metadata
	// attributes.
	if metadata.OnGCE() {
		if config, err := config.ReadFromGCEMetadata(configMetadataKeyName); err != nil {
			glog.Infof("Error reading config from metadata. Err: %v", err)
		} else {
			return config
		}
	}
	// If config not found in metadata, check default config on disk
	if _, err := os.Stat(defaultConfigFile); !os.IsNotExist(err) {
		return configFileToString(defaultConfigFile)
	}
	glog.Warningf("Config file %s not found. Using default config.", defaultConfigFile)
	return config.DefaultConfig()
}

func main() {
	flag.Parse()

	if *configTest {
		sysvars.Init(nil, configTestVars)
		_, err := config.Parse(configFileToString(*configFile), sysvars.Vars())
		if err != nil {
			glog.Exitf("Error parsing config file. Err: %v", err)
		}
		return
	}

	setupProfiling()

	pr, err := cloudprober.InitFromConfig(getConfig())
	if err != nil {
		glog.Exitf("Error initializing cloudprober. Err: %v", err)
	}
	pr.Start(context.Background())
}
<commit_msg>Add test_instance_name optional parameter to bbmc_image the override the default value and allow testing richer VMs naming scheme.<commit_after>// Copyright 2017 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.

/*
Binary cloudprober is a tool for running a set of probes and metric surfacers
on a GCE VM. Cloudprober takes in a config proto which dictates what probes
and surfacers should be created with what configuration, and then manages the
asynchronous fan-in/fan-out of the data between the probes and the surfacers.
*/
package main

import (
	"context"
	"io/ioutil"
	_ "net/http/pprof"
	"os"
	"os/signal"
	"runtime/pprof"

	"cloud.google.com/go/compute/metadata"
	"flag"
	"github.com/golang/glog"
	"github.com/google/cloudprober"
	"github.com/google/cloudprober/config"
	"github.com/google/cloudprober/sysvars"
)

var (
	configFile       = flag.String("config_file", "", "Config file")
	cpuprofile       = flag.String("cpuprof", "", "Write cpu profile to file")
	memprofile       = flag.String("memprof", "", "Write heap profile to file")
	configTest       = flag.Bool("configtest", false, "Dry run to test config file")
	testInstanceName = flag.String("test_instance_name", "ig-us-central1-a-01-0000", "Instance name example to be used in tests")

	// configTestVars provides a sane set of sysvars for config testing.
	configTestVars = map[string]string(nil)
)

func setupConfigTestVars() {
	configTestVars = map[string]string{
		"zone":              "us-central1-a",
		"project":           "fake-domain.com:fake-project",
		"project_id":        "12345678",
		"instance":          *testInstanceName,
		"internal_ip":       "192.168.0.10",
		"external_ip":       "10.10.10.10",
		"instance_template": "ig-us-central1-a-01",
	}
}

const (
	configMetadataKeyName = "cloudprober_config"
	defaultConfigFile     = "/etc/cloudprober.cfg"
)

func setupProfiling() {
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, os.Interrupt)
	var f *os.File
	if *cpuprofile != "" {
		var err error
		f, err = os.Create(*cpuprofile)
		if err != nil {
			glog.Exit(err)
		}
		if err = pprof.StartCPUProfile(f); err != nil {
			glog.Errorf("Could not start CPU profiling: %v", err)
		}
	}
	go func(file *os.File) {
		<-sigChan
		pprof.StopCPUProfile()
		if *cpuprofile != "" {
			if err := file.Close(); err != nil {
				glog.Exit(err)
			}
		}
		if *memprofile != "" {
			f, err := os.Create(*memprofile)
			if err != nil {
				glog.Exit(err)
			}
			if err = pprof.WriteHeapProfile(f); err != nil {
				glog.Exit(err)
			}
			if err := f.Close(); err != nil {
				glog.Exit(err)
			}
		}
		os.Exit(1)
	}(f)
}

func configFileToString(fileName string) string {
	b, err := ioutil.ReadFile(fileName)
	if err != nil {
		glog.Exitf("Failed to read the config file: %v", err)
	}
	return string(b)
}

func getConfig() string {
	if *configFile != "" {
		return configFileToString(*configFile)
	}
	// On GCE first check if there is a config in custom metadata
	// attributes.
	if metadata.OnGCE() {
		if config, err := config.ReadFromGCEMetadata(configMetadataKeyName); err != nil {
			glog.Infof("Error reading config from metadata. Err: %v", err)
		} else {
			return config
		}
	}
	// If config not found in metadata, check default config on disk
	if _, err := os.Stat(defaultConfigFile); !os.IsNotExist(err) {
		return configFileToString(defaultConfigFile)
	}
	glog.Warningf("Config file %s not found. Using default config.", defaultConfigFile)
	return config.DefaultConfig()
}

func main() {
	flag.Parse()
	setupConfigTestVars()

	if *configTest {
		sysvars.Init(nil, configTestVars)
		_, err := config.Parse(configFileToString(*configFile), sysvars.Vars())
		if err != nil {
			glog.Exitf("Error parsing config file. Err: %v", err)
		}
		return
	}

	setupProfiling()

	pr, err := cloudprober.InitFromConfig(getConfig())
	if err != nil {
		glog.Exitf("Error initializing cloudprober. Err: %v", err)
	}
	pr.Start(context.Background())
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"os"
	"strings"

	"github.com/KyleBanks/depth"
)

const (
	outputPadding    = "  "
	outputPrefix     = "├ "
	outputPrefixLast = "└ "
)

var outputJSON bool
var explainPkg string

type summary struct {
	numInternal int
	numExternal int
	numTesting  int
}

func main() {
	t, pkgs := parse(os.Args[1:])
	if err := handlePkgs(t, pkgs, outputJSON, explainPkg); err != nil {
		os.Exit(1)
	}
}

// parse constructs a depth.Tree from command-line arguments, and returns the
// remaining user-supplied package names
func parse(args []string) (*depth.Tree, []string) {
	f := flag.NewFlagSet(os.Args[0], flag.ExitOnError)

	var t depth.Tree
	f.BoolVar(&t.ResolveInternal, "internal", false, "If set, resolves dependencies of internal (stdlib) packages.")
	f.BoolVar(&t.ResolveTest, "test", false, "If set, resolves dependencies used for testing.")
	f.IntVar(&t.MaxDepth, "max", 0, "Sets the maximum depth of dependencies to resolve.")
	f.BoolVar(&outputJSON, "json", false, "If set, outputs the depencies in JSON format.")
	f.StringVar(&explainPkg, "explain", "", "If set, show which packages import the specified target")
	f.Parse(args)

	return &t, f.Args()
}

// handlePkgs takes a slice of package names, resolves a Tree on them,
// and outputs each Tree to Stdout.
func handlePkgs(t *depth.Tree, pkgs []string, outputJSON bool, explainPkg string) error {
	for _, pkg := range pkgs {

		err := t.Resolve(pkg)
		if err != nil {
			fmt.Printf("'%v': FATAL: %v\n", pkg, err)
			return err
		}

		if outputJSON {
			writePkgJSON(os.Stdout, *t.Root)
			continue
		}

		if explainPkg != "" {
			writeExplain(os.Stdout, *t.Root, []string{}, explainPkg)
			continue
		}

		writePkg(os.Stdout, *t.Root, 0, false)
		writePkgSummary(os.Stdout, *t.Root)
	}
	return nil
}

// writePkgSummary writes a summary of all packages in a tree
func writePkgSummary(w io.Writer, pkg depth.Pkg) {
	var sum summary
	set := make(map[string]struct{})
	for _, p := range pkg.Deps {
		collectSummary(&sum, p, set)
	}
	fmt.Fprintf(w, "%d dependencies (%d internal, %d external, %d testing).\n",
		sum.numInternal+sum.numExternal,
		sum.numInternal,
		sum.numExternal,
		sum.numTesting)
}

func collectSummary(sum *summary, pkg depth.Pkg, nameSet map[string]struct{}) {
	if _, ok := nameSet[pkg.Name]; !ok {
		nameSet[pkg.Name] = struct{}{}
		if pkg.Internal {
			sum.numInternal++
		} else {
			sum.numExternal++
		}
		if pkg.Test {
			sum.numTesting++
		}
		for _, p := range pkg.Deps {
			collectSummary(sum, p, nameSet)
		}
	}
}

// writePkgJSON writes the full Pkg as JSON to the provided Writer.
func writePkgJSON(w io.Writer, p depth.Pkg) {
	e := json.NewEncoder(w)
	e.SetIndent("", "  ")
	e.Encode(p)
}

// writePkg recursively prints a Pkg and its dependencies to the Writer provided.
func writePkg(w io.Writer, p depth.Pkg, indent int, isLast bool) {
	var prefix string
	if indent > 0 {
		prefix = outputPrefix

		if isLast {
			prefix = outputPrefixLast
		}
	}

	fmt.Fprintf(w, "%v%v%v\n", strings.Repeat(outputPadding, indent), prefix, p.String())

	for idx, d := range p.Deps {
		writePkg(w, d, indent+1, idx == len(p.Deps)-1)
	}
}

// writeExplain shows possible paths for a given package.
func writeExplain(w io.Writer, pkg depth.Pkg, stack []string, explain string) {
	stack = append(stack, pkg.Name)
	if pkg.Name == explain {
		fmt.Fprintln(w, strings.Join(stack, " -> "))
	}
	for _, p := range pkg.Deps {
		writeExplain(w, p, stack, explain)
	}
}
<commit_msg>nicer dependencies tree<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"os"
	"strings"

	"github.com/KyleBanks/depth"
)

const (
	outputClosedPadding = "  "
	outputOpenPadding   = "│ "
	outputPrefix        = "├ "
	outputPrefixLast    = "└ "
)

var outputJSON bool
var explainPkg string

type summary struct {
	numInternal int
	numExternal int
	numTesting  int
}

func main() {
	t, pkgs := parse(os.Args[1:])
	if err := handlePkgs(t, pkgs, outputJSON, explainPkg); err != nil {
		os.Exit(1)
	}
}

// parse constructs a depth.Tree from command-line arguments, and returns the
// remaining user-supplied package names
func parse(args []string) (*depth.Tree, []string) {
	f := flag.NewFlagSet(os.Args[0], flag.ExitOnError)

	var t depth.Tree
	f.BoolVar(&t.ResolveInternal, "internal", false, "If set, resolves dependencies of internal (stdlib) packages.")
	f.BoolVar(&t.ResolveTest, "test", false, "If set, resolves dependencies used for testing.")
	f.IntVar(&t.MaxDepth, "max", 0, "Sets the maximum depth of dependencies to resolve.")
	f.BoolVar(&outputJSON, "json", false, "If set, outputs the depencies in JSON format.")
	f.StringVar(&explainPkg, "explain", "", "If set, show which packages import the specified target")
	f.Parse(args)

	return &t, f.Args()
}

// handlePkgs takes a slice of package names, resolves a Tree on them,
// and outputs each Tree to Stdout.
func handlePkgs(t *depth.Tree, pkgs []string, outputJSON bool, explainPkg string) error {
	for _, pkg := range pkgs {

		err := t.Resolve(pkg)
		if err != nil {
			fmt.Printf("'%v': FATAL: %v\n", pkg, err)
			return err
		}

		if outputJSON {
			writePkgJSON(os.Stdout, *t.Root)
			continue
		}

		if explainPkg != "" {
			writeExplain(os.Stdout, *t.Root, []string{}, explainPkg)
			continue
		}

		writePkg(os.Stdout, *t.Root)
		writePkgSummary(os.Stdout, *t.Root)
	}
	return nil
}

// writePkgSummary writes a summary of all packages in a tree
func writePkgSummary(w io.Writer, pkg depth.Pkg) {
	var sum summary
	set := make(map[string]struct{})
	for _, p := range pkg.Deps {
		collectSummary(&sum, p, set)
	}
	fmt.Fprintf(w, "%d dependencies (%d internal, %d external, %d testing).\n",
		sum.numInternal+sum.numExternal,
		sum.numInternal,
		sum.numExternal,
		sum.numTesting)
}

func collectSummary(sum *summary, pkg depth.Pkg, nameSet map[string]struct{}) {
	if _, ok := nameSet[pkg.Name]; !ok {
		nameSet[pkg.Name] = struct{}{}
		if pkg.Internal {
			sum.numInternal++
		} else {
			sum.numExternal++
		}
		if pkg.Test {
			sum.numTesting++
		}
		for _, p := range pkg.Deps {
			collectSummary(sum, p, nameSet)
		}
	}
}

// writePkgJSON writes the full Pkg as JSON to the provided Writer.
func writePkgJSON(w io.Writer, p depth.Pkg) {
	e := json.NewEncoder(w)
	e.SetIndent("", "  ")
	e.Encode(p)
}

func writePkg(w io.Writer, p depth.Pkg) {
	fmt.Fprintf(w, "%s\n", p.String())

	for idx, d := range p.Deps {
		writePkgRec(w, d, []bool{true}, idx == len(p.Deps)-1)
	}
}

// writePkg recursively prints a Pkg and its dependencies to the Writer provided.
func writePkgRec(w io.Writer, p depth.Pkg, closed []bool, isLast bool) {
	var prefix string

	for _, c := range closed {
		if c {
			prefix += outputClosedPadding
			continue
		}

		prefix += outputOpenPadding
	}

	closed = append(closed, false)
	if isLast {
		prefix += outputPrefixLast
		closed[len(closed)-1] = true
	} else {
		prefix += outputPrefix
	}

	fmt.Fprintf(w, "%v%v\n", prefix, p.String())

	for idx, d := range p.Deps {
		writePkgRec(w, d, closed, idx == len(p.Deps)-1)
	}
}

// writeExplain shows possible paths for a given package.
func writeExplain(w io.Writer, pkg depth.Pkg, stack []string, explain string) {
	stack = append(stack, pkg.Name)
	if pkg.Name == explain {
		fmt.Fprintln(w, strings.Join(stack, " -> "))
	}
	for _, p := range pkg.Deps {
		writeExplain(w, p, stack, explain)
	}
}
<|endoftext|>