<commit_before>/*
Copyright 2017 The Kubernetes Authors.

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 defaulttolerationseconds

import (
	"testing"

	"k8s.io/apiserver/pkg/admission"
	api "k8s.io/kubernetes/pkg/apis/core"
	"k8s.io/kubernetes/pkg/apis/core/helper"
	"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm"
)

func TestForgivenessAdmission(t *testing.T) {
	var defaultTolerationSeconds int64 = 300

	genTolerationSeconds := func(s int64) *int64 {
		return &s
	}

	handler := NewDefaultTolerationSeconds()
	tests := []struct {
		description  string
		requestedPod api.Pod
		expectedPod  api.Pod
	}{
		{
			description: "pod has no tolerations, expect add tolerations for `notReady:NoExecute` and `unreachable:NoExecute`",
			requestedPod: api.Pod{
				Spec: api.PodSpec{},
			},
			expectedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{
							Key:               algorithm.TaintNodeNotReady,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: &defaultTolerationSeconds,
						},
						{
							Key:               algorithm.TaintNodeUnreachable,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: &defaultTolerationSeconds,
						},
					},
				},
			},
		},
		{
			description: "pod has tolerations, but none is for taint `notReady:NoExecute` or `unreachable:NoExecute`, expect add tolerations for `notReady:NoExecute` and `unreachable:NoExecute`",
			requestedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{
							Key:               "foo",
							Operator:          api.TolerationOpEqual,
							Value:             "bar",
							Effect:            api.TaintEffectNoSchedule,
							TolerationSeconds: genTolerationSeconds(700),
						},
					},
				},
			},
			expectedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{
							Key:               "foo",
							Operator:          api.TolerationOpEqual,
							Value:             "bar",
							Effect:            api.TaintEffectNoSchedule,
							TolerationSeconds: genTolerationSeconds(700),
						},
						{
							Key:               algorithm.TaintNodeNotReady,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: &defaultTolerationSeconds,
						},
						{
							Key:               algorithm.TaintNodeUnreachable,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: &defaultTolerationSeconds,
						},
					},
				},
			},
		},
		{
			description: "pod specified a toleration for taint `notReady:NoExecute`, expect add toleration for `unreachable:NoExecute`",
			requestedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{
							Key:               algorithm.TaintNodeNotReady,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: genTolerationSeconds(700),
						},
					},
				},
			},
			expectedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{
							Key:               algorithm.TaintNodeNotReady,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: genTolerationSeconds(700),
						},
						{
							Key:               algorithm.TaintNodeUnreachable,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: &defaultTolerationSeconds,
						},
					},
				},
			},
		},
		{
			description: "pod specified a toleration for taint `unreachable:NoExecute`, expect add toleration for `notReady:NoExecute`",
			requestedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{
							Key:               algorithm.TaintNodeUnreachable,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: genTolerationSeconds(700),
						},
					},
				},
			},
			expectedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{
							Key:               algorithm.TaintNodeUnreachable,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: genTolerationSeconds(700),
						},
						{
							Key:               algorithm.TaintNodeNotReady,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: &defaultTolerationSeconds,
						},
					},
				},
			},
		},
		{
			description: "pod specified tolerations for both `notReady:NoExecute` and `unreachable:NoExecute`, expect no change",
			requestedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{
							Key:               algorithm.TaintNodeNotReady,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: genTolerationSeconds(700),
						},
						{
							Key:               algorithm.TaintNodeUnreachable,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: genTolerationSeconds(700),
						},
					},
				},
			},
			expectedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{
							Key:               algorithm.TaintNodeNotReady,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: genTolerationSeconds(700),
						},
						{
							Key:               algorithm.TaintNodeUnreachable,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: genTolerationSeconds(700),
						},
					},
				},
			},
		},
		{
			description: "pod specified toleration for taint `unreachable`, expect add toleration for `notReady:NoExecute`",
			requestedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{
							Key:               algorithm.TaintNodeUnreachable,
							Operator:          api.TolerationOpExists,
							TolerationSeconds: genTolerationSeconds(700),
						},
					},
				},
			},
			expectedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{
							Key:               algorithm.TaintNodeUnreachable,
							Operator:          api.TolerationOpExists,
							TolerationSeconds: genTolerationSeconds(700),
						},
						{
							Key:               algorithm.TaintNodeNotReady,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: genTolerationSeconds(300),
						},
					},
				},
			},
		},
		{
			description: "pod has wildcard toleration for all kind of taints, expect no change",
			requestedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{Operator: api.TolerationOpExists, TolerationSeconds: genTolerationSeconds(700)},
					},
				},
			},
			expectedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{
							Operator:          api.TolerationOpExists,
							TolerationSeconds: genTolerationSeconds(700),
						},
					},
				},
			},
		},
	}

	for _, test := range tests {
		err := handler.Admit(admission.NewAttributesRecord(&test.requestedPod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil))
		if err != nil {
			t.Errorf("[%s]: unexpected error %v for pod %+v", test.description, err, test.requestedPod)
		}

		if !helper.Semantic.DeepEqual(test.expectedPod.Annotations, test.requestedPod.Annotations) {
			t.Errorf("[%s]: expected %#v got %#v", test.description, test.expectedPod.Annotations, test.requestedPod.Annotations)
		}
	}
}

func TestHandles(t *testing.T) {
	handler := NewDefaultTolerationSeconds()
	tests := map[admission.Operation]bool{
		admission.Update:  true,
		admission.Create:  true,
		admission.Delete:  false,
		admission.Connect: false,
	}
	for op, expected := range tests {
		result := handler.Handles(op)
		if result != expected {
			t.Errorf("Unexpected result for operation %s: %v\n", op, result)
		}
	}
}
<commit_msg>Fix TestForgivenessAdmission.<commit_after>/*
Copyright 2017 The Kubernetes Authors.

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 defaulttolerationseconds

import (
	"testing"

	"k8s.io/apiserver/pkg/admission"
	api "k8s.io/kubernetes/pkg/apis/core"
	"k8s.io/kubernetes/pkg/apis/core/helper"
	"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm"
)

func TestForgivenessAdmission(t *testing.T) {
	var defaultTolerationSeconds int64 = 300

	genTolerationSeconds := func(s int64) *int64 {
		return &s
	}

	handler := NewDefaultTolerationSeconds()
	tests := []struct {
		description  string
		requestedPod api.Pod
		expectedPod  api.Pod
	}{
		{
			description: "pod has no tolerations, expect add tolerations for `notReady:NoExecute` and `unreachable:NoExecute`",
			requestedPod: api.Pod{
				Spec: api.PodSpec{},
			},
			expectedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{
							Key:               algorithm.TaintNodeNotReady,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: &defaultTolerationSeconds,
						},
						{
							Key:               algorithm.TaintNodeUnreachable,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: &defaultTolerationSeconds,
						},
					},
				},
			},
		},
		{
			description: "pod has tolerations, but none is for taint `notReady:NoExecute` or `unreachable:NoExecute`, expect add tolerations for `notReady:NoExecute` and `unreachable:NoExecute`",
			requestedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{
							Key:               "foo",
							Operator:          api.TolerationOpEqual,
							Value:             "bar",
							Effect:            api.TaintEffectNoSchedule,
							TolerationSeconds: genTolerationSeconds(700),
						},
					},
				},
			},
			expectedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{
							Key:               "foo",
							Operator:          api.TolerationOpEqual,
							Value:             "bar",
							Effect:            api.TaintEffectNoSchedule,
							TolerationSeconds: genTolerationSeconds(700),
						},
						{
							Key:               algorithm.TaintNodeNotReady,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: &defaultTolerationSeconds,
						},
						{
							Key:               algorithm.TaintNodeUnreachable,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: &defaultTolerationSeconds,
						},
					},
				},
			},
		},
		{
			description: "pod specified a toleration for taint `notReady:NoExecute`, expect add toleration for `unreachable:NoExecute`",
			requestedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{
							Key:               algorithm.TaintNodeNotReady,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: genTolerationSeconds(700),
						},
					},
				},
			},
			expectedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{
							Key:               algorithm.TaintNodeNotReady,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: genTolerationSeconds(700),
						},
						{
							Key:               algorithm.TaintNodeUnreachable,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: &defaultTolerationSeconds,
						},
					},
				},
			},
		},
		{
			description: "pod specified a toleration for taint `unreachable:NoExecute`, expect add toleration for `notReady:NoExecute`",
			requestedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{
							Key:               algorithm.TaintNodeUnreachable,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: genTolerationSeconds(700),
						},
					},
				},
			},
			expectedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{
							Key:               algorithm.TaintNodeUnreachable,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: genTolerationSeconds(700),
						},
						{
							Key:               algorithm.TaintNodeNotReady,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: &defaultTolerationSeconds,
						},
					},
				},
			},
		},
		{
			description: "pod specified tolerations for both `notReady:NoExecute` and `unreachable:NoExecute`, expect no change",
			requestedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{
							Key:               algorithm.TaintNodeNotReady,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: genTolerationSeconds(700),
						},
						{
							Key:               algorithm.TaintNodeUnreachable,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: genTolerationSeconds(700),
						},
					},
				},
			},
			expectedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{
							Key:               algorithm.TaintNodeNotReady,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: genTolerationSeconds(700),
						},
						{
							Key:               algorithm.TaintNodeUnreachable,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: genTolerationSeconds(700),
						},
					},
				},
			},
		},
		{
			description: "pod specified toleration for taint `unreachable`, expect add toleration for `notReady:NoExecute`",
			requestedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{
							Key:               algorithm.TaintNodeUnreachable,
							Operator:          api.TolerationOpExists,
							TolerationSeconds: genTolerationSeconds(700),
						},
					},
				},
			},
			expectedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{
							Key:               algorithm.TaintNodeUnreachable,
							Operator:          api.TolerationOpExists,
							TolerationSeconds: genTolerationSeconds(700),
						},
						{
							Key:               algorithm.TaintNodeNotReady,
							Operator:          api.TolerationOpExists,
							Effect:            api.TaintEffectNoExecute,
							TolerationSeconds: genTolerationSeconds(300),
						},
					},
				},
			},
		},
		{
			description: "pod has wildcard toleration for all kind of taints, expect no change",
			requestedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{Operator: api.TolerationOpExists, TolerationSeconds: genTolerationSeconds(700)},
					},
				},
			},
			expectedPod: api.Pod{
				Spec: api.PodSpec{
					Tolerations: []api.Toleration{
						{
							Operator:          api.TolerationOpExists,
							TolerationSeconds: genTolerationSeconds(700),
						},
					},
				},
			},
		},
	}

	for _, test := range tests {
		err := handler.Admit(admission.NewAttributesRecord(&test.requestedPod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil))
		if err != nil {
			t.Errorf("[%s]: unexpected error %v for pod %+v", test.description, err, test.requestedPod)
		}

		if !helper.Semantic.DeepEqual(test.expectedPod.Spec.Tolerations, test.requestedPod.Spec.Tolerations) {
			t.Errorf("[%s]: expected %#v got %#v", test.description, test.expectedPod.Spec.Tolerations, test.requestedPod.Spec.Tolerations)
		}
	}
}

func TestHandles(t *testing.T) {
	handler := NewDefaultTolerationSeconds()
	tests := map[admission.Operation]bool{
		admission.Update:  true,
		admission.Create:  true,
		admission.Delete:  false,
		admission.Connect: false,
	}
	for op, expected := range tests {
		result := handler.Handles(op)
		if result != expected {
			t.Errorf("Unexpected result for operation %s: %v\n", op, result)
		}
	}
}
<|endoftext|>


<commit_before>package lexer

import "fmt"

type tokenType int

const (
	NAME tokenType = iota
	HYPHEN
	COLON
	COMMA
)

type Token struct {
	Type tokenType
	Text string
}
<commit_msg>Make Token printable.<commit_after>package lexer

import "fmt"

type tokenType int

const (
	NAME tokenType = iota
	HYPHEN
	COLON
	COMMA
)

type Token struct {
	Type tokenType
	Text string
}

func (t Token) String() string {
	var typeStr string
	switch t.Type {
	case NAME:
		typeStr = "NAME"
	case HYPHEN:
		typeStr = "HYPHEN"
	case COLON:
		typeStr = "COLON"
	case COMMA:
		typeStr = "COMMA"
	}
	return fmt.Sprintf("Token(%s, %s)", typeStr, t.Text)
}
<|endoftext|>


<commit_before>package blockexplorer

import (
	"errors"

	"github.com/NebulousLabs/Sia/build"
	"github.com/NebulousLabs/Sia/crypto"
	"github.com/NebulousLabs/Sia/encoding"
	"github.com/NebulousLabs/Sia/modules"
	"github.com/NebulousLabs/Sia/types"
	"github.com/boltdb/bolt"
)

// addHashType adds an entry in the Hashes bucket for identifing that hash
func addHashType(tx *bolt.Tx, hash crypto.Hash, hashType int) error {
	b := tx.Bucket([]byte("Hashes"))
	if b == nil {
		return errors.New("bucket Hashes does not exist")
	}

	return b.Put(encoding.Marshal(hash), encoding.Marshal(hashType))
}

// addAddress either creates a new list of transactions for the given
// address, or adds the txid to the list if such a list already exists
func addAddress(tx *bolt.Tx, addr types.UnlockHash, txid crypto.Hash) error {
	err := addHashType(tx, crypto.Hash(addr), hashUnlockHash)
	if err != nil {
		return err
	}

	b := tx.Bucket([]byte("Addresses"))
	if b == nil {
		return errors.New("Addresses bucket does not exist")
	}

	txBytes := b.Get(encoding.Marshal(addr))
	if txBytes == nil {
		err := b.Put(encoding.Marshal(addr), encoding.Marshal([]crypto.Hash{txid}))
		if err != nil {
			return err
		}
		return nil
	}

	var txns []crypto.Hash
	err = encoding.Unmarshal(txBytes, &txns)
	if err != nil {
		return err
	}

	txns = append(txns, txid)

	return b.Put(encoding.Marshal(addr), encoding.Marshal(txns))
}

// addSiacoinInput changes an existing outputTransactions struct to
// point to the place where that output was used
func addSiacoinInput(tx *bolt.Tx, outputID types.SiacoinOutputID, txid crypto.Hash) error {
	b := tx.Bucket([]byte("SiacoinOutputs"))
	if b == nil {
		return errors.New("bucket SiacoinOutputs does not exist")
	}

	outputBytes := b.Get(encoding.Marshal(outputID))
	if outputBytes == nil {
		return errors.New("output for id does not exist")
	}

	var ot outputTransactions
	err := encoding.Unmarshal(outputBytes, &ot)
	if err != nil {
		return err
	}

	ot.InputTx = txid

	return b.Put(encoding.Marshal(outputID), encoding.Marshal(ot))
}

// addSiafundInpt does the same thing as addSiacoinInput except with siafunds
func addSiafundInput(tx *bolt.Tx, outputID types.SiafundOutputID, txid crypto.Hash) error {
	b := tx.Bucket([]byte("SiafundOutputs"))
	if b == nil {
		return errors.New("bucket SaifundOutputs does not exist")
	}

	outputBytes := b.Get(encoding.Marshal(outputID))
	if outputBytes == nil {
		return errors.New("output for id does not exist")
	}

	var ot outputTransactions
	err := encoding.Unmarshal(outputBytes, &ot)
	if err != nil {
		return err
	}

	ot.InputTx = txid

	return b.Put(encoding.Marshal(outputID), encoding.Marshal(ot))
}

// addFcRevision changes an existing fcInfo struct to contain the txid
// of the contract revision
func addFcRevision(tx *bolt.Tx, fcid types.FileContractID, txid crypto.Hash) error {
	b := tx.Bucket([]byte("FileContracts"))
	if b == nil {
		return errors.New("bucket FileContracts does not exist")
	}

	fiBytes := b.Get(encoding.Marshal(fcid))
	if fiBytes == nil {
		return errors.New("filecontract does not exist in database")
	}

	var fi fcInfo
	err := encoding.Unmarshal(fiBytes, &fi)
	if err != nil {
		return err
	}

	fi.Revisions = append(fi.Revisions, txid)

	return b.Put(encoding.Marshal(fcid), encoding.Marshal(fi))
}

// addFcProof changes an existing fcInfo struct in the database to
// contain the txid of its storage proof
func addFcProof(tx *bolt.Tx, fcid types.FileContractID, txid crypto.Hash) error {
	b := tx.Bucket([]byte("FileContracts"))
	if b == nil {
		return errors.New("bucket FileContracts does not exist")
	}

	fiBytes := b.Get(encoding.Marshal(fcid))
	if fiBytes == nil {
		return errors.New("filecontract does not exist in database")
	}

	var fi fcInfo
	err := encoding.Unmarshal(fiBytes, &fi)
	if err != nil {
		return err
	}

	fi.Proof = txid

	return b.Put(encoding.Marshal(fcid), encoding.Marshal(fi))
}

// addNewOutput creats a new outputTransactions struct and adds it to the database
func addNewOutput(tx *bolt.Tx, outputID types.SiacoinOutputID, txid crypto.Hash) error {
	err := addHashType(tx, crypto.Hash(outputID), hashCoinOutputID)
	if err != nil {
		return err
	}

	b := tx.Bucket([]byte("SiacoinOutputs"))
	if b == nil {
		return errors.New("bucket SiacoinOutputs does not exist")
	}

	return b.Put(encoding.Marshal(outputID), encoding.Marshal(outputTransactions{
		OutputTx: txid,
	}))
}

// addNewSFOutput does the same thing as addNewOutput does, except for siafunds
func addNewSFOutput(tx *bolt.Tx, outputID types.SiafundOutputID, txid crypto.Hash) error {
	b := tx.Bucket([]byte("SiafundOutputs"))
	if b == nil {
		return errors.New("bucket SaifundOutputs does not exist")
	}

	return b.Put(encoding.Marshal(outputID), encoding.Marshal(outputTransactions{
		OutputTx: txid,
	}))
}

// addBlock creates a new blockData struct containing a block and adds
// it to the database
func addBlock(tx *bolt.Tx, id types.BlockID, bd blockData) error {
	b := tx.Bucket([]byte("Blocks"))
	if b == nil {
		return errors.New("bucket Blocks does not exist")
	}

	return b.Put(encoding.Marshal(id), encoding.Marshal(bd))
}

// addTxid creates a new txInfo struct and adds it to the database
func addTxid(tx *bolt.Tx, txid crypto.Hash, ti txInfo) error {
	err := addHashType(tx, txid, hashTransaction)
	if err != nil {
		return err
	}

	b := tx.Bucket([]byte("Transactions"))
	if b == nil {
		return errors.New("bucket Transactions does not exist")
	}

	return b.Put(encoding.Marshal(txid), encoding.Marshal(ti))
}

// addFcid creates a new fcInfo struct about a file contract and adds
// it to the database
func addFcid(tx *bolt.Tx, fcid types.FileContractID, fi fcInfo) error {
	err := addHashType(tx, crypto.Hash(fcid), hashFilecontract)
	if err != nil {
		return err
	}

	b := tx.Bucket([]byte("FileContracts"))
	if b == nil {
		return errors.New("bucket FileContracts does not exist")
	}

	return b.Put(encoding.Marshal(fcid), encoding.Marshal(fi))
}

// addHeight adds a block summary (modules.ExplorerBlockData) to the
// database with a height as the key
func addHeight(tx *bolt.Tx, height types.BlockHeight, bs modules.ExplorerBlockData) error {
	b := tx.Bucket([]byte("Heights"))
	if b == nil {
		return errors.New("bucket Blocks does not exist")
	}

	return b.Put(encoding.Marshal(height), encoding.Marshal(bs))
}

// addBlockDB parses a block and adds it to the database
func (be *BlockExplorer) addBlockDB(b types.Block) error {
	// Special case for the genesis block, which does not have a
	// valid parent, and for testing, as tests will not always use
	// blocks in consensus
	var blocktarget types.Target
	if b.ID() == be.genesisBlockID {
		blocktarget = types.RootDepth
	} else {
		var exists bool
		blocktarget, exists = be.cs.ChildTarget(b.ParentID)
		if build.DEBUG {
			if build.Release == "testing" {
				blocktarget = types.RootDepth
			}
			if !exists {
				panic("Applied block not in consensus")
			}

		}
	}

	tx, err := be.db.Begin(true)
	if err != nil {
		return err
	}
	defer tx.Rollback()

	// Construct the struct that will be inside the database
	blockStruct := blockData{
		Block:  b,
		Height: be.blockchainHeight,
	}

	err = addBlock(tx, b.ID(), blockStruct)
	if err != nil {
		return err
	}

	bSum := modules.ExplorerBlockData{
		ID:        b.ID(),
		Timestamp: b.Timestamp,
		Target:    blocktarget,
		Size:      uint64(len(encoding.Marshal(b))),
	}

	err = addHeight(tx, be.blockchainHeight, bSum)
	if err != nil {
		return err
	}
	err = addHashType(tx, crypto.Hash(b.ID()), hashBlock)
	if err != nil {
		return err
	}

	// Insert the miner payouts as new outputs
	for i, payout := range b.MinerPayouts {
		err = addAddress(tx, payout.UnlockHash, crypto.Hash(b.ID()))
		if err != nil {
			return err
		}
		err = addNewOutput(tx, b.MinerPayoutID(i), crypto.Hash(b.ID()))
		if err != nil {
			return err
		}
	}

	// Insert each transaction
	for i, txn := range b.Transactions {
		err = addTxid(tx, txn.ID(), txInfo{b.ID(), i})
		if err != nil {
			return err
		}
		err = be.addTransaction(tx, txn)
		if err != nil {
			return err
		}
	}

	return tx.Commit()
}

// addTransaction is called from addBlockDB, and delegates the adding
// of information to the database to the functions defined above
func (be *BlockExplorer) addTransaction(btx *bolt.Tx, tx types.Transaction) error {
	// Store this for quick lookup
	txid := tx.ID()

	// Append each input to the list of modifications
	for _, input := range tx.SiacoinInputs {
		err := addSiacoinInput(btx, input.ParentID, txid)
		if err != nil {
			return err
		}
	}

	// Handle all the transaction outputs
	for i, output := range tx.SiacoinOutputs {
		err := addAddress(btx, output.UnlockHash, txid)
		if err != nil {
			return err
		}
		err = addNewOutput(btx, tx.SiacoinOutputID(i), txid)
		if err != nil {
			return err
		}
	}

	// Handle each file contract individually
	for i, contract := range tx.FileContracts {
		fcid := tx.FileContractID(i)
		err := addFcid(btx, fcid, fcInfo{
			Contract: txid,
		})
		if err != nil {
			return err
		}

		for j, output := range contract.ValidProofOutputs {
			err = addAddress(btx, output.UnlockHash, txid)
			if err != nil {
				return err
			}
			err = addNewOutput(btx, fcid.StorageProofOutputID(true, j), txid)
			if err != nil {
				return err
			}
		}
		for j, output := range contract.MissedProofOutputs {
			err = addAddress(btx, output.UnlockHash, txid)
			if err != nil {
				return err
			}
			err = addNewOutput(btx, fcid.StorageProofOutputID(false, j), txid)
			if err != nil {
				return err
			}
		}

		err = addAddress(btx, contract.UnlockHash, txid)
		if err != nil {
			return err
		}
	}

	// Update the list of revisions
	for _, revision := range tx.FileContractRevisions {
		err := addFcRevision(btx, revision.ParentID, txid)
		if err != nil {
			return err
		}

		// Note the old outputs will still be there in the
		// database. This is to provide information to the
		// people who may just need it.
		for i, output := range revision.NewValidProofOutputs {
			err = addAddress(btx, output.UnlockHash, txid)
			if err != nil {
				return err
			}
			err = addNewOutput(btx, revision.ParentID.StorageProofOutputID(true, i), txid)
			if err != nil {
				return err
			}
		}
		for i, output := range revision.NewMissedProofOutputs {
			err = addAddress(btx, output.UnlockHash, txid)
			if err != nil {
				return err
			}
			err = addNewOutput(btx, revision.ParentID.StorageProofOutputID(false, i), txid)
			if err != nil {
				return err
			}
		}

		addAddress(btx, revision.NewUnlockHash, txid)
	}

	// Update the list of storage proofs
	for _, proof := range tx.StorageProofs {
		err := addFcProof(btx, proof.ParentID, txid)
		if err != nil {
			return err
		}
	}

	// Append all the siafund inputs to the modification list
	for _, input := range tx.SiafundInputs {
		err := addSiafundInput(btx, input.ParentID, txid)
		if err != nil {
			return err
		}
	}

	// Handle all the siafund outputs
	for i, output := range tx.SiafundOutputs {
		err := addAddress(btx, output.UnlockHash, txid)
		if err != nil {
			return err
		}
		err = addNewSFOutput(btx, tx.SiafundOutputID(i), txid)
		if err != nil {
			return err
		}

	}

	return addHashType(btx, txid, hashTransaction)
}
<commit_msg>Combine helper functions in addblock.go<commit_after>package blockexplorer

import (
	"errors"

	"github.com/NebulousLabs/Sia/build"
	"github.com/NebulousLabs/Sia/crypto"
	"github.com/NebulousLabs/Sia/encoding"
	"github.com/NebulousLabs/Sia/modules"
	"github.com/NebulousLabs/Sia/types"
	"github.com/boltdb/bolt"
)

// addHashType adds an entry in the Hashes bucket for identifing that hash
func addHashType(tx *bolt.Tx, hash crypto.Hash, hashType int) error {
	b := tx.Bucket([]byte("Hashes"))
	if b == nil {
		return errors.New("bucket Hashes does not exist")
	}

	return b.Put(encoding.Marshal(hash), encoding.Marshal(hashType))
}

// addAddress either creates a new list of transactions for the given
// address, or adds the txid to the list if such a list already exists
func addAddress(tx *bolt.Tx, addr types.UnlockHash, txid crypto.Hash) error {
	err := addHashType(tx, crypto.Hash(addr), hashUnlockHash)
	if err != nil {
		return err
	}

	b := tx.Bucket([]byte("Addresses"))
	if b == nil {
		return errors.New("Addresses bucket does not exist")
	}

	txBytes := b.Get(encoding.Marshal(addr))
	if txBytes == nil {
		err := b.Put(encoding.Marshal(addr), encoding.Marshal([]crypto.Hash{txid}))
		if err != nil {
			return err
		}
		return nil
	}

	var txns []crypto.Hash
	err = encoding.Unmarshal(txBytes, &txns)
	if err != nil {
		return err
	}

	txns = append(txns, txid)

	return b.Put(encoding.Marshal(addr), encoding.Marshal(txns))
}

// addSiacoinInput changes an existing outputTransactions struct to
// point to the place where that output was used
func addSiacoinInput(tx *bolt.Tx, outputID types.SiacoinOutputID, txid crypto.Hash) error {
	b := tx.Bucket([]byte("SiacoinOutputs"))
	if b == nil {
		return errors.New("bucket SiacoinOutputs does not exist")
	}

	outputBytes := b.Get(encoding.Marshal(outputID))
	if outputBytes == nil {
		return errors.New("output for id does not exist")
	}

	var ot outputTransactions
	err := encoding.Unmarshal(outputBytes, &ot)
	if err != nil {
		return err
	}

	ot.InputTx = txid

	return b.Put(encoding.Marshal(outputID), encoding.Marshal(ot))
}

// addSiafundInpt does the same thing as addSiacoinInput except with siafunds
func addSiafundInput(tx *bolt.Tx, outputID types.SiafundOutputID, txid crypto.Hash) error {
	b := tx.Bucket([]byte("SiafundOutputs"))
	if b == nil {
		return errors.New("bucket SaifundOutputs does not exist")
	}

	outputBytes := b.Get(encoding.Marshal(outputID))
	if outputBytes == nil {
		return errors.New("output for id does not exist")
	}

	var ot outputTransactions
	err := encoding.Unmarshal(outputBytes, &ot)
	if err != nil {
		return err
	}

	ot.InputTx = txid

	return b.Put(encoding.Marshal(outputID), encoding.Marshal(ot))
}

// addFcRevision changes an existing fcInfo struct to contain the txid
// of the contract revision
func addFcRevision(tx *bolt.Tx, fcid types.FileContractID, txid crypto.Hash) error {
	b := tx.Bucket([]byte("FileContracts"))
	if b == nil {
		return errors.New("bucket FileContracts does not exist")
	}

	fiBytes := b.Get(encoding.Marshal(fcid))
	if fiBytes == nil {
		return errors.New("filecontract does not exist in database")
	}

	var fi fcInfo
	err := encoding.Unmarshal(fiBytes, &fi)
	if err != nil {
		return err
	}

	fi.Revisions = append(fi.Revisions, txid)

	return b.Put(encoding.Marshal(fcid), encoding.Marshal(fi))
}

// addFcProof changes an existing fcInfo struct in the database to
// contain the txid of its storage proof
func addFcProof(tx *bolt.Tx, fcid types.FileContractID, txid crypto.Hash) error {
	b := tx.Bucket([]byte("FileContracts"))
	if b == nil {
		return errors.New("bucket FileContracts does not exist")
	}

	fiBytes := b.Get(encoding.Marshal(fcid))
	if fiBytes == nil {
		return errors.New("filecontract does not exist in database")
	}

	var fi fcInfo
	err := encoding.Unmarshal(fiBytes, &fi)
	if err != nil {
		return err
	}

	fi.Proof = txid

	return b.Put(encoding.Marshal(fcid), encoding.Marshal(fi))
}

func addNewHash(tx *bolt.Tx, bucketName string, t int, hash crypto.Hash, value interface{}) error {
	err := addHashType(tx, hash, t)
	if err != nil {
		return err
	}

	b := tx.Bucket([]byte(bucketName))
	if b == nil {
		return errors.New("bucket does not exist: " + bucketName)
	}
	return b.Put(encoding.Marshal(hash), encoding.Marshal(value))
}

// addNewOutput creats a new outputTransactions struct and adds it to the database
func addNewOutput(tx *bolt.Tx, outputID types.SiacoinOutputID, txid crypto.Hash) error {
	otx := outputTransactions{txid, crypto.Hash{}}
	return addNewHash(tx, "SiacoinOutputs", hashCoinOutputID, crypto.Hash(outputID), otx)
}

// addNewSFOutput does the same thing as addNewOutput does, except for siafunds
func addNewSFOutput(tx *bolt.Tx, outputID types.SiafundOutputID, txid crypto.Hash) error {
	otx := outputTransactions{txid, crypto.Hash{}}
	return addNewHash(tx, "SiafundOutputs", hashFundOutputID, crypto.Hash(outputID), otx)
}

// addHeight adds a block summary (modules.ExplorerBlockData) to the
// database with a height as the key
func addHeight(tx *bolt.Tx, height types.BlockHeight, bs modules.ExplorerBlockData) error {
	b := tx.Bucket([]byte("Heights"))
	if b == nil {
		return errors.New("bucket Blocks does not exist")
	}

	return b.Put(encoding.Marshal(height), encoding.Marshal(bs))
}

// addBlockDB parses a block and adds it to the database
func (be *BlockExplorer) addBlockDB(b types.Block) error {
	// Special case for the genesis block, which does not have a
	// valid parent, and for testing, as tests will not always use
	// blocks in consensus
	var blocktarget types.Target
	if b.ID() == be.genesisBlockID {
		blocktarget = types.RootDepth
	} else {
		var exists bool
		blocktarget, exists = be.cs.ChildTarget(b.ParentID)
		if build.DEBUG {
			if build.Release == "testing" {
				blocktarget = types.RootDepth
			}
			if !exists {
				panic("Applied block not in consensus")
			}

		}
	}

	tx, err := be.db.Begin(true)
	if err != nil {
		return err
	}
	defer tx.Rollback()

	// Construct the struct that will be inside the database
	blockStruct := blockData{
		Block:  b,
		Height: be.blockchainHeight,
	}

	err = addNewHash(tx, "Blocks", hashBlock, crypto.Hash(b.ID()), blockStruct)
	if err != nil {
		return err
	}

	bSum := modules.ExplorerBlockData{
		ID:        b.ID(),
		Timestamp: b.Timestamp,
		Target:    blocktarget,
		Size:      uint64(len(encoding.Marshal(b))),
	}

	err = addHeight(tx, be.blockchainHeight, bSum)
	if err != nil {
		return err
	}
	err = addHashType(tx, crypto.Hash(b.ID()), hashBlock)
	if err != nil {
		return err
	}

	// Insert the miner payouts as new outputs
	for i, payout := range b.MinerPayouts {
		err = addAddress(tx, payout.UnlockHash, crypto.Hash(b.ID()))
		if err != nil {
			return err
		}
		err = addNewOutput(tx, b.MinerPayoutID(i), crypto.Hash(b.ID()))
		if err != nil {
			return err
		}
	}

	// Insert each transaction
	for i, txn := range b.Transactions {
		err = addNewHash(tx, "Transactions", hashTransaction, txn.ID(), txInfo{b.ID(), i})
		if err != nil {
			return err
		}
		err = be.addTransaction(tx, txn)
		if err != nil {
			return err
		}
	}

	return tx.Commit()
}

// addTransaction is called from addBlockDB, and delegates the adding
// of information to the database to the functions defined above
func (be *BlockExplorer) addTransaction(btx *bolt.Tx, tx types.Transaction) error {
	// Store this for quick lookup
	txid := tx.ID()

	// Append each input to the list of modifications
	for _, input := range tx.SiacoinInputs {
		err := addSiacoinInput(btx, input.ParentID, txid)
		if err != nil {
			return err
		}
	}

	// Handle all the transaction outputs
	for i, output := range tx.SiacoinOutputs {
		err := addAddress(btx, output.UnlockHash, txid)
		if err != nil {
			return err
		}
		err = addNewOutput(btx, tx.SiacoinOutputID(i), txid)
		if err != nil {
			return err
		}
	}

	// Handle each file contract individually
	for i, contract := range tx.FileContracts {
		fcid := tx.FileContractID(i)
		err := addNewHash(btx, "FileContracts", hashFilecontract, crypto.Hash(fcid), fcInfo{
			Contract: txid,
		})
		if err != nil {
			return err
		}

		for j, output := range contract.ValidProofOutputs {
			err = addAddress(btx, output.UnlockHash, txid)
			if err != nil {
				return err
			}
			err = addNewOutput(btx, fcid.StorageProofOutputID(true, j), txid)
			if err != nil {
				return err
			}
		}
		for j, output := range contract.MissedProofOutputs {
			err = addAddress(btx, output.UnlockHash, txid)
			if err != nil {
				return err
			}
			err = addNewOutput(btx, fcid.StorageProofOutputID(false, j), txid)
			if err != nil {
				return err
			}
		}

		err = addAddress(btx, contract.UnlockHash, txid)
		if err != nil {
			return err
		}
	}

	// Update the list of revisions
	for _, revision := range tx.FileContractRevisions {
		err := addFcRevision(btx, revision.ParentID, txid)
		if err != nil {
			return err
		}

		// Note the old outputs will still be there in the
		// database. This is to provide information to the
		// people who may just need it.
		for i, output := range revision.NewValidProofOutputs {
			err = addAddress(btx, output.UnlockHash, txid)
			if err != nil {
				return err
			}
			err = addNewOutput(btx, revision.ParentID.StorageProofOutputID(true, i), txid)
			if err != nil {
				return err
			}
		}
		for i, output := range revision.NewMissedProofOutputs {
			err = addAddress(btx, output.UnlockHash, txid)
			if err != nil {
				return err
			}
			err = addNewOutput(btx, revision.ParentID.StorageProofOutputID(false, i), txid)
			if err != nil {
				return err
			}
		}

		addAddress(btx, revision.NewUnlockHash, txid)
	}

	// Update the list of storage proofs
	for _, proof := range tx.StorageProofs {
		err := addFcProof(btx, proof.ParentID, txid)
		if err != nil {
			return err
		}
	}

	// Append all the siafund inputs to the modification list
	for _, input := range tx.SiafundInputs {
		err := addSiafundInput(btx, input.ParentID, txid)
		if err != nil {
			return err
		}
	}

	// Handle all the siafund outputs
	for i, output := range tx.SiafundOutputs {
		err := addAddress(btx, output.UnlockHash, txid)
		if err != nil {
			return err
		}
		err = addNewSFOutput(btx, tx.SiafundOutputID(i), txid)
		if err != nil {
			return err
		}

	}

	return addHashType(btx, txid, hashTransaction)
}
<|endoftext|>


<commit_before>package primitive

import (
	"fmt"
	"image"
	"time"

	"github.com/fogleman/gg"
)

type Model struct {
	W, H    int
	Target  *image.RGBA
	Current *image.RGBA
	Buffer  *image.RGBA
	Score   float64
	Context *gg.Context
}

func NewModel(target image.Image) *Model {
	c := averageImageColor(target)
	size := target.Bounds().Size()
	model := &Model{}
	model.W = size.X
	model.H = size.Y
	model.Target = imageToRGBA(target)
	model.Current = uniformRGBA(target.Bounds(), c)
	model.Buffer = uniformRGBA(target.Bounds(), c)
	model.Score = differenceFull(model.Target, model.Current)
	model.Context = gg.NewContext(model.W*4, model.H*4)
	model.Context.Scale(4, 4)
	model.Context.SetColor(c)
	model.Context.Clear()
	return model
}

func (model *Model) Run() {
	frame := 0
	start := time.Now()
	for {
		model.Step()
		elapsed := time.Since(start).Seconds()
		fmt.Printf("%d, %.3f, %.6f\n", frame, elapsed, model.Score)
		if frame%1 == 0 {
			path := fmt.Sprintf("out%03d.png", frame)
			// SavePNG(path, model.Current)
			model.Context.SavePNG(path)
		}
		frame++
	}
}

func (model *Model) Step() {
	// state := NewState(model, NewRandomTriangle(model.W, model.H))
	// state := NewState(model, NewRandomRectangle(model.W, model.H))
	state := NewState(model, NewRandomCircle(model.W, model.H))
	// fmt.Println(PreAnneal(state, 10000))
	state = Anneal(state, 0.2, 0.0001, 10000).(*State)
	model.Add(state.Shape)
}

func (model *Model) Add(shape Shape) {
	lines := shape.Rasterize()
	c := model.computeColor(lines, 128)
	s := model.computeScore(lines, c)
	Draw(model.Current, c, lines)
	model.Score = s
	shape.Draw(model.Context)
	model.Context.SetRGBA255(c.R, c.G, c.B, c.A)
	model.Context.Fill()
}

func (model *Model) computeColor(lines []Scanline, alpha int) Color {
	var count int
	var rsum, gsum, bsum float64
	a := float64(alpha) / 255
	for _, line := range lines {
		i := model.Target.PixOffset(line.X1, line.Y)
		for x := line.X1; x <= line.X2; x++ {
			count++
			tr := float64(model.Target.Pix[i])
			tg := float64(model.Target.Pix[i+1])
			tb := float64(model.Target.Pix[i+2])
			cr := float64(model.Current.Pix[i])
			cg := float64(model.Current.Pix[i+1])
			cb := float64(model.Current.Pix[i+2])
			i += 4
			rsum += (a*cr - cr + tr) / a
			gsum += (a*cg - cg + tg) / a
			bsum += (a*cb - cb + tb) / a
		}
	}
	if count == 0 {
		return Color{}
	}
	r := clampInt(int(rsum/float64(count)), 0, 255)
	g := clampInt(int(gsum/float64(count)), 0, 255)
	b := clampInt(int(bsum/float64(count)), 0, 255)
	return Color{r, g, b, alpha}
}

func (model *Model) computeScore(lines []Scanline, c Color) float64 {
	copy(model.Buffer.Pix, model.Current.Pix)
	Draw(model.Buffer, c, lines)
	return differencePartial(model.Target, model.Current, model.Buffer, model.Score, lines)
}
<commit_msg>tweaks<commit_after>package primitive

import (
	"fmt"
	"image"
	"image/color"
	"time"

	"github.com/fogleman/gg"
)

const Scale = 4

type Model struct {
	W, H    int
	Target  *image.RGBA
	Current *image.RGBA
	Buffer  *image.RGBA
	Score   float64
	Context *gg.Context
}

func NewModel(target image.Image) *Model {
	c := averageImageColor(target)
	c = color.White
	// c = color.Black
	size := target.Bounds().Size()
	model := &Model{}
	model.W = size.X
	model.H = size.Y
	model.Target = imageToRGBA(target)
	model.Current = uniformRGBA(target.Bounds(), c)
	model.Buffer = uniformRGBA(target.Bounds(), c)
	model.Score = differenceFull(model.Target, model.Current)
	model.Context = gg.NewContext(model.W*Scale, model.H*Scale)
	model.Context.Scale(Scale, Scale)
	model.Context.SetColor(c)
	model.Context.Clear()
	return model
}

func (model *Model) Run() {
	frame := 0
	start := time.Now()
	for {
		model.Step()
		elapsed := time.Since(start).Seconds()
		fmt.Printf("%d, %.3f, %.6f\n", frame, elapsed, model.Score)
		if frame%1 == 0 {
			path := fmt.Sprintf("out%03d.png", frame)
			// SavePNG(path, model.Current)
			model.Context.SavePNG(path)
		}
		frame++
	}
}

func (model *Model) Step() {
	// state := NewState(model, NewRandomTriangle(model.W, model.H))
	// state := NewState(model, NewRandomRectangle(model.W, model.H))
	state := NewState(model, NewRandomCircle(model.W, model.H))
	// fmt.Println(PreAnneal(state, 10000))
	state = Anneal(state, 0.2, 0.0001, 50000).(*State)
	model.Add(state.Shape)
}

func (model *Model) Add(shape Shape) {
	lines := shape.Rasterize()
	c := model.computeColor(lines, 128)
	s := model.computeScore(lines, c)
	Draw(model.Current, c, lines)
	model.Score = s
	shape.Draw(model.Context)
	model.Context.SetRGBA255(c.R, c.G, c.B, c.A)
	model.Context.Fill()
}

func (model *Model) computeColor(lines []Scanline, alpha int) Color {
	var count int
	var rsum, gsum, bsum float64
	a := float64(alpha) / 255
	for _, line := range lines {
		i := model.Target.PixOffset(line.X1, line.Y)
		for x := line.X1; x <= line.X2; x++ {
			count++
			tr := float64(model.Target.Pix[i])
			tg := float64(model.Target.Pix[i+1])
			tb := float64(model.Target.Pix[i+2])
			cr := float64(model.Current.Pix[i])
			cg := float64(model.Current.Pix[i+1])
			cb := float64(model.Current.Pix[i+2])
			i += 4
			rsum += (a*cr - cr + tr) / a
			gsum += (a*cg - cg + tg) / a
			bsum += (a*cb - cb + tb) / a
		}
	}
	if count == 0 {
		return Color{}
	}
	r := clampInt(int(rsum/float64(count)), 0, 255)
	g := clampInt(int(gsum/float64(count)), 0, 255)
	b := clampInt(int(bsum/float64(count)), 0, 255)
	return Color{r, g, b, alpha}
}

func (model *Model) computeScore(lines []Scanline, c Color) float64 {
	copy(model.Buffer.Pix, model.Current.Pix)
	Draw(model.Buffer, c, lines)
	return differencePartial(model.Target, model.Current, model.Buffer, model.Score, lines)
}
<|endoftext|>


<commit_before>package ds

import (
	"strconv"

	"cloud.google.com/go/datastore"
)

// Model is the base model
// every model should have this Model
type Model struct {
	key *datastore.Key
	ID  string `datastore:"-"`
}

// Key returns key from model
func (x *Model) Key() *datastore.Key {
	return x.key
}

// SetKey sets model key to given key
func (x *Model) SetKey(key *datastore.Key) {
	x.key = key
	if key == nil {
		x.ID = ""
		return
	}
	if key.Name != "" {
		x.ID = key.Name
		return
	}
	if key.ID != 0 {
		x.ID = strconv.FormatInt(key.ID, 10)
	}
}

// KeyGetter interface
type KeyGetter interface {
	Key() *datastore.Key
}

// KeySetter interface
type KeySetter interface {
	SetKey(*datastore.Key)
}

// KeyGetSetter interface
type KeyGetSetter interface {
	KeyGetter
	KeySetter
}

// KindGetter interface
type KindGetter interface {
	Kind() string
}
<commit_msg>add set id key and set name key<commit_after>package ds

import (
	"strconv"

	"cloud.google.com/go/datastore"
)

// Model is the base model
// every model should have this Model
type Model struct {
	key *datastore.Key
	ID  string `datastore:"-"`
}

// Key returns key from model
func (x *Model) Key() *datastore.Key {
	return x.key
}

// SetKey sets model key to given key
func (x *Model) SetKey(key *datastore.Key) {
	x.key = key
	if key == nil {
		x.ID = ""
		return
	}
	if key.Name != "" {
		x.ID = key.Name
		return
	}
	if key.ID != 0 {
		x.ID = strconv.FormatInt(key.ID, 10)
	}
}

// SetIDKey sets id to model
func (x *Model) SetIDKey(id string) {
	x.SetKey(datastore.IDKey(interface{}(x).(KindGetter).Kind(), parseID(id), nil))
}

// SetNameKey sets id to model
func (x *Model) SetNameKey(name string) {
	x.SetKey(datastore.NameKey(interface{}(x).(KindGetter).Kind(), name, nil))
}

// KeyGetter interface
type KeyGetter interface {
	Key() *datastore.Key
}

// KeySetter interface
type KeySetter interface {
	SetKey(*datastore.Key)
}

// KeyGetSetter interface
type KeyGetSetter interface {
	KeyGetter
	KeySetter
}

// KindGetter interface
type KindGetter interface {
	Kind() string
}
<|endoftext|>


<commit_before>package prompt

import (
	"bytes"
	"strconv"
)

// VT100Writer generates VT100 escape sequences.
type VT100Writer struct {
	buffer []byte
}

// WriteRaw to write raw byte array
func (w *VT100Writer) WriteRaw(data []byte) {
	w.buffer = append(w.buffer, data...)
	return
}

// Write to write safety byte array by removing control sequences.
func (w *VT100Writer) Write(data []byte) {
	w.WriteRaw(bytes.Replace(data, []byte{0x1b}, []byte{'?'}, -1))
	return
}

// WriteRawStr to write raw string
func (w *VT100Writer) WriteRawStr(data string) {
	w.WriteRaw([]byte(data))
	return
}

// WriteStr to write safety string by removing control sequences.
func (w *VT100Writer) WriteStr(data string) {
	w.Write([]byte(data))
	return
}

/* Erase */

