<commit_before>//: ----------------------------------------------------------------------------
//: Copyright (C) 2017 Verizon.  All Rights Reserved.
//: All Rights Reserved
//:
//: file:    nsq.go
//: details: vflow nsq producer plugin
//: author:  Mehrdad Arshad Rad
//: date:    02/01/2017
//:
//: 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 producer

import (
	"io/ioutil"
	"log"

	"github.com/bitly/go-nsq"
	"gopkg.in/yaml.v2"
)

// NSQ represents nsq producer
type NSQ struct {
	producer *nsq.Producer
	config   NSQConfig
	logger   *log.Logger
}

// NSQConfig represents NSQ configuration
type NSQConfig struct {
	Server string `json:"server"`
}

func (n *NSQ) setup(configFile string, logger *log.Logger) error {
	var (
		err error
		cfg = nsq.NewConfig()
	)

	// set default values
	n.config = NSQConfig{
		Server: "localhost:4150",
	}

	// load configuration if available
	if err = n.load(configFile); err != nil {
		logger.Println(err)
	}

	cfg.ClientID = "vflow.nsq"

	n.producer, err = nsq.NewProducer(n.config.Server, cfg)
	if err != nil {
		logger.Println(err)
		return err
	}

	n.logger = logger

	return nil
}

func (n *NSQ) inputMsg(topic string, mCh chan []byte, ec *uint64) {
	var (
		msg []byte
		err error
		ok  bool
	)

	n.logger.Printf("start producer: NSQ, server: %+v, topic: %s\n",
		n.config.Server, topic)

	for {
		msg, ok = <-mCh
		if !ok {
			break
		}

		err = n.producer.Publish(topic, msg)
		if err != nil {
			n.logger.Println(err)
			*ec++
		}
	}
}

func (n *NSQ) load(f string) error {
	b, err := ioutil.ReadFile(f)
	if err != nil {
		return err
	}

	err = yaml.Unmarshal(b, &n.config)
	if err != nil {
		return err
	}

	return nil
}
<commit_msg>fix json to yaml tag<commit_after>//: ----------------------------------------------------------------------------
//: Copyright (C) 2017 Verizon.  All Rights Reserved.
//: All Rights Reserved
//:
//: file:    nsq.go
//: details: vflow nsq producer plugin
//: author:  Mehrdad Arshad Rad
//: date:    02/01/2017
//:
//: 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 producer

import (
	"io/ioutil"
	"log"

	"github.com/bitly/go-nsq"
	"gopkg.in/yaml.v2"
)

// NSQ represents nsq producer
type NSQ struct {
	producer *nsq.Producer
	config   NSQConfig
	logger   *log.Logger
}

// NSQConfig represents NSQ configuration
type NSQConfig struct {
	Server string `yaml:"server"`
}

func (n *NSQ) setup(configFile string, logger *log.Logger) error {
	var (
		err error
		cfg = nsq.NewConfig()
	)

	// set default values
	n.config = NSQConfig{
		Server: "localhost:4150",
	}

	// load configuration if available
	if err = n.load(configFile); err != nil {
		logger.Println(err)
	}

	cfg.ClientID = "vflow.nsq"

	n.producer, err = nsq.NewProducer(n.config.Server, cfg)
	if err != nil {
		logger.Println(err)
		return err
	}

	n.logger = logger

	return nil
}

func (n *NSQ) inputMsg(topic string, mCh chan []byte, ec *uint64) {
	var (
		msg []byte
		err error
		ok  bool
	)

	n.logger.Printf("start producer: NSQ, server: %+v, topic: %s\n",
		n.config.Server, topic)

	for {
		msg, ok = <-mCh
		if !ok {
			break
		}

		err = n.producer.Publish(topic, msg)
		if err != nil {
			n.logger.Println(err)
			*ec++
		}
	}
}

func (n *NSQ) load(f string) error {
	b, err := ioutil.ReadFile(f)
	if err != nil {
		return err
	}

	err = yaml.Unmarshal(b, &n.config)
	if err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package ethchain

import (
	"bytes"
	"container/list"
	"fmt"
	"math/big"
	"sync"
	"time"

	"github.com/ethereum/eth-go/ethcrypto"
	"github.com/ethereum/eth-go/ethlog"
	"github.com/ethereum/eth-go/ethreact"
	"github.com/ethereum/eth-go/ethstate"
	"github.com/ethereum/eth-go/ethutil"
	"github.com/ethereum/eth-go/ethwire"
)

var statelogger = ethlog.NewLogger("STATE")

type BlockProcessor interface {
	ProcessBlock(block *Block)
}

type Peer interface {
	Inbound() bool
	LastSend() time.Time
	LastPong() int64
	Host() []byte
	Port() uint16
	Version() string
	PingTime() string
	Connected() *int32
}

type EthManager interface {
	StateManager() *StateManager
	BlockChain() *BlockChain
	TxPool() *TxPool
	Broadcast(msgType ethwire.MsgType, data []interface{})
	Reactor() *ethreact.ReactorEngine
	PeerCount() int
	IsMining() bool
	IsListening() bool
	Peers() *list.List
	KeyManager() *ethcrypto.KeyManager
	ClientIdentity() ethwire.ClientIdentity
	Db() ethutil.Database
}

type StateManager struct {
	// Mutex for locking the block processor. Blocks can only be handled one at a time
	mutex sync.Mutex
	// Canonical block chain
	bc *BlockChain
	// non-persistent key/value memory storage
	mem map[string]*big.Int
	// Proof of work used for validating
	Pow PoW
	// The ethereum manager interface
	Ethereum EthManager
	// The managed states
	// Transiently state. The trans state isn't ever saved, validated and
	// it could be used for setting account nonces without effecting
	// the main states.
	transState *ethstate.State
	// Mining state. The mining state is used purely and solely by the mining
	// operation.
	miningState *ethstate.State

	// The last attempted block is mainly used for debugging purposes
	// This does not have to be a valid block and will be set during
	// 'Process' & canonical validation.
	lastAttemptedBlock *Block
}

func NewStateManager(ethereum EthManager) *StateManager {
	sm := &StateManager{
		mem:      make(map[string]*big.Int),
		Pow:      &EasyPow{},
		Ethereum: ethereum,
		bc:       ethereum.BlockChain(),
	}
	sm.transState = ethereum.BlockChain().CurrentBlock.State().Copy()
	sm.miningState = ethereum.BlockChain().CurrentBlock.State().Copy()

	return sm
}

func (sm *StateManager) CurrentState() *ethstate.State {
	return sm.Ethereum.BlockChain().CurrentBlock.State()
}

func (sm *StateManager) TransState() *ethstate.State {
	return sm.transState
}

func (sm *StateManager) MiningState() *ethstate.State {
	return sm.miningState
}

func (sm *StateManager) NewMiningState() *ethstate.State {
	sm.miningState = sm.Ethereum.BlockChain().CurrentBlock.State().Copy()

	return sm.miningState
}

func (sm *StateManager) BlockChain() *BlockChain {
	return sm.bc
}

func (self *StateManager) ProcessTransactions(coinbase *ethstate.StateObject, state *ethstate.State, block, parent *Block, txs Transactions) (Receipts, Transactions, Transactions, error) {
	var (
		receipts           Receipts
		handled, unhandled Transactions
		totalUsedGas       = big.NewInt(0)
		err                error
	)

done:
	for i, tx := range txs {
		txGas := new(big.Int).Set(tx.Gas)

		cb := state.GetStateObject(coinbase.Address())
		st := NewStateTransition(cb, tx, state, block)
		err = st.TransitionState()
		if err != nil {
			statelogger.Infoln(err)
			switch {
			case IsNonceErr(err):
				err = nil // ignore error
				continue
			case IsGasLimitErr(err):
				unhandled = txs[i:]

				break done
			default:
				statelogger.Infoln(err)
				err = nil
				//return nil, nil, nil, err
			}
		}

		// Notify all subscribers
		self.Ethereum.Reactor().Post("newTx:post", tx)

		// Update the state with pending changes
		state.Update()

		txGas.Sub(txGas, st.gas)
		accumelative := new(big.Int).Set(totalUsedGas.Add(totalUsedGas, txGas))
		receipt := &Receipt{tx, ethutil.CopyBytes(state.Root().([]byte)), accumelative}

		if i < len(block.Receipts()) {
			original := block.Receipts()[i]
			if !original.Cmp(receipt) {
				return nil, nil, nil, fmt.Errorf("err diff #%d (r) %v ~ %x  <=>  (c) %v ~ %x (%x)\n", i+1, original.CumulativeGasUsed, original.PostState[0:4], receipt.CumulativeGasUsed, receipt.PostState[0:4], receipt.Tx.Hash())
			}
		}

		receipts = append(receipts, receipt)
		handled = append(handled, tx)

		if ethutil.Config.Diff && ethutil.Config.DiffType == "all" {
			state.CreateOutputForDiff()
		}
	}

	parent.GasUsed = totalUsedGas

	return receipts, handled, unhandled, err
}

func (sm *StateManager) Process(block *Block, dontReact bool) (err error) {
	// Processing a blocks may never happen simultaneously
	sm.mutex.Lock()
	defer sm.mutex.Unlock()

	if sm.bc.HasBlock(block.Hash()) {
		return nil
	}

	if !sm.bc.HasBlock(block.PrevHash) {
		return ParentError(block.PrevHash)
	}

	sm.lastAttemptedBlock = block

	var (
		parent = sm.bc.GetBlock(block.PrevHash)
		state  = parent.State()
	)

	// Defer the Undo on the Trie. If the block processing happened
	// we don't want to undo but since undo only happens on dirty
	// nodes this won't happen because Commit would have been called
	// before that.
	defer state.Reset()

	if ethutil.Config.Diff && ethutil.Config.DiffType == "all" {
		fmt.Printf("## %x %x ##\n", block.Hash(), block.Number)
	}

	receipts, err := sm.ApplyDiff(state, parent, block)
	if err != nil {
		return err
	}

	txSha := CreateTxSha(receipts)
	if bytes.Compare(txSha, block.TxSha) != 0 {
		return fmt.Errorf("Error validating tx sha. Received %x, got %x", block.TxSha, txSha)
	}

	// Block validation
	if err = sm.ValidateBlock(block); err != nil {
		statelogger.Errorln("Error validating block:", err)
		return err
	}

	// I'm not sure, but I don't know if there should be thrown
	// any errors at this time.
	if err = sm.AccumelateRewards(state, block); err != nil {
		statelogger.Errorln("Error accumulating reward", err)
		return err
	}

	if !block.State().Cmp(state) {
		err = fmt.Errorf("Invalid merkle root.\nrec: %x\nis:  %x", block.State().Trie.Root, state.Trie.Root)
		return
	}

	// Calculate the new total difficulty and sync back to the db
	if sm.CalculateTD(block) {
		// Sync the current block's state to the database and cancelling out the deferred Undo
		state.Sync()

		// Add the block to the chain
		sm.bc.Add(block)

		// Create a bloom bin for this block
		filter := sm.createBloomFilter(state)
		// Persist the data
		fk := append([]byte("bloom"), block.Hash()...)
		sm.Ethereum.Db().Put(fk, filter.Bin())

		statelogger.Infof("Added block #%d (%x)\n", block.Number, block.Hash())
		if dontReact == false {
			sm.Ethereum.Reactor().Post("newBlock", block)

			state.Manifest().Reset()
		}

		sm.Ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{block.Value().Val})

		sm.Ethereum.TxPool().RemoveInvalid(state)
	} else {
		statelogger.Errorln("total diff failed")
	}

	return nil
}

func (sm *StateManager) ApplyDiff(state *ethstate.State, parent, block *Block) (receipts Receipts, err error) {
	coinbase := state.GetOrNewStateObject(block.Coinbase)
	coinbase.SetGasPool(block.CalcGasLimit(parent))

	// Process the transactions on to current block
	receipts, _, _, err = sm.ProcessTransactions(coinbase, state, block, parent, block.Transactions())
	if err != nil {
		return nil, err
	}

	return receipts, nil
}

func (sm *StateManager) CalculateTD(block *Block) bool {
	uncleDiff := new(big.Int)
	for _, uncle := range block.Uncles {
		uncleDiff = uncleDiff.Add(uncleDiff, uncle.Difficulty)
	}

	// TD(genesis_block) = 0 and TD(B) = TD(B.parent) + sum(u.difficulty for u in B.uncles) + B.difficulty
	td := new(big.Int)
	td = td.Add(sm.bc.TD, uncleDiff)
	td = td.Add(td, block.Difficulty)

	// The new TD will only be accepted if the new difficulty is
	// is greater than the previous.
	if td.Cmp(sm.bc.TD) > 0 {
		// Set the new total difficulty back to the block chain
		sm.bc.SetTotalDifficulty(td)

		return true
	}

	return false
}

// Validates the current block. Returns an error if the block was invalid,
// an uncle or anything that isn't on the current block chain.
// Validation validates easy over difficult (dagger takes longer time = difficult)
func (sm *StateManager) ValidateBlock(block *Block) error {
	// TODO
	// 2. Check if the difficulty is correct

	// Check each uncle's previous hash. In order for it to be valid
	// is if it has the same block hash as the current
	previousBlock := sm.bc.GetBlock(block.PrevHash)
	for _, uncle := range block.Uncles {
		if bytes.Compare(uncle.PrevHash, previousBlock.PrevHash) != 0 {
			return ValidationError("Mismatch uncle's previous hash. Expected %x, got %x", previousBlock.PrevHash, uncle.PrevHash)
		}
	}

	diff := block.Time - previousBlock.Time
	if diff < 0 {
		return ValidationError("Block timestamp less then prev block %v (%v - %v)", diff, block.Time, sm.bc.CurrentBlock.Time)
	}

	/* XXX
	// New blocks must be within the 15 minute range of the last block.
	if diff > int64(15*time.Minute) {
		return ValidationError("Block is too far in the future of last block (> 15 minutes)")
	}
	*/

	// Verify the nonce of the block. Return an error if it's not valid
	if !sm.Pow.Verify(block.HashNoNonce(), block.Difficulty, block.Nonce) {
		return ValidationError("Block's nonce is invalid (= %v)", ethutil.Bytes2Hex(block.Nonce))
	}

	return nil
}

