<commit_before>// Copyright (c) 2014-2018 Bitmark Inc.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package block

import (
	"encoding/binary"
	"reflect"
	"sync"

	"github.com/bitmark-inc/bitmarkd/background"
	"github.com/bitmark-inc/bitmarkd/blockdigest"
	"github.com/bitmark-inc/bitmarkd/blockheader"
	"github.com/bitmark-inc/bitmarkd/blockrecord"
	"github.com/bitmark-inc/bitmarkd/fault"
	"github.com/bitmark-inc/bitmarkd/merkle"
	"github.com/bitmark-inc/bitmarkd/mode"
	"github.com/bitmark-inc/bitmarkd/storage"
	"github.com/bitmark-inc/bitmarkd/transactionrecord"
	"github.com/bitmark-inc/logger"
)

const BlockValidationCounts = 10

// globals for background process
type blockData struct {
	sync.RWMutex // to allow locking

	log *logger.L

	rebuild bool       // set if all indexes are being rebuild
	blk     blockstore // for sequencing block storage

	// for background
	background *background.T

	// set once during initialise
	initialised bool
}

// global data
var globalData blockData

func validateTransactionData(header *blockrecord.Header, digest blockdigest.Digest, data []byte) error {
	oldBlockOwnerTxs := map[string]struct{}{}
	for i := header.TransactionCount; i > 0; i-- {
		transaction, n, err := transactionrecord.Packed(data).Unpack(mode.IsTesting())
		if err != nil {
			globalData.log.Error("can not unpack transaction")
			return err
		}

		txId := merkle.NewDigest(data[:n])

		switch tx := transaction.(type) {
		case *transactionrecord.OldBaseData:
			globalData.log.Warnf("not processing base record: %+v", tx)
		case *transactionrecord.BlockFoundation:
			foundationTxId := blockrecord.FoundationTxId(header, digest)
			globalData.log.Debugf("get a foundation transaction. foundationTxId: %s", foundationTxId)

			globalData.log.Debugf("validate the foundation transaction indexed. foundationTxId: %s", foundationTxId)
			if !storage.Pool.Transactions.Has(foundationTxId[:]) {
				globalData.log.Error("foundation tx is not indexed")
				return fault.ErrTransactionIsNotIndexed
			}

			if _, ok := oldBlockOwnerTxs[txId.String()]; !ok {
				globalData.log.Debugf("validate ownership indexed. foundationTxId: %s", foundationTxId)
				if !storage.Pool.BlockOwnerTxIndex.Has(foundationTxId[:]) {
					globalData.log.Error("ownership is not indexed")
					return fault.ErrOwnershipIsNotIndexed
				}

				packedPayment, err := tx.Payments.Pack(mode.IsTesting())
				if err != nil {
					globalData.log.Error("fail to get packed payments")
					return err
				}

				blockNumberKey := make([]byte, 8)
				binary.BigEndian.PutUint64(blockNumberKey, header.Number)
				globalData.log.Debugf("validate payment info identical. foundationTxId: %s", foundationTxId)
				if !reflect.DeepEqual(storage.Pool.BlockOwnerPayment.Get(blockNumberKey[:]), packedPayment) {
					globalData.log.Error("payment info data is not consistent")
					return fault.ErrDataInconsistent
				}
			}

		case *transactionrecord.BlockOwnerTransfer:
			globalData.log.Debugf("get a owner transfer transaction. txId: %s", txId)
			globalData.log.Debugf("validate transaction indexed. txId: %s", txId)
			if !storage.Pool.Transactions.Has(txId[:]) {
				globalData.log.Error("tx is not indexed")
				return fault.ErrTransactionIsNotIndexed
			}

			globalData.log.Debugf("validate previous ownership cleaned. txId: %s", txId)
			if storage.Pool.BlockOwnerTxIndex.Has(tx.Link[:]) {
				globalData.log.Error("ownership is not cleaned")
				return fault.ErrOwnershipIsNotCleaned
			}
			oldBlockOwnerTxs[tx.Link.String()] = struct{}{}

			if _, ok := oldBlockOwnerTxs[txId.String()]; !ok {
				// validate ownership indexed only if the txId is not added into olderBlockOwnerTxs
				globalData.log.Debugf("validate ownership indexed. txId: %s", txId)
				blockNumberKey := storage.Pool.BlockOwnerTxIndex.Get(txId[:])
				if blockNumberKey == nil {
					globalData.log.Error("ownership is not indexed")
					return fault.ErrOwnershipIsNotIndexed
				}

				packedPayment, err := tx.Payments.Pack(mode.IsTesting())
				if err != nil {
					globalData.log.Error("fail to get packed payments")
					return err
				}

				binary.BigEndian.PutUint64(blockNumberKey, header.Number)
				globalData.log.Debugf("validate payment info identical. txId: %s", txId)
				if !reflect.DeepEqual(storage.Pool.BlockOwnerPayment.Get(blockNumberKey[:]), packedPayment) {
					globalData.log.Error("payment info data is not consistent")
					return fault.ErrDataInconsistent
				}
			}

		case *transactionrecord.AssetData:
			globalData.log.Debugf("get an asset transaction. txId: %s", txId)
			globalData.log.Debugf("validate the asset indexed. txId: %s", txId)
			assetId := tx.AssetId()
			if !storage.Pool.Assets.Has(assetId[:]) {
				globalData.log.Error("asset is not indexed")
				return fault.ErrAssetIsNotIndexed
			}
		case *transactionrecord.BitmarkIssue, *transactionrecord.BitmarkTransferUnratified, *transactionrecord.BitmarkTransferCountersigned:
			globalData.log.Debugf("get a regular transaction. txId: %s", txId)
			globalData.log.Debugf("validate the regular transaction indexed. txId: %s", txId)
			if !storage.Pool.Transactions.Has(txId[:]) {
				globalData.log.Error("tx is not indexed")
				return fault.ErrTransactionIsNotIndexed
			}
		case *transactionrecord.BitmarkShare, *transactionrecord.ShareGrant, *transactionrecord.ShareSwap:
			globalData.log.Debugf("get a share transaction. txId: %s", txId)
			globalData.log.Debugf("validate the share transaction indexed. txId: %s", txId)
			if !storage.Pool.Transactions.Has(txId[:]) {
				globalData.log.Error("tx is not indexed")
				return fault.ErrTransactionIsNotIndexed
			}
		default:
			globalData.log.Errorf("unexpected transaction record: %+v", tx)
			return fault.ErrUnexpectedTransaction
		}
		data = data[n:]
	}

	return nil
}

func validateAndReturnLastBlock(last storage.Element) (*blockrecord.Header, blockdigest.Digest, error) {
	var header *blockrecord.Header
	var digest blockdigest.Digest

	blocks := [][]byte{last.Value}
	lastBlockNumber := binary.BigEndian.Uint64(last.Key)
	lastCheckedBlockNumber := lastBlockNumber - BlockValidationCounts
	if lastCheckedBlockNumber < 1 {
		lastCheckedBlockNumber = 1
	}

	for blockNumber := lastBlockNumber - 1; blockNumber > lastCheckedBlockNumber; blockNumber-- {
		blockNumberKey := make([]byte, 8)
		binary.BigEndian.PutUint64(blockNumberKey, blockNumber)
		block := storage.Pool.Blocks.Get(blockNumberKey)
		blocks = append(blocks, block) // append
	}

	for i, blockData := range blocks {
		var data []byte
		var err error

		h, d, data, err := blockrecord.ExtractHeader(blockData)
		if err != nil {
			globalData.log.Error("can not extract header")
			return h, d, err
		}

		// set the last block header and digest by index 0, since we validate blocks by descending order
		if i == 0 {
			header = h
			digest = d
		}

		globalData.log.Infof("validate block. block number: %d, transaction count: %d", h.Number, h.TransactionCount)

		if err := validateTransactionData(h, d, data); err != nil {
			return h, d, err
		}
	}

	return header, digest, nil
}

// setup the current block data
func Initialise(migrate, reindex bool) error {
	globalData.Lock()
	defer globalData.Unlock()

	// no need to start if already started
	if globalData.initialised {
		return fault.ErrAlreadyInitialised
	}

	log := logger.New("block")
	globalData.log = log
	log.Info("starting…")

	// check storage is initialised
	if nil == storage.Pool.Blocks {
		log.Critical("storage pool is not initialised")
		return fault.ErrNotInitialised
	}

	if migrate {
		log.Info("start block migration…")
		globalData.rebuild = true
		globalData.Unlock()
		err := doBlockHeaderHash()
		globalData.Lock()
		if nil != err {
			log.Criticalf("blocks migration error: %s", err)
			return err
		}
		log.Info("block migration completed")
	}

	if reindex {
		log.Warn("start index rebuild…")
		globalData.rebuild = true
		globalData.Unlock()
		err := doRecovery()
		globalData.Lock()
		if nil != err {
			log.Criticalf("index rebuild error: %s", err)
			return err
		}
		log.Warn("index rebuild completed")
	}

	// ensure not in rebuild mode
	globalData.rebuild = false

	// detect if any blocks on file
	if last, ok := storage.Pool.Blocks.LastElement(); ok {

		// start validating block indexes
		header, digest, err := validateAndReturnLastBlock(last)
		if nil != err {
			log.Criticalf("failed to validate blocks from storage  error: %s", err)
			return err
		}

		height := header.Number
		blockheader.Set(height, digest, header.Version, header.Timestamp)

		log.Infof("highest block from storage: %d", height)
	}

	// initialise background tasks
	if err := globalData.blk.initialise(); nil != err {
		return err
	}

	// all data initialised
	globalData.initialised = true

	// start background processes
	log.Info("start background…")

	processes := background.Processes{
		&globalData.blk,
	}

	globalData.background = background.Start(processes, log)

	return nil
}

// shutdown the block system
func Finalise() error {

	if !globalData.initialised {
		return fault.ErrNotInitialised
	}

	globalData.log.Info("shutting down…")
	globalData.log.Flush()

	globalData.background.Stop()

	// finally...
	globalData.initialised = false

	globalData.log.Info("finished")
	globalData.log.Flush()

	return nil
}
<commit_msg>[block] improve the block validation by go through the provenance of a tx<commit_after>// Copyright (c) 2014-2018 Bitmark Inc.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package block

import (
	"encoding/binary"
	"reflect"
	"sync"

	"github.com/bitmark-inc/bitmarkd/background"
	"github.com/bitmark-inc/bitmarkd/blockdigest"
	"github.com/bitmark-inc/bitmarkd/blockheader"
	"github.com/bitmark-inc/bitmarkd/blockrecord"
	"github.com/bitmark-inc/bitmarkd/fault"
	"github.com/bitmark-inc/bitmarkd/merkle"
	"github.com/bitmark-inc/bitmarkd/mode"
	"github.com/bitmark-inc/bitmarkd/storage"
	"github.com/bitmark-inc/bitmarkd/transactionrecord"
	"github.com/bitmark-inc/logger"
)

const BlockValidationCounts = 10

// globals for background process
type blockData struct {
	sync.RWMutex // to allow locking

	log *logger.L

	rebuild bool       // set if all indexes are being rebuild
	blk     blockstore // for sequencing block storage

	// for background
	background *background.T

	// set once during initialise
	initialised bool
}

// global data
var globalData blockData

// isTxWipedOut will check whether a transaction is cleaned up from the index db
func isTxWipedOut(txId merkle.Digest) bool {
	if storage.Pool.OwnerData.Has(txId[:]) {
		globalData.log.Error("tx data is not cleaned")
		return false
	}

	_, packed := storage.Pool.Transactions.GetNB(txId[:])
	transaction, _, err := transactionrecord.Packed(packed).Unpack(mode.IsTesting())
	if err != nil {
		globalData.log.Errorf("can not fetch transaction. error: %s", err)
		return false
	}

	switch tx := transaction.(type) {
	case *transactionrecord.BitmarkIssue:
		txIndexKey := append(tx.Owner.Bytes(), txId[:]...)
		if storage.Pool.OwnerTxIndex.Has(txIndexKey) {
			globalData.log.Error("owner tx index is not cleaned")
			return false
		}
	case transactionrecord.BitmarkTransfer:
		txIndexKey := append(tx.GetOwner().Bytes(), txId[:]...)
		if storage.Pool.OwnerTxIndex.Has(txIndexKey) {
			globalData.log.Error("owner tx index is not cleaned")
			return false
		}
	default:
		globalData.log.Critical("invalid type of transaction")
		return false
	}

	return true
}