// EraseScreen erases the screen with the background colour and moves the cursor to home.
func (w *VT100Writer) EraseScreen() {
	w.WriteRaw([]byte{0x1b, '[', '2', 'J'})
	return
}

// EraseUp erases the screen from the current line up to the top of the screen.
func (w *VT100Writer) EraseUp() {
	w.WriteRaw([]byte{0x1b, '[', '1', 'J'})
	return
}

// EraseDown erases the screen from the current line down to the bottom of the screen.
func (w *VT100Writer) EraseDown() {
	w.WriteRaw([]byte{0x1b, '[', 'J'})
	return
}

// EraseStartOfLine erases from the current cursor position to the start of the current line.
func (w *VT100Writer) EraseStartOfLine() {
	w.WriteRaw([]byte{0x1b, '[', '1', 'K'})
	return
}

// EraseEndOfLine erases from the current cursor position to the end of the current line.
func (w *VT100Writer) EraseEndOfLine() {
	w.WriteRaw([]byte{0x1b, '[', 'K'})
	return
}

// EraseLine erases the entire current line.
func (w *VT100Writer) EraseLine() {
	w.WriteRaw([]byte{0x1b, '[', '2', 'K'})
	return
}

/* Cursor */

// ShowCursor stops blinking cursor and show.
func (w *VT100Writer) ShowCursor() {
	w.WriteRaw([]byte{0x1b, '[', '?', '1', '2', 'l', 0x1b, '[', '?', '2', '5', 'h'})
}