func CalculateBlockReward(block *Block, uncleLength int) *big.Int {
	base := new(big.Int)
	for i := 0; i < uncleLength; i++ {
		base.Add(base, UncleInclusionReward)
	}

	return base.Add(base, BlockReward)
}

func CalculateUncleReward(block *Block) *big.Int {
	return UncleReward
}

func (sm *StateManager) AccumelateRewards(state *ethstate.State, block *Block) error {
	// Get the account associated with the coinbase
	account := state.GetAccount(block.Coinbase)
	// Reward amount of ether to the coinbase address
	account.AddAmount(CalculateBlockReward(block, len(block.Uncles)))

	addr := make([]byte, len(block.Coinbase))
	copy(addr, block.Coinbase)
	state.UpdateStateObject(account)

	for _, uncle := range block.Uncles {
		uncleAccount := state.GetAccount(uncle.Coinbase)
		uncleAccount.AddAmount(CalculateUncleReward(uncle))

		state.UpdateStateObject(uncleAccount)
	}

	return nil
}

func (sm *StateManager) Stop() {
	sm.bc.Stop()
}

// Manifest will handle both creating notifications and generating bloom bin data
func (sm *StateManager) createBloomFilter(state *ethstate.State) *BloomFilter {
	bloomf := NewBloomFilter(nil)

	for addr, stateObject := range state.Manifest().ObjectChanges {
		// Set the bloom filter's bin
		bloomf.Set([]byte(addr))

		sm.Ethereum.Reactor().Post("object:"+addr, stateObject)
	}

	for stateObjectAddr, mappedObjects := range state.Manifest().StorageChanges {
		for addr, value := range mappedObjects {
			// Set the bloom filter's bin
			bloomf.Set(ethcrypto.Sha3Bin([]byte(stateObjectAddr + addr)))

			sm.Ethereum.Reactor().Post("storage:"+stateObjectAddr+":"+addr, &ethstate.StorageState{[]byte(stateObjectAddr), []byte(addr), value})
		}
	}

	return bloomf
}

func (sm *StateManager) GetMessages(block *Block) (messages []*ethstate.Message, err error) {
	if !sm.bc.HasBlock(block.PrevHash) {
		return nil, ParentError(block.PrevHash)
	}

	sm.lastAttemptedBlock = block

	var (
		parent = sm.bc.GetBlock(block.PrevHash)
		state  = parent.State().Copy()
	)

	defer state.Reset()

	if ethutil.Config.Diff && ethutil.Config.DiffType == "all" {
		fmt.Printf("## %x %x ##\n", block.Hash(), block.Number)
	}

	receipts, err := sm.ApplyDiff(state, parent, block)
	if err != nil {
		return nil, err
	}

	txSha := CreateTxSha(receipts)
	if bytes.Compare(txSha, block.TxSha) != 0 {
		return nil, fmt.Errorf("Error validating tx sha. Received %x, got %x", block.TxSha, txSha)
	}

	// Block validation
	if err = sm.ValidateBlock(block); err != nil {
		statelogger.Errorln("Error validating block:", err)
		return nil, err
	}

	// I'm not sure, but I don't know if there should be thrown
	// any errors at this time.
	if err = sm.AccumelateRewards(state, block); err != nil {
		statelogger.Errorln("Error accumulating reward", err)
		return nil, err
	}

	if !block.State().Cmp(state) {
		err = fmt.Errorf("Invalid merkle root.\nrec: %x\nis:  %x", block.State().Trie.Root, state.Trie.Root)
		return nil, err
	}

	return state.Manifest().Messages, nil
}
<commit_msg>Removed validation check from GetMessages<commit_after>package ethchain

import (
	"bytes"
	"container/list"
	"fmt"
	"math/big"
	"sync"
	"time"

	"github.com/ethereum/eth-go/ethcrypto"
	"github.com/ethereum/eth-go/ethlog"
	"github.com/ethereum/eth-go/ethreact"
	"github.com/ethereum/eth-go/ethstate"
	"github.com/ethereum/eth-go/ethutil"
	"github.com/ethereum/eth-go/ethwire"
)

var statelogger = ethlog.NewLogger("STATE")

type BlockProcessor interface {
	ProcessBlock(block *Block)
}

type Peer interface {
	Inbound() bool
	LastSend() time.Time
	LastPong() int64
	Host() []byte
	Port() uint16
	Version() string
	PingTime() string
	Connected() *int32
}

type EthManager interface {
	StateManager() *StateManager
	BlockChain() *BlockChain
	TxPool() *TxPool
	Broadcast(msgType ethwire.MsgType, data []interface{})
	Reactor() *ethreact.ReactorEngine
	PeerCount() int
	IsMining() bool
	IsListening() bool
	Peers() *list.List
	KeyManager() *ethcrypto.KeyManager
	ClientIdentity() ethwire.ClientIdentity
	Db() ethutil.Database
}

type StateManager struct {
	// Mutex for locking the block processor. Blocks can only be handled one at a time
	mutex sync.Mutex
	// Canonical block chain
	bc *BlockChain
	// non-persistent key/value memory storage
	mem map[string]*big.Int
	// Proof of work used for validating
	Pow PoW
	// The ethereum manager interface
	Ethereum EthManager
	// The managed states
	// Transiently state. The trans state isn't ever saved, validated and
	// it could be used for setting account nonces without effecting
	// the main states.
	transState *ethstate.State
	// Mining state. The mining state is used purely and solely by the mining
	// operation.
	miningState *ethstate.State

	// The last attempted block is mainly used for debugging purposes
	// This does not have to be a valid block and will be set during
	// 'Process' & canonical validation.
	lastAttemptedBlock *Block
}

func NewStateManager(ethereum EthManager) *StateManager {
	sm := &StateManager{
		mem:      make(map[string]*big.Int),
		Pow:      &EasyPow{},
		Ethereum: ethereum,
		bc:       ethereum.BlockChain(),
	}
	sm.transState = ethereum.BlockChain().CurrentBlock.State().Copy()
	sm.miningState = ethereum.BlockChain().CurrentBlock.State().Copy()

	return sm
}

func (sm *StateManager) CurrentState() *ethstate.State {
	return sm.Ethereum.BlockChain().CurrentBlock.State()
}

func (sm *StateManager) TransState() *ethstate.State {
	return sm.transState
}

func (sm *StateManager) MiningState() *ethstate.State {
	return sm.miningState
}

func (sm *StateManager) NewMiningState() *ethstate.State {
	sm.miningState = sm.Ethereum.BlockChain().CurrentBlock.State().Copy()

	return sm.miningState
}

func (sm *StateManager) BlockChain() *BlockChain {
	return sm.bc
}

func (self *StateManager) ProcessTransactions(coinbase *ethstate.StateObject, state *ethstate.State, block, parent *Block, txs Transactions) (Receipts, Transactions, Transactions, error) {
	var (
		receipts           Receipts
		handled, unhandled Transactions
		totalUsedGas       = big.NewInt(0)
		err                error
	)

done:
	for i, tx := range txs {
		txGas := new(big.Int).Set(tx.Gas)

		cb := state.GetStateObject(coinbase.Address())
		st := NewStateTransition(cb, tx, state, block)
		err = st.TransitionState()
		if err != nil {
			statelogger.Infoln(err)
			switch {
			case IsNonceErr(err):
				err = nil // ignore error
				continue
			case IsGasLimitErr(err):
				unhandled = txs[i:]

				break done
			default:
				statelogger.Infoln(err)
				err = nil
				//return nil, nil, nil, err
			}
		}

		// Notify all subscribers
		self.Ethereum.Reactor().Post("newTx:post", tx)

		// Update the state with pending changes
		state.Update()

		txGas.Sub(txGas, st.gas)
		accumelative := new(big.Int).Set(totalUsedGas.Add(totalUsedGas, txGas))
		receipt := &Receipt{tx, ethutil.CopyBytes(state.Root().([]byte)), accumelative}

		if i < len(block.Receipts()) {
			original := block.Receipts()[i]
			if !original.Cmp(receipt) {
				return nil, nil, nil, fmt.Errorf("err diff #%d (r) %v ~ %x  <=>  (c) %v ~ %x (%x)\n", i+1, original.CumulativeGasUsed, original.PostState[0:4], receipt.CumulativeGasUsed, receipt.PostState[0:4], receipt.Tx.Hash())
			}
		}

		receipts = append(receipts, receipt)
		handled = append(handled, tx)

		if ethutil.Config.Diff && ethutil.Config.DiffType == "all" {
			state.CreateOutputForDiff()
		}
	}

	parent.GasUsed = totalUsedGas

	return receipts, handled, unhandled, err
}

func (sm *StateManager) Process(block *Block, dontReact bool) (err error) {
	// Processing a blocks may never happen simultaneously
	sm.mutex.Lock()
	defer sm.mutex.Unlock()

	if sm.bc.HasBlock(block.Hash()) {
		return nil
	}

	if !sm.bc.HasBlock(block.PrevHash) {
		return ParentError(block.PrevHash)
	}

	sm.lastAttemptedBlock = block

	var (
		parent = sm.bc.GetBlock(block.PrevHash)
		state  = parent.State()
	)

	// Defer the Undo on the Trie. If the block processing happened
	// we don't want to undo but since undo only happens on dirty
	// nodes this won't happen because Commit would have been called
	// before that.
	defer state.Reset()

	if ethutil.Config.Diff && ethutil.Config.DiffType == "all" {
		fmt.Printf("## %x %x ##\n", block.Hash(), block.Number)
	}

	receipts, err := sm.ApplyDiff(state, parent, block)
	if err != nil {
		return err
	}

	txSha := CreateTxSha(receipts)
	if bytes.Compare(txSha, block.TxSha) != 0 {
		return fmt.Errorf("Error validating tx sha. Received %x, got %x", block.TxSha, txSha)
	}

	// Block validation
	if err = sm.ValidateBlock(block); err != nil {
		statelogger.Errorln("Error validating block:", err)
		return err
	}

	// I'm not sure, but I don't know if there should be thrown
	// any errors at this time.
	if err = sm.AccumelateRewards(state, block); err != nil {
		statelogger.Errorln("Error accumulating reward", err)
		return err
	}

	if !block.State().Cmp(state) {
		err = fmt.Errorf("Invalid merkle root.\nrec: %x\nis:  %x", block.State().Trie.Root, state.Trie.Root)
		return
	}

	// Calculate the new total difficulty and sync back to the db
	if sm.CalculateTD(block) {
		// Sync the current block's state to the database and cancelling out the deferred Undo
		state.Sync()

		// Add the block to the chain
		sm.bc.Add(block)

		// Create a bloom bin for this block
		filter := sm.createBloomFilter(state)
		// Persist the data
		fk := append([]byte("bloom"), block.Hash()...)
		sm.Ethereum.Db().Put(fk, filter.Bin())

		statelogger.Infof("Added block #%d (%x)\n", block.Number, block.Hash())
		if dontReact == false {
			sm.Ethereum.Reactor().Post("newBlock", block)

			state.Manifest().Reset()
		}

		sm.Ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{block.Value().Val})

		sm.Ethereum.TxPool().RemoveInvalid(state)
	} else {
		statelogger.Errorln("total diff failed")
	}

	return nil
}

func (sm *StateManager) ApplyDiff(state *ethstate.State, parent, block *Block) (receipts Receipts, err error) {
	coinbase := state.GetOrNewStateObject(block.Coinbase)
	coinbase.SetGasPool(block.CalcGasLimit(parent))

	// Process the transactions on to current block
	receipts, _, _, err = sm.ProcessTransactions(coinbase, state, block, parent, block.Transactions())
	if err != nil {
		return nil, err
	}

	return receipts, nil
}

func (sm *StateManager) CalculateTD(block *Block) bool {
	uncleDiff := new(big.Int)
	for _, uncle := range block.Uncles {
		uncleDiff = uncleDiff.Add(uncleDiff, uncle.Difficulty)
	}

	// TD(genesis_block) = 0 and TD(B) = TD(B.parent) + sum(u.difficulty for u in B.uncles) + B.difficulty
	td := new(big.Int)
	td = td.Add(sm.bc.TD, uncleDiff)
	td = td.Add(td, block.Difficulty)

	// The new TD will only be accepted if the new difficulty is
	// is greater than the previous.
	if td.Cmp(sm.bc.TD) > 0 {
		// Set the new total difficulty back to the block chain
		sm.bc.SetTotalDifficulty(td)

		return true
	}

	return false
}