func validateTransactionData(header *blockrecord.Header, digest blockdigest.Digest, data []byte) error {
	oldBlockOwnerTxs := map[string]struct{}{}
	priorTxOwnerTxs := map[string]struct{}{}
	for i := header.TransactionCount; i > 0; i-- {
		transaction, n, err := transactionrecord.Packed(data).Unpack(mode.IsTesting())
		if err != nil {
			globalData.log.Error("can not unpack transaction")
			return err
		}

		txId := merkle.NewDigest(data[:n])

		switch tx := transaction.(type) {
		case *transactionrecord.OldBaseData:
			globalData.log.Warnf("not processing base record: %+v", tx)
		case *transactionrecord.BlockFoundation:
			foundationTxId := blockrecord.FoundationTxId(header, digest)
			globalData.log.Debugf("get a foundation transaction. foundationTxId: %s", foundationTxId)

			globalData.log.Debugf("validate the foundation transaction indexed. foundationTxId: %s", foundationTxId)
			if !storage.Pool.Transactions.Has(foundationTxId[:]) {
				globalData.log.Error("foundation tx is not indexed")
				return fault.ErrTransactionIsNotIndexed
			}

			if _, ok := oldBlockOwnerTxs[txId.String()]; !ok {
				globalData.log.Debugf("validate ownership indexed. foundationTxId: %s", foundationTxId)
				if !storage.Pool.BlockOwnerTxIndex.Has(foundationTxId[:]) {
					globalData.log.Error("ownership is not indexed")
					return fault.ErrOwnershipIsNotIndexed
				}

				packedPayment, err := tx.Payments.Pack(mode.IsTesting())
				if err != nil {
					globalData.log.Error("fail to get packed payments")
					return err
				}

				blockNumberKey := make([]byte, 8)
				binary.BigEndian.PutUint64(blockNumberKey, header.Number)
				globalData.log.Debugf("validate payment info identical. foundationTxId: %s", foundationTxId)
				if !reflect.DeepEqual(storage.Pool.BlockOwnerPayment.Get(blockNumberKey[:]), packedPayment) {
					globalData.log.Error("payment info data is not consistent")
					return fault.ErrDataInconsistent
				}
			}

		case *transactionrecord.BlockOwnerTransfer:
			globalData.log.Debugf("get a owner transfer transaction. txId: %s", txId)
			globalData.log.Debugf("validate transaction indexed. txId: %s", txId)
			if !storage.Pool.Transactions.Has(txId[:]) {
				globalData.log.Error("tx is not indexed")
				return fault.ErrTransactionIsNotIndexed
			}

			globalData.log.Debugf("validate previous ownership cleaned. txId: %s", txId)
			if storage.Pool.BlockOwnerTxIndex.Has(tx.Link[:]) {
				globalData.log.Error("ownership is not cleaned")
				return fault.ErrOwnershipIsNotCleaned
			}
			oldBlockOwnerTxs[tx.Link.String()] = struct{}{}

			if _, ok := oldBlockOwnerTxs[txId.String()]; !ok {
				// validate ownership indexed only if the txId is not added into olderBlockOwnerTxs
				globalData.log.Debugf("validate ownership indexed. txId: %s", txId)
				blockNumberKey := storage.Pool.BlockOwnerTxIndex.Get(txId[:])
				if blockNumberKey == nil {
					globalData.log.Error("ownership is not indexed")
					return fault.ErrOwnershipIsNotIndexed
				}

				packedPayment, err := tx.Payments.Pack(mode.IsTesting())
				if err != nil {
					globalData.log.Error("fail to get packed payments")
					return err
				}

				binary.BigEndian.PutUint64(blockNumberKey, header.Number)
				globalData.log.Debugf("validate payment info identical. txId: %s", txId)
				if !reflect.DeepEqual(storage.Pool.BlockOwnerPayment.Get(blockNumberKey[:]), packedPayment) {
					globalData.log.Error("payment info data is not consistent")
					return fault.ErrDataInconsistent
				}
			}

		case *transactionrecord.AssetData:
			globalData.log.Debugf("get an asset transaction. txId: %s", txId)
			globalData.log.Debugf("validate the asset indexed. txId: %s", txId)
			assetId := tx.AssetId()
			if !storage.Pool.Assets.Has(assetId[:]) {
				globalData.log.Error("asset is not indexed")
				return fault.ErrAssetIsNotIndexed
			}
		case *transactionrecord.BitmarkIssue:
			globalData.log.Debugf("get a regular transaction. txId: %s", txId)
			globalData.log.Debugf("validate the regular transaction indexed. txId: %s", txId)
			if !storage.Pool.Transactions.Has(txId[:]) {
				globalData.log.Error("tx is not indexed")
				return fault.ErrTransactionIsNotIndexed
			}

		case transactionrecord.BitmarkTransfer:
			globalData.log.Debugf("get a regular transaction. txId: %s", txId)
			globalData.log.Debugf("validate the regular transaction indexed. txId: %s", txId)
			if !storage.Pool.Transactions.Has(txId[:]) {
				globalData.log.Error("tx not found")
				return errors.New("tx not found")
			}

			if !isTxWipedOut(tx.GetLink()) {
				return errors.New("previous tx is not totally wiped out.")
			}

			if _, ok := priorTxOwnerTxs[txId.String()]; !ok {
				// if a tx is not in the list of prior transaction, it should be the latest tx.
				txIndexKey := append(tx.GetOwner().Bytes(), txId[:]...)
				count := storage.Pool.OwnerTxIndex.Get(txIndexKey)

				ownerListKey := append(tx.GetOwner().Bytes(), count[:]...)
				txIdFromList := storage.Pool.OwnerList.Get(ownerListKey)

				if !reflect.DeepEqual(txIdFromList[:], txId[:]) {
					globalData.log.Error("tx record inconsistent")
					return errors.New("tx record inconsistent")
				}
				priorTxOwnerTxs[txId.String()] = struct{}{}
			}

		case *transactionrecord.BitmarkShare, *transactionrecord.ShareGrant, *transactionrecord.ShareSwap:
			globalData.log.Debugf("get a share transaction. txId: %s", txId)
			globalData.log.Debugf("validate the share transaction indexed. txId: %s", txId)
			if !storage.Pool.Transactions.Has(txId[:]) {
				globalData.log.Error("tx is not indexed")
				return fault.ErrTransactionIsNotIndexed
			}
		default:
			globalData.log.Errorf("unexpected transaction record: %+v", tx)
			return fault.ErrUnexpectedTransaction
		}
		data = data[n:]
	}

	return nil
}

func validateAndReturnLastBlock(last storage.Element) (*blockrecord.Header, blockdigest.Digest, error) {
	var header *blockrecord.Header
	var digest blockdigest.Digest

	blocks := [][]byte{last.Value}
	lastBlockNumber := binary.BigEndian.Uint64(last.Key)
	lastCheckedBlockNumber := lastBlockNumber - BlockValidationCounts
	if lastCheckedBlockNumber < 1 {
		lastCheckedBlockNumber = 1
	}

	for blockNumber := lastBlockNumber - 1; blockNumber > lastCheckedBlockNumber; blockNumber-- {
		blockNumberKey := make([]byte, 8)
		binary.BigEndian.PutUint64(blockNumberKey, blockNumber)
		block := storage.Pool.Blocks.Get(blockNumberKey)
		blocks = append(blocks, block) // append
	}

	for i, blockData := range blocks {
		var data []byte
		var err error

		h, d, data, err := blockrecord.ExtractHeader(blockData)
		if err != nil {
			globalData.log.Error("can not extract header")
			return h, d, err
		}

		// set the last block header and digest by index 0, since we validate blocks by descending order
		if i == 0 {
			header = h
			digest = d
		}

		globalData.log.Infof("validate block. block number: %d, transaction count: %d", h.Number, h.TransactionCount)

		if err := validateTransactionData(h, d, data); err != nil {
			return h, d, err
		}
	}

	return header, digest, nil
}

// setup the current block data
func Initialise(migrate, reindex bool) error {
	globalData.Lock()
	defer globalData.Unlock()

	// no need to start if already started
	if globalData.initialised {
		return fault.ErrAlreadyInitialised
	}

	log := logger.New("block")
	globalData.log = log
	log.Info("starting…")

	// check storage is initialised
	if nil == storage.Pool.Blocks {
		log.Critical("storage pool is not initialised")
		return fault.ErrNotInitialised
	}

	if migrate {
		log.Info("start block migration…")
		globalData.rebuild = true
		globalData.Unlock()
		err := doBlockHeaderHash()
		globalData.Lock()
		if nil != err {
			log.Criticalf("blocks migration error: %s", err)
			return err
		}
		log.Info("block migration completed")
	}

	if reindex {
		log.Warn("start index rebuild…")
		globalData.rebuild = true
		globalData.Unlock()
		err := doRecovery()
		globalData.Lock()
		if nil != err {
			log.Criticalf("index rebuild error: %s", err)
			return err
		}
		log.Warn("index rebuild completed")
	}

	// ensure not in rebuild mode
	globalData.rebuild = false

	// detect if any blocks on file
	if last, ok := storage.Pool.Blocks.LastElement(); ok {

		// start validating block indexes
		header, digest, err := validateAndReturnLastBlock(last)
		if nil != err {
			log.Criticalf("failed to validate blocks from storage  error: %s", err)
			return err
		}

		height := header.Number
		blockheader.Set(height, digest, header.Version, header.Timestamp)

		log.Infof("highest block from storage: %d", height)
	}

	// initialise background tasks
	if err := globalData.blk.initialise(); nil != err {
		return err
	}

	// all data initialised
	globalData.initialised = true

	// start background processes
	log.Info("start background…")

	processes := background.Processes{
		&globalData.blk,
	}

	globalData.background = background.Start(processes, log)

	return nil
}

// shutdown the block system
func Finalise() error {

	if !globalData.initialised {
		return fault.ErrNotInitialised
	}

	globalData.log.Info("shutting down…")
	globalData.log.Flush()

	globalData.background.Stop()

	// finally...
	globalData.initialised = false

	globalData.log.Info("finished")
	globalData.log.Flush()

	return nil
}
<|endoftext|>


<commit_before>package testutil

import (
	"path/filepath"

	"veyron.io/tools/lib/envutil"
	"veyron.io/tools/lib/util"
)

// VeyronBrowserTest runs an integration test for the veyron browser.
//
// TODO(aghassemi): Port the veyron browser test logic from shell to Go.
func VeyronBrowserTest(ctx *util.Context, testName string) (*TestResult, error) {
	root, err := util.VeyronRoot()
	if err != nil {
		return nil, err
	}
	provaOutputFile := filepath.Join(root, "veyron_browser_test.out")

	// Initialize the test.
	cleanup, err := initTest(ctx, testName, []string{"web"})
	if err != nil {
		return nil, err
	}
	defer cleanup()

	// Invoke "make clean" for the veyron browser and remove the test output file if it exists.
	browserDir := filepath.Join(root, "veyron-browser")
	if err := ctx.Run().Chdir(browserDir); err != nil {
		return nil, err
	}
	if err := ctx.Run().Command("make", "clean"); err != nil {
		return nil, err
	}
	if err := ctx.Run().RemoveAll(provaOutputFile); err != nil {
		return nil, err
	}

	// Invoke "make test" for the veyron browser.
	opts := ctx.Run().Opts()
	env := envutil.NewSnapshotFromOS()
	env.Set("PROVA_OUTPUT_FILE", provaOutputFile)
	opts.Env = env.Map()
	if err := ctx.Run().CommandWithOpts(opts, "make", "test"); err != nil {
		return &TestResult{Status: TestFailed}, nil
	}

	return &TestResult{Status: TestPassed}, nil
}
<commit_msg>veyron.io/tools/testutil: veyron-browser can now output xunit XML file.<commit_after>package testutil

import (
	"path/filepath"

	"veyron.io/tools/lib/envutil"
	"veyron.io/tools/lib/util"
)