// HideCursor hides cursor.
func (w *VT100Writer) HideCursor() {
	w.WriteRaw([]byte{0x1b, '[', '?', '2', '5', 'l'})
	return
}

// CursorGoTo sets the cursor position where subsequent text will begin.
func (w *VT100Writer) CursorGoTo(row, col int) {
	if row == 0 && col == 0 {
		// If no row/column parameters are provided (ie. <ESC>[H), the cursor will move to the home position.
		w.WriteRaw([]byte{0x1b, '[', 'H'})
		return
	}
	r := strconv.Itoa(row)
	c := strconv.Itoa(col)
	w.WriteRaw([]byte{0x1b, '['})
	w.WriteRaw([]byte(r))
	w.WriteRaw([]byte{';'})
	w.WriteRaw([]byte(c))
	w.WriteRaw([]byte{'H'})
	return
}

// CursorUp moves the cursor up by 'n' rows; the default count is 1.
func (w *VT100Writer) CursorUp(n int) {
	if n == 0 {
		return
	} else if n < 0 {
		w.CursorDown(-n)
		return
	}
	s := strconv.Itoa(n)
	w.WriteRaw([]byte{0x1b, '['})
	w.WriteRaw([]byte(s))
	w.WriteRaw([]byte{'A'})
	return
}