// Validates the current block. Returns an error if the block was invalid,
// an uncle or anything that isn't on the current block chain.
// Validation validates easy over difficult (dagger takes longer time = difficult)
func (sm *StateManager) ValidateBlock(block *Block) error {
	// TODO
	// 2. Check if the difficulty is correct

	// Check each uncle's previous hash. In order for it to be valid
	// is if it has the same block hash as the current
	previousBlock := sm.bc.GetBlock(block.PrevHash)
	for _, uncle := range block.Uncles {
		if bytes.Compare(uncle.PrevHash, previousBlock.PrevHash) != 0 {
			return ValidationError("Mismatch uncle's previous hash. Expected %x, got %x", previousBlock.PrevHash, uncle.PrevHash)
		}
	}

	diff := block.Time - previousBlock.Time
	if diff < 0 {
		return ValidationError("Block timestamp less then prev block %v (%v - %v)", diff, block.Time, sm.bc.CurrentBlock.Time)
	}

	/* XXX
	// New blocks must be within the 15 minute range of the last block.
	if diff > int64(15*time.Minute) {
		return ValidationError("Block is too far in the future of last block (> 15 minutes)")
	}
	*/

	// Verify the nonce of the block. Return an error if it's not valid
	if !sm.Pow.Verify(block.HashNoNonce(), block.Difficulty, block.Nonce) {
		return ValidationError("Block's nonce is invalid (= %v)", ethutil.Bytes2Hex(block.Nonce))
	}

	return nil
}

func CalculateBlockReward(block *Block, uncleLength int) *big.Int {
	base := new(big.Int)
	for i := 0; i < uncleLength; i++ {
		base.Add(base, UncleInclusionReward)
	}

	return base.Add(base, BlockReward)
}

func CalculateUncleReward(block *Block) *big.Int {
	return UncleReward
}

func (sm *StateManager) AccumelateRewards(state *ethstate.State, block *Block) error {
	// Get the account associated with the coinbase
	account := state.GetAccount(block.Coinbase)
	// Reward amount of ether to the coinbase address
	account.AddAmount(CalculateBlockReward(block, len(block.Uncles)))

	addr := make([]byte, len(block.Coinbase))
	copy(addr, block.Coinbase)
	state.UpdateStateObject(account)

	for _, uncle := range block.Uncles {
		uncleAccount := state.GetAccount(uncle.Coinbase)
		uncleAccount.AddAmount(CalculateUncleReward(uncle))

		state.UpdateStateObject(uncleAccount)
	}

	return nil
}

func (sm *StateManager) Stop() {
	sm.bc.Stop()
}

// Manifest will handle both creating notifications and generating bloom bin data
func (sm *StateManager) createBloomFilter(state *ethstate.State) *BloomFilter {
	bloomf := NewBloomFilter(nil)

	for addr, stateObject := range state.Manifest().ObjectChanges {
		// Set the bloom filter's bin
		bloomf.Set([]byte(addr))

		sm.Ethereum.Reactor().Post("object:"+addr, stateObject)
	}

	for stateObjectAddr, mappedObjects := range state.Manifest().StorageChanges {
		for addr, value := range mappedObjects {
			// Set the bloom filter's bin
			bloomf.Set(ethcrypto.Sha3Bin([]byte(stateObjectAddr + addr)))

			sm.Ethereum.Reactor().Post("storage:"+stateObjectAddr+":"+addr, &ethstate.StorageState{[]byte(stateObjectAddr), []byte(addr), value})
		}
	}

	return bloomf
}

func (sm *StateManager) GetMessages(block *Block) (messages []*ethstate.Message, err error) {
	if !sm.bc.HasBlock(block.PrevHash) {
		return nil, ParentError(block.PrevHash)
	}

	sm.lastAttemptedBlock = block

	var (
		parent = sm.bc.GetBlock(block.PrevHash)
		state  = parent.State().Copy()
	)

	defer state.Reset()

	sm.ApplyDiff(state, parent, block)

	sm.AccumelateRewards(state, block)

	return state.Manifest().Messages, nil
}
<|endoftext|>


<commit_before>package libvirt

import (
	"encoding/xml"
	"fmt"
	libvirt "github.com/dmacvicar/libvirt-go"
	"github.com/hashicorp/terraform/helper/schema"
	"log"
	"time"
)

func resourceLibvirtDomain() *schema.Resource {
	return &schema.Resource{
		Create: resourceLibvirtDomainCreate,
		Read:   resourceLibvirtDomainRead,
		Delete: resourceLibvirtDomainDelete,
		Schema: map[string]*schema.Schema{
			"name": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"vcpu": &schema.Schema{
				Type:     schema.TypeInt,
				Optional: true,
				Default:  1,
				ForceNew: true,
			},
			"memory": &schema.Schema{
				Type:     schema.TypeInt,
				Optional: true,
				Default:  512,
				ForceNew: true,
			},
			"disk": &schema.Schema{
				Type:     schema.TypeList,
				Optional: true,
				Required: false,
				ForceNew: true,
				Elem: &schema.Resource{
					Schema: diskCommonSchema(),
				},
			},
			"network_interface": &schema.Schema{
				Type:     schema.TypeList,
				Optional: true,
				Required: false,
				ForceNew: true,
				Elem: &schema.Resource{
					Schema: networkInterfaceCommonSchema(),
				},
			},
		},
	}
}

func resourceLibvirtDomainCreate(d *schema.ResourceData, meta interface{}) error {
	virConn := meta.(*Client).libvirt
	if virConn == nil {
		return fmt.Errorf("The libvirt connection was nil.")
	}

	disksCount := d.Get("disk.#").(int)
	disks := make([]defDisk, 0, disksCount)
	for i := 0; i < disksCount; i++ {
		prefix := fmt.Sprintf("disk.%d", i)
		disk := newDefDisk()
		disk.Target.Dev = fmt.Sprintf("vd%s", DiskLetterForIndex(i))

		volumeKey := d.Get(prefix + ".volume_id").(string)
		diskVolume, err := virConn.LookupStorageVolByKey(volumeKey)
		if err != nil {
			return fmt.Errorf("Can't retrieve volume %s", volumeKey)
		}
		diskVolumeName, err := diskVolume.GetName()
		if err != nil {
			return fmt.Errorf("Error retrieving volume name: %s", err)
		}
		diskPool, err := diskVolume.LookupPoolByVolume()
		if err != nil {
			return fmt.Errorf("Error retrieving pool for volume: %s", err)
		}
		diskPoolName, err := diskPool.GetName()
		if err != nil {
			return fmt.Errorf("Error retrieving pool name: %s", err)
		}

		disk.Source.Volume = diskVolumeName
		disk.Source.Pool = diskPoolName

		disks = append(disks, disk)
	}

	netIfacesCount := d.Get("network_interface.#").(int)
	netIfaces := make([]defNetworkInterface, 0, netIfacesCount)
	for i := 0; i < netIfacesCount; i++ {
		prefix := fmt.Sprintf("network_interface.%d", i)
		netIface := newDefNetworkInterface()

		if mac, ok := d.GetOk(prefix + ".mac"); ok {
			netIface.Mac.Address = mac.(string)
		}

		if network, ok := d.GetOk(prefix + ".network"); ok {
			netIface.Source.Network = network.(string)
		}
		netIfaces = append(netIfaces, netIface)
	}

	domainDef := newDomainDef()
	if name, ok := d.GetOk("name"); ok {
		domainDef.Name = name.(string)
	}

	domainDef.Memory.Amount = d.Get("memory").(int)
	domainDef.VCpu.Amount = d.Get("vcpu").(int)
	domainDef.Devices.Disks = disks
	domainDef.Devices.NetworkInterfaces = netIfaces

	connectURI, err := virConn.GetURI()
	if err != nil {
		return fmt.Errorf("Error retrieving libvirt connection URI: %s", err)
	}
	log.Printf("[INFO] Creating libvirt domain at %s", connectURI)

	data, err := xml.Marshal(domainDef)
	if err != nil {
		return fmt.Errorf("Error serializing libvirt domain: %s", err)
	}

	domain, err := virConn.DomainCreateXML(string(data), libvirt.VIR_DOMAIN_NONE)
	if err != nil {
		return fmt.Errorf("Error crearing libvirt domain: %s", err)
	}
	defer domain.Free()

	id, err := domain.GetUUIDString()
	if err != nil {
		return fmt.Errorf("Error retrieving libvirt domain id: %s", err)
	}
	d.SetId(id)

	log.Printf("[INFO] Domain ID: %s", d.Id())

	err = waitForDomainUp(domain)
	if err != nil {
		return fmt.Errorf("Error waiting for domain to reach RUNNING state: %s", err)
	}

	err = waitForNetworkAddresses(d, domain)
	if err != nil {
		return err
	}

	return resourceLibvirtDomainRead(d, meta)
}

func resourceLibvirtDomainRead(d *schema.ResourceData, meta interface{}) error {
	virConn := meta.(*Client).libvirt
	if virConn == nil {
		return fmt.Errorf("The libvirt connection was nil.")
	}

	domain, err := virConn.LookupByUUIDString(d.Id())
	if err != nil {
		return fmt.Errorf("Error retrieving libvirt domain: %s", err)
	}
	defer domain.Free()

	xmlDesc, err := domain.GetXMLDesc(0)
	if err != nil {
		return fmt.Errorf("Error retrieving libvirt domain XML description: %s", err)
	}

	domainDef := newDomainDef()
	err = xml.Unmarshal([]byte(xmlDesc), &domainDef)
	if err != nil {
		return fmt.Errorf("Error reading libvirt domain XML description: %s", err)
	}

	d.Set("name", domainDef.Name)
	d.Set("vpu", domainDef.VCpu)
	d.Set("memory", domainDef.Memory)

	disks := make([]map[string]interface{}, 0)
	for _, diskDef := range domainDef.Devices.Disks {
		virPool, err := virConn.LookupStoragePoolByName(diskDef.Source.Pool)
		if err != nil {
			return fmt.Errorf("Error retrieving pool for disk: %s", err)
		}
		defer virPool.Free()

		virVol, err := virPool.LookupStorageVolByName(diskDef.Source.Volume)
		if err != nil {
			return fmt.Errorf("Error retrieving volume for disk: %s", err)
		}
		defer virVol.Free()

		virVolKey, err := virVol.GetKey()
		if err != nil {
			return fmt.Errorf("Error retrieving volume ke for disk: %s", err)
		}

		disk := map[string]interface{}{
			"volume_id": virVolKey,
		}
		disks = append(disks, disk)
	}
	d.Set("disks", disks)

	// look interfaces with addresses
	ifacesWithAddr, err := domain.ListAllInterfaceAddresses(libvirt.VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE)
	if err != nil {
		return fmt.Errorf("Error retrieving interface addresses: %s", err)
	}

	netIfaces := make([]map[string]interface{}, 0)
	for _, networkInterfaceDef := range domainDef.Devices.NetworkInterfaces {

		if networkInterfaceDef.Type != "network" {
			log.Printf("[DEBUG] ignoring interface of type '%s'", networkInterfaceDef.Type)
			continue
		}

		netIface := map[string]interface{}{
			"network": networkInterfaceDef.Source.Network,
			"mac":     networkInterfaceDef.Mac.Address,
		}

		netIfaceAddrs := make([]map[string]interface{}, 0)
		// look for an ip address and try to match it with the mac address
		// not sure if using the target device name is a better idea here
		for _, ifaceWithAddr := range ifacesWithAddr {
			if ifaceWithAddr.Hwaddr == networkInterfaceDef.Mac.Address {
				for _, addr := range ifaceWithAddr.Addrs {
					netIfaceAddr := map[string]interface{}{
						"type": func() string {
							switch addr.Type {
							case libvirt.VIR_IP_ADDR_TYPE_IPV4:
								return "ipv4"
							case libvirt.VIR_IP_ADDR_TYPE_IPV6:
								return "ipv6"
							default:
								return "other"
							}
						}(),
						"address": addr.Addr,
						"prefix":  addr.Prefix,
					}
					netIfaceAddrs = append(netIfaceAddrs, netIfaceAddr)
				}
			}
		}

		log.Printf("[DEBUG] %d addresses for %s\n", len(netIfaceAddrs), networkInterfaceDef.Mac.Address)
		netIface["address"] = netIfaceAddrs
		netIfaces = append(netIfaces, netIface)
	}
	d.Set("network_interface", netIfaces)

	if len(ifacesWithAddr) > 0 {
		d.SetConnInfo(map[string]string{
			"type": "ssh",
			"host": ifacesWithAddr[0].Addrs[0].Addr,
		})
	}
	return nil
}

func resourceLibvirtDomainDelete(d *schema.ResourceData, meta interface{}) error {
	virConn := meta.(*Client).libvirt
	if virConn == nil {
		return fmt.Errorf("The libvirt connection was nil.")
	}

	domain, err := virConn.LookupByUUIDString(d.Id())
	if err != nil {
		return fmt.Errorf("Error retrieving libvirt domain: %s", err)
	}
	defer domain.Free()

	if err := domain.Destroy(); err != nil {
		return fmt.Errorf("Couldn't destroy libvirt domain: %s", err)
	}

	err = waitForDomainDestroyed(virConn, d.Id())
	if err != nil {
		return fmt.Errorf("Error waiting for domain to be destroyed: %s", err)
	}

	return nil
}

// wait for domain to be up and timeout after 5 minutes.
func waitForDomainUp(domain libvirt.VirDomain) error {
	start := time.Now()
	for {
		state, err := domain.GetState()
		if err != nil {
			return err
		}

		running := true
		if state[0] != libvirt.VIR_DOMAIN_RUNNING {
			running = false
		}

		if running {
			return nil
		}
		time.Sleep(1 * time.Second)
		if time.Since(start) > 5*time.Minute {
			return fmt.Errorf("Domain didn't switch to state RUNNING in 5 minutes")
		}
	}
}

// wait for domain to be up and timeout after 5 minutes.
func waitForDomainDestroyed(virConn *libvirt.VirConnection, uuid string) error {
	start := time.Now()
	for {
		log.Printf("Waiting for domain %s to be destroyed", uuid)
		_, err := virConn.LookupByUUIDString(uuid)
		if err.(libvirt.VirError).Code == libvirt.VIR_ERR_NO_DOMAIN {
			return nil
		}

		time.Sleep(1 * time.Second)
		if time.Since(start) > 5*time.Minute {
			return fmt.Errorf("Domain is still there after 5 minutes")
		}
	}
}