// VeyronBrowserTest runs an integration test for the veyron browser.
//
// TODO(aghassemi): Port the veyron browser test logic from shell to Go.
func VeyronBrowserTest(ctx *util.Context, testName string) (*TestResult, error) {
	root, err := util.VeyronRoot()
	if err != nil {
		return nil, err
	}
	xUnitFile := XUnitReportPath(testName)

	// Initialize the test.
	cleanup, err := initTest(ctx, testName, []string{"web"})
	if err != nil {
		return nil, err
	}
	defer cleanup()

	// Invoke "make clean" for the veyron browser and remove the test output file if it exists.
	browserDir := filepath.Join(root, "veyron-browser")
	if err := ctx.Run().Chdir(browserDir); err != nil {
		return nil, err
	}
	if err := ctx.Run().Command("make", "clean"); err != nil {
		return nil, err
	}
	if err := ctx.Run().RemoveAll(xUnitFile); err != nil {
		return nil, err
	}

	// Invoke "make test" for the veyron browser.
	opts := ctx.Run().Opts()
	env := envutil.NewSnapshotFromOS()
	env.Set("XUNIT_OUTPUT_FILE", xUnitFile)
	opts.Env = env.Map()
	if err := ctx.Run().CommandWithOpts(opts, "make", "test"); err != nil {
		return &TestResult{Status: TestFailed}, nil
	}

	return &TestResult{Status: TestPassed}, nil
}
<|endoftext|>


<commit_before>package util

import (
	"gigawatt-common/pkg/concurrency"

	"github.com/samuel/go-zookeeper/zk"
)

func RecursivelyDelete(conn *zk.Conn, path string, numRetries ...int) error {
	var wipe func(conn *zk.Conn, path string) error

	wipe = func(conn *zk.Conn, path string) error {
		exists, stat, err := conn.Exists(path)
		if err != nil && err != zk.ErrNoNode {
			return err
		}
		if exists {
			// Wipe out any and all children.
			var children []string
			if children, _, err = conn.Children(path); err != nil && err != zk.ErrNoNode {
				return err
			}
			deleterFuncs := make([]func() error, 0, len(children))
			for _, child := range children {
				func(child string) {
					deleterFunc := func() (err error) {
						if err = wipe(conn, path+"/"+child); err != nil {
							return
						}
						return
					}
					deleterFuncs = append(deleterFuncs, deleterFunc)
				}(child)
			}
			if err = concurrency.MultiGo(deleterFuncs...); err != nil {
				return err
			}
			if err = conn.Delete(path, stat.Version); err != nil && err != zk.ErrNoNode {
				return err
			}
		}
		return nil
	}

	attempt := 0
Retry:
	if err := wipe(conn, path); err != nil {
		if err == zk.ErrConnectionClosed && len(numRetries) > 0 && numRetries[0] > attempt {
			attempt++
			log.Notice("Retrying failed deletion attempt #%v", attempt)
			goto Retry
		}
		return err
	}
	return nil
}
<commit_msg>Changed zk recursive deletion retry logic to apply to specific operations.<commit_after>package util

import (
	"time"

	"gigawatt-common/pkg/concurrency"

	"github.com/samuel/go-zookeeper/zk"
)

func RecursivelyDelete(conn *zk.Conn, path string, numRetries ...int) error {
	var wipe func(conn *zk.Conn, path string) error

	wipe = func(conn *zk.Conn, path string) error {
		exists, stat, err := conn.Exists(path)
		if err != nil && err != zk.ErrNoNode {
			return err
		}
		if exists {
			// Wipe out any and all children.
			var children []string
			if children, _, err = conn.Children(path); err != nil && err != zk.ErrNoNode {
				return err
			}
			deleterFuncs := make([]func() error, 0, len(children))
			for _, child := range children {
				func(child string) {
					deleterFunc := func() (err error) {
						attempt := 0
					Retry:
						if err = wipe(conn, path+"/"+child); err != nil {
							if (err == zk.ErrConnectionClosed || err == zk.ErrNotEmpty) && len(numRetries) > 0 && numRetries[0] > attempt {
								attempt++
								log.Notice("Retrying failed deletion attempt #%v", attempt)
								time.Sleep(1 * time.Millisecond)
								goto Retry
							}
							return
						}
						return
					}
					deleterFuncs = append(deleterFuncs, deleterFunc)
				}(child)
			}
			if err = concurrency.MultiGo(deleterFuncs...); err != nil {
				return err
			}
			if err = conn.Delete(path, stat.Version); err != nil && err != zk.ErrNoNode {
				return err
			}
		}
		return nil
	}

	if err := wipe(conn, path); err != nil {
		return err
	}
	return nil
}
<|endoftext|>


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

package strutil

import (
	"testing"
)

var quotetests = []struct {
	in    string
	out   string
	ascii string
}{
	{"\a\b\f\r\n\t\v", `"\a\b\f\r\n\t\v"`, `"\a\b\f\r\n\t\v"`},
	{"\\", `"\\"`, `"\\"`},
	{"abc\xffdef", `"abc\xffdef"`, `"abc\xffdef"`},
	{"\u263a", `"☺"`, `"\u263a"`},
	{"\U0010ffff", `"\U0010ffff"`, `"\U0010ffff"`},
	{"\x04", `"\x04"`, `"\x04"`},
}