// CursorDown moves the cursor down by 'n' rows; the default count is 1.
func (w *VT100Writer) CursorDown(n int) {
	if n == 0 {
		return
	} else if n < 0 {
		w.CursorUp(-n)
		return
	}
	s := strconv.Itoa(n)
	w.WriteRaw([]byte{0x1b, '['})
	w.WriteRaw([]byte(s))
	w.WriteRaw([]byte{'B'})
	return
}

// CursorForward moves the cursor forward by 'n' columns; the default count is 1.
func (w *VT100Writer) CursorForward(n int) {
	if n == 0 {
		return
	} else if n < 0 {
		w.CursorBackward(-n)
		return
	}
	s := strconv.Itoa(n)
	w.WriteRaw([]byte{0x1b, '['})
	w.WriteRaw([]byte(s))
	w.WriteRaw([]byte{'C'})
	return
}

// CursorBackward moves the cursor backward by 'n' columns; the default count is 1.
func (w *VT100Writer) CursorBackward(n int) {
	if n == 0 {
		return
	} else if n < 0 {
		w.CursorForward(-n)
		return
	}
	s := strconv.Itoa(n)
	w.WriteRaw([]byte{0x1b, '['})
	w.WriteRaw([]byte(s))
	w.WriteRaw([]byte{'D'})
	return
}