func waitForNetworkAddresses(d *schema.ResourceData, domain libvirt.VirDomain) error {
	log.Printf("[DEBUG] waiting for network addresses.\n")
	// wait for network interfaces with 'wait_for_lease' to get an address
	netIfacesCount := d.Get("network_interface.#").(int)
	for i := 0; i < netIfacesCount; i++ {
		prefix := fmt.Sprintf("network_interface.%d", i)

		if wait, ok := d.GetOk(prefix + ".wait_for_lease"); !ok || !wait.(bool) {
			continue
		}

		var mac string
		if v, ok := d.GetOk(prefix + ".mac"); !ok {
			// we can't get the ip without a mac address
			continue
		} else {
			mac = v.(string)
		}
		log.Printf("[DEBUG] waiting for network addresses on %s\n", mac)

		// loop until address appear, with timeout
		start := time.Now()
	waitLoop:
		for {
			ifacesWithAddr, err := domain.ListAllInterfaceAddresses(libvirt.VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE)
			if err != nil {
				return fmt.Errorf("Error retrieving interface addresses: %s", err)
			}

			for _, ifaceWithAddr := range ifacesWithAddr {
				// found
				if mac == ifaceWithAddr.Hwaddr {
					break waitLoop
				}
			}

			time.Sleep(1 * time.Second)
			if time.Since(start) > 5*time.Minute {
				return fmt.Errorf("Timeout waiting for interface addresses")
			}
		}
	}

	return nil
}
<commit_msg>Make clear that we are retrying until the address appears.<commit_after>package libvirt

import (
	"encoding/xml"
	"fmt"
	libvirt "github.com/dmacvicar/libvirt-go"
	"github.com/hashicorp/terraform/helper/schema"
	"log"
	"time"
)

func resourceLibvirtDomain() *schema.Resource {
	return &schema.Resource{
		Create: resourceLibvirtDomainCreate,
		Read:   resourceLibvirtDomainRead,
		Delete: resourceLibvirtDomainDelete,
		Schema: map[string]*schema.Schema{
			"name": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"vcpu": &schema.Schema{
				Type:     schema.TypeInt,
				Optional: true,
				Default:  1,
				ForceNew: true,
			},
			"memory": &schema.Schema{
				Type:     schema.TypeInt,
				Optional: true,
				Default:  512,
				ForceNew: true,
			},
			"disk": &schema.Schema{
				Type:     schema.TypeList,
				Optional: true,
				Required: false,
				ForceNew: true,
				Elem: &schema.Resource{
					Schema: diskCommonSchema(),
				},
			},
			"network_interface": &schema.Schema{
				Type:     schema.TypeList,
				Optional: true,
				Required: false,
				ForceNew: true,
				Elem: &schema.Resource{
					Schema: networkInterfaceCommonSchema(),
				},
			},
		},
	}
}

func resourceLibvirtDomainCreate(d *schema.ResourceData, meta interface{}) error {
	virConn := meta.(*Client).libvirt
	if virConn == nil {
		return fmt.Errorf("The libvirt connection was nil.")
	}

	disksCount := d.Get("disk.#").(int)
	disks := make([]defDisk, 0, disksCount)
	for i := 0; i < disksCount; i++ {
		prefix := fmt.Sprintf("disk.%d", i)
		disk := newDefDisk()
		disk.Target.Dev = fmt.Sprintf("vd%s", DiskLetterForIndex(i))

		volumeKey := d.Get(prefix + ".volume_id").(string)
		diskVolume, err := virConn.LookupStorageVolByKey(volumeKey)
		if err != nil {
			return fmt.Errorf("Can't retrieve volume %s", volumeKey)
		}
		diskVolumeName, err := diskVolume.GetName()
		if err != nil {
			return fmt.Errorf("Error retrieving volume name: %s", err)
		}
		diskPool, err := diskVolume.LookupPoolByVolume()
		if err != nil {
			return fmt.Errorf("Error retrieving pool for volume: %s", err)
		}
		diskPoolName, err := diskPool.GetName()
		if err != nil {
			return fmt.Errorf("Error retrieving pool name: %s", err)
		}

		disk.Source.Volume = diskVolumeName
		disk.Source.Pool = diskPoolName

		disks = append(disks, disk)
	}

	netIfacesCount := d.Get("network_interface.#").(int)
	netIfaces := make([]defNetworkInterface, 0, netIfacesCount)
	for i := 0; i < netIfacesCount; i++ {
		prefix := fmt.Sprintf("network_interface.%d", i)
		netIface := newDefNetworkInterface()

		if mac, ok := d.GetOk(prefix + ".mac"); ok {
			netIface.Mac.Address = mac.(string)
		}

		if network, ok := d.GetOk(prefix + ".network"); ok {
			netIface.Source.Network = network.(string)
		}
		netIfaces = append(netIfaces, netIface)
	}

	domainDef := newDomainDef()
	if name, ok := d.GetOk("name"); ok {
		domainDef.Name = name.(string)
	}

	domainDef.Memory.Amount = d.Get("memory").(int)
	domainDef.VCpu.Amount = d.Get("vcpu").(int)
	domainDef.Devices.Disks = disks
	domainDef.Devices.NetworkInterfaces = netIfaces

	connectURI, err := virConn.GetURI()
	if err != nil {
		return fmt.Errorf("Error retrieving libvirt connection URI: %s", err)
	}
	log.Printf("[INFO] Creating libvirt domain at %s", connectURI)

	data, err := xml.Marshal(domainDef)
	if err != nil {
		return fmt.Errorf("Error serializing libvirt domain: %s", err)
	}

	domain, err := virConn.DomainCreateXML(string(data), libvirt.VIR_DOMAIN_NONE)
	if err != nil {
		return fmt.Errorf("Error crearing libvirt domain: %s", err)
	}
	defer domain.Free()

	id, err := domain.GetUUIDString()
	if err != nil {
		return fmt.Errorf("Error retrieving libvirt domain id: %s", err)
	}
	d.SetId(id)

	log.Printf("[INFO] Domain ID: %s", d.Id())

	err = waitForDomainUp(domain)
	if err != nil {
		return fmt.Errorf("Error waiting for domain to reach RUNNING state: %s", err)
	}

	err = waitForNetworkAddresses(d, domain)
	if err != nil {
		return err
	}

	return resourceLibvirtDomainRead(d, meta)
}

func resourceLibvirtDomainRead(d *schema.ResourceData, meta interface{}) error {
	virConn := meta.(*Client).libvirt
	if virConn == nil {
		return fmt.Errorf("The libvirt connection was nil.")
	}

	domain, err := virConn.LookupByUUIDString(d.Id())
	if err != nil {
		return fmt.Errorf("Error retrieving libvirt domain: %s", err)
	}
	defer domain.Free()

	xmlDesc, err := domain.GetXMLDesc(0)
	if err != nil {
		return fmt.Errorf("Error retrieving libvirt domain XML description: %s", err)
	}

	domainDef := newDomainDef()
	err = xml.Unmarshal([]byte(xmlDesc), &domainDef)
	if err != nil {
		return fmt.Errorf("Error reading libvirt domain XML description: %s", err)
	}

	d.Set("name", domainDef.Name)
	d.Set("vpu", domainDef.VCpu)
	d.Set("memory", domainDef.Memory)

	disks := make([]map[string]interface{}, 0)
	for _, diskDef := range domainDef.Devices.Disks {
		virPool, err := virConn.LookupStoragePoolByName(diskDef.Source.Pool)
		if err != nil {
			return fmt.Errorf("Error retrieving pool for disk: %s", err)
		}
		defer virPool.Free()

		virVol, err := virPool.LookupStorageVolByName(diskDef.Source.Volume)
		if err != nil {
			return fmt.Errorf("Error retrieving volume for disk: %s", err)
		}
		defer virVol.Free()

		virVolKey, err := virVol.GetKey()
		if err != nil {
			return fmt.Errorf("Error retrieving volume ke for disk: %s", err)
		}

		disk := map[string]interface{}{
			"volume_id": virVolKey,
		}
		disks = append(disks, disk)
	}
	d.Set("disks", disks)

	// look interfaces with addresses
	ifacesWithAddr, err := domain.ListAllInterfaceAddresses(libvirt.VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE)
	if err != nil {
		return fmt.Errorf("Error retrieving interface addresses: %s", err)
	}

	netIfaces := make([]map[string]interface{}, 0)
	for _, networkInterfaceDef := range domainDef.Devices.NetworkInterfaces {

		if networkInterfaceDef.Type != "network" {
			log.Printf("[DEBUG] ignoring interface of type '%s'", networkInterfaceDef.Type)
			continue
		}

		netIface := map[string]interface{}{
			"network": networkInterfaceDef.Source.Network,
			"mac":     networkInterfaceDef.Mac.Address,
		}

		netIfaceAddrs := make([]map[string]interface{}, 0)
		// look for an ip address and try to match it with the mac address
		// not sure if using the target device name is a better idea here
		for _, ifaceWithAddr := range ifacesWithAddr {
			if ifaceWithAddr.Hwaddr == networkInterfaceDef.Mac.Address {
				for _, addr := range ifaceWithAddr.Addrs {
					netIfaceAddr := map[string]interface{}{
						"type": func() string {
							switch addr.Type {
							case libvirt.VIR_IP_ADDR_TYPE_IPV4:
								return "ipv4"
							case libvirt.VIR_IP_ADDR_TYPE_IPV6:
								return "ipv6"
							default:
								return "other"
							}
						}(),
						"address": addr.Addr,
						"prefix":  addr.Prefix,
					}
					netIfaceAddrs = append(netIfaceAddrs, netIfaceAddr)
				}
			}
		}

		log.Printf("[DEBUG] %d addresses for %s\n", len(netIfaceAddrs), networkInterfaceDef.Mac.Address)
		netIface["address"] = netIfaceAddrs
		netIfaces = append(netIfaces, netIface)
	}
	d.Set("network_interface", netIfaces)

	if len(ifacesWithAddr) > 0 {
		d.SetConnInfo(map[string]string{
			"type": "ssh",
			"host": ifacesWithAddr[0].Addrs[0].Addr,
		})
	}
	return nil
}

func resourceLibvirtDomainDelete(d *schema.ResourceData, meta interface{}) error {
	virConn := meta.(*Client).libvirt
	if virConn == nil {
		return fmt.Errorf("The libvirt connection was nil.")
	}

	domain, err := virConn.LookupByUUIDString(d.Id())
	if err != nil {
		return fmt.Errorf("Error retrieving libvirt domain: %s", err)
	}
	defer domain.Free()

	if err := domain.Destroy(); err != nil {
		return fmt.Errorf("Couldn't destroy libvirt domain: %s", err)
	}

	err = waitForDomainDestroyed(virConn, d.Id())
	if err != nil {
		return fmt.Errorf("Error waiting for domain to be destroyed: %s", err)
	}

	return nil
}

// wait for domain to be up and timeout after 5 minutes.
func waitForDomainUp(domain libvirt.VirDomain) error {
	start := time.Now()
	for {
		state, err := domain.GetState()
		if err != nil {
			return err
		}

		running := true
		if state[0] != libvirt.VIR_DOMAIN_RUNNING {
			running = false
		}

		if running {
			return nil
		}
		time.Sleep(1 * time.Second)
		if time.Since(start) > 5*time.Minute {
			return fmt.Errorf("Domain didn't switch to state RUNNING in 5 minutes")
		}
	}
}

// wait for domain to be up and timeout after 5 minutes.
func waitForDomainDestroyed(virConn *libvirt.VirConnection, uuid string) error {
	start := time.Now()
	for {
		log.Printf("Waiting for domain %s to be destroyed", uuid)
		_, err := virConn.LookupByUUIDString(uuid)
		if err.(libvirt.VirError).Code == libvirt.VIR_ERR_NO_DOMAIN {
			return nil
		}

		time.Sleep(1 * time.Second)
		if time.Since(start) > 5*time.Minute {
			return fmt.Errorf("Domain is still there after 5 minutes")
		}
	}
}

func waitForNetworkAddresses(d *schema.ResourceData, domain libvirt.VirDomain) error {
	log.Printf("[DEBUG] waiting for network addresses.\n")
	// wait for network interfaces with 'wait_for_lease' to get an address
	netIfacesCount := d.Get("network_interface.#").(int)
	for i := 0; i < netIfacesCount; i++ {
		prefix := fmt.Sprintf("network_interface.%d", i)

		if wait, ok := d.GetOk(prefix + ".wait_for_lease"); !ok || !wait.(bool) {
			continue
		}

		var mac string
		if v, ok := d.GetOk(prefix + ".mac"); !ok {
			// we can't get the ip without a mac address
			continue
		} else {
			mac = v.(string)
		}

		// loop until address appear, with timeout
		start := time.Now()
	waitLoop:
		for {
			log.Printf("[DEBUG] waiting for network address for interface with hwaddr: '%s'\n", mac)
			ifacesWithAddr, err := domain.ListAllInterfaceAddresses(libvirt.VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE)
			if err != nil {
				return fmt.Errorf("Error retrieving interface addresses: %s", err)
			}

			for _, ifaceWithAddr := range ifacesWithAddr {
				// found
				if mac == ifaceWithAddr.Hwaddr {
					break waitLoop
				}
			}

			time.Sleep(1 * time.Second)
			if time.Since(start) > 5*time.Minute {
				return fmt.Errorf("Timeout waiting for interface addresses")
			}
		}
	}

	return nil
}
<|endoftext|>


<commit_before>// Quick and dirty uploader and serial terminal for LPC8xx chips.
// -jcw, 2015-02-02

package main