var unquotetests = []struct {
	in  string
	out string
}{
	{`""`, ""},
	{`"a"`, "a"},
	{`"abc"`, "abc"},
	{`"☺"`, "☺"},
	{`"hello world"`, "hello world"},
	{`"\xFF"`, "\xFF"},
	{`"\377"`, "\377"},
	{`"\u1234"`, "\u1234"},
	{`"\U00010111"`, "\U00010111"},
	{`"\U0001011111"`, "\U0001011111"},
	{`"\a\b\f\n\r\t\v\\\""`, "\a\b\f\n\r\t\v\\\""},
	{`"'"`, "'"},

	{`''`, ""},
	{`'a'`, "a"},
	{`'abc'`, "abc"},
	{`'☺'`, "☺"},
	{`'hello world'`, "hello world"},
	{`'\ahéllo world'`, "\ahéllo world"},
	{`'\xFF'`, "\xFF"},
	{`'\377'`, "\377"},
	{`'\u1234'`, "\u1234"},
	{`'\U00010111'`, "\U00010111"},
	{`'\U0001011111'`, "\U0001011111"},
	{`'\a\b\f\n\r\t\v\\\''`, "\a\b\f\n\r\t\v\\'"},
	{`'"'`, "\""},

	{"``", ``},
	{"`a`", `a`},
	{"`abc`", `abc`},
	{"`☺`", `☺`},
	{"`hello world`", `hello world`},
	{"`\\xFF`", `\xFF`},
	{"`\\377`", `\377`},
	{"`\\`", `\`},
	{"`\n`", "\n"},
	{"`	`", `	`},
}

var misquoted = []string{
	``,
	`"`,
	`"a`,
	`"'`,
	`b"`,
	`"\"`,
	`"\9"`,
	`"\19"`,
	`"\129"`,
	`'\'`,
	`'\9'`,
	`'\19'`,
	`'\129'`,
	`"\x1!"`,
	`"\U12345678"`,
	`"\z"`,
	"`",
	"`xxx",
	"`\"",
	`"\'"`,
	`'\"'`,
	"\"\n\"",
	"\"\\n\n\"",
	"'\n'",
	"`1`9`",
	`1231`,
	`'\xF'`,
	`""12345"`,
}

func TestUnquote(t *testing.T) {
	for _, tt := range unquotetests {
		if out, err := Unquote(tt.in); err != nil && out != tt.out {
			t.Errorf("Unquote(%#q) = %q, %v want %q, nil", tt.in, out, err, tt.out)
		}
	}

	// Run the quote tests too, backward.
	for _, tt := range quotetests {
		if in, err := Unquote(tt.out); in != tt.in {
			t.Errorf("Unquote(%#q) = %q, %v, want %q, nil", tt.out, in, err, tt.in)
		}
	}

	for _, s := range misquoted {
		if out, err := Unquote(s); out != "" || err != ErrSyntax {
			t.Errorf("Unquote(%#q) = %q, %v want %q, %v", s, out, err, "", ErrSyntax)
		}
	}
}
<commit_msg>Add unit test case to improve test coverage for quote.go (#7482)<commit_after>// Copyright 2015 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package strutil

import (
	"testing"
)

var quotetests = []struct {
	in    string
	out   string
	ascii string
}{
	{"\a\b\f\r\n\t\v", `"\a\b\f\r\n\t\v"`, `"\a\b\f\r\n\t\v"`},
	{"\\", `"\\"`, `"\\"`},
	{"abc\xffdef", `"abc\xffdef"`, `"abc\xffdef"`},
	{"\u263a", `"☺"`, `"\u263a"`},
	{"\U0010ffff", `"\U0010ffff"`, `"\U0010ffff"`},
	{"\x04", `"\x04"`, `"\x04"`},
}

var unquotetests = []struct {
	in  string
	out string
}{
	{`""`, ""},
	{`"a"`, "a"},
	{`"abc"`, "abc"},
	{`"☺"`, "☺"},
	{`"hello world"`, "hello world"},
	{`"\xFF"`, "\xFF"},
	{`"\377"`, "\377"},
	{`"\u1234"`, "\u1234"},
	{`"\U00010111"`, "\U00010111"},
	{`"\U0001011111"`, "\U0001011111"},
	{`"\a\b\f\n\r\t\v\\\""`, "\a\b\f\n\r\t\v\\\""},
	{`"'"`, "'"},

	{`''`, ""},
	{`'a'`, "a"},
	{`'abc'`, "abc"},
	{`'☺'`, "☺"},
	{`'hello world'`, "hello world"},
	{`'\ahéllo world'`, "\ahéllo world"},
	{`'\xFF'`, "\xFF"},
	{`'\377'`, "\377"},
	{`'\u1234'`, "\u1234"},
	{`'\U00010111'`, "\U00010111"},
	{`'\U0001011111'`, "\U0001011111"},
	{`'\a\b\f\n\r\t\v\\\''`, "\a\b\f\n\r\t\v\\'"},
	{`'"'`, "\""},

	{"``", ``},
	{"`a`", `a`},
	{"`abc`", `abc`},
	{"`☺`", `☺`},
	{"`hello world`", `hello world`},
	{"`\\xFF`", `\xFF`},
	{"`\\377`", `\377`},
	{"`\\`", `\`},
	{"`\n`", "\n"},
	{"`	`", `	`},
}

var misquoted = []string{
	``,
	`"`,
	`"a`,
	`"'`,
	`b"`,
	`"\"`,
	`"\9"`,
	`"\19"`,
	`"\129"`,
	`'\'`,
	`'\9'`,
	`'\19'`,
	`'\129'`,
	`'\400'`,
	`"\x1!"`,
	`"\U12345678"`,
	`"\z"`,
	"`",
	"`xxx",
	"`\"",
	`"\'"`,
	`'\"'`,
	"\"\n\"",
	"\"\\n\n\"",
	"'\n'",
	"`1`9`",
	`1231`,
	`'\xF'`,
	`""12345"`,
}

func TestUnquote(t *testing.T) {
	for _, tt := range unquotetests {
		if out, err := Unquote(tt.in); err != nil && out != tt.out {
			t.Errorf("Unquote(%#q) = %q, %v want %q, nil", tt.in, out, err, tt.out)
		}
	}

	// Run the quote tests too, backward.
	for _, tt := range quotetests {
		if in, err := Unquote(tt.out); in != tt.in {
			t.Errorf("Unquote(%#q) = %q, %v, want %q, nil", tt.out, in, err, tt.in)
		}
	}

	for _, s := range misquoted {
		if out, err := Unquote(s); out != "" || err != ErrSyntax {
			t.Errorf("Unquote(%#q) = %q, %v want %q, %v", s, out, err, "", ErrSyntax)
		}
	}
}
<|endoftext|>


<commit_before>package brokers_test

import (
	"testing"

	"errors"
	"github.com/RichardKnop/machinery/v1"
	"github.com/RichardKnop/machinery/v1/brokers"
	"github.com/RichardKnop/machinery/v1/config"
	"github.com/RichardKnop/machinery/v1/retry"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/sqs"
	"github.com/stretchr/testify/assert"
)

var (
	testBroker           brokers.Interface
	testAWSSQSBroker     *brokers.AWSSQSBroker
	errAWSSQSBroker      *brokers.AWSSQSBroker
	cnf                  *config.Config
	receiveMessageOutput *sqs.ReceiveMessageOutput
)

func init() {
	testAWSSQSBroker = brokers.TestAWSSQSBroker
	errAWSSQSBroker = brokers.ErrAWSSQSBroker
	cnf = brokers.TestConf
	receiveMessageOutput = brokers.ReceiveMessageOutput
	testBroker = brokers.NewAWSSQSBroker(cnf)
}

func TestNewAWSSQSBroker(t *testing.T) {
	assert.IsType(t, testAWSSQSBroker, testBroker)
}

func TestPrivateFunc_continueReceivingMessages(t *testing.T) {
	qURL := testAWSSQSBroker.DefaultQueueURLForTesting()
	deliveries := make(chan *sqs.ReceiveMessageOutput)
	nextStep := make(chan int)
	go func() {
		stopReceivingChan := testAWSSQSBroker.GetStopReceivingChanForTesting()
		stopReceivingChan <- 1
	}()

	var (
		whetherContinue bool
		err             error
	)
	go func() {
		whetherContinue, err = testAWSSQSBroker.ContinueReceivingMessagesForTesting(qURL, deliveries)
		nextStep <- 1
	}()
	assert.False(t, whetherContinue)
	assert.Nil(t, err)

	<-nextStep
	whetherContinue, err = testAWSSQSBroker.ContinueReceivingMessagesForTesting(qURL, deliveries)
	assert.True(t, whetherContinue)
	assert.Nil(t, err)
	d := <-deliveries
	assert.Equal(t, receiveMessageOutput, d)

	whetherContinue, err = errAWSSQSBroker.ContinueReceivingMessagesForTesting(qURL, deliveries)
	assert.True(t, whetherContinue)
	assert.NotNil(t, err)

	outputCopy := *receiveMessageOutput
	receiveMessageOutput.Messages = []*sqs.Message{}
	whetherContinue, err = testAWSSQSBroker.ContinueReceivingMessagesForTesting(qURL, deliveries)
	assert.True(t, whetherContinue)
	assert.Nil(t, err)
	*receiveMessageOutput = outputCopy

}

func TestPrivateFunc_consume(t *testing.T) {
	server1, err := machinery.NewServer(cnf)
	if err != nil {
		t.Fatal(err)
	}
	wk := server1.NewWorker("sms_worker", 0)
	deliveries := make(chan *sqs.ReceiveMessageOutput)
	outputCopy := *receiveMessageOutput
	outputCopy.Messages = []*sqs.Message{}
	go func() { deliveries <- &outputCopy }()

	// an infinite loop will be executed only when there is no error
	err = testAWSSQSBroker.ConsumeForTesting(deliveries, 0, wk)
	assert.NotNil(t, err)

}

func TestPrivateFunc_consumeOne(t *testing.T) {
	server1, err := machinery.NewServer(cnf)
	if err != nil {
		t.Fatal(err)
	}
	wk := server1.NewWorker("sms_worker", 0)
	err = testAWSSQSBroker.ConsumeOneForTesting(receiveMessageOutput, wk)
	assert.Nil(t, err)

	outputCopy := *receiveMessageOutput
	outputCopy.Messages = []*sqs.Message{}
	err = testAWSSQSBroker.ConsumeOneForTesting(&outputCopy, wk)
	assert.NotNil(t, err)

	outputCopy.Messages = []*sqs.Message{
		&sqs.Message{
			Body: aws.String("foo message"),
		},
	}
	err = testAWSSQSBroker.ConsumeOneForTesting(&outputCopy, wk)
	assert.NotNil(t, err)
}

func TestPrivateFunc_initializePool(t *testing.T) {
	concurrency := 9
	pool := make(chan struct{}, concurrency)
	testAWSSQSBroker.InitializePoolForTesting(pool, concurrency)
	assert.Len(t, pool, concurrency)
}

func TestPrivateFunc_startConsuming(t *testing.T) {
	server1, err := machinery.NewServer(cnf)
	if err != nil {
		t.Fatal(err)
	}

	wk := server1.NewWorker("sms_worker", 0)
	retryFunc := testAWSSQSBroker.GetRetryFuncForTesting()
	stopChan := testAWSSQSBroker.GetStopChanForTesting()
	retryStopChan := testAWSSQSBroker.GetRetryStopChanForTesting()
	assert.Nil(t, retryFunc)
	testAWSSQSBroker.StartConsumingForTesting("fooTag", wk)
	assert.IsType(t, retryFunc, retry.Closure())
	assert.Equal(t, len(stopChan), 0)
	assert.Equal(t, len(retryStopChan), 0)
}

func TestPrivateFuncDefaultQueueURL(t *testing.T) {
	qURL := testAWSSQSBroker.DefaultQueueURLForTesting()

	assert.EqualValues(t, *qURL, "https://sqs.foo.amazonaws.com.cn/test_queue")
}

func TestPrivateFunc_stopReceiving(t *testing.T) {
	go testAWSSQSBroker.StopReceivingForTesting()
	stopReceivingChan := testAWSSQSBroker.GetStopReceivingChanForTesting()
	assert.NotNil(t, <-stopReceivingChan)
}

func TestPrivateFunc_receiveMessage(t *testing.T) {
	qURL := testAWSSQSBroker.DefaultQueueURLForTesting()
	output, err := testAWSSQSBroker.ReceiveMessageForTesting(qURL)
	assert.Nil(t, err)
	assert.Equal(t, receiveMessageOutput, output)
}

func TestPrivateFunc_consumeDeliveries(t *testing.T) {
	concurrency := 0
	pool := make(chan struct{}, concurrency)
	errorsChan := make(chan error)
	deliveries := make(chan *sqs.ReceiveMessageOutput)
	server1, err := machinery.NewServer(cnf)
	if err != nil {
		t.Fatal(err)
	}
	wk := server1.NewWorker("sms_worker", 0)
	go func() { deliveries <- receiveMessageOutput }()
	err = testAWSSQSBroker.ConsumeDeliveriesForTesting(deliveries, concurrency, wk, pool, errorsChan)

	assert.Nil(t, err)

	go func() { errorsChan <- errors.New("foo error") }()
	err = testAWSSQSBroker.ConsumeDeliveriesForTesting(deliveries, concurrency, wk, pool, errorsChan)
	assert.NotNil(t, err)

	go func() { testAWSSQSBroker.GetStopChanForTesting() <- 1 }()
	err = testAWSSQSBroker.ConsumeDeliveriesForTesting(deliveries, concurrency, wk, pool, errorsChan)
	assert.Nil(t, err)

	outputCopy := *receiveMessageOutput
	outputCopy.Messages = []*sqs.Message{}
	go func() { deliveries <- &outputCopy }()
	err = testAWSSQSBroker.ConsumeDeliveriesForTesting(deliveries, concurrency, wk, pool, errorsChan)
	e := <-errorsChan
	assert.NotNil(t, e)
	assert.Nil(t, err)

	go func() { pool <- struct{}{} }()
	go func() { deliveries <- receiveMessageOutput }()
	err = testAWSSQSBroker.ConsumeDeliveriesForTesting(deliveries, concurrency, wk, pool, errorsChan)
	p := <-pool
	assert.NotNil(t, p)
	assert.Nil(t, err)
}

func TestPrivateFunc_deleteOne(t *testing.T) {
	err := testAWSSQSBroker.DeleteOneForTesting(receiveMessageOutput)
	assert.Nil(t, err)

	err = errAWSSQSBroker.DeleteOneForTesting(receiveMessageOutput)
	assert.NotNil(t, err)
}
<commit_msg>test fix<commit_after>package brokers_test

import (
	"testing"

	"errors"
	"github.com/RichardKnop/machinery/v1"
	"github.com/RichardKnop/machinery/v1/brokers"
	"github.com/RichardKnop/machinery/v1/config"
	"github.com/RichardKnop/machinery/v1/retry"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/sqs"
	"github.com/stretchr/testify/assert"
)

var (
	testBroker           brokers.Interface
	testAWSSQSBroker     *brokers.AWSSQSBroker
	errAWSSQSBroker      *brokers.AWSSQSBroker
	cnf                  *config.Config
	receiveMessageOutput *sqs.ReceiveMessageOutput
)

func init() {
	testAWSSQSBroker = brokers.TestAWSSQSBroker
	errAWSSQSBroker = brokers.ErrAWSSQSBroker
	cnf = brokers.TestConf
	receiveMessageOutput = brokers.ReceiveMessageOutput
	testBroker = brokers.NewAWSSQSBroker(cnf)
}

func TestNewAWSSQSBroker(t *testing.T) {
	assert.IsType(t, testAWSSQSBroker, testBroker)
}

func TestPrivateFunc_continueReceivingMessages(t *testing.T) {
	qURL := testAWSSQSBroker.DefaultQueueURLForTesting()
	deliveries := make(chan *sqs.ReceiveMessageOutput)
	nextStep := make(chan int)
	go func() {
		stopReceivingChan := testAWSSQSBroker.GetStopReceivingChanForTesting()
		stopReceivingChan <- 1
	}()

	var (
		whetherContinue bool
		err             error
	)
	go func() {
		whetherContinue, err = testAWSSQSBroker.ContinueReceivingMessagesForTesting(qURL, deliveries)
		nextStep <- 1
	}()
	assert.False(t, whetherContinue)
	assert.Nil(t, err)

	<-nextStep
	whetherContinue, err = testAWSSQSBroker.ContinueReceivingMessagesForTesting(qURL, deliveries)
	assert.True(t, whetherContinue)
	assert.Nil(t, err)

	whetherContinue, err = errAWSSQSBroker.ContinueReceivingMessagesForTesting(qURL, deliveries)
	assert.True(t, whetherContinue)
	assert.NotNil(t, err)

	outputCopy := *receiveMessageOutput
	receiveMessageOutput.Messages = []*sqs.Message{}
	whetherContinue, err = testAWSSQSBroker.ContinueReceivingMessagesForTesting(qURL, deliveries)
	assert.True(t, whetherContinue)
	assert.Nil(t, err)
	*receiveMessageOutput = outputCopy

}

func TestPrivateFunc_consume(t *testing.T) {
	server1, err := machinery.NewServer(cnf)
	if err != nil {
		t.Fatal(err)
	}
	wk := server1.NewWorker("sms_worker", 0)
	deliveries := make(chan *sqs.ReceiveMessageOutput)
	outputCopy := *receiveMessageOutput
	outputCopy.Messages = []*sqs.Message{}
	go func() { deliveries <- &outputCopy }()

	// an infinite loop will be executed only when there is no error
	err = testAWSSQSBroker.ConsumeForTesting(deliveries, 0, wk)
	assert.NotNil(t, err)

}

func TestPrivateFunc_consumeOne(t *testing.T) {
	server1, err := machinery.NewServer(cnf)
	if err != nil {
		t.Fatal(err)
	}
	wk := server1.NewWorker("sms_worker", 0)
	err = testAWSSQSBroker.ConsumeOneForTesting(receiveMessageOutput, wk)
	assert.Nil(t, err)

	outputCopy := *receiveMessageOutput
	outputCopy.Messages = []*sqs.Message{}
	err = testAWSSQSBroker.ConsumeOneForTesting(&outputCopy, wk)
	assert.NotNil(t, err)

	outputCopy.Messages = []*sqs.Message{
		&sqs.Message{
			Body: aws.String("foo message"),
		},
	}
	err = testAWSSQSBroker.ConsumeOneForTesting(&outputCopy, wk)
	assert.NotNil(t, err)
}

func TestPrivateFunc_initializePool(t *testing.T) {
	concurrency := 9
	pool := make(chan struct{}, concurrency)
	testAWSSQSBroker.InitializePoolForTesting(pool, concurrency)
	assert.Len(t, pool, concurrency)
}

func TestPrivateFunc_startConsuming(t *testing.T) {
	server1, err := machinery.NewServer(cnf)
	if err != nil {
		t.Fatal(err)
	}

	wk := server1.NewWorker("sms_worker", 0)
	retryFunc := testAWSSQSBroker.GetRetryFuncForTesting()
	stopChan := testAWSSQSBroker.GetStopChanForTesting()
	retryStopChan := testAWSSQSBroker.GetRetryStopChanForTesting()
	assert.Nil(t, retryFunc)
	testAWSSQSBroker.StartConsumingForTesting("fooTag", wk)
	assert.IsType(t, retryFunc, retry.Closure())
	assert.Equal(t, len(stopChan), 0)
	assert.Equal(t, len(retryStopChan), 0)
}

func TestPrivateFuncDefaultQueueURL(t *testing.T) {
	qURL := testAWSSQSBroker.DefaultQueueURLForTesting()

	assert.EqualValues(t, *qURL, "https://sqs.foo.amazonaws.com.cn/test_queue")
}

func TestPrivateFunc_stopReceiving(t *testing.T) {
	go testAWSSQSBroker.StopReceivingForTesting()
	stopReceivingChan := testAWSSQSBroker.GetStopReceivingChanForTesting()
	assert.NotNil(t, <-stopReceivingChan)
}

func TestPrivateFunc_receiveMessage(t *testing.T) {
	qURL := testAWSSQSBroker.DefaultQueueURLForTesting()
	output, err := testAWSSQSBroker.ReceiveMessageForTesting(qURL)
	assert.Nil(t, err)
	assert.Equal(t, receiveMessageOutput, output)
}

func TestPrivateFunc_consumeDeliveries(t *testing.T) {
	concurrency := 0
	pool := make(chan struct{}, concurrency)
	errorsChan := make(chan error)
	deliveries := make(chan *sqs.ReceiveMessageOutput)
	server1, err := machinery.NewServer(cnf)
	if err != nil {
		t.Fatal(err)
	}
	wk := server1.NewWorker("sms_worker", 0)
	go func() { deliveries <- receiveMessageOutput }()
	err = testAWSSQSBroker.ConsumeDeliveriesForTesting(deliveries, concurrency, wk, pool, errorsChan)

	assert.Nil(t, err)

	go func() { errorsChan <- errors.New("foo error") }()
	err = testAWSSQSBroker.ConsumeDeliveriesForTesting(deliveries, concurrency, wk, pool, errorsChan)
	assert.NotNil(t, err)

	go func() { testAWSSQSBroker.GetStopChanForTesting() <- 1 }()
	err = testAWSSQSBroker.ConsumeDeliveriesForTesting(deliveries, concurrency, wk, pool, errorsChan)
	assert.Nil(t, err)

	outputCopy := *receiveMessageOutput
	outputCopy.Messages = []*sqs.Message{}
	go func() { deliveries <- &outputCopy }()
	err = testAWSSQSBroker.ConsumeDeliveriesForTesting(deliveries, concurrency, wk, pool, errorsChan)
	e := <-errorsChan
	assert.NotNil(t, e)
	assert.Nil(t, err)

	go func() { pool <- struct{}{} }()
	go func() { deliveries <- receiveMessageOutput }()
	err = testAWSSQSBroker.ConsumeDeliveriesForTesting(deliveries, concurrency, wk, pool, errorsChan)
	p := <-pool
	assert.NotNil(t, p)
	assert.Nil(t, err)
}

func TestPrivateFunc_deleteOne(t *testing.T) {
	err := testAWSSQSBroker.DeleteOneForTesting(receiveMessageOutput)
	assert.Nil(t, err)

	err = errAWSSQSBroker.DeleteOneForTesting(receiveMessageOutput)
	assert.NotNil(t, err)
}
<|endoftext|>


<commit_before>package main

import (
    "fmt"
    "os"
    "log"
)

func checkError(err error) {
    if err != nil {
        log.Fatal(err)
        os.Exit(1)
    }
}
func main() {
    //open dictionary file
    file , err := os.Open("dictionary")
    checkError(err)
    data := make([]byte, 100)
    count, err := file.Read(data)
    checkError(err)

    fmt.Println("read %d bytes: %q\n", count, data[:count])
}
<commit_msg>can search word<commit_after>package main

import (
    "fmt"
    "os"
    "log"
    "strings"
)

func checkError(err error) {
    if err != nil {
        log.Fatal(err)
        os.Exit(1)
    }
}

func readDictionary() []byte {
    //open dictionary file
    file , err := os.Open("dictionary")
    checkError(err)
    defer file.Close()

    //get the file size
    stat, err := file.Stat()
    checkError(err)

    //read the file
    data := make([]byte, stat.Size())
    _, err = file.Read(data)
    checkError(err)

    return data
}

func searchWordLine(word string) string {
    data := string(readDictionary())
    wordLines := strings.Split(data, "\n")
    var wordLine string
    for i := 0; i < len(wordLines); i++ {
        target := strings.Split(wordLines[i], ":")[0]
        if strings.ToLower(word) == strings.ToLower(target) {
            wordLine = wordLines[i]
        }
    }
    return wordLine
}

func printWordLine(wordLine string) {
    for i := 0; i < len(strings.Split(wordLine, ":")); i++ {
        fmt.Println(strings.Split(wordLine, ":")[i])
    }
    fmt.Println("finished")
}

func main() {
    word := os.Args[1]

    wordLine := searchWordLine(word)

    printWordLine(wordLine)
}
<|endoftext|>


<commit_before>package jsonpointer

import (
	"log"
	"reflect"
)

// DiffType represents the type of difference between two JSON
// structures.
type DiffType int

const (
	// MissingA designates a path that was missing from the first
	// argument of the diff.
	MissingA = DiffType(iota)
	// MissingB designates a path taht was missing from the second
	// argument of the diff.
	MissingB
	// Different designates a path that is found in both
	// arguments, but with different values.
	Different
)

var diffNames = []string{"missing a", "missing b", "different"}

func (d DiffType) String() string {
	return diffNames[d]
}

func must(err error) {
	if err != nil {
		log.Panic(err)
	}
}

// Diff returns the differences between two json blobs.
func Diff(a, b []byte) (map[string]DiffType, error) {
	alist, err := ListPointers(a)
	if err != nil {
		return nil, err
	}
	blist, err := ListPointers(b)
	if err != nil {
		return nil, err
	}

	amap := map[string]bool{}
	bmap := map[string]bool{}
	for _, v := range alist {
		amap[v] = true
	}
	for _, v := range blist {
		bmap[v] = true
	}

	rv := map[string]DiffType{}

	for _, v := range alist {
		if v == "" {
			continue
		}
		if bmap[v] {
			var aval, bval interface{}
			must(FindDecode(a, v, &aval))
			must(FindDecode(b, v, &bval))
			if !reflect.DeepEqual(aval, bval) {
				rv[v] = Different
			}
		} else {
			rv[v] = MissingB
		}
	}

	for _, v := range blist {
		if !amap[v] {
			rv[v] = MissingA
		}
	}

	return rv, nil
}
<commit_msg>Remove some redundant code in diff calculation<commit_after>package jsonpointer

import (
	"log"
	"reflect"
)

// DiffType represents the type of difference between two JSON
// structures.
type DiffType int

const (
	// MissingA designates a path that was missing from the first
	// argument of the diff.
	MissingA = DiffType(iota)
	// MissingB designates a path taht was missing from the second
	// argument of the diff.
	MissingB
	// Different designates a path that is found in both
	// arguments, but with different values.
	Different
)

var diffNames = []string{"missing a", "missing b", "different"}

func (d DiffType) String() string {
	return diffNames[d]
}

func must(err error) {
	if err != nil {
		log.Panic(err)
	}
}

func pointerSet(j []byte) (map[string]bool, error) {
	a, err := ListPointers(j)
	if err != nil {
		return nil, err
	}
	rv := map[string]bool{}
	for _, v := range a {
		rv[v] = true
	}
	return rv, nil
}

// Diff returns the differences between two json blobs.
func Diff(a, b []byte) (map[string]DiffType, error) {
	amap, err := pointerSet(a)
	if err != nil {
		return nil, err
	}
	bmap, err := pointerSet(b)
	if err != nil {
		return nil, err
	}

	rv := map[string]DiffType{}

	for v := range amap {
		if v == "" {
			continue
		}
		if bmap[v] {
			var aval, bval interface{}
			must(FindDecode(a, v, &aval))
			must(FindDecode(b, v, &bval))
			if !reflect.DeepEqual(aval, bval) {
				rv[v] = Different
			}
		} else {
			rv[v] = MissingB
		}
	}

	for v := range bmap {
		if !amap[v] {
			rv[v] = MissingA
		}
	}

	return rv, nil
}
<|endoftext|>


<commit_before><commit_msg>another bug in git<commit_after>package box

import (
//	"fmt"
)

// Elastic tabstop experiment section. Not ready for general use by any means
// the text/tabwriter package implements elastic tabstops, but that package
// assumes that all chars are the same width and that text needs to be rescanned.
//
// The frame already distinguishes between tabs, newlines, and plain text characters
// by encapsulating them in measured boxes. A direct copy of the tabwriter code would
// ignore the datastructures in the frame and their sublinear runtime cost.
//
// A few cases need to be handles for elastic tabstops:
//
// Insertion:
// 	An insert always creates a new box, this box can take on the form '\n', '\t'
//  or be part of the plain text character set which for this purpose is the set
//  of characters not equal to '\t' or '\n'. A successful insert operation runs
//  to completion and results in a net gain of runes (not taking into consideration
//  the runes which run off the frame and are deleted). An insert never subtracts
//  of boxes assuming that all characters stay on the frame. There are now a few
//  cases:
//
//  1. The insert contains plain text characters
//		This is already a non-trivial case. Plaintext characters can move a column of
//		text far enough to extend the range of the column's tab stop. The procedure then
//		is to seek forth and determine if a tab follows the insertion point. This can be
//		completed in sub-linear time, as plain text boxes are merged into one before the
//		start of a hard newline or soft wrap (when a box width exceeds frame.r.Max). The
//		soft line wrap property of boxes may aggregate the runtime performance of this
//		implementation by containing sparse newlines. In this case we consider an algorithm
//		that gives up and favors performance over elasticity. Elastic tabstops have little
//		use in binary files anyway and we probably want to give users the opportunity to turn
//		them off. The seek forth operation scans forward and locates the first newline, while
//		counting the occurrence of \t boxes and measuring their width. The maximum width column
//		is tracked as well. The seek forth operation terminates whenever a column-less line is
//		located (formally defined as a run of boxes separated by a newline containing no \t boxes
//

func (f *Run) Stretch(nb int) {
	//	fmt.Println()
	//	fmt.Printf("\n\ntrace bn=%d\n", nb)
	nc := 0
	nl := 0
	dx := 0

	cmax := make(map[int]int)
	cbox := make(map[int][]int)

	nb = f.FindCell(nb)
Loop:
	for ; nb < f.Nbox; nb++ {
		switch b := &f.Box[nb]; b.BC {
		case '\t':
			dx += b.Width
			cbox[nc] = append(cbox[nc], nb)
			max := cmax[nc]
			if dx > max {
				cmax[nc] = dx
			}
			nc++
			dx = 0
		case '\n':
			nl++
			dx = 0
			if nc == 0 {
				// A line with no tabs; end of cell
				break Loop
			}
			nc = 0
		default:
			dx += b.Width
		}
	}
	for c, bns := range cbox {
		max := cmax[c]
		for _, bn := range bns {
			b := &f.Box[bn]
			b.Width = max
			if bn == 0 {
				continue
			}
			pb := f.Box[bn-1]
			if pb.BC != '\n' {
				b.Width -= f.Box[bn-1].Width
			}
		}
	}
}

func (f *Run) Findcol(bn int, coln int) (cbn int, xmax int) {
	c := 0
	for ; bn < f.Nbox; bn++ {
		b := &f.Box[bn]
		if b.BC == '\t' {
			c++
		}
		if b.BC != '\n' {
			xmax += b.Width
		}
		if c == coln {
			break
		}
		bn++
	}
	if c != coln {
		return -1, 0
	}
	return bn, xmax

}

func (f *Run) Colof(bn int) (coln, xmax int) {
	if bn == 0 {
		return 0, 0
	}
	bs := f.StartLine(bn)
	for {
		b := &f.Box[bs]
		if b.BC == '\t' {
			coln++
		}
		if b.BC != '\n' {
			xmax += b.Width
		}
		if bn == bs {
			break
		}
		bs++
	}
	if xmax != 0 {
		coln++
	}
	return coln, xmax
}

// FindCell returns the first box in the cell
func (f *Run) FindCell(bn int) int {
	if bn == 0 {
		return 0
	}
	ncols := 0
	nrows := 0
	oldbn := bn
	bn = f.EndLine(bn)
	b := &f.Box[bn]
	for bn-1 != 0 {
		b = &f.Box[bn-1]
		switch b.BC {
		case '\n':

			if ncols == 0 {
				if nrows == 0 {
					return oldbn
				}
				return bn + 1
			}
			nrows++
			ncols = 0
		case '\t':
			ncols++
		default:
		}
		bn--
	}
	return bn
}

func (f *Run) StartLine(bn int) int {
	for ; bn-1 >= 0; bn-- {
		b := &f.Box[bn-1]
		if b.BC == '\n' {
			break
		}
	}
	return bn
}

func (f *Run) EndLine(bn int) int {
	for bn < f.Nbox {
		b := &f.Box[bn]
		if b.BC == '\n' {
			break
		}
		bn++
	}
	return bn
}

func (f *Run) NextLine(bn int) int {
	bn = f.EndLine(bn)
	if bn < f.Nbox {
		return bn + 1
	}
	return bn
}

func (f *Run) PrevLine(bn int) int {
	for ; bn >= 0; bn-- {
		b := &f.Box[bn]
		if b.BC == '\n' {
			break
		}
	}
	if bn == -1 && f.Box[0].BC == '\n' {
		return 0
	}
	for bn-1 >= 0 {
		b := &f.Box[bn-1]
		if b.BC == '\n' {
			break
		}
		bn--
	}
	return bn
}
<|endoftext|>


<commit_before>package dnsr

import (
	"fmt"
	"strings"
	"sync"
	"time"

	lru "github.com/hashicorp/golang-lru"
	"github.com/miekg/dns"
)

type Resolver struct {
	cache  *lru.Cache
	client *dns.Client
}

func New(size int) *Resolver {
	if size < 0 {
		size = 10000
	}
	cache, _ := lru.New(size)
	r := &Resolver{
		client: &dns.Client{},
		cache:  cache,
	}
	r.cacheRoot()
	return r
}

func (r *Resolver) Resolve(qname string, qtype uint16) <-chan dns.RR {
	c := make(chan dns.RR, 20)
	go func() {
		qname = toLowerFQDN(qname)
		defer close(c)
		if rrs := r.cacheGet(qname, qtype); rrs != nil {
			inject(c, rrs...)
			return
		}
		pname, ok := qname, true
		if qtype == dns.TypeNS {
			pname, ok = parent(qname)
		}
	outer:
		for ; ok; pname, ok = parent(pname) {
			for nrr := range r.Resolve(pname, dns.TypeNS) {
				ns, ok := nrr.(*dns.NS)
				if !ok {
					fmt.Printf("; non-NS record! %s\n", nrr.String())
					continue
				}
				for arr := range r.Resolve(ns.Ns, dns.TypeA) {
					a, ok := arr.(*dns.A)
					if !ok {
						fmt.Printf("; non-A record!\n")
						continue
					}
					addr := a.A.String() + ":53"
					qmsg := &dns.Msg{}
					qmsg.SetQuestion(qname, qtype)
					qmsg.MsgHdr.RecursionDesired = false
					fmt.Printf(";; dig +norecurse @%s %s %s\n", a.A.String(), qname, dns.TypeToString[qtype])
					rmsg, _, err := r.client.Exchange(qmsg, addr)
					if err != nil {
						continue // FIXME: handle errors better from flaky/failing NS servers
					}
					if rmsg.Rcode == dns.RcodeNameError {
						r.cacheAdd(qname, qtype) // FIXME: cache NXDOMAIN responses responsibly
					}
					r.cacheSave(rmsg.Answer...)
					r.cacheSave(rmsg.Ns...)
					r.cacheSave(rmsg.Extra...)
					// if qtype == dns.TypeNS {
					// 	for _, rr := range rmsg.Ns {
					// 		if rr.Header().Rrtype == dns.TypeNS {
					// 			// fmt.Printf("; Found NS server: %s -> %s\n", qname, rr.(*dns.NS).Ns)
					// 			r.cacheAdd(qname, qtype, rr)
					// 			// c <- rr
					// 			// return
					// 		}
					// 	}
					// }
					break outer
				}
			}
		}

		if rrs := r.cacheGet(qname, qtype); rrs != nil {
			inject(c, rrs...)
			return
		}
		fmt.Printf(";; FAILED: %s %s\n", qname, dns.TypeToString[qtype])

		for _, crr := range r.cacheGet(qname, dns.TypeCNAME) {
			cn, ok := crr.(*dns.CNAME)
			if !ok {
				continue
			}
			r.cacheAdd(qname, qtype, crr)
			for rr := range r.Resolve(cn.Target, qtype) {
				fmt.Printf("%s\n", rr.String())
				r.cacheAdd(qname, qtype, rr)
				c <- rr
			}
		}
	}()
	return c
}

func inject(c chan<- dns.RR, rrs ...dns.RR) {
	for _, rr := range rrs {
		c <- rr
	}
}

func parent(name string) (string, bool) {
	labels := dns.SplitDomainName(name)
	if labels == nil {
		return "", false
	}
	return toLowerFQDN(strings.Join(labels[1:], ".")), true
}

func toLowerFQDN(name string) string {
	return dns.Fqdn(strings.ToLower(name))
}

type key struct {
	qname string
	qtype uint16
}

type entry struct {
	m   sync.RWMutex
	exp time.Time
	rrs map[dns.RR]struct{}
}

func (r *Resolver) cacheRoot() {
	for t := range dns.ParseZone(strings.NewReader(root), "", "") {
		if t.Error == nil {
			r.cacheSave(t.RR)
		}
	}
}

// cacheGet returns a randomly ordered slice of DNS records.
func (r *Resolver) cacheGet(qname string, qtype uint16) []dns.RR {
	e := r.getEntry(qname, qtype)
	if e == nil {
		return nil
	}
	e.m.RLock()
	defer e.m.RUnlock()
	rrs := make([]dns.RR, 0, len(e.rrs))
	for rr, _ := range e.rrs {
		rrs = append(rrs, rr)
	}
	return rrs
}

// cacheSave saves 1 or more DNS records to the resolver cache.
func (r *Resolver) cacheSave(rrs ...dns.RR) {
	for _, rr := range rrs {
		h := rr.Header()
		r.cacheAdd(h.Name, h.Rrtype, rr)
	}
}

// cacheAdd adds 0 or more DNS records to the resolver cache for a specific
// domain name and record type. This ensures the cache entry exists, even
// if empty, for NXDOMAIN responses.
func (r *Resolver) cacheAdd(qname string, qtype uint16, rrs ...dns.RR) {
	qname = toLowerFQDN(qname)
	now := time.Now()
	e := r.getEntry(qname, qtype)
	if e == nil {
		e = &entry{
			exp: now.Add(24 * time.Hour),
			rrs: make(map[dns.RR]struct{}, 0),
		}
		r.cache.Add(key{qname, qtype}, e)
	}
	e.m.Lock()
	defer e.m.Unlock()
	for _, rr := range rrs {
		h := rr.Header()
		if h.Rrtype != qtype {
			continue
		}
		e.rrs[rr] = struct{}{}
		exp := now.Add(time.Duration(h.Ttl) * time.Second)
		if exp.Before(e.exp) {
			e.exp = exp
		}
	}
}

func (r *Resolver) getEntry(qname string, qtype uint16) *entry {
	c, ok := r.cache.Get(key{qname, qtype})
	if !ok {
		return nil
	}
	e := c.(*entry)
	if time.Now().After(e.exp) {
		return nil
	}
	return e
}
<commit_msg>less debugging<commit_after>package dnsr

import (
	"fmt"
	"strings"
	"sync"
	"time"

	lru "github.com/hashicorp/golang-lru"
	"github.com/miekg/dns"
)

type Resolver struct {
	cache  *lru.Cache
	client *dns.Client
}

func New(size int) *Resolver {
	if size < 0 {
		size = 10000
	}
	cache, _ := lru.New(size)
	r := &Resolver{
		client: &dns.Client{},
		cache:  cache,
	}
	r.cacheRoot()
	return r
}

func (r *Resolver) Resolve(qname string, qtype uint16) <-chan dns.RR {
	c := make(chan dns.RR, 20)
	go func() {
		qname = toLowerFQDN(qname)
		defer close(c)
		if rrs := r.cacheGet(qname, qtype); rrs != nil {
			inject(c, rrs...)
			return
		}
		pname, ok := qname, true
		if qtype == dns.TypeNS {
			pname, ok = parent(qname)
		}
	outer:
		for ; ok; pname, ok = parent(pname) {
			for nrr := range r.Resolve(pname, dns.TypeNS) {
				ns, ok := nrr.(*dns.NS)
				if !ok {
					fmt.Printf("; non-NS record! %s\n", nrr.String())
					continue
				}
				for arr := range r.Resolve(ns.Ns, dns.TypeA) {
					a, ok := arr.(*dns.A)
					if !ok {
						fmt.Printf("; non-A record!\n")
						continue
					}
					addr := a.A.String() + ":53"
					qmsg := &dns.Msg{}
					qmsg.SetQuestion(qname, qtype)
					qmsg.MsgHdr.RecursionDesired = false
					fmt.Printf(";; dig +norecurse @%s %s %s\n", a.A.String(), qname, dns.TypeToString[qtype])
					rmsg, _, err := r.client.Exchange(qmsg, addr)
					if err != nil {
						continue // FIXME: handle errors better from flaky/failing NS servers
					}
					if rmsg.Rcode == dns.RcodeNameError {
						r.cacheAdd(qname, qtype) // FIXME: cache NXDOMAIN responses responsibly
					}
					r.cacheSave(rmsg.Answer...)
					r.cacheSave(rmsg.Ns...)
					r.cacheSave(rmsg.Extra...)
					// if qtype == dns.TypeNS {
					// 	for _, rr := range rmsg.Ns {
					// 		if rr.Header().Rrtype == dns.TypeNS {
					// 			// fmt.Printf("; Found NS server: %s -> %s\n", qname, rr.(*dns.NS).Ns)
					// 			r.cacheAdd(qname, qtype, rr)
					// 			// c <- rr
					// 			// return
					// 		}
					// 	}
					// }
					break outer
				}
			}
		}

		if rrs := r.cacheGet(qname, qtype); rrs != nil {
			inject(c, rrs...)
			return
		}
		// fmt.Printf(";; FAILED: %s %s\n", qname, dns.TypeToString[qtype])

		for _, crr := range r.cacheGet(qname, dns.TypeCNAME) {
			cn, ok := crr.(*dns.CNAME)
			if !ok {
				continue
			}
			r.cacheAdd(qname, qtype, crr)
			for rr := range r.Resolve(cn.Target, qtype) {
				fmt.Printf("%s\n", rr.String())
				r.cacheAdd(qname, qtype, rr)
				c <- rr
			}
		}
	}()
	return c
}

func inject(c chan<- dns.RR, rrs ...dns.RR) {
	for _, rr := range rrs {
		c <- rr
	}
}

func parent(name string) (string, bool) {
	labels := dns.SplitDomainName(name)
	if labels == nil {
		return "", false
	}
	return toLowerFQDN(strings.Join(labels[1:], ".")), true
}

func toLowerFQDN(name string) string {
	return dns.Fqdn(strings.ToLower(name))
}

type key struct {
	qname string
	qtype uint16
}

type entry struct {
	m   sync.RWMutex
	exp time.Time
	rrs map[dns.RR]struct{}
}

func (r *Resolver) cacheRoot() {
	for t := range dns.ParseZone(strings.NewReader(root), "", "") {
		if t.Error == nil {
			r.cacheSave(t.RR)
		}
	}
}

// cacheGet returns a randomly ordered slice of DNS records.
func (r *Resolver) cacheGet(qname string, qtype uint16) []dns.RR {
	e := r.getEntry(qname, qtype)
	if e == nil {
		return nil
	}
	e.m.RLock()
	defer e.m.RUnlock()
	rrs := make([]dns.RR, 0, len(e.rrs))
	for rr, _ := range e.rrs {
		rrs = append(rrs, rr)
	}
	return rrs
}

// cacheSave saves 1 or more DNS records to the resolver cache.
func (r *Resolver) cacheSave(rrs ...dns.RR) {
	for _, rr := range rrs {
		h := rr.Header()
		r.cacheAdd(h.Name, h.Rrtype, rr)
	}
}

// cacheAdd adds 0 or more DNS records to the resolver cache for a specific
// domain name and record type. This ensures the cache entry exists, even
// if empty, for NXDOMAIN responses.
func (r *Resolver) cacheAdd(qname string, qtype uint16, rrs ...dns.RR) {
	qname = toLowerFQDN(qname)
	now := time.Now()
	e := r.getEntry(qname, qtype)
	if e == nil {
		e = &entry{
			exp: now.Add(24 * time.Hour),
			rrs: make(map[dns.RR]struct{}, 0),
		}
		r.cache.Add(key{qname, qtype}, e)
	}
	e.m.Lock()
	defer e.m.Unlock()
	for _, rr := range rrs {
		h := rr.Header()
		if h.Rrtype != qtype {
			continue
		}
		e.rrs[rr] = struct{}{}
		exp := now.Add(time.Duration(h.Ttl) * time.Second)
		if exp.Before(e.exp) {
			e.exp = exp
		}
	}
}

func (r *Resolver) getEntry(qname string, qtype uint16) *entry {
	c, ok := r.cache.Get(key{qname, qtype})
	if !ok {
		return nil
	}
	e := c.(*entry)
	if time.Now().After(e.exp) {
		return nil
	}
	return e
}
<|endoftext|>


<commit_before>/*
   Copyright 2013 Juliano Martinez <juliano@martinez.io>

   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.

   @author: Juliano Martinez
*/

package utils

import (
	"fmt"
	"log"
	"log/syslog"
)

var (
	_log, s_err = syslog.New(syslog.LOG_ERR, "hpr")
)

func Check(err error, message string) {
	check(err, message, false)
}

func CheckPanic(err error, message string) {
	check(err, message, true)
}

func Log(message string) {
	CheckPanic(s_err, "Unable to write syslog message")
	_log.Info(message)
	defer _log.Close()
}

func check(err error, message string, _panic bool) {
	if err != nil {
		msg := fmt.Sprintf("%s: %s", message, err)
		if s_err != nil {
			log.Fatalln("Unable to write syslog message")
		}
		_log.Warning(msg)
		defer _log.Close()
		log.Fatalln(msg)
		if _panic {
			panic(msg)
		}
	}
}
<commit_msg>fixing check to no panic without panic<commit_after>/*
   Copyright 2013 Juliano Martinez <juliano@martinez.io>

   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.

   @author: Juliano Martinez
*/

package utils

import (
	"fmt"
	"log"
	"log/syslog"
)

var (
	_log, s_err = syslog.New(syslog.LOG_ERR, "hpr")
)

func Check(err error, message string) {
	check(err, message, false)
}

func CheckPanic(err error, message string) {
	check(err, message, true)
}

func Log(message string) {
	CheckPanic(s_err, "Unable to write syslog message")
	_log.Info(message)
	defer _log.Close()
}

func check(err error, message string, _panic bool) {
	if err != nil {
		msg := fmt.Sprintf("%s: %s", message, err)
		if s_err != nil {
			log.Fatalln("Unable to write syslog message")
		}
		_log.Warning(msg)
		defer _log.Close()
		log.Println(msg)
		if _panic {
			panic(msg)
		}
	}
}
<|endoftext|>


<commit_before>package utils

import (
	"io/ioutil"
	"log"
	"os"
	"os/user"

	"gopkg.in/yaml.v2"
)

var history_file string = ".git-checkout-history"

type BranchList struct {
	Branches []string
}

func getHomeDir() string {
	usr, err := user.Current()
	if err != nil {
		log.Fatal(err)
	}
	return usr.HomeDir
}

func OpenHistoryFile() (f *os.File, err error) {
	file_path := getHomeDir() + "/" + history_file
	if _, err := os.Stat(file_path); os.IsNotExist(err) {
		return os.Create(file_path)
	} else {
		return os.Open(file_path)
	}
}

func Store(branch string) {
	branchList := BranchList{}
	rcfile, err := OpenHistoryFile()
	if err != nil {
		log.Fatal(err)
	}
	rcfile.Close()

	file_path := getHomeDir() + "/" + history_file
	data, err := ioutil.ReadFile(file_path)
	if err != nil {
		log.Fatal(err)
	}

	err = yaml.Unmarshal(data, &branchList)
	if err != nil {
		log.Fatal(err)
	}

	branchList.Branches = append([]string{branch}, branchList.Branches...)

	data, err = yaml.Marshal(&branchList)
	if err != nil {
		log.Fatal(err)
	}

	err = ioutil.WriteFile(file_path, data, 0644)
	if err != nil {
		log.Fatal(err)
	}
}

func Branches() []string {
	branchList := BranchList{}

	file_path := getHomeDir() + "/" + history_file
	data, err := ioutil.ReadFile(file_path)
	if err != nil {
		log.Fatal(err)
	}

	err = yaml.Unmarshal(data, &branchList)
	if err != nil {
		log.Fatal(err)
	}

	return branchList.Branches
}
<commit_msg>utils.go: Change error message when no history file<commit_after>package utils

import (
	"io/ioutil"
	"log"
	"os"
	"os/user"

	"gopkg.in/yaml.v2"
)

var history_file string = ".git-checkout-history"

type BranchList struct {
	Branches []string
}

func getHomeDir() string {
	usr, err := user.Current()
	if err != nil {
		log.Fatal(err)
	}
	return usr.HomeDir
}

func OpenHistoryFile() (f *os.File, err error) {
	file_path := getHomeDir() + "/" + history_file
	if _, err := os.Stat(file_path); os.IsNotExist(err) {
		return os.Create(file_path)
	} else {
		return os.Open(file_path)
	}
}

func Store(branch string) {
	branchList := BranchList{}
	rcfile, err := OpenHistoryFile()
	if err != nil {
		log.Fatal(err)
	}
	rcfile.Close()

	file_path := getHomeDir() + "/" + history_file
	data, err := ioutil.ReadFile(file_path)
	if err != nil {
		log.Fatal(err)
	}

	err = yaml.Unmarshal(data, &branchList)
	if err != nil {
		log.Fatal(err)
	}

	branchList.Branches = append([]string{branch}, branchList.Branches...)

	data, err = yaml.Marshal(&branchList)
	if err != nil {
		log.Fatal(err)
	}

	err = ioutil.WriteFile(file_path, data, 0644)
	if err != nil {
		log.Fatal(err)
	}
}

func Branches() []string {
	branchList := BranchList{}

	file_path := getHomeDir() + "/" + history_file
	data, err := ioutil.ReadFile(file_path)
	if err != nil {
		log.Fatal("ERROR: No checkout history file. Run `checkout-store` to create it.")
	}

	err = yaml.Unmarshal(data, &branchList)
	if err != nil {
		log.Fatal(err)
	}

	return branchList.Branches
}
<|endoftext|>


<commit_before>package valid

import (
	"strings"

	"github.com/ije/gox/utils"
)

var (
	v09        = &Validator{{'0', '9'}}
	vaz        = &Validator{{'a', 'z'}}
	vazAZ      = &Validator{{'a', 'z'}, {'A', 'Z'}}
	v09AZ      = &Validator{{'0', '9'}, {'A', 'Z'}}
	vHex       = &Validator{{'0', '9'}, {'a', 'f'}, {'A', 'F'}}
	vSlug      = &Validator{{'0', '9'}, {'a', 'z'}, {'A', 'Z'}, {'.', 0}, {'-', 0}}
	vEmailName = &Validator{{'0', '9'}, {'a', 'z'}, {'A', 'Z'}, {'.', 0}, {'-', 0}, {'_', 0}}
)

func IsNumber(s string, a ...int) bool {
	return v09.Is(s, a...)
}

func IsHexString(s string, a ...int) bool {
	return vHex.Is(s, a...)
}

func IsIETFLangTag(s string) bool {
	l, c := utils.SplitByFirstByte(s, '-')
	if !vaz.Is(l, 2) {
		return false
	}
	if len(c) > 0 {
		return v09AZ.Is(c)
	}
	return true
}

func IsIPv4(s string) bool {
	for i, p := range strings.Split(s, ".") {
		if i > 3 || !v09.Is(p, 1, 3) || p[0] > '2' {
			return false
		}
	}
	return true
}

func IsDomain(s string) bool {
	if len(s) < 4 {
		return false
	}
	dn, dt := utils.SplitByLastByte(s, '.')
	return IsSlug(dn, 0) && vazAZ.Is(dt)
}

func IsSlug(s string, a ...int) bool {
	var maxLen int
	if len(a) > 0 {
		maxLen = a[0]
	}
	l := len(s)
	if l == 0 || (maxLen > 0 && l > maxLen) {
		return false
	}
	for _, c := range []byte{s[0], s[l-1]} {
		switch c {
		case '.', '-':
			return false
		}
	}
	return vSlug.Is(s)
}

func IsEmail(s string) bool {
	if len(s) < 6 {
		return false
	}
	name, domain := utils.SplitByLastByte(s, '@')
	if !IsDomain(domain) {
		return false
	}
	nl := len(name)
	if nl == 0 {
		return false
	}
	for _, c := range []byte{name[0], name[nl-1]} {
		switch c {
		case '.', '_', '-':
			return false
		}
	}
	return vEmailName.Is(name)
}
<commit_msg>add ipv6 validator(fake...)<commit_after>package valid

import (
	"strings"

	"github.com/ije/gox/utils"
)

var (
	v09        = &Validator{{'0', '9'}}
	vaz        = &Validator{{'a', 'z'}}
	vazAZ      = &Validator{{'a', 'z'}, {'A', 'Z'}}
	v09AZ      = &Validator{{'0', '9'}, {'A', 'Z'}}
	vHex       = &Validator{{'0', '9'}, {'a', 'f'}, {'A', 'F'}}
	vSlug      = &Validator{{'0', '9'}, {'a', 'z'}, {'A', 'Z'}, {'.', 0}, {'-', 0}}
	vEmailName = &Validator{{'0', '9'}, {'a', 'z'}, {'A', 'Z'}, {'.', 0}, {'-', 0}, {'_', 0}}
)

func IsNumber(s string, a ...int) bool {
	return v09.Is(s, a...)
}

func IsHexString(s string, a ...int) bool {
	return vHex.Is(s, a...)
}

func IsIETFLangTag(s string) bool {
	l, c := utils.SplitByFirstByte(s, '-')
	if !vaz.Is(l, 2) {
		return false
	}
	if len(c) > 0 {
		return v09AZ.Is(c)
	}
	return true
}

func IsIP(s string) bool {
	return IsIPv4(s) || IsIPv6(s)
}

func IsIPv4(s string) bool {
	for i, p := range strings.Split(s, ".") {
		if i > 3 || !v09.Is(p, 1, 3) || p[0] > '2' {
			return false
		}
	}
	return true
}

func IsIPv6(s string) bool {
	return false
}

func IsDomain(s string) bool {
	if len(s) < 4 {
		return false
	}
	dn, dt := utils.SplitByLastByte(s, '.')
	return IsSlug(dn, 0) && vazAZ.Is(dt)
}

func IsSlug(s string, a ...int) bool {
	var maxLen int
	if len(a) > 0 {
		maxLen = a[0]
	}
	l := len(s)
	if l == 0 || (maxLen > 0 && l > maxLen) {
		return false
	}
	for _, c := range []byte{s[0], s[l-1]} {
		switch c {
		case '.', '-':
			return false
		}
	}
	return vSlug.Is(s)
}

func IsEmail(s string) bool {
	if len(s) < 6 {
		return false
	}
	name, domain := utils.SplitByLastByte(s, '@')
	if !IsDomain(domain) {
		return false
	}
	nl := len(name)
	if nl == 0 {
		return false
	}
	for _, c := range []byte{name[0], name[nl-1]} {
		switch c {
		case '.', '_', '-':
			return false
		}
	}
	return vEmailName.Is(name)
}
<|endoftext|>


<commit_before>package kloud

import (
	"fmt"

	"koding/kites/kloud/eventer"
	"koding/kites/kloud/kloud/machinestate"
	"koding/kites/kloud/kloud/protocol"

	"github.com/koding/kite"
)

type Controller struct {
	// Incoming arguments
	MachineId    string
	ImageName    string
	InstanceName string

	// Populated later
	CurrenState machinestate.State `json:"-"`
	Provider    protocol.Provider  `json:"-"`
	MachineData *MachineData       `json:"-"`
	Eventer     eventer.Eventer    `json:"-"`
}

type InfoResponse struct {
	State string
	Data  interface{}
}

type controlFunc func(*kite.Request, *Controller) (interface{}, error)

type statePair struct {
	initial machinestate.State
	final   machinestate.State
}

var states = map[string]*statePair{
	"start":   &statePair{initial: machinestate.Starting, final: machinestate.Running},
	"stop":    &statePair{initial: machinestate.Stopping, final: machinestate.Stopped},
	"destroy": &statePair{initial: machinestate.Terminating, final: machinestate.Terminated},
	"restart": &statePair{initial: machinestate.Rebooting, final: machinestate.Running},
}

func (k *Kloud) ControlFunc(method string, control controlFunc) {
	handler := func(r *kite.Request) (interface{}, error) {
		k.Log.Debug("[controller] got a request for method: '%s' with args: %v",
			method, string(r.Args.Raw))

		// this locks are important to prevent consecutive calls from the same user
		k.idlock.Get(r.Username).Lock()
		c, err := k.controller(r)
		if err != nil {
			k.idlock.Get(r.Username).Unlock()
			return nil, err
		}
		k.idlock.Get(r.Username).Unlock()

		// now lock for machine-ids
		k.idlock.Get(c.MachineId).Lock()
		defer k.idlock.Get(c.MachineId).Unlock()

		return control(r, c)
	}

	k.Kite.HandleFunc(method, handler)
}

// controller returns the Controller struct with all necessary entities
// responsible for the given machine Id. It also calls provider.Prepare before
// returning.
func (k *Kloud) controller(r *kite.Request) (*Controller, error) {
	args := &Controller{}
	if err := r.Args.One().Unmarshal(args); err != nil {
		return nil, err
	}

	if args.MachineId == "" {
		return nil, NewError(ErrMachineIdMissing)
	}

	m, err := k.Storage.Get(args.MachineId, &GetOption{
		IncludeMachine:    true,
		IncludeCredential: true,
	})
	if err != nil {
		return nil, err
	}

	k.Log.Debug("[controller]: got machine: %v", m.Machine)

	// prevent request if the machine is terminated. However we want the user
	// to be able to build again
	if (m.Machine.State() == machinestate.Terminating ||
		m.Machine.State() == machinestate.Terminated) &&
		r.Method != "build" {
		return nil, NewError(ErrMachineTerminating)
	}

	provider, ok := providers[m.Provider]
	if !ok {
		return nil, NewError(ErrProviderNotFound)
	}

	if err := provider.Prepare(m.Credential.Meta, m.Machine.Meta); err != nil {
		return nil, err
	}

	return &Controller{
		MachineId:    args.MachineId,
		ImageName:    args.ImageName,
		InstanceName: args.InstanceName,
		Provider:     provider,
		MachineData:  m,
		CurrenState:  m.Machine.State(),
	}, nil
}

// coreMethods is running and returning the event id for the methods start,
// stop, restart and destroy. This method is used to avoid duplication in other
// methods.
func (k *Kloud) coreMethods(r *kite.Request, c *Controller, fn func(*protocol.MachineOptions) error) (interface{}, error) {
	// all core methods works only for machines that are initialized
	if c.CurrenState == machinestate.NotInitialized {
		return nil, NewError(ErrNotInitialized)
	}

	// get our state pair
	s, ok := states[r.Method]
	if !ok {
		return nil, fmt.Errorf("no state pair available for %s", r.Method)
	}
	k.Storage.UpdateState(c.MachineId, s.initial)

	machOptions := &protocol.MachineOptions{
		MachineId: c.MachineId,
		Username:  r.Username,
		Eventer:   k.NewEventer(r.Method + "-" + c.MachineId),
	}

	go func() {
		k.idlock.Get(c.MachineId).Lock()
		defer k.idlock.Get(c.MachineId).Unlock()

		status := s.final
		msg := fmt.Sprintf("%s is finished successfully.", r.Method)

		k.Log.Debug("[controller]: running method %s with mach options %v", r.Method, machOptions)
		err := fn(machOptions)
		if err != nil {
			k.Log.Error("[controller] %s failed: %s. Machine state is Unknown now.", r.Method, err.Error())
			status = machinestate.Unknown
			msg = err.Error()
		}

		k.Storage.UpdateState(c.MachineId, status)
		c.Eventer.Push(&eventer.Event{
			Message:    msg,
			Status:     status,
			Percentage: 100,
		})
	}()

	return ControlResult{
		EventId: c.Eventer.Id(),
		State:   s.initial,
	}, nil
}

func (k *Kloud) start(r *kite.Request, c *Controller) (interface{}, error) {
	fn := func(m *protocol.MachineOptions) error {
		return c.Provider.Start(m)
	}

	return k.coreMethods(r, c, fn)
}

func (k *Kloud) stop(r *kite.Request, c *Controller) (interface{}, error) {
	fn := func(m *protocol.MachineOptions) error {
		return c.Provider.Stop(m)
	}

	return k.coreMethods(r, c, fn)
}

func (k *Kloud) destroy(r *kite.Request, c *Controller) (interface{}, error) {
	fn := func(m *protocol.MachineOptions) error {
		return c.Provider.Destroy(m)
	}

	return k.coreMethods(r, c, fn)
}

func (k *Kloud) restart(r *kite.Request, c *Controller) (interface{}, error) {
	fn := func(m *protocol.MachineOptions) error {
		return c.Provider.Restart(m)
	}

	return k.coreMethods(r, c, fn)
}

func (k *Kloud) info(r *kite.Request, c *Controller) (interface{}, error) {
	if c.CurrenState == machinestate.NotInitialized {
		return nil, NewError(ErrNotInitialized)
	}

	machOptions := &protocol.MachineOptions{
		MachineId: c.MachineId,
		Username:  r.Username,
		Eventer:   c.Eventer,
	}

	info, err := c.Provider.Info(machOptions)
	if err != nil {
		return nil, err
	}

	return &InfoResponse{
		State: c.MachineData.Machine.Status.State,
		Data:  info,
	}, nil
}
<commit_msg>kloud: fix panicking of eventer<commit_after>package kloud

import (
	"fmt"

	"koding/kites/kloud/eventer"
	"koding/kites/kloud/kloud/machinestate"
	"koding/kites/kloud/kloud/protocol"

	"github.com/koding/kite"
)

type Controller struct {
	// Incoming arguments
	MachineId    string
	ImageName    string
	InstanceName string

	// Populated later
	CurrenState machinestate.State `json:"-"`
	Provider    protocol.Provider  `json:"-"`
	MachineData *MachineData       `json:"-"`
	Eventer     eventer.Eventer    `json:"-"`
}

type InfoResponse struct {
	State string
	Data  interface{}
}

type controlFunc func(*kite.Request, *Controller) (interface{}, error)

type statePair struct {
	initial machinestate.State
	final   machinestate.State
}

var states = map[string]*statePair{
	"start":   &statePair{initial: machinestate.Starting, final: machinestate.Running},
	"stop":    &statePair{initial: machinestate.Stopping, final: machinestate.Stopped},
	"destroy": &statePair{initial: machinestate.Terminating, final: machinestate.Terminated},
	"restart": &statePair{initial: machinestate.Rebooting, final: machinestate.Running},
}

func (k *Kloud) ControlFunc(method string, control controlFunc) {
	handler := func(r *kite.Request) (interface{}, error) {
		k.Log.Debug("[controller] got a request for method: '%s' with args: %v",
			method, string(r.Args.Raw))

		// this locks are important to prevent consecutive calls from the same user
		k.idlock.Get(r.Username).Lock()
		c, err := k.controller(r)
		if err != nil {
			k.idlock.Get(r.Username).Unlock()
			return nil, err
		}
		k.idlock.Get(r.Username).Unlock()

		// now lock for machine-ids
		k.idlock.Get(c.MachineId).Lock()
		defer k.idlock.Get(c.MachineId).Unlock()

		return control(r, c)
	}

	k.Kite.HandleFunc(method, handler)
}

// controller returns the Controller struct with all necessary entities
// responsible for the given machine Id. It also calls provider.Prepare before
// returning.
func (k *Kloud) controller(r *kite.Request) (*Controller, error) {
	args := &Controller{}
	if err := r.Args.One().Unmarshal(args); err != nil {
		return nil, err
	}

	if args.MachineId == "" {
		return nil, NewError(ErrMachineIdMissing)
	}

	m, err := k.Storage.Get(args.MachineId, &GetOption{
		IncludeMachine:    true,
		IncludeCredential: true,
	})
	if err != nil {
		return nil, err
	}

	k.Log.Debug("[controller]: got machine: %v", m.Machine)

	// prevent request if the machine is terminated. However we want the user
	// to be able to build again
	if (m.Machine.State() == machinestate.Terminating ||
		m.Machine.State() == machinestate.Terminated) &&
		r.Method != "build" {
		return nil, NewError(ErrMachineTerminating)
	}

	provider, ok := providers[m.Provider]
	if !ok {
		return nil, NewError(ErrProviderNotFound)
	}

	if err := provider.Prepare(m.Credential.Meta, m.Machine.Meta); err != nil {
		return nil, err
	}

	return &Controller{
		MachineId:    args.MachineId,
		ImageName:    args.ImageName,
		InstanceName: args.InstanceName,
		Provider:     provider,
		MachineData:  m,
		CurrenState:  m.Machine.State(),
	}, nil
}

// coreMethods is running and returning the event id for the methods start,
// stop, restart and destroy. This method is used to avoid duplication in other
// methods.
func (k *Kloud) coreMethods(r *kite.Request, c *Controller, fn func(*protocol.MachineOptions) error) (interface{}, error) {
	// all core methods works only for machines that are initialized
	if c.CurrenState == machinestate.NotInitialized {
		return nil, NewError(ErrNotInitialized)
	}

	// get our state pair
	s, ok := states[r.Method]
	if !ok {
		return nil, fmt.Errorf("no state pair available for %s", r.Method)
	}
	k.Storage.UpdateState(c.MachineId, s.initial)

	c.Eventer = k.NewEventer(r.Method + "-" + c.MachineId)

	machOptions := &protocol.MachineOptions{
		MachineId: c.MachineId,
		Username:  r.Username,
		Eventer:   c.Eventer,
	}

	go func() {
		k.idlock.Get(c.MachineId).Lock()
		defer k.idlock.Get(c.MachineId).Unlock()

		status := s.final
		msg := fmt.Sprintf("%s is finished successfully.", r.Method)

		k.Log.Debug("[controller]: running method %s with mach options %v", r.Method, machOptions)
		err := fn(machOptions)
		if err != nil {
			k.Log.Error("[controller] %s failed: %s. Machine state is Unknown now.", r.Method, err.Error())
			status = machinestate.Unknown
			msg = err.Error()
		}

		k.Storage.UpdateState(c.MachineId, status)
		c.Eventer.Push(&eventer.Event{
			Message:    msg,
			Status:     status,
			Percentage: 100,
		})
	}()

	return ControlResult{
		EventId: c.Eventer.Id(),
		State:   s.initial,
	}, nil
}

func (k *Kloud) start(r *kite.Request, c *Controller) (interface{}, error) {
	fn := func(m *protocol.MachineOptions) error {
		return c.Provider.Start(m)
	}

	return k.coreMethods(r, c, fn)
}

func (k *Kloud) stop(r *kite.Request, c *Controller) (interface{}, error) {
	fn := func(m *protocol.MachineOptions) error {
		return c.Provider.Stop(m)
	}

	return k.coreMethods(r, c, fn)
}

func (k *Kloud) destroy(r *kite.Request, c *Controller) (interface{}, error) {
	fn := func(m *protocol.MachineOptions) error {
		return c.Provider.Destroy(m)
	}

	return k.coreMethods(r, c, fn)
}

func (k *Kloud) restart(r *kite.Request, c *Controller) (interface{}, error) {
	fn := func(m *protocol.MachineOptions) error {
		return c.Provider.Restart(m)
	}

	return k.coreMethods(r, c, fn)
}

func (k *Kloud) info(r *kite.Request, c *Controller) (interface{}, error) {
	if c.CurrenState == machinestate.NotInitialized {
		return nil, NewError(ErrNotInitialized)
	}

	machOptions := &protocol.MachineOptions{
		MachineId: c.MachineId,
		Username:  r.Username,
		Eventer:   c.Eventer,
	}

	info, err := c.Provider.Info(machOptions)
	if err != nil {
		return nil, err
	}

	return &InfoResponse{
		State: c.MachineData.Machine.Status.State,
		Data:  info,
	}, nil
}
<|endoftext|>


<commit_before>// Package libsacloud is the SAKURA CLOUD API v1.1 Client for Go.
package libsacloud

// Version バージョン
const Version = "1.25.1"
<commit_msg>Bump to v1.26.0<commit_after>// Package libsacloud is the SAKURA CLOUD API v1.1 Client for Go.
package libsacloud

// Version バージョン
const Version = "1.26.0"
<|endoftext|>