// AskForCPR asks for a cursor position report (CPR).
func (w *VT100Writer) AskForCPR() {
	// CPR: Cursor Position Request.
	w.WriteRaw([]byte{0x1b, '[', '6', 'n'})
	return
}

// SaveCursor saves current cursor position.
func (w *VT100Writer) SaveCursor() {
	w.WriteRaw([]byte{0x1b, '[', 's'})
	return
}

// UnSaveCursor restores cursor position after a Save Cursor.
func (w *VT100Writer) UnSaveCursor() {
	w.WriteRaw([]byte{0x1b, '[', 'u'})
	return
}

/* Scrolling */

// ScrollDown scrolls display down one line.
func (w *VT100Writer) ScrollDown() {
	w.WriteRaw([]byte{0x1b, 'D'})
	return
}

// ScrollUp scroll display up one line.
func (w *VT100Writer) ScrollUp() {
	w.WriteRaw([]byte{0x1b, 'M'})
	return
}

/* Title */

// SetTitle sets a title of terminal window.
func (w *VT100Writer) SetTitle(title string) {
	titleBytes := []byte(title)
	patterns := []struct {
		from []byte
		to   []byte
	}{
		{
			from: []byte{0x13},
			to:   []byte{},
		},
		{
			from: []byte{0x07},
			to:   []byte{},
		},
	}
	for i := range patterns {
		titleBytes = bytes.Replace(titleBytes, patterns[i].from, patterns[i].to, -1)
	}

	w.WriteRaw([]byte{0x1b, ']', '2', ';'})
	w.WriteRaw(titleBytes)
	w.WriteRaw([]byte{0x07})
	return
}

// ClearTitle clears a title of terminal window.
func (w *VT100Writer) ClearTitle() {
	w.WriteRaw([]byte{0x1b, ']', '2', ';', 0x07})
	return
}

/* Font */

// SetColor sets text and background colors. and specify whether text is bold.
func (w *VT100Writer) SetColor(fg, bg Color, bold bool) {
	if bold {
		w.SetDisplayAttributes(fg, bg, DisplayBold)
	} else {
		w.SetDisplayAttributes(fg, bg, DisplayDefaultFont, DisplayReset)
	}
	return
}

// SetDisplayAttributes to set VT100 display attributes.
func (w *VT100Writer) SetDisplayAttributes(fg, bg Color, attrs ...DisplayAttribute) {
	w.WriteRaw([]byte{0x1b, '['}) // control sequence introducer
	defer w.WriteRaw([]byte{'m'}) // final character

	var separator byte = ';'
	for i := range attrs {
		p, ok := displayAttributeParameters[attrs[i]]
		if !ok {
			continue
		}
		w.WriteRaw(p)
		w.WriteRaw([]byte{separator})
	}

	f, ok := foregroundANSIColors[fg]
	if !ok {
		f = foregroundANSIColors[DefaultColor]
	}
	w.WriteRaw(f)
	w.WriteRaw([]byte{separator})
	b, ok := backgroundANSIColors[bg]
	if !ok {
		b = backgroundANSIColors[DefaultColor]
	}
	w.WriteRaw(b)
	return
}

var displayAttributeParameters = map[DisplayAttribute][]byte{
	DisplayReset:        {'0'},
	DisplayBold:         {'1'},
	DisplayLowIntensity: {'2'},
	DisplayItalic:       {'3'},
	DisplayUnderline:    {'4'},
	DisplayBlink:        {'5'},
	DisplayRapidBlink:   {'6'},
	DisplayReverse:      {'7'},
	DisplayInvisible:    {'8'},
	DisplayCrossedOut:   {'9'},
	DisplayDefaultFont:  {'1', '0'},
}

var foregroundANSIColors = map[Color][]byte{
	DefaultColor: {'3', '9'},

	// Low intensity.
	Black:     {'3', '0'},
	DarkRed:   {'3', '1'},
	DarkGreen: {'3', '2'},
	Brown:     {'3', '3'},
	DarkBlue:  {'3', '4'},
	Purple:    {'3', '5'},
	Cyan:      {'3', '6'},
	LightGray: {'3', '7'},

	// High intensity.
	DarkGray:  {'9', '0'},
	Red:       {'9', '1'},
	Green:     {'9', '2'},
	Yellow:    {'9', '3'},
	Blue:      {'9', '4'},
	Fuchsia:   {'9', '5'},
	Turquoise: {'9', '6'},
	White:     {'9', '7'},
}

var backgroundANSIColors = map[Color][]byte{
	DefaultColor: {'4', '9'},

	// Low intensity.
	Black:     {'4', '0'},
	DarkRed:   {'4', '1'},
	DarkGreen: {'4', '2'},
	Brown:     {'4', '3'},
	DarkBlue:  {'4', '4'},
	Purple:    {'4', '5'},
	Cyan:      {'4', '6'},
	LightGray: {'4', '7'},

	// High intensity
	DarkGray:  {'1', '0', '0'},
	Red:       {'1', '0', '1'},
	Green:     {'1', '0', '2'},
	Yellow:    {'1', '0', '3'},
	Blue:      {'1', '0', '4'},
	Fuchsia:   {'1', '0', '5'},
	Turquoise: {'1', '0', '6'},
	White:     {'1', '0', '7'},
}
<commit_msg>Fix resetting attributes for arch linux<commit_after>package prompt

import (
	"bytes"
	"strconv"
)

// VT100Writer generates VT100 escape sequences.
type VT100Writer struct {
	buffer []byte
}

// WriteRaw to write raw byte array
func (w *VT100Writer) WriteRaw(data []byte) {
	w.buffer = append(w.buffer, data...)
	return
}

// Write to write safety byte array by removing control sequences.
func (w *VT100Writer) Write(data []byte) {
	w.WriteRaw(bytes.Replace(data, []byte{0x1b}, []byte{'?'}, -1))
	return
}

// WriteRawStr to write raw string
func (w *VT100Writer) WriteRawStr(data string) {
	w.WriteRaw([]byte(data))
	return
}

// WriteStr to write safety string by removing control sequences.
func (w *VT100Writer) WriteStr(data string) {
	w.Write([]byte(data))
	return
}

/* Erase */

// EraseScreen erases the screen with the background colour and moves the cursor to home.
func (w *VT100Writer) EraseScreen() {
	w.WriteRaw([]byte{0x1b, '[', '2', 'J'})
	return
}

// EraseUp erases the screen from the current line up to the top of the screen.
func (w *VT100Writer) EraseUp() {
	w.WriteRaw([]byte{0x1b, '[', '1', 'J'})
	return
}

// EraseDown erases the screen from the current line down to the bottom of the screen.
func (w *VT100Writer) EraseDown() {
	w.WriteRaw([]byte{0x1b, '[', 'J'})
	return
}

// EraseStartOfLine erases from the current cursor position to the start of the current line.
func (w *VT100Writer) EraseStartOfLine() {
	w.WriteRaw([]byte{0x1b, '[', '1', 'K'})
	return
}

// EraseEndOfLine erases from the current cursor position to the end of the current line.
func (w *VT100Writer) EraseEndOfLine() {
	w.WriteRaw([]byte{0x1b, '[', 'K'})
	return
}

// EraseLine erases the entire current line.
func (w *VT100Writer) EraseLine() {
	w.WriteRaw([]byte{0x1b, '[', '2', 'K'})
	return
}

/* Cursor */

// ShowCursor stops blinking cursor and show.
func (w *VT100Writer) ShowCursor() {
	w.WriteRaw([]byte{0x1b, '[', '?', '1', '2', 'l', 0x1b, '[', '?', '2', '5', 'h'})
}

// HideCursor hides cursor.
func (w *VT100Writer) HideCursor() {
	w.WriteRaw([]byte{0x1b, '[', '?', '2', '5', 'l'})
	return
}

// CursorGoTo sets the cursor position where subsequent text will begin.
func (w *VT100Writer) CursorGoTo(row, col int) {
	if row == 0 && col == 0 {
		// If no row/column parameters are provided (ie. <ESC>[H), the cursor will move to the home position.
		w.WriteRaw([]byte{0x1b, '[', 'H'})
		return
	}
	r := strconv.Itoa(row)
	c := strconv.Itoa(col)
	w.WriteRaw([]byte{0x1b, '['})
	w.WriteRaw([]byte(r))
	w.WriteRaw([]byte{';'})
	w.WriteRaw([]byte(c))
	w.WriteRaw([]byte{'H'})
	return
}

// CursorUp moves the cursor up by 'n' rows; the default count is 1.
func (w *VT100Writer) CursorUp(n int) {
	if n == 0 {
		return
	} else if n < 0 {
		w.CursorDown(-n)
		return
	}
	s := strconv.Itoa(n)
	w.WriteRaw([]byte{0x1b, '['})
	w.WriteRaw([]byte(s))
	w.WriteRaw([]byte{'A'})
	return
}

// CursorDown moves the cursor down by 'n' rows; the default count is 1.
func (w *VT100Writer) CursorDown(n int) {
	if n == 0 {
		return
	} else if n < 0 {
		w.CursorUp(-n)
		return
	}
	s := strconv.Itoa(n)
	w.WriteRaw([]byte{0x1b, '['})
	w.WriteRaw([]byte(s))
	w.WriteRaw([]byte{'B'})
	return
}