import (
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/chimera/rs232"
	"github.com/jeelabs/embello/tools/uploader/serflash"
	"golang.org/x/crypto/ssh/terminal"
)

var (
	offsetFlag = flag.Int("o", 0, "upload offset (must be multiple of 1024)")
	serialFlag = flag.Bool("s", false, "launch as serial terminal after upload")
	waitFlag   = flag.Bool("w", false, "wait for connection to the boot loader")
	idleFlag   = flag.Int("i", 0, "exit terminal after N idle seconds (0: off)")
	telnetFlag = flag.Bool("t", false, "use telnet protocol for RTS & DTR")
	debugFlag  = flag.Bool("d", false, "verbose debugging output")
)

func main() {
	log.SetFlags(0) // no timestamps

	flag.Usage = func() {
		fmt.Fprintln(os.Stderr, "Usage: lpc8xx ?options? tty ?binfile?")
		flag.PrintDefaults()
	}

	flag.Parse()

	if flag.NArg() < 1 {
		flag.Usage()
		os.Exit(2)
	}

	ttyName := flag.Arg(0)
	binFile := ""
	if flag.NArg() > 1 {
		binFile = flag.Arg(1)
	}

	conn := connect(ttyName)

	id, info, hwuid := conn.Identify()
	fmt.Printf("found: %X - %s\n", id, info)
	fmt.Printf("hwuid: %X\n", hwuid)

	if binFile != "" {
		data, err := ioutil.ReadFile(binFile)
		Check(err)

		fmt.Print("flash: 0000 ")
		for n := range conn.Program(*offsetFlag, data) {
			fmt.Printf("\b\b\b\b\b%04X ", n)
			if *debugFlag {
				fmt.Println()
			}
		}
		fmt.Println("done,", len(data), "bytes")
	}

	conn.SetDTR(true) // pulse DTR to reset
	conn.SetDTR(false)

	if *serialFlag {
		*debugFlag = false
		fmt.Println("entering terminal mode, press <ESC> to quit:\n")
		terminalMode(conn)
		fmt.Println()
	}
}

func connect(port string) *serflash.Conn {
	var dev io.ReadWriter

	if _, err := os.Stat(port); os.IsNotExist(err) {
		// if nonexistent, it's an ip address + port and open as network port
		dev, err = net.Dial("tcp", port)
		Check(err)
		// RTS and DTR will be ignored unless telnet is specified
	} else {
		// else assume the tty is an existing device, open as rs232 port
		opt := rs232.Options{BitRate: 115200, DataBits: 8, StopBits: 1}
		dev, err = rs232.Open(port, opt)
		Check(err)
	}

	if *telnetFlag {
		dev = serflash.UseTelnet(dev)
	}

	return serflash.New(dev, *debugFlag, *waitFlag)
}

func terminalMode(c *serflash.Conn) {
	timeout := time.Duration(*idleFlag) * time.Second
	idleTimer := time.NewTimer(timeout)

	// FIXME still in line mode, so only complete lines will be shown
	go func() {
		for line := range c.Lines {
			idleTimer.Reset(timeout)
			fmt.Println(line)
		}
	}()

	// put stdin in raw mode
	oldState, err := terminal.MakeRaw(0)
	Check(err)
	defer terminal.Restore(0, oldState)

	// cleanup when program is terminated via a signal
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, os.Interrupt, syscall.SIGHUP, syscall.SIGTERM)
	go func() {
		sigMsg := <-sigChan
		terminal.Restore(0, oldState)
		log.Fatal(sigMsg)
	}()

	// cleanup when idle timer fires, and exit cleanly
	if *idleFlag > 0 {
		go func() {
			<-idleTimer.C
			terminal.Restore(0, oldState)
			fmt.Println("\nidle timeout")
			os.Exit(0)
		}()
	}

	// copy key presses to the serial port
	for {
		var b [1]byte
		n, _ := os.Stdin.Read(b[:])
		idleTimer.Reset(timeout)
		if n < 1 || b[0] == 0x1B { // ESC
			break
		}
		c.Write(b[:n])
	}

}

func Check(e error) {
	if e != nil {
		log.Fatal(e)
	}
}
<commit_msg>update name<commit_after>// Quick and dirty uploader and serial terminal for LPC8xx chips.
// -jcw, 2015-02-02

package main

import (
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/chimera/rs232"
	"github.com/jeelabs/embello/tools/uploader/serflash"
	"golang.org/x/crypto/ssh/terminal"
)

var (
	offsetFlag = flag.Int("o", 0, "upload offset (must be multiple of 1024)")
	serialFlag = flag.Bool("s", false, "launch as serial terminal after upload")
	waitFlag   = flag.Bool("w", false, "wait for connection to the boot loader")
	idleFlag   = flag.Int("i", 0, "exit terminal after N idle seconds (0: off)")
	telnetFlag = flag.Bool("t", false, "use telnet protocol for RTS & DTR")
	debugFlag  = flag.Bool("d", false, "verbose debugging output")
)

func main() {
	log.SetFlags(0) // no timestamps

	flag.Usage = func() {
		fmt.Fprintln(os.Stderr, "Usage: uploader ?options? tty ?binfile?")
		flag.PrintDefaults()
	}

	flag.Parse()

	if flag.NArg() < 1 {
		flag.Usage()
		os.Exit(2)
	}

	ttyName := flag.Arg(0)
	binFile := ""
	if flag.NArg() > 1 {
		binFile = flag.Arg(1)
	}

	conn := connect(ttyName)

	id, info, hwuid := conn.Identify()
	fmt.Printf("found: %X - %s\n", id, info)
	fmt.Printf("hwuid: %X\n", hwuid)

	if binFile != "" {
		data, err := ioutil.ReadFile(binFile)
		Check(err)

		fmt.Print("flash: 0000 ")
		for n := range conn.Program(*offsetFlag, data) {
			fmt.Printf("\b\b\b\b\b%04X ", n)
			if *debugFlag {
				fmt.Println()
			}
		}
		fmt.Println("done,", len(data), "bytes")
	}

	conn.SetDTR(true) // pulse DTR to reset
	conn.SetDTR(false)

	if *serialFlag {
		*debugFlag = false
		fmt.Println("entering terminal mode, press <ESC> to quit:\n")
		terminalMode(conn)
		fmt.Println()
	}
}

func connect(port string) *serflash.Conn {
	var dev io.ReadWriter

	if _, err := os.Stat(port); os.IsNotExist(err) {
		// if nonexistent, it's an ip address + port and open as network port
		dev, err = net.Dial("tcp", port)
		Check(err)
		// RTS and DTR will be ignored unless telnet is specified
	} else {
		// else assume the tty is an existing device, open as rs232 port
		opt := rs232.Options{BitRate: 115200, DataBits: 8, StopBits: 1}
		dev, err = rs232.Open(port, opt)
		Check(err)
	}

	if *telnetFlag {
		dev = serflash.UseTelnet(dev)
	}

	return serflash.New(dev, *debugFlag, *waitFlag)
}

func terminalMode(c *serflash.Conn) {
	timeout := time.Duration(*idleFlag) * time.Second
	idleTimer := time.NewTimer(timeout)

	// FIXME still in line mode, so only complete lines will be shown
	go func() {
		for line := range c.Lines {
			idleTimer.Reset(timeout)
			fmt.Println(line)
		}
	}()

	// put stdin in raw mode
	oldState, err := terminal.MakeRaw(0)
	Check(err)
	defer terminal.Restore(0, oldState)

	// cleanup when program is terminated via a signal
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, os.Interrupt, syscall.SIGHUP, syscall.SIGTERM)
	go func() {
		sigMsg := <-sigChan
		terminal.Restore(0, oldState)
		log.Fatal(sigMsg)
	}()

	// cleanup when idle timer fires, and exit cleanly
	if *idleFlag > 0 {
		go func() {
			<-idleTimer.C
			terminal.Restore(0, oldState)
			fmt.Println("\nidle timeout")
			os.Exit(0)
		}()
	}

	// copy key presses to the serial port
	for {
		var b [1]byte
		n, _ := os.Stdin.Read(b[:])
		idleTimer.Reset(timeout)
		if n < 1 || b[0] == 0x1B { // ESC
			break
		}
		c.Write(b[:n])
	}

}

func Check(e error) {
	if e != nil {
		log.Fatal(e)
	}
}
<|endoftext|>


<commit_before>
package main

import (
	"unicode"
	"fmt"
)

type path []rune

func (p path) ToUpper() {
	for i, c := range p {
		p[i] = unicode.ToUpper(c)
	}
}

func main() {
	paths := []path{path("/usr/bin/tso"), path("/home/filipe/gonçalves"),
		path("/집/사용자/test/파일"), path("/こんにちは/世界/パス"),
		path("/ェ/エ/"), path("/home/josé/niño/ßẞeta/läöür/ẞẞ/€€—")}
	for _, s := range paths {
		p := s;
		fmt.Printf("%s\n", string(p))
		p.ToUpper()
		fmt.Printf("%s\n\n", string(p))
	}
}
<commit_msg>Updated ToUpper description<commit_after>/* Exercise taken from http://blog.golang.org/slices
 *
 * type path []byte
 *
 * func (p path) ToUpper() {
 *     for i, b := range p {
 *         if 'a' <= b && b <= 'z' {
 *             p[i] = b + 'A' - 'a'
 *         }
 *     }
 * }
 *
 * func main() {
 *     pathName := path("/usr/bin/tso")
 *     pathName.ToUpper()
 *     fmt.Printf("%s\n", pathName)
 * }
 *
 * Advanced exercise: Convert the ToUpper method to handle Unicode letters, not just ASCII.
 *
 */

package main

import (
	"unicode"
	"fmt"
)

type path []rune

func (p path) ToUpper() {
	for i, c := range p {
		p[i] = unicode.ToUpper(c)
	}
}

func main() {
	paths := []path{path("/usr/bin/tso"), path("/home/filipe/gonçalves"),
		path("/집/사용자/test/파일"), path("/こんにちは/世界/パス"),
		path("/ェ/エ/"), path("/home/josé/niño/ßẞeta/läöür/ẞẞ/€€—")}
	for _, s := range paths {
		p := s;
		fmt.Printf("%s\n", string(p))
		p.ToUpper()
		fmt.Printf("%s\n\n", string(p))
	}
}
<|endoftext|>


<commit_before>package sia

import (
	"errors"
	"fmt"
	"testing"
)

type testingEnvironment struct {
	wallets []*Wallet
	state   *State
}

// Creates a wallet and a state to use for testing.
func createEnvironment() (testEnv *testingEnvironment, err error) {
	testEnv = new(testingEnvironment)

	firstWallet, err := CreateWallet()
	if err != nil {
		return
	}
	testEnv.wallets = append(testEnv.wallets, firstWallet)

	testEnv.state = CreateGenesisState(testEnv.wallets[0].CoinAddress)

	if len(testEnv.state.ConsensusState.UnspentOutputs) != 1 {
		err = fmt.Errorf("Genesis state should have a single upspent output, has", len(testEnv.state.ConsensusState.UnspentOutputs))
		return
	}

	return
}

// Creates an empty block and applies it to the state.
func addEmptyBlock(testEnv *testingEnvironment) (err error) {
	// Make sure that the block will actually be empty.
	if len(testEnv.state.ConsensusState.TransactionList) != 0 {
		err = errors.New("cannot add an empty block without an empty transaction pool.")
		return
	}

	// Generate a valid empty block using GenerateBlock.
	emptyBlock := testEnv.state.GenerateBlock(testEnv.wallets[0].CoinAddress)
	if len(emptyBlock.Transactions) != 0 {
		err = errors.New("failed to make an empty block...")
		return
	}

	expectedOutputs := len(testEnv.state.ConsensusState.UnspentOutputs) + 1
	err = testEnv.state.AcceptBlock(*emptyBlock)
	if err != nil {
		return
	}
	if len(testEnv.state.ConsensusState.UnspentOutputs) != expectedOutputs {
		err = fmt.Errorf("Expecting", expectedOutputs, "outputs, got", len(testEnv.state.ConsensusState.UnspentOutputs), "outputs")
		return
	}

	return
}