// CursorForward moves the cursor forward by 'n' columns; the default count is 1.
func (w *VT100Writer) CursorForward(n int) {
	if n == 0 {
		return
	} else if n < 0 {
		w.CursorBackward(-n)
		return
	}
	s := strconv.Itoa(n)
	w.WriteRaw([]byte{0x1b, '['})
	w.WriteRaw([]byte(s))
	w.WriteRaw([]byte{'C'})
	return
}

// CursorBackward moves the cursor backward by 'n' columns; the default count is 1.
func (w *VT100Writer) CursorBackward(n int) {
	if n == 0 {
		return
	} else if n < 0 {
		w.CursorForward(-n)
		return
	}
	s := strconv.Itoa(n)
	w.WriteRaw([]byte{0x1b, '['})
	w.WriteRaw([]byte(s))
	w.WriteRaw([]byte{'D'})
	return
}

// AskForCPR asks for a cursor position report (CPR).
func (w *VT100Writer) AskForCPR() {
	// CPR: Cursor Position Request.
	w.WriteRaw([]byte{0x1b, '[', '6', 'n'})
	return
}

// SaveCursor saves current cursor position.
func (w *VT100Writer) SaveCursor() {
	w.WriteRaw([]byte{0x1b, '[', 's'})
	return
}

// UnSaveCursor restores cursor position after a Save Cursor.
func (w *VT100Writer) UnSaveCursor() {
	w.WriteRaw([]byte{0x1b, '[', 'u'})
	return
}

/* Scrolling */

// ScrollDown scrolls display down one line.
func (w *VT100Writer) ScrollDown() {
	w.WriteRaw([]byte{0x1b, 'D'})
	return
}

// ScrollUp scroll display up one line.
func (w *VT100Writer) ScrollUp() {
	w.WriteRaw([]byte{0x1b, 'M'})
	return
}

/* Title */

// SetTitle sets a title of terminal window.
func (w *VT100Writer) SetTitle(title string) {
	titleBytes := []byte(title)
	patterns := []struct {
		from []byte
		to   []byte
	}{
		{
			from: []byte{0x13},
			to:   []byte{},
		},
		{
			from: []byte{0x07},
			to:   []byte{},
		},
	}
	for i := range patterns {
		titleBytes = bytes.Replace(titleBytes, patterns[i].from, patterns[i].to, -1)
	}

	w.WriteRaw([]byte{0x1b, ']', '2', ';'})
	w.WriteRaw(titleBytes)
	w.WriteRaw([]byte{0x07})
	return
}

// ClearTitle clears a title of terminal window.
func (w *VT100Writer) ClearTitle() {
	w.WriteRaw([]byte{0x1b, ']', '2', ';', 0x07})
	return
}

/* Font */

// SetColor sets text and background colors. and specify whether text is bold.
func (w *VT100Writer) SetColor(fg, bg Color, bold bool) {
	if bold {
		w.SetDisplayAttributes(fg, bg, DisplayBold)
	} else {
		// If using `DisplayDefualt`, it will be broken in some environment.
		// Details are https://github.com/c-bata/go-prompt/pull/85
		w.SetDisplayAttributes(fg, bg, DisplayReset)
	}
	return
}

// SetDisplayAttributes to set VT100 display attributes.
func (w *VT100Writer) SetDisplayAttributes(fg, bg Color, attrs ...DisplayAttribute) {
	w.WriteRaw([]byte{0x1b, '['}) // control sequence introducer
	defer w.WriteRaw([]byte{'m'}) // final character

	var separator byte = ';'
	for i := range attrs {
		p, ok := displayAttributeParameters[attrs[i]]
		if !ok {
			continue
		}
		w.WriteRaw(p)
		w.WriteRaw([]byte{separator})
	}

	f, ok := foregroundANSIColors[fg]
	if !ok {
		f = foregroundANSIColors[DefaultColor]
	}
	w.WriteRaw(f)
	w.WriteRaw([]byte{separator})
	b, ok := backgroundANSIColors[bg]
	if !ok {
		b = backgroundANSIColors[DefaultColor]
	}
	w.WriteRaw(b)
	return
}

var displayAttributeParameters = map[DisplayAttribute][]byte{
	DisplayReset:        {'0'},
	DisplayBold:         {'1'},
	DisplayLowIntensity: {'2'},
	DisplayItalic:       {'3'},
	DisplayUnderline:    {'4'},
	DisplayBlink:        {'5'},
	DisplayRapidBlink:   {'6'},
	DisplayReverse:      {'7'},
	DisplayInvisible:    {'8'},
	DisplayCrossedOut:   {'9'},
	DisplayDefaultFont:  {'1', '0'},
}

var foregroundANSIColors = map[Color][]byte{
	DefaultColor: {'3', '9'},

	// Low intensity.
	Black:     {'3', '0'},
	DarkRed:   {'3', '1'},
	DarkGreen: {'3', '2'},
	Brown:     {'3', '3'},
	DarkBlue:  {'3', '4'},
	Purple:    {'3', '5'},
	Cyan:      {'3', '6'},
	LightGray: {'3', '7'},

	// High intensity.
	DarkGray:  {'9', '0'},
	Red:       {'9', '1'},
	Green:     {'9', '2'},
	Yellow:    {'9', '3'},
	Blue:      {'9', '4'},
	Fuchsia:   {'9', '5'},
	Turquoise: {'9', '6'},
	White:     {'9', '7'},
}

var backgroundANSIColors = map[Color][]byte{
	DefaultColor: {'4', '9'},

	// Low intensity.
	Black:     {'4', '0'},
	DarkRed:   {'4', '1'},
	DarkGreen: {'4', '2'},
	Brown:     {'4', '3'},
	DarkBlue:  {'4', '4'},
	Purple:    {'4', '5'},
	Cyan:      {'4', '6'},
	LightGray: {'4', '7'},

	// High intensity
	DarkGray:  {'1', '0', '0'},
	Red:       {'1', '0', '1'},
	Green:     {'1', '0', '2'},
	Yellow:    {'1', '0', '3'},
	Blue:      {'1', '0', '4'},
	Fuchsia:   {'1', '0', '5'},
	Turquoise: {'1', '0', '6'},
	White:     {'1', '0', '7'},
}
<|endoftext|>


<commit_before>package internal

import (
	"github.com/kuzzleio/sdk-go/types"
	"github.com/stretchr/testify/mock"
	"time"
)

var OfflineQueue []types.QueryObject

type MockedConnection struct {
	mock.Mock
	MockSend      func([]byte, types.QueryOptions) types.KuzzleResponse
	MockEmitEvent func(int, interface{})
	MockGetRooms  func() *types.RoomList
}

func (c MockedConnection) Send(query []byte, options types.QueryOptions, responseChannel chan<- types.KuzzleResponse, requestId string) error {
	if c.MockSend != nil {
		responseChannel <- c.MockSend(query, options)
	}

	return nil
}

func (c MockedConnection) Connect() (bool, error) {
	OfflineQueue = make([]types.QueryObject, 1)
	return false, nil
}

func (c MockedConnection) Close() error {
	return nil
}

func (c MockedConnection) AddListener(event int, channel chan<- interface{}) {}

func (c MockedConnection) GetState() *int {
	state := 0
	return &state
}

func (c MockedConnection) GetOfflineQueue() *[]types.QueryObject {
	return &OfflineQueue
}

func (c MockedConnection) EmitEvent(event int, arg interface{}) {
	if c.MockEmitEvent != nil {
		c.MockEmitEvent(event, arg)
	}
}

func (c MockedConnection) RegisterRoom(roomId, id string, room types.IRoom) {
}

func (c MockedConnection) UnregisterRoom(id string) {}

func (c MockedConnection) GetRequestHistory() *map[string]time.Time {
	r := make(map[string]time.Time)

	return &r
}

func (c MockedConnection) RenewSubscriptions() {}

func (c MockedConnection) GetRooms() *types.RoomList {
	v := c.MockGetRooms()

	return v
}
<commit_msg>fix mock<commit_after>package internal

import (
	"github.com/kuzzleio/sdk-go/types"
	"github.com/stretchr/testify/mock"
	"time"
)

var OfflineQueue []types.QueryObject

type MockedConnection struct {
	mock.Mock
	MockSend      func([]byte, types.QueryOptions) types.KuzzleResponse
	MockEmitEvent func(int, interface{})
	MockGetRooms  func() *types.RoomList
}

func (c MockedConnection) Send(query []byte, options types.QueryOptions, responseChannel chan<- types.KuzzleResponse, requestId string) error {
	if c.MockSend != nil {
		responseChannel <- c.MockSend(query, options)
	}

	return nil
}

func (c MockedConnection) Connect() (bool, error) {
	OfflineQueue = make([]types.QueryObject, 1)
	return false, nil
}

func (c MockedConnection) Close() error {
	return nil
}

func (c MockedConnection) AddListener(event int, channel chan<- interface{}) {}

func (c MockedConnection) GetState() *int {
	state := 0
	return &state
}

func (c MockedConnection) GetOfflineQueue() *[]types.QueryObject {
	return &OfflineQueue
}

func (c MockedConnection) EmitEvent(event int, arg interface{}) {
	if c.MockEmitEvent != nil {
		c.MockEmitEvent(event, arg)
	}
}

func (c MockedConnection) RegisterRoom(roomId, id string, room types.IRoom) {
}

func (c MockedConnection) UnregisterRoom(id string) {}

func (c MockedConnection) GetRequestHistory() *map[string]time.Time {
	r := make(map[string]time.Time)

	return &r
}

func (c MockedConnection) RenewSubscriptions() {}

func (c MockedConnection) GetRooms() *types.RoomList {
	v := c.MockGetRooms()

	return v
}

func (c MockedConnection) RemoveListener(event int) {}<|endoftext|>


<commit_before>package sdk

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

type httpClient interface {
	Do(*http.Request) (*http.Response, error)
}

type HTTPSender struct {
	client httpClient
}

func NewHTTPSender(client httpClient) *HTTPSender {
	return &HTTPSender{client: client}
}

func (s *HTTPSender) Send(request *http.Request) (content []byte, err error) {
	response, err := s.client.Do(request)
	if err != nil {
		return nil, err
	}

	content, err = ioutil.ReadAll(response.Body)
	if err != nil {
		return nil, err
	}

	if response.StatusCode != http.StatusOK {
		response.Body.Close()
		return nil, fmt.Errorf("Non-200 status: %s\n%s", response.Status, string(content))
	}

	return content, response.Body.Close()

}
<commit_msg>Added TODO item related to a bug when not closing response.<commit_after>package sdk

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

type httpClient interface {
	Do(*http.Request) (*http.Response, error)
}

type HTTPSender struct {
	client httpClient
}

func NewHTTPSender(client httpClient) *HTTPSender {
	return &HTTPSender{client: client}
}

func (s *HTTPSender) Send(request *http.Request) (content []byte, err error) {
	response, err := s.client.Do(request)
	if err != nil {
		return nil, err
	}

	content, err = ioutil.ReadAll(response.Body)
	if err != nil {
		// BUG: if we get a response (and it has a body), it should always be closed
		return nil, err
	}

	if response.StatusCode != http.StatusOK {
		response.Body.Close()
		return nil, fmt.Errorf("Non-200 status: %s\n%s", response.Status, string(content))
	}

	return content, response.Body.Close()

}
<|endoftext|>


<commit_before>package version

// Client returns the client version as a string.
//
const Client = "7.0.0-SNAPSHOT"
<commit_msg>Update the package version to 8.0.0-SNAPSHOT<commit_after>package version

// Client returns the client version as a string.
//
const Client = "8.0.0-SNAPSHOT"
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"sync"

	"github.com/brnstz/routine/wikimg"
)

var (
	// print a blank line with the given 256 ANSI color
	fmtSpec = "\x1b[30;48;5;%dm%-80s\x1b[0m\n"
)