// transactionPoolTests adds a few wallets to the test environment, creating
// transactions that fund each and probes the overall efficiency of the
// transaction pool structures.
func transactionPoolTests(testEnv *testingEnvironment) (err error) {
	// The current wallet design means that it will double spend on
	// sequential transactions - meaning that if you make two transactions
	// in the same block, the wallet will use the same input for each.
	// We'll fix this sooner rather than later, but for now the problem has
	// been left so we can focus on other things.
	// Record the size of the transaction pool and the transaction list.

	// One thing we can do to increase the modularity of this function is
	// create a block at the beginning, and use the coinbase to create a
	// bunch of new wallets. This would also clear out the transaction pool
	// right at the beginning of the function.

	txnPoolLen := len(testEnv.state.ConsensusState.TransactionPool)
	txnListLen := len(testEnv.state.ConsensusState.TransactionList)

	// Create a new wallet for the test environment.
	wallet, err := CreateWallet()
	if err != nil {
		return
	}
	testEnv.wallets = append(testEnv.wallets, wallet)

	// Create a transaction to send to that wallet.
	transaction, err := testEnv.wallets[0].SpendCoins(Currency(3), testEnv.wallets[len(testEnv.wallets)-1].CoinAddress, testEnv.state)
	if err != nil {
		return
	}
	err = testEnv.state.AcceptTransaction(transaction)
	if err != nil {
		return
	}

	// Attempt to create a conflicting transaction and see if it is rejected from the pool.
	transaction.Outputs[0].SpendHash[0] = ^transaction.Outputs[0].SpendHash[0] // Change the output address
	transactionSigHash := transaction.SigHash(0)
	transaction.Signatures[0].Signature, err = SignBytes(transactionSigHash[:], testEnv.wallets[0].SecretKey) // Re-sign
	if err != nil {
		return
	}
	err = testEnv.state.AcceptTransaction(transaction)
	if err == nil {
		err = errors.New("Added a conflicting transaction to the transaction pool without error.")
		return
	}
	err = nil

	// The length of the transaction list should have grown by 1, and the
	// transaction pool should have grown by the number of outputs.
	if len(testEnv.state.ConsensusState.TransactionPool) != txnPoolLen+len(transaction.Inputs) {
		err = fmt.Errorf(
			"transaction pool did not grow by expected length. Started at %v and ended at %v but should have grown by %v",
			txnPoolLen,
			len(testEnv.state.ConsensusState.TransactionPool),
			len(transaction.Inputs),
		)
		return
	}
	if len(testEnv.state.ConsensusState.TransactionList) != txnListLen+1 {
		err = errors.New("transaction list did not grow by the expected length.")
		return
	}

	// Put a block through, which should clear the transaction pool
	// completely. Give the subsidy to the old wallet to replenish for
	// funding new wallets.
	transactionBlock := testEnv.state.GenerateBlock(testEnv.wallets[0].CoinAddress)
	if len(transactionBlock.Transactions) == 0 {
		err = errors.New("block created without accepting the transactions in the pool.")
		return
	}
	err = testEnv.state.AcceptBlock(*transactionBlock)
	if err != nil {
		return
	}

	// Check that the transaction pool has been cleared out.
	if len(testEnv.state.ConsensusState.TransactionPool) != 0 {
		err = errors.New("transaction pool not cleared out after getting a block.")
		return
	}
	if len(testEnv.state.ConsensusState.TransactionList) != 0 {
		err = errors.New("transaction list not cleared out after getting a block.")
		return
	}

	return
}

// For now, this is really just a catch-all test. I'm not really sure how to
// modularize the various components =/
func TestBlockBuilding(t *testing.T) {
	// Initialize the testing evironment.
	testEnv, err := createEnvironment()
	if err != nil {
		t.Fatal(err)
	}

	// Add an empty block to the testing environment.
	err = addEmptyBlock(testEnv)
	if err != nil {
		t.Fatal(err)
	}

	// Create a few new wallets and send coins to each in a block.
	err = transactionPoolTests(testEnv)
	if err != nil {
		t.Fatal(err)
	}

	// Create a third block with transactions.

	// Create a thrid block containing the transaction, add it.

	// Create a block with multiple transactions, but one isn't valid.
	// This will see if the reverse code works correctly.
}
<commit_msg>simple forking test<commit_after>package sia

import (
	"errors"
	"fmt"
	"testing"
)

type testingEnvironment struct {
	wallets []*Wallet
	state   *State
}

// Creates a wallet and a state to use for testing.
func createEnvironment() (testEnv *testingEnvironment, err error) {
	testEnv = new(testingEnvironment)

	firstWallet, err := CreateWallet()
	if err != nil {
		return
	}
	testEnv.wallets = append(testEnv.wallets, firstWallet)

	testEnv.state = CreateGenesisState(testEnv.wallets[0].CoinAddress)

	if len(testEnv.state.ConsensusState.UnspentOutputs) != 1 {
		err = fmt.Errorf("Genesis state should have a single upspent output, has", len(testEnv.state.ConsensusState.UnspentOutputs))
		return
	}

	return
}

// Creates an empty block and applies it to the state.
func addEmptyBlock(testEnv *testingEnvironment) (err error) {
	// Make sure that the block will actually be empty.
	if len(testEnv.state.ConsensusState.TransactionList) != 0 {
		err = errors.New("cannot add an empty block without an empty transaction pool.")
		return
	}

	// Generate a valid empty block using GenerateBlock.
	emptyBlock := testEnv.state.GenerateBlock(testEnv.wallets[0].CoinAddress)
	if len(emptyBlock.Transactions) != 0 {
		err = errors.New("failed to make an empty block...")
		return
	}

	expectedOutputs := len(testEnv.state.ConsensusState.UnspentOutputs) + 1
	err = testEnv.state.AcceptBlock(*emptyBlock)
	if err != nil {
		return
	}
	if len(testEnv.state.ConsensusState.UnspentOutputs) != expectedOutputs {
		err = fmt.Errorf("Expecting", expectedOutputs, "outputs, got", len(testEnv.state.ConsensusState.UnspentOutputs), "outputs")
		return
	}

	return
}

// transactionPoolTests adds a few wallets to the test environment, creating
// transactions that fund each and probes the overall efficiency of the
// transaction pool structures.
func transactionPoolTests(testEnv *testingEnvironment) (err error) {
	// The current wallet design means that it will double spend on
	// sequential transactions - meaning that if you make two transactions
	// in the same block, the wallet will use the same input for each.
	// We'll fix this sooner rather than later, but for now the problem has
	// been left so we can focus on other things.
	// Record the size of the transaction pool and the transaction list.

	// One thing we can do to increase the modularity of this function is
	// create a block at the beginning, and use the coinbase to create a
	// bunch of new wallets. This would also clear out the transaction pool
	// right at the beginning of the function.

	txnPoolLen := len(testEnv.state.ConsensusState.TransactionPool)
	txnListLen := len(testEnv.state.ConsensusState.TransactionList)

	// Create a new wallet for the test environment.
	wallet, err := CreateWallet()
	if err != nil {
		return
	}
	testEnv.wallets = append(testEnv.wallets, wallet)

	// Create a transaction to send to that wallet.
	transaction, err := testEnv.wallets[0].SpendCoins(Currency(3), testEnv.wallets[len(testEnv.wallets)-1].CoinAddress, testEnv.state)
	if err != nil {
		return
	}
	err = testEnv.state.AcceptTransaction(transaction)
	if err != nil {
		return
	}

	// Attempt to create a conflicting transaction and see if it is rejected from the pool.
	transaction.Outputs[0].SpendHash[0] = ^transaction.Outputs[0].SpendHash[0] // Change the output address
	transactionSigHash := transaction.SigHash(0)
	transaction.Signatures[0].Signature, err = SignBytes(transactionSigHash[:], testEnv.wallets[0].SecretKey) // Re-sign
	if err != nil {
		return
	}
	err = testEnv.state.AcceptTransaction(transaction)
	if err == nil {
		err = errors.New("Added a conflicting transaction to the transaction pool without error.")
		return
	}
	err = nil

	// The length of the transaction list should have grown by 1, and the
	// transaction pool should have grown by the number of outputs.
	if len(testEnv.state.ConsensusState.TransactionPool) != txnPoolLen+len(transaction.Inputs) {
		err = fmt.Errorf(
			"transaction pool did not grow by expected length. Started at %v and ended at %v but should have grown by %v",
			txnPoolLen,
			len(testEnv.state.ConsensusState.TransactionPool),
			len(transaction.Inputs),
		)
		return
	}
	if len(testEnv.state.ConsensusState.TransactionList) != txnListLen+1 {
		err = errors.New("transaction list did not grow by the expected length.")
		return
	}

	// Put a block through, which should clear the transaction pool
	// completely. Give the subsidy to the old wallet to replenish for
	// funding new wallets.
	transactionBlock := testEnv.state.GenerateBlock(testEnv.wallets[0].CoinAddress)
	if len(transactionBlock.Transactions) == 0 {
		err = errors.New("block created without accepting the transactions in the pool.")
		return
	}
	err = testEnv.state.AcceptBlock(*transactionBlock)
	if err != nil {
		return
	}

	// Check that the transaction pool has been cleared out.
	if len(testEnv.state.ConsensusState.TransactionPool) != 0 {
		err = errors.New("transaction pool not cleared out after getting a block.")
		return
	}
	if len(testEnv.state.ConsensusState.TransactionList) != 0 {
		err = errors.New("transaction list not cleared out after getting a block.")
		return
	}

	return
}

func blockForkingTests(testEnv *testingEnvironment) (err error) {
	// Fork from the current chain to a different chain, requiring a block
	// rewind.
	{
		// Create two blocks on the same parent.
		fork1a := testEnv.state.GenerateBlock(testEnv.wallets[0].CoinAddress) // A block along 1 fork
		fork2a := testEnv.state.GenerateBlock(testEnv.wallets[1].CoinAddress) // A block along a different fork.
		err = testEnv.state.AcceptBlock(*fork1a)
		if err != nil {
			return
		}

		// Add one block, mine on it to create a 'heaviest chain' and
		// then rewind the block, so that you can move the state along
		// the other chain.
		fork1b := testEnv.state.GenerateBlock(testEnv.wallets[0].CoinAddress) // Fork 1 is now heaviest
		testEnv.state.rewindABlock()                                          // Rewind to parent

		// Make fork2 the chosen fork.
		err = testEnv.state.AcceptBlock(*fork2a)
		if err != nil {
			return
		}
		// Verify that fork2a is the current block.
		if testEnv.state.ConsensusState.CurrentBlock != fork2a.ID() {
			err = errors.New("fork2 not accepted as farthest node.")
			return
		}

		// Add fork1b (rewinding does not remove a block from the
		// state) to the state and see if the forking happens.
		err = testEnv.state.AcceptBlock(*fork1b)
		if err != nil {
			return
		}
		// Verify that fork1b is the current block.
		if testEnv.state.ConsensusState.CurrentBlock != fork1b.ID() {
			err = errors.New("switching to a heavier chain did not appear to work.")
			return
		}
	}

	// Fork from the current chain to a different chain, but be required to
	// double back from validation problems.

	return
}

// For now, this is really just a catch-all test. I'm not really sure how to
// modularize the various components =/
func TestBlockBuilding(t *testing.T) {
	// Initialize the testing evironment.
	testEnv, err := createEnvironment()
	if err != nil {
		t.Fatal(err)
	}

	// Add an empty block to the testing environment.
	err = addEmptyBlock(testEnv)
	if err != nil {
		t.Fatal(err)
	}

	// Create a few new wallets and send coins to each in a block.
	err = transactionPoolTests(testEnv)
	if err != nil {
		t.Fatal(err)
	}

	// Create a test that submits and removes transactions with multiple
	// inputs and outputs.

	// Test rewinding a block.

	err = blockForkingTests(testEnv)
	if err != nil {
		t.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package proxy

import (
	"bytes"
	"io/ioutil"
	"log"

	"github.com/andystanton/proxybastard/util"

	"golang.org/x/crypto/ssh"
)

// ExecuteBoot2DockerSSHCommand executes a bootdocker command
func ExecuteBoot2DockerSSHCommand() {
	sshKeyFile := "~/.ssh/id_boot2docker"

	keyBytes, err := ioutil.ReadFile(util.SanitisePath(sshKeyFile))
	if err != nil {
		log.Fatal(err)
	}
	signer, err := ssh.ParsePrivateKey(keyBytes)
	if err != nil {
		log.Fatal(err)
	}

	config := &ssh.ClientConfig{
		User: "docker",
		Auth: []ssh.AuthMethod{
			ssh.PublicKeys(signer),
		},
	}

	conn, err := ssh.Dial("tcp", "192.168.59.103:22", config)
	if err != nil {
		log.Fatalf("unable to connect: %s", err)
	}
	session, err := conn.NewSession()
	if err != nil {
		log.Fatalf("session failed:%v", err)
	}
	defer session.Close()

	var stdoutBuf bytes.Buffer
	session.Stdout = &stdoutBuf
	err = session.Run("whoami")
	if err != nil {
		log.Fatalf("Run failed:%v", err)
	}
	log.Printf("%s", stdoutBuf.String())
}
<commit_msg>Boot2docker progress<commit_after>package proxy

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"log"

	"github.com/andystanton/proxybastard/util"

	"golang.org/x/crypto/ssh"
)

// ExecuteBoot2DockerSSHCommand executes a bootdocker command
func ExecuteBoot2DockerSSHCommand() {

	checkBoot2Docker()
}

func rebootBoot2docker() {
	doSSHCommand("sudo reboot now")
}

func checkBoot2Docker() {
	boot2dockerProfile := "/var/lib/boot2docker/profile"
	log.Println(doSSHCommand(fmt.Sprintf("cat %s", boot2dockerProfile)))
}

func addToBoot2Docker(proxyHost string, proxyPort string) {
	boot2dockerProfile := "/var/lib/boot2docker/profile"

	addScript := `
b2d_profile=%s
b2d_proxy=%s
if [ ! -f "${b2d_profile}" ]; then
	touch "${b2d_profile}"
fi
sudo sh -c "echo -e \"export http_proxy=${b2d_proxy}\" >>${b2d_profile}"
sudo sh -c "echo -e \"export https_proxy=${b2d_proxy}\" >>${b2d_profile}"
`

	doSSHCommand(fmt.Sprintf(addScript, boot2dockerProfile, fmt.Sprintf("%s:%s", proxyHost, proxyPort)))
}

func removeFromBoot2Docker() {
	boot2dockerProfile := "/var/lib/boot2docker/profile"

	removeScript := `
b2d_profile=%s
if [ -f "${b2d_profile}" ]; then
	sudo sed -i '/http\(s\)\{0,1\}_proxy=/d' ${b2d_profile}
fi
`

	doSSHCommand(fmt.Sprintf(removeScript, boot2dockerProfile))
}

func doSSHCommand(command string) string {
	sshKeyFile := "~/.ssh/id_boot2docker"
	boot2dockerIP := "192.168.59.103"
	boot2dockerSSHPort := 22

	keyBytes, err := ioutil.ReadFile(util.SanitisePath(sshKeyFile))
	if err != nil {
		log.Fatal(err)
	}
	signer, err := ssh.ParsePrivateKey(keyBytes)
	if err != nil {
		log.Fatal(err)
	}

	config := &ssh.ClientConfig{
		User: "docker",
		Auth: []ssh.AuthMethod{
			ssh.PublicKeys(signer),
		},
	}

	conn, err := ssh.Dial("tcp", fmt.Sprintf("%s:%d", boot2dockerIP, boot2dockerSSHPort), config)
	if err != nil {
		log.Fatalf("unable to connect: %s", err)
	}

	session, err := conn.NewSession()
	if err != nil {
		log.Fatalf("session failed:%v", err)
	}
	defer session.Close()

	var stdoutBuf bytes.Buffer
	session.Stdout = &stdoutBuf
	err = session.Run(command)
	if err != nil {
		log.Fatalf("Run failed:%v", err)
	}
	return stdoutBuf.String()
}
<|endoftext|>


<commit_before>package transaction

import (
	"database/sql"
	"errors"
	"github.com/DataDrake/ApacheLog2DB/agent"
	"github.com/DataDrake/ApacheLog2DB/destination"
	"github.com/DataDrake/ApacheLog2DB/global"
	"github.com/DataDrake/ApacheLog2DB/source"
	"github.com/DataDrake/ApacheLog2DB/user"
	"time"
)

type Transaction struct {
	ID       int
	Ident    string
	Verb     string
	Protocol string
	Status   int
	Size     int
	Referrer string
	Occurred time.Time
	Source   *source.Source
	Dest     *destination.Destination
	Agent    *agent.UserAgent
	User     *user.User
}

var CREATE_TABLE = map[string]string{
	"mysql": `CREATE TABLE txns ( id INTEGER AUTO_INCREMENT,
	ident TEXT, verb TEXT, protocol TEXT, status INTEGER,
	size INTEGER, referrer TEXT, occured DATETIME, sourceid INTEGER,
	destid INTEGER, agentid INTEGER, userid INTEGER,
	PRIMARY KEY (id), FOREIGN KEY(sourceid) REFERENCES sources(id),
	FOREIGN KEY(destid) REFERENCES destinations(id),
	FOREIGN KEY(agentid) REFERENCES user_agents(id),
	FOREIGN KEY(userid) REFERENCES users(id) )`,

	"sqlite": `CREATE TABLE txns ( id INTEGER PRIMARY KEY AUTOINCREMENT,
	ident TEXT, verb TEXT, protocol TEXT, status INTEGER,
	size INTEGER, referrer TEXT, occured DATETIME, sourceid INTEGER,
	destid INTEGER, agentid INTEGER, userid INTEGER,
	FOREIGN KEY(sourceid) REFERENCES sources(id),
	FOREIGN KEY(destid) REFERENCES destinations(id),
	FOREIGN KEY(agentid) REFERENCES user_agents(id),
	FOREIGN KEY(userid) REFERENCES users(id) )`,
}

func CreateTable(d *sql.DB) error {
	_, err := d.Exec(CREATE_TABLE[global.DB_TYPE])
	return err
}

func Insert(d *sql.DB, t *Transaction) error {
	_, err := d.Exec("INSERT INTO txns VALUES( NULL,?,?,?,?,?,?,?,?,?,?,? )",
		t.Ident, t.Verb, t.Protocol, t.Status, t.Size, t.Referrer, t.Occurred,
		t.Source.ID,
		t.Dest.ID,
		t.Agent.ID,
		t.User.ID)
	return err
}

func Read(d *sql.DB, id int) (*Transaction, error) {
	t := &Transaction{}
	var err error
	row := d.QueryRow("SELECT * FROM txns WHERE id=?", id)
	if row != nil {
		err = errors.New("Transaction not found")
	} else {
		var sourceid int
		var destid int
		var agentid int
		var userid int
		err = row.Scan(&t.ID, &t.Ident, &t.Verb, &t.Protocol, &t.Status, &t.Size, &t.Referrer, &t.Occurred, &sourceid, &destid, &agentid, &userid)
		if err == nil {
			t.Source, err = source.Read(d, sourceid)
			if err != nil {
				return nil, err
			}

			t.Dest, err = destination.Read(d, destid)
			if err != nil {
				return nil, err
			}

			t.Agent, err = agent.Read(d, agentid)
			if err != nil {
				return nil, err
			}

			t.User, err = user.Read(d, userid)
			if err != nil {
				return nil, err
			}
		}
	}
	return t, err
}

func ReadAll(db *sql.DB) ([]*Transaction, error) {
	ts := make([]*Transaction, 0)
	rows, err := db.Query("SELECT * FROM txns")
	if err == nil {
		for rows.Next() {
			var sourceid int
			var destid int
			var agentid int
			var userid int
			t := &Transaction{}
			rows.Scan(&t.ID, &t.Ident, &t.Verb, &t.Protocol, &t.Status, &t.Size, &t.Referrer, &t.Occurred, &sourceid, &destid, &agentid, &userid)

			t.Source, err = source.Read(db, sourceid)
			if err != nil {
				return nil, err
			}

			t.Dest, err = destination.Read(db, destid)
			if err != nil {
				return nil, err
			}

			t.Agent, err = agent.Read(db, agentid)
			if err != nil {
				return nil, err
			}

			t.User, err = user.Read(db, userid)
			if err != nil {
				return nil, err
			}

			ts = append(ts, t)
		}
		rows.Close()
	}
	return ts, err
}

func Update(d *sql.DB, t *Transaction) error {
	_, err := d.Exec("UPDATE txns SET ident=?,verb=?,protocol=?,status=?,size=?,referrer=?,occurred=?,sourceid=?,destid=?,agentid=?,userid=? WHERE id=?",
		t.Ident, t.Verb, t.Protocol, t.Status, t.Size, t.Referrer, t.Occurred, t.Source.ID, t.Dest.ID, t.Agent.ID, t.User.ID)
	return err
}

func ReadWork(d *sql.DB, sourceid int, start time.Time, stop time.Time) ([]*Transaction, error) {
	ts := make([]*Transaction, 0)
	var err error
	row, err := d.Query("SELECT * FROM txns WHERE sourceid=? AND occured>=? AND occured<?", sourceid, start)
	if err != nil {
		return ts, err
	}
	for row.Next() {
		var sourceid int
		var destid int
		var agentid int
		var userid int
		t := &Transaction{}
		err = row.Scan(&t.ID, &t.Ident, &t.Verb, &t.Protocol, &t.Status, &t.Size, &t.Referrer, &t.Occurred, &sourceid, &destid, &agentid, &userid)
		if err == nil {
			t.Source, err = source.Read(d, sourceid)
			if err != nil {
				continue
			}

			t.Dest, err = destination.Read(d, destid)
			if err != nil {
				continue
			}

			t.Agent, err = agent.Read(d, agentid)
			if err != nil {
				continue
			}

			t.User, err = user.Read(d, userid)
			if err != nil {
				continue
			}
			ts = append(ts, t)
		}
	}
	return ts, nil
}
<commit_msg>helps to not forget an argument<commit_after>package transaction

import (
	"database/sql"
	"errors"
	"github.com/DataDrake/ApacheLog2DB/agent"
	"github.com/DataDrake/ApacheLog2DB/destination"
	"github.com/DataDrake/ApacheLog2DB/global"
	"github.com/DataDrake/ApacheLog2DB/source"
	"github.com/DataDrake/ApacheLog2DB/user"
	"time"
)

type Transaction struct {
	ID       int
	Ident    string
	Verb     string
	Protocol string
	Status   int
	Size     int
	Referrer string
	Occurred time.Time
	Source   *source.Source
	Dest     *destination.Destination
	Agent    *agent.UserAgent
	User     *user.User
}

var CREATE_TABLE = map[string]string{
	"mysql": `CREATE TABLE txns ( id INTEGER AUTO_INCREMENT,
	ident TEXT, verb TEXT, protocol TEXT, status INTEGER,
	size INTEGER, referrer TEXT, occured DATETIME, sourceid INTEGER,
	destid INTEGER, agentid INTEGER, userid INTEGER,
	PRIMARY KEY (id), FOREIGN KEY(sourceid) REFERENCES sources(id),
	FOREIGN KEY(destid) REFERENCES destinations(id),
	FOREIGN KEY(agentid) REFERENCES user_agents(id),
	FOREIGN KEY(userid) REFERENCES users(id) )`,

	"sqlite": `CREATE TABLE txns ( id INTEGER PRIMARY KEY AUTOINCREMENT,
	ident TEXT, verb TEXT, protocol TEXT, status INTEGER,
	size INTEGER, referrer TEXT, occured DATETIME, sourceid INTEGER,
	destid INTEGER, agentid INTEGER, userid INTEGER,
	FOREIGN KEY(sourceid) REFERENCES sources(id),
	FOREIGN KEY(destid) REFERENCES destinations(id),
	FOREIGN KEY(agentid) REFERENCES user_agents(id),
	FOREIGN KEY(userid) REFERENCES users(id) )`,
}

func CreateTable(d *sql.DB) error {
	_, err := d.Exec(CREATE_TABLE[global.DB_TYPE])
	return err
}

func Insert(d *sql.DB, t *Transaction) error {
	_, err := d.Exec("INSERT INTO txns VALUES( NULL,?,?,?,?,?,?,?,?,?,?,? )",
		t.Ident, t.Verb, t.Protocol, t.Status, t.Size, t.Referrer, t.Occurred,
		t.Source.ID,
		t.Dest.ID,
		t.Agent.ID,
		t.User.ID)
	return err
}

func Read(d *sql.DB, id int) (*Transaction, error) {
	t := &Transaction{}
	var err error
	row := d.QueryRow("SELECT * FROM txns WHERE id=?", id)
	if row != nil {
		err = errors.New("Transaction not found")
	} else {
		var sourceid int
		var destid int
		var agentid int
		var userid int
		err = row.Scan(&t.ID, &t.Ident, &t.Verb, &t.Protocol, &t.Status, &t.Size, &t.Referrer, &t.Occurred, &sourceid, &destid, &agentid, &userid)
		if err == nil {
			t.Source, err = source.Read(d, sourceid)
			if err != nil {
				return nil, err
			}

			t.Dest, err = destination.Read(d, destid)
			if err != nil {
				return nil, err
			}

			t.Agent, err = agent.Read(d, agentid)
			if err != nil {
				return nil, err
			}

			t.User, err = user.Read(d, userid)
			if err != nil {
				return nil, err
			}
		}
	}
	return t, err
}

func ReadAll(db *sql.DB) ([]*Transaction, error) {
	ts := make([]*Transaction, 0)
	rows, err := db.Query("SELECT * FROM txns")
	if err == nil {
		for rows.Next() {
			var sourceid int
			var destid int
			var agentid int
			var userid int
			t := &Transaction{}
			rows.Scan(&t.ID, &t.Ident, &t.Verb, &t.Protocol, &t.Status, &t.Size, &t.Referrer, &t.Occurred, &sourceid, &destid, &agentid, &userid)

			t.Source, err = source.Read(db, sourceid)
			if err != nil {
				return nil, err
			}

			t.Dest, err = destination.Read(db, destid)
			if err != nil {
				return nil, err
			}

			t.Agent, err = agent.Read(db, agentid)
			if err != nil {
				return nil, err
			}

			t.User, err = user.Read(db, userid)
			if err != nil {
				return nil, err
			}

			ts = append(ts, t)
		}
		rows.Close()
	}
	return ts, err
}

func Update(d *sql.DB, t *Transaction) error {
	_, err := d.Exec("UPDATE txns SET ident=?,verb=?,protocol=?,status=?,size=?,referrer=?,occurred=?,sourceid=?,destid=?,agentid=?,userid=? WHERE id=?",
		t.Ident, t.Verb, t.Protocol, t.Status, t.Size, t.Referrer, t.Occurred, t.Source.ID, t.Dest.ID, t.Agent.ID, t.User.ID)
	return err
}

func ReadWork(d *sql.DB, sourceid int, start time.Time, stop time.Time) ([]*Transaction, error) {
	ts := make([]*Transaction, 0)
	var err error
	row, err := d.Query("SELECT * FROM txns WHERE sourceid=? AND occured>=? AND occured<?", sourceid, start, stop)
	if err != nil {
		return ts, err
	}
	for row.Next() {
		var sourceid int
		var destid int
		var agentid int
		var userid int
		t := &Transaction{}
		err = row.Scan(&t.ID, &t.Ident, &t.Verb, &t.Protocol, &t.Status, &t.Size, &t.Referrer, &t.Occurred, &sourceid, &destid, &agentid, &userid)
		if err == nil {
			t.Source, err = source.Read(d, sourceid)
			if err != nil {
				continue
			}

			t.Dest, err = destination.Read(d, destid)
			if err != nil {
				continue
			}

			t.Agent, err = agent.Read(d, agentid)
			if err != nil {
				continue
			}

			t.User, err = user.Read(d, userid)
			if err != nil {
				continue
			}
			ts = append(ts, t)
		}
	}
	return ts, nil
}
<|endoftext|>


<commit_before>package vsolver

import (
	"reflect"
	"testing"
)

// ExternalReach uses an easily separable algorithm, wmToReach(), to turn a
// discovered set of packages and their imports into a proper external reach
// map.
//
// That algorithm is purely symbolic (no filesystem interaction), and thus is
// easy to test. This is that test.
func TestWorkmapToReach(t *testing.T) {
	table := map[string]struct {
		name    string
		workmap map[string]wm
		basedir string
		out     map[string][]string
		err     error
	}{
		"single": {
			workmap: map[string]wm{
				"foo": {
					ex: make(map[string]struct{}),
					in: make(map[string]struct{}),
				},
			},
			out: map[string][]string{
				"foo": {},
			},
		},
		"no external": {
			workmap: map[string]wm{
				"foo": {
					ex: make(map[string]struct{}),
					in: make(map[string]struct{}),
				},
				"foo/bar": {
					ex: make(map[string]struct{}),
					in: make(map[string]struct{}),
				},
			},
			out: map[string][]string{
				"foo":     {},
				"foo/bar": {},
			},
		},
		"no external with subpkg": {
			workmap: map[string]wm{
				"foo": {
					ex: make(map[string]struct{}),
					in: map[string]struct{}{
						"foo/bar": struct{}{},
					},
				},
				"foo/bar": {
					ex: make(map[string]struct{}),
					in: make(map[string]struct{}),
				},
			},
			out: map[string][]string{
				"foo":     {},
				"foo/bar": {},
			},
		},
		"simple base transitive": {
			workmap: map[string]wm{
				"foo": {
					ex: make(map[string]struct{}),
					in: map[string]struct{}{
						"foo/bar": struct{}{},
					},
				},
				"foo/bar": {
					ex: map[string]struct{}{
						"baz": struct{}{},
					},
					in: make(map[string]struct{}),
				},
			},
			out: map[string][]string{
				"foo": {
					"baz",
				},
				"foo/bar": {
					"baz",
				},
			},
		},
	}

	for name, fix := range table {
		out, err := wmToReach(fix.workmap, fix.basedir)

		if fix.out == nil {
			if err == nil {
				t.Errorf("wmToReach(%q): Error expected but not received", name)
			}
			continue
		}

		if err != nil {
			t.Errorf("wmToReach(%q): %v", name, err)
			continue
		}

		if !reflect.DeepEqual(out, fix.out) {
			t.Errorf("wmToReach(%q): Did not get expected reach map:\n\t(GOT): %s\n\t(WNT): %s", name, out, fix.out)
		}
	}
}
<commit_msg>Not so much verbose map creation<commit_after>package vsolver

import (
	"reflect"
	"testing"
)

// ExternalReach uses an easily separable algorithm, wmToReach(), to turn a
// discovered set of packages and their imports into a proper external reach
// map.
//
// That algorithm is purely symbolic (no filesystem interaction), and thus is
// easy to test. This is that test.
func TestWorkmapToReach(t *testing.T) {
	empty := func() map[string]struct{} {
		return make(map[string]struct{})
	}

	table := map[string]struct {
		name    string
		workmap map[string]wm
		basedir string
		out     map[string][]string
		err     error
	}{
		"single": {
			workmap: map[string]wm{
				"foo": {
					ex: empty(),
					in: empty(),
				},
			},
			out: map[string][]string{
				"foo": {},
			},
		},
		"no external": {
			workmap: map[string]wm{
				"foo": {
					ex: empty(),
					in: empty(),
				},
				"foo/bar": {
					ex: empty(),
					in: empty(),
				},
			},
			out: map[string][]string{
				"foo":     {},
				"foo/bar": {},
			},
		},
		"no external with subpkg": {
			workmap: map[string]wm{
				"foo": {
					ex: empty(),
					in: map[string]struct{}{
						"foo/bar": struct{}{},
					},
				},
				"foo/bar": {
					ex: empty(),
					in: empty(),
				},
			},
			out: map[string][]string{
				"foo":     {},
				"foo/bar": {},
			},
		},
		"simple base transitive": {
			workmap: map[string]wm{
				"foo": {
					ex: empty(),
					in: map[string]struct{}{
						"foo/bar": struct{}{},
					},
				},
				"foo/bar": {
					ex: map[string]struct{}{
						"baz": struct{}{},
					},
					in: empty(),
				},
			},
			out: map[string][]string{
				"foo": {
					"baz",
				},
				"foo/bar": {
					"baz",
				},
			},
		},
	}

	for name, fix := range table {
		out, err := wmToReach(fix.workmap, fix.basedir)

		if fix.out == nil {
			if err == nil {
				t.Errorf("wmToReach(%q): Error expected but not received", name)
			}
			continue
		}

		if err != nil {
			t.Errorf("wmToReach(%q): %v", name, err)
			continue
		}

		if !reflect.DeepEqual(out, fix.out) {
			t.Errorf("wmToReach(%q): Did not get expected reach map:\n\t(GOT): %s\n\t(WNT): %s", name, out, fix.out)
		}
	}
}
<|endoftext|>


<commit_before>package slugify

import (
	"testing"
)

var tests = []struct{ in, out string }{
	{"simple test", "simple-test"},
	{"I'm go developer", "i-m-go-developer"},
	{"Simples código em go", "simples-codigo-em-go"},
	{"日本語の手紙をテスト", "日本語の手紙をテスト"},
	{"--->simple test<---", "simple-test"},
}

func TestSlugify(t *testing.T) {
	for _, test := range tests {
		if out := Slugify(test.in); out != test.out {
			t.Errorf("%q: %q != %q", test.in, out, test.out)
		}
	}
}

func TestSlugifyf(t *testing.T) {
	for _, test := range tests {
		t.Run(test.out, func(t *testing.T) {
			if out := Slugifyf("%s", test.in); out != test.out {
				t.Errorf("%q: %q != %q", test.in, out, test.out)
			}
		})
	}
}
<commit_msg>remove subtests to solve build issue<commit_after>package slugify

import (
	"testing"
)

var tests = []struct{ in, out string }{
	{"simple test", "simple-test"},
	{"I'm go developer", "i-m-go-developer"},
	{"Simples código em go", "simples-codigo-em-go"},
	{"日本語の手紙をテスト", "日本語の手紙をテスト"},
	{"--->simple test<---", "simple-test"},
}

func TestSlugify(t *testing.T) {
	for _, test := range tests {
		if out := Slugify(test.in); out != test.out {
			t.Errorf("%q: %q != %q", test.in, out, test.out)
		}
	}
}

func TestSlugifyf(t *testing.T) {
	for _, test := range tests {
		if out := Slugifyf("%s", test.in); out != test.out {
			t.Errorf("%q: %q != %q", test.in, out, test.out)
		}
	}
}
<|endoftext|>


<commit_before>package method

import "reflect"

// The short for HasMethod
func Has(t interface{}, method string) bool {
	return HasMethod(t, method)
}

// The short for GetMethod
func Get(t interface{}, method string) interface{} {
	return GetMethod(t, method)
}

// The short for CallMethod
func Call(t interface{}, method string, args ...interface{}) []interface{} {
	return CallMethod(t, method, args...)
}

func HasMethod(t interface{}, method string) bool {
	_, b := reflect.TypeOf(t).MethodByName(method)
	if b {
		return true
	}
	return false
}

func getMethod(t interface{}, method string) reflect.Value {
	m, b := reflect.TypeOf(t).MethodByName(method)
	if !b {
		return reflect.ValueOf(nil)
	}
	return m.Func
}

func GetMethod(t interface{}, method string) interface{} {
	return getMethod(t, method).Interface()
}

func CallMethod(t interface{}, method string, args ...interface{}) []interface{} {
	in := []reflect.Value{reflect.ValueOf(t)}
	for _, arg := range args {
		in = append(in, reflect.ValueOf(arg))
	}
	out := getMethod(t, method).Call(in)
	result := make([]interface{}, 0)
	for _, arg := range out {
		result = append(result, arg.Interface())
	}
	return result
}
<commit_msg>Add the comment.<commit_after>package method

import "reflect"

// The short for HasMethod
func Has(t interface{}, method string) bool {
	return HasMethod(t, method)
}

// The short for GetMethod
func Get(t interface{}, method string) interface{} {
	return GetMethod(t, method)
}

// The short for CallMethod
func Call(t interface{}, method string, args ...interface{}) []interface{} {
	return CallMethod(t, method, args...)
}

// Return true if `t` has the method of `method`.
func HasMethod(t interface{}, method string) bool {
	_, b := reflect.TypeOf(t).MethodByName(method)
	if b {
		return true
	}
	return false
}

func getMethod(t interface{}, method string) reflect.Value {
	m, b := reflect.TypeOf(t).MethodByName(method)
	if !b {
		return reflect.ValueOf(nil)
	}
	return m.Func
}

// Return the method, `method`, of `t`. If not, return nil.
func GetMethod(t interface{}, method string) interface{} {
	return getMethod(t, method).Interface()
}

// Call the method, `method`, of `t`, and return the result which that method
// returned. It will panic if `t` does not have the method of `method`.
func CallMethod(t interface{}, method string, args ...interface{}) []interface{} {
	in := []reflect.Value{reflect.ValueOf(t)}
	for _, arg := range args {
		in = append(in, reflect.ValueOf(arg))
	}
	out := getMethod(t, method).Call(in)
	result := make([]interface{}, 0)
	for _, arg := range out {
		result = append(result, arg.Interface())
	}
	return result
}
<|endoftext|>


<commit_before>package urknall

import (
	"fmt"
	"github.com/dynport/urknall/cmd"
	"github.com/dynport/urknall/utils"
	"runtime/debug"
)

// A runlist is a container for commands. Use the following methods to add new commands.
type Runlist struct {
	commands []cmd.Command
	pkg      Package
	name     string // Name of the compilable.
}

func (rl *Runlist) Add(c interface{}) {
	switch t := c.(type) {
	case *cmd.ShellCommand:
		t.Command = utils.MustRenderTemplate(t.Command, rl.pkg)
		rl.commands = append(rl.commands, t)
	case *cmd.FileCommand:
		t.Content = utils.MustRenderTemplate(t.Content, rl.pkg)
		rl.commands = append(rl.commands, t)
	case cmd.Command:
		rl.commands = append(rl.commands, t)
	case string:
		// No explicit expansion required as the function is called recursively with a ShellCommand type, that has
		// explicitly renders the template.
		rl.Add(&cmd.ShellCommand{Command: t})
	default:
		panic(fmt.Sprintf("type %T not supported!", t))
	}
}

func (rl *Runlist) compile() (e error) {
	defer func() {
		if r := recover(); r != nil {
			var ok bool
			e, ok = r.(error)
			if !ok {
				e = fmt.Errorf("failed to precompile package: %v", rl.name)
			}
			logger.Info(e.Error())
			logger.Debug(string(debug.Stack()))
		}
	}()

	if e = validatePackage(rl.pkg); e != nil {
		return e
	}

	rl.pkg.Package(rl)
	logger.Debugf("Precompiled package %s", rl.name)
	return nil
}
<commit_msg>fixed handling of panic on precompile<commit_after>package urknall

import (
	"fmt"
	"github.com/dynport/urknall/cmd"
	"github.com/dynport/urknall/utils"
	"runtime/debug"
)

// A runlist is a container for commands. Use the following methods to add new commands.
type Runlist struct {
	commands []cmd.Command
	pkg      Package
	name     string // Name of the compilable.
}

func (rl *Runlist) Add(c interface{}) {
	switch t := c.(type) {
	case *cmd.ShellCommand:
		t.Command = utils.MustRenderTemplate(t.Command, rl.pkg)
		rl.commands = append(rl.commands, t)
	case *cmd.FileCommand:
		t.Content = utils.MustRenderTemplate(t.Content, rl.pkg)
		rl.commands = append(rl.commands, t)
	case cmd.Command:
		rl.commands = append(rl.commands, t)
	case string:
		// No explicit expansion required as the function is called recursively with a ShellCommand type, that has
		// explicitly renders the template.
		rl.Add(&cmd.ShellCommand{Command: t})
	default:
		panic(fmt.Sprintf("type %T not supported!", t))
	}
}

func (rl *Runlist) compile() (e error) {
	defer func() {
		if r := recover(); r != nil {
			var ok bool
			e, ok = r.(error)
			if !ok {
				e = fmt.Errorf("failed to precompile package: %v %q", rl.name, r)
			}
			logger.Info(e.Error())
			logger.Debug(string(debug.Stack()))
		}
	}()

	if e = validatePackage(rl.pkg); e != nil {
		return e
	}

	rl.pkg.Package(rl)
	logger.Debugf("Precompiled package %s", rl.name)
	return nil
}
<|endoftext|>


<commit_before>package gmx

// pkg/runtime instrumentation

import "runtime"

func init() {
	Publish("runtime.gomaxprocs", runtimeGOMAXPROCS)
	Publish("runtime.cgocalls", runtimeCgocalls)
	Publish("runtime.numcpu", runtimeNumCPU)
	Publish("runtime.version", runtimeVersion)

	Publish("runtime.memstats", runtimeMemStats)
}

func runtimeGOMAXPROCS() interface{} {
	return runtime.GOMAXPROCS(0)
}

func runtimeCgocalls() interface{} {
	return runtime.Cgocalls()
}

func runtimeNumCPU() interface{} {
	return runtime.NumCPU()
}

func runtimeVersion() interface{} {
	return runtime.Version()
}

func runtimeMemStats() interface{} {
	runtime.UpdateMemStats()
	return runtime.MemStats
}
<commit_msg>Update runtime instruments<commit_after>package gmx

// pkg/runtime instrumentation

import "runtime"

var memstats runtime.MemStats

func init() {
	Publish("runtime.gomaxprocs", runtimeGOMAXPROCS)
	Publish("runtime.cgocalls", runtimeCgocalls)
	Publish("runtime.numcpu", runtimeNumCPU)
	Publish("runtime.version", runtimeVersion)

	Publish("runtime.memstats", runtimeMemStats)
}

func runtimeGOMAXPROCS() interface{} {
	return runtime.GOMAXPROCS(0)
}

func runtimeCgocalls() interface{} {
	return runtime.Cgocalls()
}

func runtimeNumCPU() interface{} {
	return runtime.NumCPU()
}

func runtimeVersion() interface{} {
	return runtime.Version()
}

func runtimeMemStats() interface{} {
	runtime.ReadMemStats(&memstats)
	return memstats
}
<|endoftext|>