func main() {
	var max, workers, buffer int

	flag.IntVar(&max, "max", 10, "maximum number of images to retrieve")
	flag.IntVar(&workers, "workers", 5, "number of background workers")
	flag.IntVar(&buffer, "buffer", 0, "buffer size of image channel")
	flag.Parse()

	// Create a new image puller with our max
	p := wikimg.NewPuller(max)

	// Create a buffered channel for communicating between image
	// puller loop and workers
	imgURLs := make(chan string, buffer)

	wg := sync.WaitGroup{}

	for i := 0; i < workers; i++ {
		wg.Add(1)
		go func() {
			for imgURL := range imgURLs {
				// Get the top color in this image
				color, err := wikimg.OneColor(imgURL)
				if err != nil {
					log.Println(err)
					continue
				}

				// Print color to the terminal
				fmt.Printf(fmtSpec, color.XTermCode, "")
			}
			wg.Done()
		}()
	}

	// Loop to retrieve more images
	for {
		imgURL, err := p.Next()

		if err == wikimg.EndOfResults {
			// Break from loop when end of results is reached
			break

		} else if err != nil {
			// Log error and continue getting URLs
			log.Println(err)
			continue
		}

		imgURLs <- imgURL
	}
	close(imgURLs)
	wg.Wait()

}
<commit_msg>spacing fix<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"sync"

	"github.com/brnstz/routine/wikimg"
)

var (
	// print a blank line with the given 256 ANSI color
	fmtSpec = "\x1b[30;48;5;%dm%-80s\x1b[0m\n"
)

func main() {
	var max, workers, buffer int

	flag.IntVar(&max, "max", 10, "maximum number of images to retrieve")
	flag.IntVar(&workers, "workers", 5, "number of background workers")
	flag.IntVar(&buffer, "buffer", 0, "buffer size of image channel")
	flag.Parse()

	// Create a new image puller with our max
	p := wikimg.NewPuller(max)

	// Create a buffered channel for communicating between image
	// puller loop and workers
	imgURLs := make(chan string, buffer)

	wg := sync.WaitGroup{}

	for i := 0; i < workers; i++ {
		wg.Add(1)
		go func() {
			for imgURL := range imgURLs {
				// Get the top color in this image
				color, err := wikimg.OneColor(imgURL)
				if err != nil {
					log.Println(err)
					continue
				}

				// Print color to the terminal
				fmt.Printf(fmtSpec, color.XTermCode, "")
			}
			wg.Done()
		}()
	}

	// Loop to retrieve more images
	for {
		imgURL, err := p.Next()

		if err == wikimg.EndOfResults {
			// Break from loop when end of results is reached
			break

		} else if err != nil {
			// Log error and continue getting URLs
			log.Println(err)
			continue
		}

		imgURLs <- imgURL
	}
	close(imgURLs)
	wg.Wait()
}
<|endoftext|>


<commit_before>/*
Released under MIT License <http://www.opensource.org/licenses/mit-license.php
Copyright (C) ITsysCOM GmbH. All Rights Reserved.

Provides Asterisk ARI connector from Go programming language.
*/

package aringo

import (
	"encoding/json"
	"errors"
	"net/http"
	"net/url"
	"sync"
	"time"

	"golang.org/x/net/websocket"
)

var (
	ErrZeroConnectAttempts = errors.New("ZERO_CONNECT_ATTEMPTS")
)

// successive Fibonacci numbers.
func Fib() func() time.Duration {
	a, b := 0, 1
	return func() time.Duration {
		a, b = b, a+b
		return time.Duration(a) * time.Second
	}
}

func NewARInGO(wsUrl, wsOrigin string, evChannel chan *json.RawMessage, errChannel chan error, connectAttempts, reconnects int) (ari *ARInGO, err error) {
	if connectAttempts == 0 {
		return nil, ErrZeroConnectAttempts
	}
	ari = &ARInGO{httpClient: new(http.Client), wsUrl: wsUrl, wsOrigin: wsOrigin, reconnects: reconnects,
		evChannel: evChannel, errChannel: errChannel,
		wsMux: new(sync.RWMutex), wsListenerMux: new(sync.Mutex)}
	delay := Fib()
	i := 0
	for {
		if err = ari.connect(); err == nil {
			break
		}
		i++
		if connectAttempts != -1 && i >= connectAttempts { // -1 for infinite attempts
			break
		}
		time.Sleep(delay()) // Increased delay to randomize network load
	}
	return
}

// ARInGO represents one ARI connection/application
type ARInGO struct {
	httpClient     *http.Client
	wsUrl          string
	wsOrigin       string
	ws             *websocket.Conn
	reconnects     int
	wsMux          *sync.RWMutex
	evChannel      chan *json.RawMessage // Events coming from Asterisk are posted here
	errChannel     chan error            // Errors are posted here
	wsListenerExit chan struct{}         // Signal dispatcher to stop listening
	wsListenerMux  *sync.Mutex           // Use it to get access to wsListenerExit recreation
}

// wsDispatcher listens for JSON rawMessages and stores them into the evChannel
func (ari *ARInGO) wsEventListener(chanExit chan struct{}) {
	for {
		select {
		case <-chanExit:
			break
		default:
			var data json.RawMessage
			if err := websocket.JSON.Receive(ari.ws, &data); err != nil { // ToDo: Add reconnects here
				ari.disconnect()
				ari.errChannel <- err
				return
			}
			ari.evChannel <- &data
		}
	}
}

// connect connects to Asterisk Websocket and starts listener
func (ari *ARInGO) connect() (err error) {
	ari.wsMux.Lock()
	defer ari.wsMux.Unlock()
	ari.ws, err = websocket.Dial(ari.wsUrl, "", ari.wsOrigin)
	if err != nil {
		return
	}
	// Connected, start listener
	ari.wsListenerMux.Lock()
	if ari.wsListenerExit != nil {
		close(ari.wsListenerExit) // Order previous listener to stop before proceeding
	}
	ari.wsListenerExit = make(chan struct{})
	go ari.wsEventListener(ari.wsListenerExit)
	ari.wsListenerMux.Unlock()
	return nil
}

func (ari *ARInGO) disconnect() error {
	ari.wsListenerMux.Lock()
	close(ari.wsListenerExit) // Order previous listener to stop
	ari.wsListenerMux.Unlock()
	return ari.ws.Close()
}

// Call represents one REST call to Asterisk using httpClient
// Returns a http.Response so we can process additional data out of it
func (ari *ARInGO) Call(url string, data url.Values, resp *http.Response) error {
	if reply, err := ari.httpClient.PostForm(url, data); err != nil {
		return err
	} else {
		*resp = *reply
	}
	return nil
}
<commit_msg>Use map[string]interface{} to represent events coming from Asterisk<commit_after>/*
Released under MIT License <http://www.opensource.org/licenses/mit-license.php
Copyright (C) ITsysCOM GmbH. All Rights Reserved.

Provides Asterisk ARI connector from Go programming language.
*/

package aringo

import (
	"errors"
	"net/http"
	"net/url"
	"sync"
	"time"

	"golang.org/x/net/websocket"
)

var (
	ErrZeroConnectAttempts = errors.New("ZERO_CONNECT_ATTEMPTS")
)

// successive Fibonacci numbers.
func Fib() func() time.Duration {
	a, b := 0, 1
	return func() time.Duration {
		a, b = b, a+b
		return time.Duration(a) * time.Second
	}
}

func NewARInGO(wsUrl, wsOrigin string, evChannel chan map[string]interface{}, errChannel chan error, connectAttempts, reconnects int) (ari *ARInGO, err error) {
	if connectAttempts == 0 {
		return nil, ErrZeroConnectAttempts
	}
	ari = &ARInGO{httpClient: new(http.Client), wsUrl: wsUrl, wsOrigin: wsOrigin, reconnects: reconnects,
		evChannel: evChannel, errChannel: errChannel,
		wsMux: new(sync.RWMutex), wsListenerMux: new(sync.Mutex)}
	delay := Fib()
	i := 0
	for {
		if err = ari.connect(); err == nil {
			break
		}
		i++
		if connectAttempts != -1 && i >= connectAttempts { // -1 for infinite attempts
			break
		}
		time.Sleep(delay()) // Increased delay to randomize network load
	}
	return
}

// ARInGO represents one ARI connection/application
type ARInGO struct {
	httpClient     *http.Client
	wsUrl          string
	wsOrigin       string
	ws             *websocket.Conn
	reconnects     int
	wsMux          *sync.RWMutex
	evChannel      chan map[string]interface{} // Events coming from Asterisk are posted here
	errChannel     chan error                  // Errors are posted here
	wsListenerExit chan struct{}               // Signal dispatcher to stop listening
	wsListenerMux  *sync.Mutex                 // Use it to get access to wsListenerExit recreation
}

// wsDispatcher listens for JSON rawMessages and stores them into the evChannel
func (ari *ARInGO) wsEventListener(chanExit chan struct{}) {
	for {
		select {
		case <-chanExit:
			break
		default:
			var ev map[string]interface{}
			if err := websocket.JSON.Receive(ari.ws, &ev); err != nil { // ToDo: Add reconnects here
				ari.disconnect()
				ari.errChannel <- err
				return
			}
			ari.evChannel <- ev
		}
	}
}

// connect connects to Asterisk Websocket and starts listener
func (ari *ARInGO) connect() (err error) {
	ari.wsMux.Lock()
	defer ari.wsMux.Unlock()
	ari.ws, err = websocket.Dial(ari.wsUrl, "", ari.wsOrigin)
	if err != nil {
		return
	}
	// Connected, start listener
	ari.wsListenerMux.Lock()
	if ari.wsListenerExit != nil {
		close(ari.wsListenerExit) // Order previous listener to stop before proceeding
	}
	ari.wsListenerExit = make(chan struct{})
	go ari.wsEventListener(ari.wsListenerExit)
	ari.wsListenerMux.Unlock()
	return nil
}

func (ari *ARInGO) disconnect() error {
	ari.wsListenerMux.Lock()
	close(ari.wsListenerExit) // Order previous listener to stop
	ari.wsListenerMux.Unlock()
	return ari.ws.Close()
}

// Call represents one REST call to Asterisk using httpClient
// Returns a http.Response so we can process additional data out of it
func (ari *ARInGO) Call(url string, data url.Values, resp *http.Response) error {
	if reply, err := ari.httpClient.PostForm(url, data); err != nil {
		return err
	} else {
		*resp = *reply
	}
	return nil
}
<|endoftext|>


<commit_before>// package assert provides convenience assert methods to complement
// the built in go testing library. It's intended to add onto standard
// Go tests. Example usage:
//	func TestSomething(t *testing.T) {
//		i, err := doSomething()
//    assert.NoErr(err)
//    assert.Equal(i, 123, "returned integer")
//  }
package assert

import (
	"fmt"
	"runtime"
	"testing"
	"reflect"
)

// callerStr returns a string representation of the code numFrames stack
// frames above the code that called callerStr
func callerStr(numFrames int) string {
	_, file, line, _ := runtime.Caller(1 + numFrames)
	return fmt.Sprintf("%s:%d", file, line)
}

// callerStrErrorf calls t.Errorf with fmtStr and vals in it, prefixed
// by a callerStr representation of the code numFrames above the caller of
// this function
func callerStrf(numFrames int, fmtStr string, vals ...interface{}) string {
	origStr := fmt.Sprintf(fmtStr, vals...)
	return fmt.Sprintf("%s: %s", callerStr(1+numFrames), origStr)
}

// True calls t.Errorf if the provided bool is false, does nothing
// otherwise
func True(t *testing.T, b bool, fmtStr string, vals ...interface{}) {
	if !b {
		t.Errorf(callerStrf(1, fmtStr, vals...))
	}
}

// False is the equivalent of True(t, !b, fmtStr, vals...)
func False(t *testing.T, b bool, fmtStr string, vals ...interface{}) {
	if b {
		t.Errorf(callerStrf(1, fmtStr, vals...))
	}
}

// Nil calls t.Errorf if i is not nil
func Nil(t *testing.T, i interface{}, fmtStr string, vals ...interface{}) {
	if i != nil {
		t.Errorf(callerStrf(1, fmtStr, vals...))
	}
}

// NoErr calls t.Errorf if e is not nil
func NoErr(t *testing.T, e error) {
	if e != nil {
		t.Errorf(callerStrf(1, "expected no error but got %s", e))
	}
}

// Err calls t.Errorf if expected is not equal to actual
func Err(t *testing.T, expected error, actual error) {
	if expected != actual {
		t.Errorf(callerStrf(1, "expected error %s but got %s", expected, actual))
	}
}

// Equal ensures that the actual value returned from a test was equal to an
// expected. it uses reflect.DeepEqual to do so.
// name is the name used to describe the values being compared.
// it's used in the error string if actual != expected
func Equal(t *testing.T, actual, expected interface{}, noun string) {
	if !reflect.DeepEqual(actual, expected) {
		t.Errorf(callerStrf(1, "actual %s [%+v] != expected %s [%+v]", noun, actual, noun, expected))
	}
}
<commit_msg>fixing func Nil Fixes #3<commit_after>// package assert provides convenience assert methods to complement
// the built in go testing library. It's intended to add onto standard
// Go tests. Example usage:
//	func TestSomething(t *testing.T) {
//		i, err := doSomething()
//    assert.NoErr(err)
//    assert.Equal(i, 123, "returned integer")
//  }
package assert

import (
	"fmt"
	"runtime"
	"testing"
	"reflect"
)

// callerStr returns a string representation of the code numFrames stack
// frames above the code that called callerStr
func callerStr(numFrames int) string {
	_, file, line, _ := runtime.Caller(1 + numFrames)
	return fmt.Sprintf("%s:%d", file, line)
}

// callerStrErrorf calls t.Errorf with fmtStr and vals in it, prefixed
// by a callerStr representation of the code numFrames above the caller of
// this function
func callerStrf(numFrames int, fmtStr string, vals ...interface{}) string {
	origStr := fmt.Sprintf(fmtStr, vals...)
	return fmt.Sprintf("%s: %s", callerStr(1+numFrames), origStr)
}

// True calls t.Errorf if the provided bool is false, does nothing
// otherwise
func True(t *testing.T, b bool, fmtStr string, vals ...interface{}) {
	if !b {
		t.Errorf(callerStrf(1, fmtStr, vals...))
	}
}

// False is the equivalent of True(t, !b, fmtStr, vals...)
func False(t *testing.T, b bool, fmtStr string, vals ...interface{}) {
	if b {
		t.Errorf(callerStrf(1, fmtStr, vals...))
	}
}

// Nil calls t.Errorf if i is not nil
func Nil(t *testing.T, i interface{}, fmtStr string, vals ...interface{}) {
	if !reflect.DeepEqual(i, nil) {
		t.Errorf(callerStrf(1, fmtStr, vals...))
	}
}

// NoErr calls t.Errorf if e is not nil
func NoErr(t *testing.T, e error) {
	if e != nil {
		t.Errorf(callerStrf(1, "expected no error but got %s", e))
	}
}

// Err calls t.Errorf if expected is not equal to actual
func Err(t *testing.T, expected error, actual error) {
	if expected != actual {
		t.Errorf(callerStrf(1, "expected error %s but got %s", expected, actual))
	}
}

// Equal ensures that the actual value returned from a test was equal to an
// expected. it uses reflect.DeepEqual to do so.
// name is the name used to describe the values being compared.
// it's used in the error string if actual != expected
func Equal(t *testing.T, actual, expected interface{}, noun string) {
	if !reflect.DeepEqual(actual, expected) {
		t.Errorf(callerStrf(1, "actual %s [%+v] != expected %s [%+v]", noun, actual, noun, expected))
	}
}
<|endoftext|>


<commit_before>package money

import (
	"fmt"
	"math/big"
	"strings"

	"github.com/juju/errors"
)

// Money represents a monetary value
type Money struct {
	rat *big.Rat
}

// New creates a new instance with a zero value.
func New() *Money {
	return &Money{
		rat: big.NewRat(0, 1),
	}
}

// Parse a string to create a new money value. It can read `XX.YY` and `XX,YY`.
func Parse(s string) (*Money, error) {
	s = strings.Replace(s, ",", ".", -1)

	rat := new(big.Rat)
	if _, err := fmt.Sscan(s, rat); err != nil {
		return nil, errors.Trace(err)
	}

	return &Money{rat}, nil
}

// Cents returns the value with cents precision (2 decimal places) as a number.
func (money *Money) Cents() int64 {
	cents := big.NewInt(100)

	v := money.rat.Num()
	v.Mul(v, cents)
	v.Quo(v, money.rat.Denom())

	return v.Int64()
}

// Format the money value with a specific decimal precision.
func (money *Money) Format(prec int) string {
	return money.rat.FloatString(prec)
}

// Mul multiplies the money value n times and returns the result.
func (money *Money) Mul(n int64) *Money {
	b := big.NewRat(n, 1)
	result := New()
	result.rat.Mul(money.rat, b)
	return result
}

// Add two money values together and returns the result.
func (money *Money) Add(other *Money) *Money {
	result := New()
	result.rat.Add(money.rat, other.rat)
	return result
}

// Sub subtracts two money values and returns the result.
func (money *Money) Sub(other *Money) *Money {
	result := New()
	result.rat.Sub(money.rat, other.rat)
	return result
}

// Div divides two money values and returns the result.
func (money *Money) Div(other *Money) *Money {
	result := New()
	result.rat.Quo(money.rat, other.rat)
	return result
}

// LessThan returns true if a money value is less than the other.
func (money *Money) LessThan(other *Money) bool {
	return money.rat.Cmp(other.rat) == -1
}
<commit_msg>Parse an empty money value as zero.<commit_after>package money

import (
	"fmt"
	"math/big"
	"strings"

	"github.com/juju/errors"
)

// Money represents a monetary value
type Money struct {
	rat *big.Rat
}

// New creates a new instance with a zero value.
func New() *Money {
	return &Money{
		rat: big.NewRat(0, 1),
	}
}

// Parse a string to create a new money value. It can read `XX.YY` and `XX,YY`.
// An empty string is parsed as zero.
func Parse(s string) (*Money, error) {
	if len(s) == 0 {
		return New(), nil
	}

	s = strings.Replace(s, ",", ".", -1)

	rat := new(big.Rat)
	if _, err := fmt.Sscan(s, rat); err != nil {
		return nil, errors.Trace(err)
	}

	return &Money{rat}, nil
}

// Cents returns the value with cents precision (2 decimal places) as a number.
func (money *Money) Cents() int64 {
	cents := big.NewInt(100)

	v := money.rat.Num()
	v.Mul(v, cents)
	v.Quo(v, money.rat.Denom())

	return v.Int64()
}

// Format the money value with a specific decimal precision.
func (money *Money) Format(prec int) string {
	return money.rat.FloatString(prec)
}

// Mul multiplies the money value n times and returns the result.
func (money *Money) Mul(n int64) *Money {
	b := big.NewRat(n, 1)
	result := New()
	result.rat.Mul(money.rat, b)
	return result
}

// Add two money values together and returns the result.
func (money *Money) Add(other *Money) *Money {
	result := New()
	result.rat.Add(money.rat, other.rat)
	return result
}

// Sub subtracts two money values and returns the result.
func (money *Money) Sub(other *Money) *Money {
	result := New()
	result.rat.Sub(money.rat, other.rat)
	return result
}

// Div divides two money values and returns the result.
func (money *Money) Div(other *Money) *Money {
	result := New()
	result.rat.Quo(money.rat, other.rat)
	return result
}

// LessThan returns true if a money value is less than the other.
func (money *Money) LessThan(other *Money) bool {
	return money.rat.Cmp(other.rat) == -1
}
<|endoftext|>


<commit_before><commit_msg>Added indentation to result JSON<commit_after><|endoftext|>


<commit_before><commit_msg>disable heap check<commit_after><|endoftext|>


<commit_before>package iface

import (
	"fmt"
	"log"
	"net"
	"os/exec"
	"strconv"

	"github.com/songgao/water"
)

type Iface struct {
	name string
	ip   string
	mtu  int
	ifce *water.Interface
}

func New(name, ip string, mtu int) *Iface {
	return &Iface{
		name: name,
		ip:   ip,
		mtu:  mtu,
	}
}

func (i *Iface) Start() error {
	ip, netIP, err := net.ParseCIDR(i.ip)
	if err != nil {
		return fmt.Errorf("parse IP err: %s", err)
	}
	config := water.Config{
		DeviceType: water.TUN,
	}
	//config.Name = i.name
	i.ifce, err = water.New(config)
	if err != nil {
		return fmt.Errorf("iface create err: %s", err)
	}
	mask := netIP.Mask
	netmask := fmt.Sprintf("%d.%d.%d.%d", mask[0], mask[1], mask[2], mask[3])
	log.Printf("iface name: %s", i.Name())
	log.Printf("ip: %s", ip.String())
	cmd := exec.Command("ifconfig", i.Name(),
		ip.String(), "netmask", netmask,
		"mtu", strconv.Itoa(i.mtu), "up")
	output, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("ifconfig run err: %s %s", err, string(output))
	}
	return nil
}

func (i *Iface) Name() string {
	return i.ifce.Name()
}

func (i *Iface) Read(pkt PacketIP) (int, error) {
	return i.ifce.Read(pkt)
}

func (i *Iface) Write(pkt PacketIP) (int, error) {
	return i.ifce.Write(pkt)
}
<commit_msg>platform fix<commit_after>package iface

import (
	"fmt"
	"log"
	"net"
	"os/exec"
	"strconv"

	"github.com/songgao/water"
)

func (i *Iface) Start() error {
	ip, netIP, err := net.ParseCIDR(i.ip)
	if err != nil {
		return fmt.Errorf("parse IP err: %s", err)
	}
	config := water.Config{
		DeviceType: water.TUN,
	}
	//config.Name = i.name
	i.ifce, err = water.New(config)
	if err != nil {
		return fmt.Errorf("iface create err: %s", err)
	}
	mask := netIP.Mask
	netmask := fmt.Sprintf("%d.%d.%d.%d", mask[0], mask[1], mask[2], mask[3])
	log.Printf("iface name: %s", i.Name())
	log.Printf("ip: %s", ip.String())
	cmd := exec.Command("ifconfig", i.Name(),
		ip.String(), "netmask", netmask,
		"mtu", strconv.Itoa(i.mtu), "up")
	output, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("ifconfig run err: %s %s", err, string(output))
	}
	return nil
}
<|endoftext|>


<commit_before>package rpm

import (
	"io/ioutil"
	"path/filepath"
	"strings"
	"testing"
)

func TestReadRPMFile(t *testing.T) {
	dir := "./rpms"

	// list RPM files
	files, err := ioutil.ReadDir(dir)
	if err != nil {
		t.Fatalf(err.Error())
	}

	valid := 0
	for _, f := range files {
		if strings.HasSuffix(f.Name(), ".rpm") {
			path := filepath.Join(dir, f.Name())
			_, err := OpenPackage(path)
			if err != nil {
				t.Errorf("Error loading RPM file %s: %s", f.Name(), err)
			} else {
				valid++
			}
		}
	}

	if valid == 0 {
		t.Errorf("No RPM files found for testing with in %s", dir)
	} else {
		t.Logf("Validated %d RPM files", valid)
	}
}
<commit_msg>Added envvar to package tests for rpm file location<commit_after>package rpm

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"testing"
)

func TestReadRPMFile(t *testing.T) {
	// get a directory full of rpms from RPM_DIR environment variable
	dir := os.Getenv("RPM_DIR")
	if dir == "" {
		t.Fatalf("$RPM_DIR is not set.")
	}

	// list RPM files
	files, err := ioutil.ReadDir(dir)
	if err != nil {
		t.Fatalf(err.Error())
	}

	valid := 0
	for _, f := range files {
		if strings.HasSuffix(f.Name(), ".rpm") {
			path := filepath.Join(dir, f.Name())
			_, err := OpenPackage(path)
			if err != nil {
				t.Errorf("Error loading RPM file %s: %s", f.Name(), err)
			} else {
				valid++
			}
		}
	}

	if valid == 0 {
		t.Errorf("No RPM files found for testing with in %s", dir)
	} else {
		t.Logf("Validated %d RPM files", valid)
	}
}
<|endoftext|>