<|start_filename|>Godeps/_workspace/src/github.com/socketplane/go-fastping/icmp.go<|end_filename|>
// Almost all this code is taken from go net ipraw_test.go implementation.
// It's under a BSD-style license.

// Copyright (c) 2012 The Go Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//    * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//    * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

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

package fastping

import (
	"errors"
)

func ipv4Payload(b []byte) []byte {
	if len(b) < 20 {
		return b
	}
	hdrlen := int(b[0]&0x0f) << 2
	return b[hdrlen:]
}

const (
	icmpv4EchoReply     = 0
	icmpv4UnReach       = 3
	icmpv4SourceQuench  = 4
	icmpv4Redirect      = 5
	icmpv4EchoRequest   = 8
	icmpv4RouteAdvert   = 9
	icmpv4RouterSolicit = 10
	icmpv4TimeExceeded  = 11
	icmpv4ParamProb     = 12
	icmpv4Tstamp        = 13
	icmpv4TstampReply   = 14
	icmpv4IReq          = 15
	icmpv4IReqReply     = 16
	icmpv4MaskReq       = 17
	icmpv4MaskReply     = 18
	icmpv6EchoRequest   = 128
	icmpv6EchoReply     = 129
)

// icmpMessage represents an ICMP message.
type icmpMessage struct {
	Type     int             // type
	Code     int             // code
	Checksum int             // checksum
	Body     icmpMessageBody // body
}

// icmpMessageBody represents an ICMP message body.
type icmpMessageBody interface {
	Len() int
	Marshal() ([]byte, error)
}

// Marshal returns the binary enconding of the ICMP echo request or
// reply message m.
func (m *icmpMessage) Marshal() ([]byte, error) {
	b := []byte{byte(m.Type), byte(m.Code), 0, 0}
	if m.Body != nil && m.Body.Len() != 0 {
		mb, err := m.Body.Marshal()
		if err != nil {
			return nil, err
		}
		b = append(b, mb...)
	}
	switch m.Type {
	case icmpv6EchoRequest, icmpv6EchoReply:
		return b, nil
	}
	csumcv := len(b) - 1 // checksum coverage
	s := uint32(0)
	for i := 0; i < csumcv; i += 2 {
		s += uint32(b[i+1])<<8 | uint32(b[i])
	}
	if csumcv&1 == 0 {
		s += uint32(b[csumcv])
	}
	s = s>>16 + s&0xffff
	s = s + s>>16
	// Place checksum back in header; using ^= avoids the
	// assumption the checksum bytes are zero.
	b[2] ^= byte(^s)
	b[3] ^= byte(^s >> 8)
	return b, nil
}

// parseICMPMessage parses b as an ICMP message.
func parseICMPMessage(b []byte) (*icmpMessage, error) {
	msglen := len(b)
	if msglen < 4 {
		return nil, errors.New("message too short")
	}
	m := &icmpMessage{Type: int(b[0]), Code: int(b[1]), Checksum: int(b[2])<<8 | int(b[3])}
	if msglen > 4 {
		var err error
		switch m.Type {
		case icmpv4EchoRequest, icmpv4EchoReply, icmpv6EchoRequest, icmpv6EchoReply:
			m.Body, err = parseICMPEcho(b[4:])
			if err != nil {
				return nil, err
			}
		}
	}
	return m, nil
}

// imcpEcho represenets an ICMP echo request or reply message body.
type icmpEcho struct {
	ID   int    // identifier
	Seq  int    // sequence number
	Data []byte // data
}

// Len returns message length in bytes
func (p *icmpEcho) Len() int {
	if p == nil {
		return 0
	}
	return 4 + len(p.Data)
}

// Marshal returns the binary enconding of the ICMP echo request or
// reply message body p.
func (p *icmpEcho) Marshal() ([]byte, error) {
	b := make([]byte, 4+len(p.Data))
	b[0], b[1] = byte(p.ID>>8), byte(p.ID)
	b[2], b[3] = byte(p.Seq>>8), byte(p.Seq)
	copy(b[4:], p.Data)
	return b, nil
}

// parseICMPEcho parses b as an ICMP echo request or reply message
// body.
func parseICMPEcho(b []byte) (*icmpEcho, error) {
	bodylen := len(b)
	p := &icmpEcho{ID: int(b[0])<<8 | int(b[1]), Seq: int(b[2])<<8 | int(b[3])}
	if bodylen > 4 {
		p.Data = make([]byte, bodylen-4)
		copy(p.Data, b[4:])
	}
	return p, nil
}


<|start_filename|>Godeps/_workspace/src/github.com/vishvananda/netlink/nl/link_linux.go<|end_filename|>
package nl

const (
	DEFAULT_CHANGE = 0xFFFFFFFF
)

const (
	IFLA_INFO_UNSPEC = iota
	IFLA_INFO_KIND   = iota
	IFLA_INFO_DATA   = iota
	IFLA_INFO_XSTATS = iota
	IFLA_INFO_MAX    = IFLA_INFO_XSTATS
)

const (
	IFLA_VLAN_UNSPEC      = iota
	IFLA_VLAN_ID          = iota
	IFLA_VLAN_FLAGS       = iota
	IFLA_VLAN_EGRESS_QOS  = iota
	IFLA_VLAN_INGRESS_QOS = iota
	IFLA_VLAN_PROTOCOL    = iota
	IFLA_VLAN_MAX         = IFLA_VLAN_PROTOCOL
)

const (
	VETH_INFO_UNSPEC = iota
	VETH_INFO_PEER   = iota
	VETH_INFO_MAX    = VETH_INFO_PEER
)

const (
	IFLA_VXLAN_UNSPEC     = iota
	IFLA_VXLAN_ID         = iota
	IFLA_VXLAN_GROUP      = iota
	IFLA_VXLAN_LINK       = iota
	IFLA_VXLAN_LOCAL      = iota
	IFLA_VXLAN_TTL        = iota
	IFLA_VXLAN_TOS        = iota
	IFLA_VXLAN_LEARNING   = iota
	IFLA_VXLAN_AGEING     = iota
	IFLA_VXLAN_LIMIT      = iota
	IFLA_VXLAN_PORT_RANGE = iota
	IFLA_VXLAN_PROXY      = iota
	IFLA_VXLAN_RSC        = iota
	IFLA_VXLAN_L2MISS     = iota
	IFLA_VXLAN_L3MISS     = iota
	IFLA_VXLAN_PORT       = iota
	IFLA_VXLAN_GROUP6     = iota
	IFLA_VXLAN_LOCAL6     = iota
	IFLA_VXLAN_MAX        = IFLA_VXLAN_LOCAL6
)

const (
	// not defined in syscall
	IFLA_NET_NS_FD = 28
)


<|start_filename|>Godeps/_workspace/src/github.com/socketplane/ecc/example/ecc_demo.go<|end_filename|>
package main

import (
	"fmt"
	"os"
	"os/signal"
	"time"

	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/socketplane/ecc"
)

const dataDir = "/tmp/ecc"

type eccListener struct {
}

func (e eccListener) NotifyNodeUpdate(nType ecc.NotifyUpdateType, nodeName string) {
	fmt.Println("CLIENT UPDATE :", nType, nodeName)
}
func (e eccListener) NotifyKeyUpdate(nType ecc.NotifyUpdateType, key string, data []byte) {
	fmt.Println("KEY UPDATE :", nType, key, data)
}
func (e eccListener) NotifyStoreUpdate(nType ecc.NotifyUpdateType, store string, data map[string][]byte) {
}
func main() {
	ecc.Start(true, true, "eth1", dataDir)
	listener := eccListener{}
	go ecc.RegisterForNodeUpdates(listener)
	go ecc.RegisterForKeyUpdates("network", "web", listener)
	keyUpdates("web")
	ecc.Delete("network", "web")
	go ecc.RegisterForKeyUpdates("network", "db", listener)
	keyUpdates("db")
	keyUpdates("web")
	// Ctrl+C handling
	ecc.Leave()
	time.Sleep(time.Second * 15)
	ecc.Start(true, true, "eth1", dataDir)

	handler := make(chan os.Signal, 1)
	signal.Notify(handler, os.Interrupt)
	for sig := range handler {
		if sig == os.Interrupt {
			time.Sleep(1e9)
			break
		}
	}
}

//Random Key updates
func keyUpdates(key string) {
	valArray, _, _ := ecc.Get("network", key)
	currVal := make([]byte, len(valArray))
	copy(currVal, valArray)
	valArray = []byte("value1")
	ecc.Put("network", key, valArray, currVal)
	time.Sleep(time.Second * 2)
	updArray := []byte("value2")
	ecc.Put("network", key, updArray, valArray)
	time.Sleep(time.Second * 2)
}


<|start_filename|>Godeps/_workspace/src/github.com/armon/gomdb/txn.go<|end_filename|>
package mdb

/*
#cgo freebsd CFLAGS: -DMDB_DSYNC=O_SYNC
#cgo openbsd CFLAGS: -DMDB_DSYNC=O_SYNC
#cgo netbsd CFLAGS: -DMDB_DSYNC=O_SYNC
#include <stdlib.h>
#include <stdio.h>
#include "lmdb.h"
*/
import "C"

import (
	"math"
	"runtime"
	"unsafe"
)

// DBIOpen Database Flags
const (
	REVERSEKEY = C.MDB_REVERSEKEY // use reverse string keys
	DUPSORT    = C.MDB_DUPSORT    // use sorted duplicates
	INTEGERKEY = C.MDB_INTEGERKEY // numeric keys in native byte order. The keys must all be of the same size.
	DUPFIXED   = C.MDB_DUPFIXED   // with DUPSORT, sorted dup items have fixed size
	INTEGERDUP = C.MDB_INTEGERDUP // with DUPSORT, dups are numeric in native byte order
	REVERSEDUP = C.MDB_REVERSEDUP // with DUPSORT, use reverse string dups
	CREATE     = C.MDB_CREATE     // create DB if not already existing
)

// put flags
const (
	NODUPDATA   = C.MDB_NODUPDATA
	NOOVERWRITE = C.MDB_NOOVERWRITE
	RESERVE     = C.MDB_RESERVE
	APPEND      = C.MDB_APPEND
	APPENDDUP   = C.MDB_APPENDDUP
)

// Txn is Opaque structure for a transaction handle.
// All database operations require a transaction handle.
// Transactions may be read-only or read-write.
type Txn struct {
	_txn *C.MDB_txn
}

func (env *Env) BeginTxn(parent *Txn, flags uint) (*Txn, error) {
	var _txn *C.MDB_txn
	var ptxn *C.MDB_txn
	if parent == nil {
		ptxn = nil
	} else {
		ptxn = parent._txn
	}
	if flags&RDONLY == 0 {
		runtime.LockOSThread()
	}
	ret := C.mdb_txn_begin(env._env, ptxn, C.uint(flags), &_txn)
	if ret != SUCCESS {
		runtime.UnlockOSThread()
		return nil, Errno(ret)
	}
	return &Txn{_txn}, nil
}

func (txn *Txn) Commit() error {
	ret := C.mdb_txn_commit(txn._txn)
	runtime.UnlockOSThread()
	if ret != SUCCESS {
		return Errno(ret)
	}
	txn._txn = nil
	return nil
}

func (txn *Txn) Abort() {
	if txn._txn == nil {
		return
	}
	C.mdb_txn_abort(txn._txn)
	runtime.UnlockOSThread()
	txn._txn = nil
}

func (txn *Txn) Reset() {
	C.mdb_txn_reset(txn._txn)
}

func (txn *Txn) Renew() error {
	ret := C.mdb_txn_renew(txn._txn)
	if ret != SUCCESS {
		return Errno(ret)
	}
	return nil
}

func (txn *Txn) DBIOpen(name string, flags uint) (DBI, error) {
	var _dbi C.MDB_dbi
	var cname *C.char
	if name == "" {
		cname = nil
	} else {
		cname = C.CString(name)
		defer C.free(unsafe.Pointer(cname))
	}
	ret := C.mdb_dbi_open(txn._txn, cname, C.uint(flags), &_dbi)
	if ret != SUCCESS {
		return DBI(math.NaN()), Errno(ret)
	}
	return DBI(_dbi), nil
}

func (txn *Txn) Stat(dbi DBI) (*Stat, error) {
	var _stat C.MDB_stat
	ret := C.mdb_stat(txn._txn, C.MDB_dbi(dbi), &_stat)
	if ret != SUCCESS {
		return nil, Errno(ret)
	}
	stat := Stat{PSize: uint(_stat.ms_psize),
		Depth:         uint(_stat.ms_depth),
		BranchPages:   uint64(_stat.ms_branch_pages),
		LeafPages:     uint64(_stat.ms_leaf_pages),
		OwerflowPages: uint64(_stat.ms_overflow_pages),
		Entries:       uint64(_stat.ms_entries)}
	return &stat, nil
}

func (txn *Txn) Drop(dbi DBI, del int) error {
	ret := C.mdb_drop(txn._txn, C.MDB_dbi(dbi), C.int(del))
	if ret != SUCCESS {
		return Errno(ret)
	}
	return nil
}

func (txn *Txn) Get(dbi DBI, key []byte) ([]byte, error) {
	ckey := &C.MDB_val{mv_size: C.size_t(len(key)),
		mv_data: unsafe.Pointer(&key[0])}
	var cval C.MDB_val
	ret := C.mdb_get(txn._txn, C.MDB_dbi(dbi), ckey, &cval)
	if ret != SUCCESS {
		return nil, Errno(ret)
	}
	val := C.GoBytes(cval.mv_data, C.int(cval.mv_size))
	return val, nil
}

func (txn *Txn) Put(dbi DBI, key []byte, val []byte, flags uint) error {
	ckey := &C.MDB_val{mv_size: C.size_t(len(key)),
		mv_data: unsafe.Pointer(&key[0])}
	cval := &C.MDB_val{mv_size: C.size_t(len(val)),
		mv_data: unsafe.Pointer(&val[0])}
	ret := C.mdb_put(txn._txn, C.MDB_dbi(dbi), ckey, cval, C.uint(flags))
	if ret != SUCCESS {
		return Errno(ret)
	}
	return nil
}

func (txn *Txn) Del(dbi DBI, key, val []byte) error {
	ckey := &C.MDB_val{mv_size: C.size_t(len(key)),
		mv_data: unsafe.Pointer(&key[0])}
	var cval *C.MDB_val
	if val == nil {
		cval = nil
	} else {
		cval = &C.MDB_val{mv_size: C.size_t(len(val)),
			mv_data: unsafe.Pointer(&val[0])}
	}
	ret := C.mdb_del(txn._txn, C.MDB_dbi(dbi), ckey, cval)
	if ret != SUCCESS {
		return Errno(ret)
	}
	return nil
}

type Cursor struct {
	_cursor *C.MDB_cursor
}

func (txn *Txn) CursorOpen(dbi DBI) (*Cursor, error) {
	var _cursor *C.MDB_cursor
	ret := C.mdb_cursor_open(txn._txn, C.MDB_dbi(dbi), &_cursor)
	if ret != SUCCESS {
		return nil, Errno(ret)
	}
	return &Cursor{_cursor}, nil
}

func (txn *Txn) CursorRenew(cursor *Cursor) error {
	ret := C.mdb_cursor_renew(txn._txn, cursor._cursor)
	if ret != SUCCESS {
		return Errno(ret)
	}
	return nil
}


<|start_filename|>Godeps/_workspace/src/github.com/mitchellh/cli/ui_colored_test.go<|end_filename|>
package cli

import (
	"testing"
)

func TestColoredUi_impl(t *testing.T) {
	var _ Ui = new(ColoredUi)
}

func TestColoredUi_noColor(t *testing.T) {
	mock := new(MockUi)
	ui := &ColoredUi{
		ErrorColor: UiColorNone,
		Ui:         mock,
	}
	ui.Error("foo")

	if mock.ErrorWriter.String() != "foo\n" {
		t.Fatalf("bad: %#v", mock.ErrorWriter.String())
	}
}

func TestColoredUi_Error(t *testing.T) {
	mock := new(MockUi)
	ui := &ColoredUi{
		ErrorColor: UiColor{Code: 33},
		Ui:         mock,
	}
	ui.Error("foo")

	if mock.ErrorWriter.String() != "\033[0;33mfoo\033[0m\n" {
		t.Fatalf("bad: %#v", mock.ErrorWriter.String())
	}
}

func TestColoredUi_Info(t *testing.T) {
	mock := new(MockUi)
	ui := &ColoredUi{
		InfoColor: UiColor{Code: 33},
		Ui:        mock,
	}
	ui.Info("foo")

	if mock.OutputWriter.String() != "\033[0;33mfoo\033[0m\n" {
		t.Fatalf("bad: %#v %#v", mock.OutputWriter.String())
	}
}

func TestColoredUi_Output(t *testing.T) {
	mock := new(MockUi)
	ui := &ColoredUi{
		OutputColor: UiColor{Code: 33},
		Ui:          mock,
	}
	ui.Output("foo")

	if mock.OutputWriter.String() != "\033[0;33mfoo\033[0m\n" {
		t.Fatalf("bad: %#v %#v", mock.OutputWriter.String())
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/command/agent/agent_test.go<|end_filename|>
package agent

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"reflect"
	"sync/atomic"
	"testing"
	"time"

	"github.com/hashicorp/consul/testutil"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/consul"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/consul/structs"
)

var offset uint64

func nextConfig() *Config {
	idx := int(atomic.AddUint64(&offset, 1))
	conf := DefaultConfig()

	conf.AdvertiseAddr = "127.0.0.1"
	conf.Bootstrap = true
	conf.Datacenter = "dc1"
	conf.NodeName = fmt.Sprintf("Node %d", idx)
	conf.BindAddr = "127.0.0.1"
	conf.Ports.DNS = 19000 + idx
	conf.Ports.HTTP = 18800 + idx
	conf.Ports.RPC = 18600 + idx
	conf.Ports.SerfLan = 18200 + idx
	conf.Ports.SerfWan = 18400 + idx
	conf.Ports.Server = 18000 + idx
	conf.Server = true
	conf.ACLDatacenter = "dc1"
	conf.ACLMasterToken = "root"

	cons := consul.DefaultConfig()
	conf.ConsulConfig = cons

	cons.SerfLANConfig.MemberlistConfig.SuspicionMult = 3
	cons.SerfLANConfig.MemberlistConfig.ProbeTimeout = 100 * time.Millisecond
	cons.SerfLANConfig.MemberlistConfig.ProbeInterval = 100 * time.Millisecond
	cons.SerfLANConfig.MemberlistConfig.GossipInterval = 100 * time.Millisecond

	cons.SerfWANConfig.MemberlistConfig.SuspicionMult = 3
	cons.SerfWANConfig.MemberlistConfig.ProbeTimeout = 100 * time.Millisecond
	cons.SerfWANConfig.MemberlistConfig.ProbeInterval = 100 * time.Millisecond
	cons.SerfWANConfig.MemberlistConfig.GossipInterval = 100 * time.Millisecond

	cons.RaftConfig.LeaderLeaseTimeout = 20 * time.Millisecond
	cons.RaftConfig.HeartbeatTimeout = 40 * time.Millisecond
	cons.RaftConfig.ElectionTimeout = 40 * time.Millisecond

	return conf
}

func makeAgentLog(t *testing.T, conf *Config, l io.Writer) (string, *Agent) {
	dir, err := ioutil.TempDir("", "agent")
	if err != nil {
		t.Fatalf(fmt.Sprintf("err: %v", err))
	}

	conf.DataDir = dir
	agent, err := Create(conf, l)
	if err != nil {
		os.RemoveAll(dir)
		t.Fatalf(fmt.Sprintf("err: %v", err))
	}

	return dir, agent
}

func makeAgentKeyring(t *testing.T, conf *Config, key string) (string, *Agent) {
	dir, err := ioutil.TempDir("", "agent")
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	conf.DataDir = dir

	fileLAN := filepath.Join(dir, serfLANKeyring)
	if err := initKeyring(fileLAN, key); err != nil {
		t.Fatalf("err: %s", err)
	}
	fileWAN := filepath.Join(dir, serfWANKeyring)
	if err := initKeyring(fileWAN, key); err != nil {
		t.Fatalf("err: %s", err)
	}

	agent, err := Create(conf, nil)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	return dir, agent
}

func makeAgent(t *testing.T, conf *Config) (string, *Agent) {
	return makeAgentLog(t, conf, nil)
}

func TestAgentStartStop(t *testing.T) {
	dir, agent := makeAgent(t, nextConfig())
	defer os.RemoveAll(dir)
	defer agent.Shutdown()

	if err := agent.Leave(); err != nil {
		t.Fatalf("err: %v", err)
	}
	if err := agent.Shutdown(); err != nil {
		t.Fatalf("err: %v", err)
	}

	select {
	case <-agent.ShutdownCh():
	default:
		t.Fatalf("should be closed")
	}
}

func TestAgent_RPCPing(t *testing.T) {
	dir, agent := makeAgent(t, nextConfig())
	defer os.RemoveAll(dir)
	defer agent.Shutdown()

	var out struct{}
	if err := agent.RPC("Status.Ping", struct{}{}, &out); err != nil {
		t.Fatalf("err: %v", err)
	}
}

func TestAgent_AddService(t *testing.T) {
	dir, agent := makeAgent(t, nextConfig())
	defer os.RemoveAll(dir)
	defer agent.Shutdown()

	srv := &structs.NodeService{
		ID:      "redis",
		Service: "redis",
		Tags:    []string{"foo"},
		Port:    8000,
	}
	chk := &CheckType{
		TTL:   time.Minute,
		Notes: "redis health check",
	}
	err := agent.AddService(srv, chk, false)
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	// Ensure we have a state mapping
	if _, ok := agent.state.Services()["redis"]; !ok {
		t.Fatalf("missing redis service")
	}

	// Ensure we have a check mapping
	if _, ok := agent.state.Checks()["service:redis"]; !ok {
		t.Fatalf("missing redis check")
	}

	// Ensure a TTL is setup
	if _, ok := agent.checkTTLs["service:redis"]; !ok {
		t.Fatalf("missing redis check ttl")
	}

	// Ensure the notes are passed through
	if agent.state.Checks()["service:redis"].Notes == "" {
		t.Fatalf("missing redis check notes")
	}
}

func TestAgent_RemoveService(t *testing.T) {
	dir, agent := makeAgent(t, nextConfig())
	defer os.RemoveAll(dir)
	defer agent.Shutdown()

	// Remove a service that doesn't exist
	if err := agent.RemoveService("redis", false); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Remove the consul service
	if err := agent.RemoveService("consul", false); err == nil {
		t.Fatalf("should have errored")
	}

	srv := &structs.NodeService{
		ID:      "redis",
		Service: "redis",
		Port:    8000,
	}
	chk := &CheckType{TTL: time.Minute}
	if err := agent.AddService(srv, chk, false); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Remove the service
	if err := agent.RemoveService("redis", false); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Ensure we have a state mapping
	if _, ok := agent.state.Services()["redis"]; ok {
		t.Fatalf("have redis service")
	}

	// Ensure we have a check mapping
	if _, ok := agent.state.Checks()["service:redis"]; ok {
		t.Fatalf("have redis check")
	}

	// Ensure a TTL is setup
	if _, ok := agent.checkTTLs["service:redis"]; ok {
		t.Fatalf("have redis check ttl")
	}
}

func TestAgent_AddCheck(t *testing.T) {
	dir, agent := makeAgent(t, nextConfig())
	defer os.RemoveAll(dir)
	defer agent.Shutdown()

	health := &structs.HealthCheck{
		Node:    "foo",
		CheckID: "mem",
		Name:    "memory util",
		Status:  structs.HealthCritical,
	}
	chk := &CheckType{
		Script:   "exit 0",
		Interval: 15 * time.Second,
	}
	err := agent.AddCheck(health, chk, false)
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	// Ensure we have a check mapping
	if _, ok := agent.state.Checks()["mem"]; !ok {
		t.Fatalf("missing mem check")
	}

	// Ensure a TTL is setup
	if _, ok := agent.checkMonitors["mem"]; !ok {
		t.Fatalf("missing mem monitor")
	}
}

func TestAgent_AddCheck_MinInterval(t *testing.T) {
	dir, agent := makeAgent(t, nextConfig())
	defer os.RemoveAll(dir)
	defer agent.Shutdown()

	health := &structs.HealthCheck{
		Node:    "foo",
		CheckID: "mem",
		Name:    "memory util",
		Status:  structs.HealthCritical,
	}
	chk := &CheckType{
		Script:   "exit 0",
		Interval: time.Microsecond,
	}
	err := agent.AddCheck(health, chk, false)
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	// Ensure we have a check mapping
	if _, ok := agent.state.Checks()["mem"]; !ok {
		t.Fatalf("missing mem check")
	}

	// Ensure a TTL is setup
	if mon, ok := agent.checkMonitors["mem"]; !ok {
		t.Fatalf("missing mem monitor")
	} else if mon.Interval != MinInterval {
		t.Fatalf("bad mem monitor interval")
	}
}

func TestAgent_RemoveCheck(t *testing.T) {
	dir, agent := makeAgent(t, nextConfig())
	defer os.RemoveAll(dir)
	defer agent.Shutdown()

	// Remove check that doesn't exist
	if err := agent.RemoveCheck("mem", false); err != nil {
		t.Fatalf("err: %v", err)
	}

	health := &structs.HealthCheck{
		Node:    "foo",
		CheckID: "mem",
		Name:    "memory util",
		Status:  structs.HealthCritical,
	}
	chk := &CheckType{
		Script:   "exit 0",
		Interval: 15 * time.Second,
	}
	err := agent.AddCheck(health, chk, false)
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	// Remove check
	if err := agent.RemoveCheck("mem", false); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Ensure we have a check mapping
	if _, ok := agent.state.Checks()["mem"]; ok {
		t.Fatalf("have mem check")
	}

	// Ensure a TTL is setup
	if _, ok := agent.checkMonitors["mem"]; ok {
		t.Fatalf("have mem monitor")
	}
}

func TestAgent_UpdateCheck(t *testing.T) {
	dir, agent := makeAgent(t, nextConfig())
	defer os.RemoveAll(dir)
	defer agent.Shutdown()

	health := &structs.HealthCheck{
		Node:    "foo",
		CheckID: "mem",
		Name:    "memory util",
		Status:  structs.HealthCritical,
	}
	chk := &CheckType{
		TTL: 15 * time.Second,
	}
	err := agent.AddCheck(health, chk, false)
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	// Remove check
	if err := agent.UpdateCheck("mem", structs.HealthPassing, "foo"); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Ensure we have a check mapping
	status := agent.state.Checks()["mem"]
	if status.Status != structs.HealthPassing {
		t.Fatalf("bad: %v", status)
	}
	if status.Output != "foo" {
		t.Fatalf("bad: %v", status)
	}
}

func TestAgent_ConsulService(t *testing.T) {
	dir, agent := makeAgent(t, nextConfig())
	defer os.RemoveAll(dir)
	defer agent.Shutdown()

	testutil.WaitForLeader(t, agent.RPC, "dc1")

	// Consul service is registered
	services := agent.state.Services()
	if _, ok := services[consul.ConsulServiceID]; !ok {
		t.Fatalf("%s service should be registered", consul.ConsulServiceID)
	}

	// Perform anti-entropy on consul service
	if err := agent.state.syncService(consul.ConsulServiceID); err != nil {
		t.Fatalf("err: %s", err)
	}

	// Consul service should be in sync
	if !agent.state.serviceStatus[consul.ConsulServiceID].inSync {
		t.Fatalf("%s service should be in sync", consul.ConsulServiceID)
	}
}

func TestAgent_PersistService(t *testing.T) {
	config := nextConfig()
	config.Server = false
	dir, agent := makeAgent(t, config)
	defer os.RemoveAll(dir)
	defer agent.Shutdown()

	svc := &structs.NodeService{
		ID:      "redis",
		Service: "redis",
		Tags:    []string{"foo"},
		Port:    8000,
	}

	file := filepath.Join(agent.config.DataDir, servicesDir, stringHash(svc.ID))

	// Check is not persisted unless requested
	if err := agent.AddService(svc, nil, false); err != nil {
		t.Fatalf("err: %v", err)
	}
	if _, err := os.Stat(file); err == nil {
		t.Fatalf("should not persist")
	}

	// Persists to file if requested
	if err := agent.AddService(svc, nil, true); err != nil {
		t.Fatalf("err: %v", err)
	}

	if _, err := os.Stat(file); err != nil {
		t.Fatalf("err: %s", err)
	}

	expected, err := json.Marshal(svc)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	content, err := ioutil.ReadFile(file)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	if !bytes.Equal(expected, content) {
		t.Fatalf("bad: %s", string(content))
	}
	agent.Shutdown()

	// Should load it back during later start
	agent2, err := Create(config, nil)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer agent2.Shutdown()

	if _, ok := agent2.state.services[svc.ID]; !ok {
		t.Fatalf("bad: %#v", agent2.state.services)
	}
}

func TestAgent_PurgeService(t *testing.T) {
	config := nextConfig()
	dir, agent := makeAgent(t, config)
	defer os.RemoveAll(dir)
	defer agent.Shutdown()

	svc := &structs.NodeService{
		ID:      "redis",
		Service: "redis",
		Tags:    []string{"foo"},
		Port:    8000,
	}

	file := filepath.Join(agent.config.DataDir, servicesDir, stringHash(svc.ID))
	if err := agent.AddService(svc, nil, true); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Not removed
	if err := agent.RemoveService(svc.ID, false); err != nil {
		t.Fatalf("err: %s", err)
	}
	if _, err := os.Stat(file); err != nil {
		t.Fatalf("err: %s", err)
	}

	// Removed
	if err := agent.RemoveService(svc.ID, true); err != nil {
		t.Fatalf("err: %s", err)
	}
	if _, err := os.Stat(file); !os.IsNotExist(err) {
		t.Fatalf("bad: %#v", err)
	}
}

func TestAgent_PurgeServiceOnDuplicate(t *testing.T) {
	config := nextConfig()
	config.Server = false
	dir, agent := makeAgent(t, config)
	defer os.RemoveAll(dir)
	defer agent.Shutdown()

	svc1 := &structs.NodeService{
		ID:      "redis",
		Service: "redis",
		Tags:    []string{"foo"},
		Port:    8000,
	}

	// First persist the service
	if err := agent.AddService(svc1, nil, true); err != nil {
		t.Fatalf("err: %v", err)
	}
	agent.Shutdown()

	// Try bringing the agent back up with the service already
	// existing in the config
	svc2 := &ServiceDefinition{
		ID:   "redis",
		Name: "redis",
		Tags: []string{"bar"},
		Port: 9000,
	}

	config.Services = []*ServiceDefinition{svc2}
	agent2, err := Create(config, nil)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer agent2.Shutdown()

	file := filepath.Join(agent.config.DataDir, servicesDir, stringHash(svc1.ID))
	if _, err := os.Stat(file); err == nil {
		t.Fatalf("should have removed persisted service")
	}
	result, ok := agent2.state.services[svc2.ID]
	if !ok {
		t.Fatalf("missing service registration")
	}
	if !reflect.DeepEqual(result.Tags, svc2.Tags) || result.Port != svc2.Port {
		t.Fatalf("bad: %#v", result)
	}
}

func TestAgent_PersistCheck(t *testing.T) {
	config := nextConfig()
	config.Server = false
	dir, agent := makeAgent(t, config)
	defer os.RemoveAll(dir)
	defer agent.Shutdown()

	check := &structs.HealthCheck{
		Node:        config.NodeName,
		CheckID:     "service:redis1",
		Name:        "redischeck",
		Status:      structs.HealthPassing,
		ServiceID:   "redis",
		ServiceName: "redis",
	}
	chkType := &CheckType{
		Script:   "/bin/true",
		Interval: 10 * time.Second,
	}

	file := filepath.Join(agent.config.DataDir, checksDir, stringHash(check.CheckID))

	// Not persisted if not requested
	if err := agent.AddCheck(check, chkType, false); err != nil {
		t.Fatalf("err: %v", err)
	}
	if _, err := os.Stat(file); err == nil {
		t.Fatalf("should not persist")
	}

	// Should persist if requested
	if err := agent.AddCheck(check, chkType, true); err != nil {
		t.Fatalf("err: %v", err)
	}

	if _, err := os.Stat(file); err != nil {
		t.Fatalf("err: %s", err)
	}

	p := persistedCheck{check, chkType}
	expected, err := json.Marshal(p)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	content, err := ioutil.ReadFile(file)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	if !bytes.Equal(expected, content) {
		t.Fatalf("bad: %s", string(content))
	}
	agent.Shutdown()

	// Should load it back during later start
	agent2, err := Create(config, nil)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer agent2.Shutdown()

	result, ok := agent2.state.checks[p.Check.CheckID]
	if !ok {
		t.Fatalf("bad: %#v", agent2.state.checks)
	}
	if result.Status != structs.HealthCritical {
		t.Fatalf("bad: %#v", result)
	}

	// Should have restored the monitor
	if _, ok := agent2.checkMonitors[p.Check.CheckID]; !ok {
		t.Fatalf("bad: %#v", agent2.checkMonitors)
	}
}

func TestAgent_PurgeCheck(t *testing.T) {
	config := nextConfig()
	dir, agent := makeAgent(t, config)
	defer os.RemoveAll(dir)
	defer agent.Shutdown()

	check := &structs.HealthCheck{
		Node:        config.NodeName,
		CheckID:     "service:redis1",
		Name:        "redischeck",
		Status:      structs.HealthPassing,
		ServiceID:   "redis",
		ServiceName: "redis",
	}

	file := filepath.Join(agent.config.DataDir, checksDir, stringHash(check.CheckID))
	if err := agent.AddCheck(check, nil, true); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Not removed
	if err := agent.RemoveCheck(check.CheckID, false); err != nil {
		t.Fatalf("err: %s", err)
	}
	if _, err := os.Stat(file); err != nil {
		t.Fatalf("err: %s", err)
	}

	// Removed
	if err := agent.RemoveCheck(check.CheckID, true); err != nil {
		t.Fatalf("err: %s", err)
	}
	if _, err := os.Stat(file); !os.IsNotExist(err) {
		t.Fatalf("bad: %#v", err)
	}
}

func TestAgent_PurgeCheckOnDuplicate(t *testing.T) {
	config := nextConfig()
	config.Server = false
	dir, agent := makeAgent(t, config)
	defer os.RemoveAll(dir)
	defer agent.Shutdown()

	check1 := &structs.HealthCheck{
		Node:        config.NodeName,
		CheckID:     "service:redis1",
		Name:        "redischeck",
		Status:      structs.HealthPassing,
		ServiceID:   "redis",
		ServiceName: "redis",
	}

	// First persist the check
	if err := agent.AddCheck(check1, nil, true); err != nil {
		t.Fatalf("err: %v", err)
	}
	agent.Shutdown()

	// Start again with the check registered in config
	check2 := &CheckDefinition{
		ID:    "service:redis1",
		Name:  "redischeck",
		Notes: "my cool notes",
		CheckType: CheckType{
			Script:   "/bin/check-redis.py",
			Interval: 30 * time.Second,
		},
	}

	config.Checks = []*CheckDefinition{check2}
	agent2, err := Create(config, nil)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer agent2.Shutdown()

	file := filepath.Join(agent.config.DataDir, checksDir, stringHash(check1.CheckID))
	if _, err := os.Stat(file); err == nil {
		t.Fatalf("should have removed persisted check")
	}
	result, ok := agent2.state.checks[check2.ID]
	if !ok {
		t.Fatalf("missing check registration")
	}
	expected := check2.HealthCheck(config.NodeName)
	if !reflect.DeepEqual(expected, result) {
		t.Fatalf("bad: %#v", result)
	}
}

func TestAgent_unloadChecks(t *testing.T) {
	config := nextConfig()
	dir, agent := makeAgent(t, config)
	defer os.RemoveAll(dir)
	defer agent.Shutdown()

	check1 := &structs.HealthCheck{
		Node:        config.NodeName,
		CheckID:     "service:redis1",
		Name:        "redischeck",
		Status:      structs.HealthPassing,
		ServiceID:   "redis",
		ServiceName: "redis",
	}

	// Register the check
	if err := agent.AddCheck(check1, nil, false); err != nil {
		t.Fatalf("err: %s", err)
	}
	found := false
	for check, _ := range agent.state.Checks() {
		if check == check1.CheckID {
			found = true
			break
		}
	}
	if !found {
		t.Fatalf("check should have been registered")
	}

	// Unload all of the checks
	if err := agent.unloadChecks(); err != nil {
		t.Fatalf("err: %s", err)
	}

	// Make sure it was unloaded
	for check, _ := range agent.state.Checks() {
		if check == check1.CheckID {
			t.Fatalf("should have unloaded checks")
		}
	}
}

func TestAgent_unloadServices(t *testing.T) {
	config := nextConfig()
	dir, agent := makeAgent(t, config)
	defer os.RemoveAll(dir)
	defer agent.Shutdown()

	svc := &structs.NodeService{
		ID:      "redis",
		Service: "redis",
		Tags:    []string{"foo"},
		Port:    8000,
	}

	// Register the service
	if err := agent.AddService(svc, nil, false); err != nil {
		t.Fatalf("err: %v", err)
	}
	found := false
	for id, _ := range agent.state.Services() {
		if id == svc.ID {
			found = true
			break
		}
	}
	if !found {
		t.Fatalf("should have registered service")
	}

	// Unload all services
	if err := agent.unloadServices(); err != nil {
		t.Fatalf("err: %s", err)
	}

	// Make sure it was unloaded and the consul service remains
	found = false
	for id, _ := range agent.state.Services() {
		if id == svc.ID {
			t.Fatalf("should have unloaded services")
		}
		if id == consul.ConsulServiceID {
			found = true
		}
	}
	if !found {
		t.Fatalf("consul service should not be removed")
	}
}

func TestAgent_ServiceMaintenanceMode(t *testing.T) {
	config := nextConfig()
	dir, agent := makeAgent(t, config)
	defer os.RemoveAll(dir)
	defer agent.Shutdown()

	svc := &structs.NodeService{
		ID:      "redis",
		Service: "redis",
		Tags:    []string{"foo"},
		Port:    8000,
	}

	// Register the service
	if err := agent.AddService(svc, nil, false); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Enter maintenance mode for the service
	if err := agent.EnableServiceMaintenance("redis"); err != nil {
		t.Fatalf("err: %s", err)
	}

	// Make sure the critical health check was added
	checkID := serviceMaintCheckID("redis")
	if _, ok := agent.state.Checks()[checkID]; !ok {
		t.Fatalf("should have registered critical maintenance check")
	}

	// Leave maintenance mode
	if err := agent.DisableServiceMaintenance("redis"); err != nil {
		t.Fatalf("err: %s", err)
	}

	// Ensure the check was deregistered
	if _, ok := agent.state.Checks()[checkID]; ok {
		t.Fatalf("should have deregistered maintenance check")
	}
}

func TestAgent_NodeMaintenanceMode(t *testing.T) {
	config := nextConfig()
	dir, agent := makeAgent(t, config)
	defer os.RemoveAll(dir)
	defer agent.Shutdown()

	// Enter maintenance mode for the node
	agent.EnableNodeMaintenance()

	// Make sure the critical health check was added
	if _, ok := agent.state.Checks()[nodeMaintCheckID]; !ok {
		t.Fatalf("should have registered critical node check")
	}

	// Leave maintenance mode
	agent.DisableNodeMaintenance()

	// Ensure the check was deregistered
	if _, ok := agent.state.Checks()[nodeMaintCheckID]; ok {
		t.Fatalf("should have deregistered critical node check")
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/serf/serf/conflict_delegate.go<|end_filename|>
package serf

import (
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/memberlist"
)

type conflictDelegate struct {
	serf *Serf
}

func (c *conflictDelegate) NotifyConflict(existing, other *memberlist.Node) {
	c.serf.handleNodeConflict(existing, other)
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/command/agent/rpc_log_stream.go<|end_filename|>
package agent

import (
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/logutils"
	"log"
)

type streamClient interface {
	Send(*responseHeader, interface{}) error
}

// logStream is used to stream logs to a client over RPC
type logStream struct {
	client streamClient
	filter *logutils.LevelFilter
	logCh  chan string
	logger *log.Logger
	seq    uint64
}

func newLogStream(client streamClient, filter *logutils.LevelFilter,
	seq uint64, logger *log.Logger) *logStream {
	ls := &logStream{
		client: client,
		filter: filter,
		logCh:  make(chan string, 512),
		logger: logger,
		seq:    seq,
	}
	go ls.stream()
	return ls
}

func (ls *logStream) HandleLog(l string) {
	// Check the log level
	if !ls.filter.Check([]byte(l)) {
		return
	}

	// Do a non-blocking send
	select {
	case ls.logCh <- l:
	default:
		// We can't log syncronously, since we are already being invoked
		// from the logWriter, and a log will need to invoke Write() which
		// already holds the lock. We must therefor do the log async, so
		// as to not deadlock
		go ls.logger.Printf("[WARN] Dropping logs to %v", ls.client)
	}
}

func (ls *logStream) Stop() {
	close(ls.logCh)
}

func (ls *logStream) stream() {
	header := responseHeader{Seq: ls.seq, Error: ""}
	rec := logRecord{Log: ""}

	for line := range ls.logCh {
		rec.Log = line
		if err := ls.client.Send(&header, &rec); err != nil {
			ls.logger.Printf("[ERR] Failed to stream log to %v: %v",
				ls.client, err)
			return
		}
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/raft/inmem_transport_test.go<|end_filename|>
package raft

import (
	"net"
	"testing"
)

func TestInmemAddrImpl(t *testing.T) {
	var inm interface{} = NewInmemAddr()
	if _, ok := inm.(net.Addr); !ok {
		t.Fatalf("InmemAddr is not a net.Addr")
	}
}

func TestInmemAddr(t *testing.T) {
	inm := NewInmemAddr()
	if inm.Network() != "inmem" {
		t.Fatalf("bad network")
	}
	if inm.String() != inm.ID {
		t.Fatalf("bad string")
	}
}

func TestInmemTransportImpl(t *testing.T) {
	var inm interface{} = &InmemTransport{}
	if _, ok := inm.(Transport); !ok {
		t.Fatalf("InmemTransport is not a Transport")
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/command/watch.go<|end_filename|>
package command

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"os"
	"strconv"
	"strings"

	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/command/agent"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/watch"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/mitchellh/cli"
)

// WatchCommand is a Command implementation that is used to setup
// a "watch" which uses a sub-process
type WatchCommand struct {
	ShutdownCh <-chan struct{}
	Ui         cli.Ui
}

func (c *WatchCommand) Help() string {
	helpText := `
Usage: consul watch [options] [child...]

  Watches for changes in a given data view from Consul. If a child process
  is specified, it will be invoked with the latest results on changes. Otherwise,
  the latest values are dumped to stdout and the watch terminates.

  Providing the watch type is required, and other parameters may be required
  or supported depending on the watch type.

Options:

  -http-addr=127.0.0.1:8500  HTTP address of the Consul agent.
  -datacenter=""             Datacenter to query. Defaults to that of agent.
  -token=""                  ACL token to use. Defaults to that of agent.

Watch Specification:

  -key=val                   Specifies the key to watch. Only for 'key' type.
  -name=val                  Specifies an event name to watch. Only for 'event' type.
  -passingonly=[true|false]  Specifies if only hosts passing all checks are displayed.
                             Optional for 'service' type. Defaults false.
  -prefix=val                Specifies the key prefix to watch. Only for 'keyprefix' type.
  -service=val               Specifies the service to watch. Required for 'service' type,
                             optional for 'checks' type.
  -state=val                 Specifies the states to watch. Optional for 'checks' type.
  -tag=val                   Specifies the service tag to filter on. Optional for 'service'
                             type.
  -type=val                  Specifies the watch type. One of key, keyprefix
                             services, nodes, service, checks, or event.
`
	return strings.TrimSpace(helpText)
}

func (c *WatchCommand) Run(args []string) int {
	var watchType, datacenter, token, key, prefix, service, tag, passingOnly, state, name string
	cmdFlags := flag.NewFlagSet("watch", flag.ContinueOnError)
	cmdFlags.Usage = func() { c.Ui.Output(c.Help()) }
	cmdFlags.StringVar(&watchType, "type", "", "")
	cmdFlags.StringVar(&datacenter, "datacenter", "", "")
	cmdFlags.StringVar(&token, "token", "", "")
	cmdFlags.StringVar(&key, "key", "", "")
	cmdFlags.StringVar(&prefix, "prefix", "", "")
	cmdFlags.StringVar(&service, "service", "", "")
	cmdFlags.StringVar(&tag, "tag", "", "")
	cmdFlags.StringVar(&passingOnly, "passingonly", "", "")
	cmdFlags.StringVar(&state, "state", "", "")
	cmdFlags.StringVar(&name, "name", "", "")
	httpAddr := HTTPAddrFlag(cmdFlags)
	if err := cmdFlags.Parse(args); err != nil {
		return 1
	}

	// Check for a type
	if watchType == "" {
		c.Ui.Error("Watch type must be specified")
		c.Ui.Error("")
		c.Ui.Error(c.Help())
		return 1
	}

	// Grab the script to execute if any
	script := strings.Join(cmdFlags.Args(), " ")

	// Compile the watch parameters
	params := make(map[string]interface{})
	if watchType != "" {
		params["type"] = watchType
	}
	if datacenter != "" {
		params["datacenter"] = datacenter
	}
	if token != "" {
		params["token"] = token
	}
	if key != "" {
		params["key"] = key
	}
	if prefix != "" {
		params["prefix"] = prefix
	}
	if service != "" {
		params["service"] = service
	}
	if tag != "" {
		params["tag"] = tag
	}
	if state != "" {
		params["state"] = state
	}
	if name != "" {
		params["name"] = name
	}
	if passingOnly != "" {
		b, err := strconv.ParseBool(passingOnly)
		if err != nil {
			c.Ui.Error(fmt.Sprintf("Failed to parse passingonly flag: %s", err))
			return 1
		}
		params["passingonly"] = b
	}

	// Create the watch
	wp, err := watch.Parse(params)
	if err != nil {
		c.Ui.Error(fmt.Sprintf("%s", err))
		return 1
	}

	// Create and test the HTTP client
	client, err := HTTPClient(*httpAddr)
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err))
		return 1
	}
	_, err = client.Agent().NodeName()
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Error querying Consul agent: %s", err))
		return 1
	}

	// Setup handler

	// errExit:
	//	0: false
	//	1: true
	errExit := 0
	if script == "" {
		wp.Handler = func(idx uint64, data interface{}) {
			defer wp.Stop()
			buf, err := json.MarshalIndent(data, "", "    ")
			if err != nil {
				c.Ui.Error(fmt.Sprintf("Error encoding output: %s", err))
				errExit = 1
			}
			c.Ui.Output(string(buf))
		}
	} else {
		wp.Handler = func(idx uint64, data interface{}) {
			// Create the command
			var buf bytes.Buffer
			var err error
			cmd, err := agent.ExecScript(script)
			if err != nil {
				c.Ui.Error(fmt.Sprintf("Error executing handler: %s", err))
				goto ERR
			}
			cmd.Env = append(os.Environ(),
				"CONSUL_INDEX="+strconv.FormatUint(idx, 10),
			)

			// Encode the input
			if err = json.NewEncoder(&buf).Encode(data); err != nil {
				c.Ui.Error(fmt.Sprintf("Error encoding output: %s", err))
				goto ERR
			}
			cmd.Stdin = &buf
			cmd.Stdout = os.Stdout
			cmd.Stderr = os.Stderr

			// Run the handler
			if err := cmd.Run(); err != nil {
				c.Ui.Error(fmt.Sprintf("Error executing handler: %s", err))
				goto ERR
			}
			return
		ERR:
			wp.Stop()
			errExit = 1
		}
	}

	// Watch for a shutdown
	go func() {
		<-c.ShutdownCh
		wp.Stop()
		os.Exit(0)
	}()

	// Run the watch
	if err := wp.Run(*httpAddr); err != nil {
		c.Ui.Error(fmt.Sprintf("Error querying Consul agent: %s", err))
		return 1
	}

	return errExit
}

func (c *WatchCommand) Synopsis() string {
	return "Watch for changes in Consul"
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/go-multierror/append_test.go<|end_filename|>
package multierror

import (
	"errors"
	"testing"
)

func TestAppend_Error(t *testing.T) {
	original := &Error{
		Errors: []error{errors.New("foo")},
	}

	result := Append(original, errors.New("bar"))
	if len(result.Errors) != 2 {
		t.Fatalf("wrong len: %d", len(result.Errors))
	}

	original = &Error{}
	result = Append(original, errors.New("bar"))
	if len(result.Errors) != 1 {
		t.Fatalf("wrong len: %d", len(result.Errors))
	}

	// Test when a typed nil is passed
	var e *Error
	result = Append(e, errors.New("baz"))
	if len(result.Errors) != 1 {
		t.Fatalf("wrong len: %d", len(result.Errors))
	}
}

func TestAppend_NonError(t *testing.T) {
	original := errors.New("foo")
	result := Append(original, errors.New("bar"))
	if len(result.Errors) != 2 {
		t.Fatalf("wrong len: %d", len(result.Errors))
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/consul/mdb_table.go<|end_filename|>
package consul

import (
	"bytes"
	"fmt"
	"reflect"
	"strings"
	"sync/atomic"
	"time"

	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/armon/gomdb"
)

var (
	noIndex       = fmt.Errorf("undefined index")
	tooManyFields = fmt.Errorf("number of fields exceeds index arity")
)

const (
	// lastIndexRowID is a special RowID used to represent the
	// last Raft index that affected the table. The index value
	// is not used by MDBTable, but is stored so that the client can map
	// back to the Raft index number
	lastIndexRowID = 0

	// deadlockTimeout is a heuristic to detect a potential MDB deadlock.
	// If we have a transaction that is left open indefinitely, it can
	// prevent new transactions from making progress and deadlocking
	// the system. If we fail to start a transaction after this long,
	// assume a potential deadlock and panic.
	deadlockTimeout = 30 * time.Second
)

/*
  An MDB table is a logical representation of a table, which is a
  generic row store. It provides a simple mechanism to store rows
  using a row id, while maintaining any number of secondary indexes.
*/
type MDBTable struct {
	// Last used rowID. Must be first to avoid 64bit alignment issues.
	lastRowID uint64

	Env     *mdb.Env
	Name    string // This is the name of the table, must be unique
	Indexes map[string]*MDBIndex
	Encoder func(interface{}) []byte
	Decoder func([]byte) interface{}
}

// MDBTables is used for when we have a collection of tables
type MDBTables []*MDBTable

// An Index is named, and uses a series of column values to
// map to the row-id containing the table
type MDBIndex struct {
	AllowBlank      bool      // Can fields be blank
	Unique          bool      // Controls if values are unique
	Fields          []string  // Fields are used to build the index
	IdxFunc         IndexFunc // Can be used to provide custom indexing
	Virtual         bool      // Virtual index does not exist, but can be used for queries
	RealIndex       string    // Virtual indexes use a RealIndex for iteration
	CaseInsensitive bool      // Controls if values are case-insensitive

	table     *MDBTable
	name      string
	dbiName   string
	realIndex *MDBIndex
}

// MDBTxn is used to wrap an underlying transaction
type MDBTxn struct {
	readonly bool
	tx       *mdb.Txn
	dbis     map[string]mdb.DBI
	after    []func()
}

// Abort is used to close the transaction
func (t *MDBTxn) Abort() {
	if t != nil && t.tx != nil {
		t.tx.Abort()
	}
}

// Commit is used to commit a transaction
func (t *MDBTxn) Commit() error {
	if err := t.tx.Commit(); err != nil {
		return err
	}
	for _, f := range t.after {
		f()
	}
	t.after = nil
	return nil
}

// Defer is used to defer a function call until a successful commit
func (t *MDBTxn) Defer(f func()) {
	t.after = append(t.after, f)
}

type IndexFunc func(*MDBIndex, []string) string

// DefaultIndexFunc is used if no IdxFunc is provided. It joins
// the columns using '||' which is reasonably unlikely to occur.
// We also prefix with a byte to ensure we never have a zero length
// key
func DefaultIndexFunc(idx *MDBIndex, parts []string) string {
	if len(parts) == 0 {
		return "_"
	}
	prefix := "_" + strings.Join(parts, "||") + "||"
	return prefix
}

// DefaultIndexPrefixFunc can be used with DefaultIndexFunc to scan
// for index prefix values. This should only be used as part of a
// virtual index.
func DefaultIndexPrefixFunc(idx *MDBIndex, parts []string) string {
	if len(parts) == 0 {
		return "_"
	}
	prefix := "_" + strings.Join(parts, "||")
	return prefix
}

// Init is used to initialize the MDBTable and ensure it's ready
func (t *MDBTable) Init() error {
	if t.Env == nil {
		return fmt.Errorf("Missing mdb env")
	}
	if t.Name == "" {
		return fmt.Errorf("Missing table name")
	}
	if t.Indexes == nil {
		return fmt.Errorf("Missing table indexes")
	}

	// Ensure we have a unique id index
	id, ok := t.Indexes["id"]
	if !ok {
		return fmt.Errorf("Missing id index")
	}
	if !id.Unique {
		return fmt.Errorf("id index must be unique")
	}
	if id.AllowBlank {
		return fmt.Errorf("id index must not allow blanks")
	}
	if id.Virtual {
		return fmt.Errorf("id index cannot be virtual")
	}

	// Create the table
	if err := t.createTable(); err != nil {
		return fmt.Errorf("table create failed: %v", err)
	}

	// Initialize the indexes
	for name, index := range t.Indexes {
		if err := index.init(t, name); err != nil {
			return fmt.Errorf("index %s error: %s", name, err)
		}
	}

	// Get the maximum row id
	if err := t.restoreLastRowID(); err != nil {
		return fmt.Errorf("error scanning table: %s", err)
	}

	return nil
}

// createTable is used to ensure the table exists
func (t *MDBTable) createTable() error {
	tx, err := t.Env.BeginTxn(nil, 0)
	if err != nil {
		return err
	}
	if _, err := tx.DBIOpen(t.Name, mdb.CREATE); err != nil {
		tx.Abort()
		return err
	}
	return tx.Commit()
}

// restoreLastRowID is used to set the last rowID that we've used
func (t *MDBTable) restoreLastRowID() error {
	tx, err := t.StartTxn(true, nil)
	if err != nil {
		return err
	}
	defer tx.Abort()

	cursor, err := tx.tx.CursorOpen(tx.dbis[t.Name])
	if err != nil {
		return err
	}
	defer cursor.Close()

	key, _, err := cursor.Get(nil, mdb.LAST)
	if err == mdb.NotFound {
		t.lastRowID = 0
		return nil
	} else if err != nil {
		return err
	}

	// Set the last row id
	t.lastRowID = bytesToUint64(key)
	return nil
}

// nextRowID returns the next usable row id
func (t *MDBTable) nextRowID() uint64 {
	return atomic.AddUint64(&t.lastRowID, 1)
}

// startTxn is used to start a transaction
func (t *MDBTable) StartTxn(readonly bool, mdbTxn *MDBTxn) (*MDBTxn, error) {
	var txFlags uint = 0
	var tx *mdb.Txn
	var err error

	// Panic if we deadlock acquiring a transaction
	timeout := time.AfterFunc(deadlockTimeout, func() {
		panic("Timeout starting MDB transaction, potential deadlock")
	})
	defer timeout.Stop()

	// Ensure the modes agree
	if mdbTxn != nil {
		if mdbTxn.readonly != readonly {
			return nil, fmt.Errorf("Cannot mix read/write transactions")
		}
		tx = mdbTxn.tx
		goto EXTEND
	}

	if readonly {
		txFlags |= mdb.RDONLY
	}

	tx, err = t.Env.BeginTxn(nil, txFlags)
	if err != nil {
		return nil, err
	}

	mdbTxn = &MDBTxn{
		readonly: readonly,
		tx:       tx,
		dbis:     make(map[string]mdb.DBI),
	}
EXTEND:
	dbi, err := tx.DBIOpen(t.Name, 0)
	if err != nil {
		tx.Abort()
		return nil, err
	}
	mdbTxn.dbis[t.Name] = dbi

	for _, index := range t.Indexes {
		if index.Virtual {
			continue
		}
		dbi, err := index.openDBI(tx)
		if err != nil {
			tx.Abort()
			return nil, err
		}
		mdbTxn.dbis[index.dbiName] = dbi
	}

	return mdbTxn, nil
}

// objIndexKeys builds the indexes for a given object
func (t *MDBTable) objIndexKeys(obj interface{}) (map[string][]byte, error) {
	// Construct the indexes keys
	indexes := make(map[string][]byte)
	for name, index := range t.Indexes {
		if index.Virtual {
			continue
		}
		key, err := index.keyFromObject(obj)
		if err != nil {
			return nil, err
		}
		indexes[name] = key
	}
	return indexes, nil
}

// Insert is used to insert or update an object
func (t *MDBTable) Insert(obj interface{}) error {
	// Start a new txn
	tx, err := t.StartTxn(false, nil)
	if err != nil {
		return err
	}
	defer tx.Abort()

	if err := t.InsertTxn(tx, obj); err != nil {
		return err
	}
	return tx.Commit()
}

// Insert is used to insert or update an object within
// a given transaction
func (t *MDBTable) InsertTxn(tx *MDBTxn, obj interface{}) error {
	var n int
	// Construct the indexes keys
	indexes, err := t.objIndexKeys(obj)
	if err != nil {
		return err
	}

	// Encode the obj
	raw := t.Encoder(obj)

	// Scan and check if this primary key already exists
	primaryDbi := tx.dbis[t.Indexes["id"].dbiName]
	_, err = tx.tx.Get(primaryDbi, indexes["id"])
	if err == mdb.NotFound {
		goto AFTER_DELETE
	}

	// Delete the existing row
	n, err = t.deleteWithIndex(tx, t.Indexes["id"], indexes["id"])
	if err != nil {
		return err
	}
	if n != 1 {
		return fmt.Errorf("unexpected number of updates: %d", n)
	}

AFTER_DELETE:
	// Insert with a new row ID
	rowId := t.nextRowID()
	encRowId := uint64ToBytes(rowId)
	table := tx.dbis[t.Name]
	if err := tx.tx.Put(table, encRowId, raw, 0); err != nil {
		return err
	}

	// Insert the new indexes
	for name, index := range t.Indexes {
		if index.Virtual {
			continue
		}
		dbi := tx.dbis[index.dbiName]
		if err := tx.tx.Put(dbi, indexes[name], encRowId, 0); err != nil {
			return err
		}
	}
	return nil
}

// Get is used to lookup one or more rows. An index an appropriate
// fields are specified. The fields can be a prefix of the index.
func (t *MDBTable) Get(index string, parts ...string) (uint64, []interface{}, error) {
	// Start a readonly txn
	tx, err := t.StartTxn(true, nil)
	if err != nil {
		return 0, nil, err
	}
	defer tx.Abort()

	// Get the last associated index
	idx, err := t.LastIndexTxn(tx)
	if err != nil {
		return 0, nil, err
	}

	// Get the actual results
	res, err := t.GetTxn(tx, index, parts...)
	return idx, res, err
}

// GetTxn is like Get but it operates within a specific transaction.
// This can be used for read that span multiple tables
func (t *MDBTable) GetTxn(tx *MDBTxn, index string, parts ...string) ([]interface{}, error) {
	// Get the associated index
	idx, key, err := t.getIndex(index, parts)
	if err != nil {
		return nil, err
	}

	// Accumulate the results
	var results []interface{}
	err = idx.iterate(tx, key, func(encRowId, res []byte) (bool, bool) {
		obj := t.Decoder(res)
		results = append(results, obj)
		return false, false
	})

	return results, err
}

// GetTxnLimit is like GetTxn limits the maximum number of
// rows it will return
func (t *MDBTable) GetTxnLimit(tx *MDBTxn, limit int, index string, parts ...string) ([]interface{}, error) {
	// Get the associated index
	idx, key, err := t.getIndex(index, parts)
	if err != nil {
		return nil, err
	}

	// Accumulate the results
	var results []interface{}
	num := 0
	err = idx.iterate(tx, key, func(encRowId, res []byte) (bool, bool) {
		num++
		obj := t.Decoder(res)
		results = append(results, obj)
		return false, num == limit
	})

	return results, err
}

// StreamTxn is like GetTxn but it streams the results over a channel.
// This can be used if the expected data set is very large. The stream
// is always closed on return.
func (t *MDBTable) StreamTxn(stream chan<- interface{}, tx *MDBTxn, index string, parts ...string) error {
	// Always close the stream on return
	defer close(stream)

	// Get the associated index
	idx, key, err := t.getIndex(index, parts)
	if err != nil {
		return err
	}

	// Stream the results
	err = idx.iterate(tx, key, func(encRowId, res []byte) (bool, bool) {
		obj := t.Decoder(res)
		stream <- obj
		return false, false
	})

	return err
}

// getIndex is used to get the proper index, and also check the arity
func (t *MDBTable) getIndex(index string, parts []string) (*MDBIndex, []byte, error) {
	// Get the index
	idx, ok := t.Indexes[index]
	if !ok {
		return nil, nil, noIndex
	}

	// Check the arity
	arity := idx.arity()
	if len(parts) > arity {
		return nil, nil, tooManyFields
	}

	if idx.CaseInsensitive {
		parts = ToLowerList(parts)
	}

	// Construct the key
	key := idx.keyFromParts(parts...)
	return idx, key, nil
}

// Delete is used to delete one or more rows. An index an appropriate
// fields are specified. The fields can be a prefix of the index.
// Returns the rows deleted or an error.
func (t *MDBTable) Delete(index string, parts ...string) (num int, err error) {
	// Start a write txn
	tx, err := t.StartTxn(false, nil)
	if err != nil {
		return 0, err
	}
	defer tx.Abort()

	num, err = t.DeleteTxn(tx, index, parts...)
	if err != nil {
		return 0, err
	}
	return num, tx.Commit()
}

// DeleteTxn is like Delete, but occurs in a specific transaction
// that can span multiple tables.
func (t *MDBTable) DeleteTxn(tx *MDBTxn, index string, parts ...string) (int, error) {
	// Get the associated index
	idx, key, err := t.getIndex(index, parts)
	if err != nil {
		return 0, err
	}

	// Delete with the index
	return t.deleteWithIndex(tx, idx, key)
}

// deleteWithIndex deletes all associated rows while scanning
// a given index for a key prefix. May perform multiple index traversals.
// This is a hack around a bug in LMDB which can cause a partial delete to
// take place. To fix this, we invoke the innerDelete until all rows are
// removed. This hack can be removed once the LMDB bug is resolved.
func (t *MDBTable) deleteWithIndex(tx *MDBTxn, idx *MDBIndex, key []byte) (int, error) {
	var total int
	var num int
	var err error
DELETE:
	num, err = t.innerDeleteWithIndex(tx, idx, key)
	total += num
	if err != nil {
		return total, err
	}
	if num > 0 {
		goto DELETE
	}
	return total, nil
}

// innerDeleteWithIndex deletes all associated rows while scanning
// a given index for a key prefix. It only traverses the index a single time.
func (t *MDBTable) innerDeleteWithIndex(tx *MDBTxn, idx *MDBIndex, key []byte) (num int, err error) {
	// Handle an error while deleting
	defer func() {
		if r := recover(); r != nil {
			num = 0
			err = fmt.Errorf("Panic while deleting: %v", r)
		}
	}()

	// Delete everything as we iterate
	err = idx.iterate(tx, key, func(encRowId, res []byte) (bool, bool) {
		// Get the object
		obj := t.Decoder(res)

		// Build index values
		indexes, err := t.objIndexKeys(obj)
		if err != nil {
			panic(err)
		}

		// Delete the indexes we are not iterating
		for name, otherIdx := range t.Indexes {
			if name == idx.name {
				continue
			}
			if idx.Virtual && name == idx.RealIndex {
				continue
			}
			if otherIdx.Virtual {
				continue
			}
			dbi := tx.dbis[otherIdx.dbiName]
			if err := tx.tx.Del(dbi, indexes[name], encRowId); err != nil {
				panic(err)
			}
		}

		// Delete the data row
		if err := tx.tx.Del(tx.dbis[t.Name], encRowId, nil); err != nil {
			panic(err)
		}

		// Delete the object
		num++
		return true, false
	})
	if err != nil {
		return 0, err
	}

	// Return the deleted count
	return num, nil
}

// Initializes an index and returns a potential error
func (i *MDBIndex) init(table *MDBTable, name string) error {
	i.table = table
	i.name = name
	i.dbiName = fmt.Sprintf("%s_%s_idx", i.table.Name, i.name)
	if i.IdxFunc == nil {
		i.IdxFunc = DefaultIndexFunc
	}
	if len(i.Fields) == 0 {
		return fmt.Errorf("index missing fields")
	}
	if err := i.createIndex(); err != nil {
		return err
	}
	// Verify real index exists
	if i.Virtual {
		if realIndex, ok := table.Indexes[i.RealIndex]; !ok {
			return fmt.Errorf("real index '%s' missing", i.RealIndex)
		} else {
			i.realIndex = realIndex
		}
	}
	return nil
}

// createIndex is used to ensure the index exists
func (i *MDBIndex) createIndex() error {
	// Do not create if this is a virtual index
	if i.Virtual {
		return nil
	}
	tx, err := i.table.Env.BeginTxn(nil, 0)
	if err != nil {
		return err
	}
	var dbFlags uint = mdb.CREATE
	if !i.Unique {
		dbFlags |= mdb.DUPSORT
	}
	if _, err := tx.DBIOpen(i.dbiName, dbFlags); err != nil {
		tx.Abort()
		return err
	}
	return tx.Commit()
}

// openDBI is used to open a handle to the index for a transaction
func (i *MDBIndex) openDBI(tx *mdb.Txn) (mdb.DBI, error) {
	var dbFlags uint
	if !i.Unique {
		dbFlags |= mdb.DUPSORT
	}
	return tx.DBIOpen(i.dbiName, dbFlags)
}

// Returns the arity of the index
func (i *MDBIndex) arity() int {
	return len(i.Fields)
}

// keyFromObject constructs the index key from the object
func (i *MDBIndex) keyFromObject(obj interface{}) ([]byte, error) {
	v := reflect.ValueOf(obj)
	v = reflect.Indirect(v) // Derefence the pointer if any
	parts := make([]string, 0, i.arity())
	for _, field := range i.Fields {
		fv := v.FieldByName(field)
		if !fv.IsValid() {
			return nil, fmt.Errorf("Field '%s' for %#v is invalid", field, obj)
		}
		val := fv.String()
		if !i.AllowBlank && val == "" {
			return nil, fmt.Errorf("Field '%s' must be set: %#v", field, obj)
		}
		if i.CaseInsensitive {
			val = strings.ToLower(val)
		}
		parts = append(parts, val)
	}
	key := i.keyFromParts(parts...)
	return key, nil
}

// keyFromParts returns the key from component parts
func (i *MDBIndex) keyFromParts(parts ...string) []byte {
	return []byte(i.IdxFunc(i, parts))
}

// iterate is used to iterate over keys matching the prefix,
// and invoking the cb with each row. We dereference the rowid,
// and only return the object row
func (i *MDBIndex) iterate(tx *MDBTxn, prefix []byte,
	cb func(encRowId, res []byte) (bool, bool)) error {
	table := tx.dbis[i.table.Name]

	// If virtual, use the correct DBI
	var dbi mdb.DBI
	if i.Virtual {
		dbi = tx.dbis[i.realIndex.dbiName]
	} else {
		dbi = tx.dbis[i.dbiName]
	}

	cursor, err := tx.tx.CursorOpen(dbi)
	if err != nil {
		return err
	}
	// Read-only cursors are NOT closed by MDB when a transaction
	// either commits or aborts, so must be closed explicitly
	if tx.readonly {
		defer cursor.Close()
	}

	var key, encRowId, objBytes []byte
	first := true
	shouldStop := false
	shouldDelete := false
	for !shouldStop {
		if first && len(prefix) > 0 {
			first = false
			key, encRowId, err = cursor.Get(prefix, mdb.SET_RANGE)
		} else if shouldDelete {
			key, encRowId, err = cursor.Get(nil, mdb.GET_CURRENT)
			shouldDelete = false

			// LMDB will return EINVAL(22) for the GET_CURRENT op if
			// there is no further keys. We treat this as no more
			// keys being found.
			if num, ok := err.(mdb.Errno); ok && num == 22 {
				err = mdb.NotFound
			}
		} else if i.Unique {
			key, encRowId, err = cursor.Get(nil, mdb.NEXT)
		} else {
			key, encRowId, err = cursor.Get(nil, mdb.NEXT_DUP)
			if err == mdb.NotFound {
				key, encRowId, err = cursor.Get(nil, mdb.NEXT)
			}
		}
		if err == mdb.NotFound {
			break
		} else if err != nil {
			return fmt.Errorf("iterate failed: %v", err)
		}

		// Bail if this does not match our filter
		if len(prefix) > 0 && !bytes.HasPrefix(key, prefix) {
			break
		}

		// Lookup the actual object
		objBytes, err = tx.tx.Get(table, encRowId)
		if err != nil {
			return fmt.Errorf("rowid lookup failed: %v (%v)", err, encRowId)
		}

		// Invoke the cb
		shouldDelete, shouldStop = cb(encRowId, objBytes)
		if shouldDelete {
			if err := cursor.Del(0); err != nil {
				return fmt.Errorf("delete failed: %v", err)
			}
		}
	}
	return nil
}

// LastIndex is get the last index that updated the table
func (t *MDBTable) LastIndex() (uint64, error) {
	// Start a readonly txn
	tx, err := t.StartTxn(true, nil)
	if err != nil {
		return 0, err
	}
	defer tx.Abort()
	return t.LastIndexTxn(tx)
}

// LastIndexTxn is like LastIndex but it operates within a specific transaction.
func (t *MDBTable) LastIndexTxn(tx *MDBTxn) (uint64, error) {
	encRowId := uint64ToBytes(lastIndexRowID)
	val, err := tx.tx.Get(tx.dbis[t.Name], encRowId)
	if err == mdb.NotFound {
		return 0, nil
	} else if err != nil {
		return 0, err
	}

	// Return the last index
	return bytesToUint64(val), nil
}

// SetLastIndex is used to set the last index that updated the table
func (t *MDBTable) SetLastIndex(index uint64) error {
	tx, err := t.StartTxn(false, nil)
	if err != nil {
		return err
	}
	defer tx.Abort()

	if err := t.SetLastIndexTxn(tx, index); err != nil {
		return err
	}
	return tx.Commit()
}

// SetLastIndexTxn is used to set the last index within a transaction
func (t *MDBTable) SetLastIndexTxn(tx *MDBTxn, index uint64) error {
	encRowId := uint64ToBytes(lastIndexRowID)
	encIndex := uint64ToBytes(index)
	return tx.tx.Put(tx.dbis[t.Name], encRowId, encIndex, 0)
}

// SetMaxLastIndexTxn is used to set the last index within a transaction
// if it exceeds the current maximum
func (t *MDBTable) SetMaxLastIndexTxn(tx *MDBTxn, index uint64) error {
	current, err := t.LastIndexTxn(tx)
	if err != nil {
		return err
	}
	if index > current {
		return t.SetLastIndexTxn(tx, index)
	}
	return nil
}

// StartTxn is used to create a transaction that spans a list of tables
func (t MDBTables) StartTxn(readonly bool) (*MDBTxn, error) {
	var tx *MDBTxn
	for _, table := range t {
		newTx, err := table.StartTxn(readonly, tx)
		if err != nil {
			tx.Abort()
			return nil, err
		}
		tx = newTx
	}
	return tx, nil
}

// LastIndexTxn is used to get the last transaction from all of the tables
func (t MDBTables) LastIndexTxn(tx *MDBTxn) (uint64, error) {
	var index uint64
	for _, table := range t {
		idx, err := table.LastIndexTxn(tx)
		if err != nil {
			return index, err
		}
		if idx > index {
			index = idx
		}
	}
	return index, nil
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/watch/watch.go<|end_filename|>
package watch

import (
	"fmt"
	"io"
	"sync"

	consulapi "github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/api"
)

// WatchPlan is the parsed version of a watch specification. A watch provides
// the details of a query, which generates a view into the Consul data store.
// This view is watched for changes and a handler is invoked to take any
// appropriate actions.
type WatchPlan struct {
	Datacenter string
	Token      string
	Type       string
	Exempt     map[string]interface{}

	Func      WatchFunc
	Handler   HandlerFunc
	LogOutput io.Writer

	address    string
	client     *consulapi.Client
	lastIndex  uint64
	lastResult interface{}

	stop     bool
	stopCh   chan struct{}
	stopLock sync.Mutex
}

// WatchFunc is used to watch for a diff
type WatchFunc func(*WatchPlan) (uint64, interface{}, error)

// HandlerFunc is used to handle new data
type HandlerFunc func(uint64, interface{})

// Parse takes a watch query and compiles it into a WatchPlan or an error
func Parse(params map[string]interface{}) (*WatchPlan, error) {
	return ParseExempt(params, nil)
}

// ParseExempt takes a watch query and compiles it into a WatchPlan or an error
// Any exempt parameters are stored in the Exempt map
func ParseExempt(params map[string]interface{}, exempt []string) (*WatchPlan, error) {
	plan := &WatchPlan{
		stopCh: make(chan struct{}),
	}

	// Parse the generic parameters
	if err := assignValue(params, "datacenter", &plan.Datacenter); err != nil {
		return nil, err
	}
	if err := assignValue(params, "token", &plan.Token); err != nil {
		return nil, err
	}
	if err := assignValue(params, "type", &plan.Type); err != nil {
		return nil, err
	}

	// Ensure there is a watch type
	if plan.Type == "" {
		return nil, fmt.Errorf("Watch type must be specified")
	}

	// Look for a factory function
	factory := watchFuncFactory[plan.Type]
	if factory == nil {
		return nil, fmt.Errorf("Unsupported watch type: %s", plan.Type)
	}

	// Get the watch func
	fn, err := factory(params)
	if err != nil {
		return nil, err
	}
	plan.Func = fn

	// Remove the exempt parameters
	if len(exempt) > 0 {
		plan.Exempt = make(map[string]interface{})
		for _, ex := range exempt {
			val, ok := params[ex]
			if ok {
				plan.Exempt[ex] = val
				delete(params, ex)
			}
		}
	}

	// Ensure all parameters are consumed
	if len(params) != 0 {
		var bad []string
		for key := range params {
			bad = append(bad, key)
		}
		return nil, fmt.Errorf("Invalid parameters: %v", bad)
	}
	return plan, nil
}

// assignValue is used to extract a value ensuring it is a string
func assignValue(params map[string]interface{}, name string, out *string) error {
	if raw, ok := params[name]; ok {
		val, ok := raw.(string)
		if !ok {
			return fmt.Errorf("Expecting %s to be a string", name)
		}
		*out = val
		delete(params, name)
	}
	return nil
}

// assignValueBool is used to extract a value ensuring it is a bool
func assignValueBool(params map[string]interface{}, name string, out *bool) error {
	if raw, ok := params[name]; ok {
		val, ok := raw.(bool)
		if !ok {
			return fmt.Errorf("Expecting %s to be a boolean", name)
		}
		*out = val
		delete(params, name)
	}
	return nil
}


<|start_filename|>Godeps/_workspace/src/github.com/mitchellh/cli/ui_colored.go<|end_filename|>
package cli

import (
	"fmt"
)

// UiColor is a posix shell color code to use.
type UiColor struct {
	Code int
	Bold bool
}

// A list of colors that are useful. These are all non-bolded by default.
var (
	UiColorNone    UiColor = UiColor{-1, false}
	UiColorRed             = UiColor{31, false}
	UiColorGreen           = UiColor{32, false}
	UiColorYellow          = UiColor{33, false}
	UiColorBlue            = UiColor{34, false}
	UiColorMagenta         = UiColor{35, false}
	UiColorCyan            = UiColor{36, false}
)

// ColoredUi is a Ui implementation that colors its output according
// to the given color schemes for the given type of output.
type ColoredUi struct {
	OutputColor UiColor
	InfoColor   UiColor
	ErrorColor  UiColor
	Ui          Ui
}

func (u *ColoredUi) Ask(query string) (string, error) {
	return u.Ui.Ask(u.colorize(query, u.OutputColor))
}

func (u *ColoredUi) Output(message string) {
	u.Ui.Output(u.colorize(message, u.OutputColor))
}

func (u *ColoredUi) Info(message string) {
	u.Ui.Info(u.colorize(message, u.InfoColor))
}

func (u *ColoredUi) Error(message string) {
	u.Ui.Error(u.colorize(message, u.ErrorColor))
}

func (u *ColoredUi) colorize(message string, color UiColor) string {
	if color.Code == -1 {
		return message
	}

	attr := 0
	if color.Bold {
		attr = 1
	}

	return fmt.Sprintf("\033[%d;%dm%s\033[0m", attr, color.Code, message)
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/command/agent/structs_test.go<|end_filename|>
package agent

import (
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/consul/structs"
	"testing"
)

func TestAgentStructs_HealthCheck(t *testing.T) {
	def := CheckDefinition{}
	check := def.HealthCheck("node1")

	// Health checks default to critical state
	if check.Status != structs.HealthCritical {
		t.Fatalf("bad: %v", check.Status)
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/consul/health_endpoint.go<|end_filename|>
package consul

import (
	"fmt"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/armon/go-metrics"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/consul/structs"
)

// Health endpoint is used to query the health information
type Health struct {
	srv *Server
}

// ChecksInState is used to get all the checks in a given state
func (h *Health) ChecksInState(args *structs.ChecksInStateRequest,
	reply *structs.IndexedHealthChecks) error {
	if done, err := h.srv.forward("Health.ChecksInState", args, args, reply); done {
		return err
	}

	// Get the state specific checks
	state := h.srv.fsm.State()
	return h.srv.blockingRPC(&args.QueryOptions,
		&reply.QueryMeta,
		state.QueryTables("ChecksInState"),
		func() error {
			reply.Index, reply.HealthChecks = state.ChecksInState(args.State)
			return nil
		})
}

// NodeChecks is used to get all the checks for a node
func (h *Health) NodeChecks(args *structs.NodeSpecificRequest,
	reply *structs.IndexedHealthChecks) error {
	if done, err := h.srv.forward("Health.NodeChecks", args, args, reply); done {
		return err
	}

	// Get the node checks
	state := h.srv.fsm.State()
	return h.srv.blockingRPC(&args.QueryOptions,
		&reply.QueryMeta,
		state.QueryTables("NodeChecks"),
		func() error {
			reply.Index, reply.HealthChecks = state.NodeChecks(args.Node)
			return nil
		})
}

// ServiceChecks is used to get all the checks for a service
func (h *Health) ServiceChecks(args *structs.ServiceSpecificRequest,
	reply *structs.IndexedHealthChecks) error {
	// Reject if tag filtering is on
	if args.TagFilter {
		return fmt.Errorf("Tag filtering is not supported")
	}

	// Potentially forward
	if done, err := h.srv.forward("Health.ServiceChecks", args, args, reply); done {
		return err
	}

	// Get the service checks
	state := h.srv.fsm.State()
	return h.srv.blockingRPC(&args.QueryOptions,
		&reply.QueryMeta,
		state.QueryTables("ServiceChecks"),
		func() error {
			reply.Index, reply.HealthChecks = state.ServiceChecks(args.ServiceName)
			return nil
		})
}

// ServiceNodes returns all the nodes registered as part of a service including health info
func (h *Health) ServiceNodes(args *structs.ServiceSpecificRequest, reply *structs.IndexedCheckServiceNodes) error {
	if done, err := h.srv.forward("Health.ServiceNodes", args, args, reply); done {
		return err
	}

	// Verify the arguments
	if args.ServiceName == "" {
		return fmt.Errorf("Must provide service name")
	}

	// Get the nodes
	state := h.srv.fsm.State()
	err := h.srv.blockingRPC(&args.QueryOptions,
		&reply.QueryMeta,
		state.QueryTables("CheckServiceNodes"),
		func() error {
			if args.TagFilter {
				reply.Index, reply.Nodes = state.CheckServiceTagNodes(args.ServiceName, args.ServiceTag)
			} else {
				reply.Index, reply.Nodes = state.CheckServiceNodes(args.ServiceName)
			}
			return nil
		})

	// Provide some metrics
	if err == nil {
		metrics.IncrCounter([]string{"consul", "health", "service", "query", args.ServiceName}, 1)
		if args.ServiceTag != "" {
			metrics.IncrCounter([]string{"consul", "health", "service", "query-tag", args.ServiceName, args.ServiceTag}, 1)
		}
		if len(reply.Nodes) == 0 {
			metrics.IncrCounter([]string{"consul", "health", "service", "not-found", args.ServiceName}, 1)
		}
	}
	return err
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/command/agent/command_test.go<|end_filename|>
package agent

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"testing"

	"github.com/hashicorp/consul/testutil"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/mitchellh/cli"
)

func TestCommand_implements(t *testing.T) {
	var _ cli.Command = new(Command)
}

func TestValidDatacenter(t *testing.T) {
	shouldMatch := []string{
		"dc1",
		"east-aws-001",
		"PROD_aws01-small",
	}
	noMatch := []string{
		"east.aws",
		"east!aws",
		"first,second",
	}
	for _, m := range shouldMatch {
		if !validDatacenter.MatchString(m) {
			t.Fatalf("expected match: %s", m)
		}
	}
	for _, m := range noMatch {
		if validDatacenter.MatchString(m) {
			t.Fatalf("expected no match: %s", m)
		}
	}
}

func TestRetryJoin(t *testing.T) {
	dir, agent := makeAgent(t, nextConfig())
	defer os.RemoveAll(dir)
	defer agent.Shutdown()

	conf2 := nextConfig()
	tmpDir, err := ioutil.TempDir("", "consul")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer os.RemoveAll(tmpDir)

	doneCh := make(chan struct{})
	shutdownCh := make(chan struct{})

	defer func() {
		close(shutdownCh)
		<-doneCh
	}()

	cmd := &Command{
		ShutdownCh: shutdownCh,
		Ui:         new(cli.MockUi),
	}

	serfAddr := fmt.Sprintf(
		"%s:%d",
		agent.config.BindAddr,
		agent.config.Ports.SerfLan)

	serfWanAddr := fmt.Sprintf(
		"%s:%d",
		agent.config.BindAddr,
		agent.config.Ports.SerfWan)

	args := []string{
		"-server",
		"-data-dir", tmpDir,
		"-node", fmt.Sprintf(`"%s"`, conf2.NodeName),
		"-retry-join", serfAddr,
		"-retry-interval", "1s",
		"-retry-join-wan", serfWanAddr,
		"-retry-interval-wan", "1s",
	}

	go func() {
		if code := cmd.Run(args); code != 0 {
			log.Printf("bad: %d", code)
		}
		close(doneCh)
	}()

	testutil.WaitForResult(func() (bool, error) {
		mem := agent.LANMembers()
		if len(mem) != 2 {
			return false, fmt.Errorf("bad: %#v", mem)
		}
		mem = agent.WANMembers()
		if len(mem) != 2 {
			return false, fmt.Errorf("bad (wan): %#v", mem)
		}
		return true, nil
	}, func(err error) {
		t.Fatalf(err.Error())
	})
}

func TestRetryJoinFail(t *testing.T) {
	conf := nextConfig()
	tmpDir, err := ioutil.TempDir("", "consul")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer os.RemoveAll(tmpDir)

	shutdownCh := make(chan struct{})
	defer close(shutdownCh)

	cmd := &Command{
		ShutdownCh: shutdownCh,
		Ui:         new(cli.MockUi),
	}

	serfAddr := fmt.Sprintf("%s:%d", conf.BindAddr, conf.Ports.SerfLan)

	args := []string{
		"-data-dir", tmpDir,
		"-retry-join", serfAddr,
		"-retry-max", "1",
	}

	if code := cmd.Run(args); code == 0 {
		t.Fatalf("bad: %d", code)
	}
}

func TestRetryJoinWanFail(t *testing.T) {
	conf := nextConfig()
	tmpDir, err := ioutil.TempDir("", "consul")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer os.RemoveAll(tmpDir)

	shutdownCh := make(chan struct{})
	defer close(shutdownCh)

	cmd := &Command{
		ShutdownCh: shutdownCh,
		Ui:         new(cli.MockUi),
	}

	serfAddr := fmt.Sprintf("%s:%d", conf.BindAddr, conf.Ports.SerfWan)

	args := []string{
		"-server",
		"-data-dir", tmpDir,
		"-retry-join-wan", serfAddr,
		"-retry-max-wan", "1",
	}

	if code := cmd.Run(args); code == 0 {
		t.Fatalf("bad: %d", code)
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/vishvananda/netlink/nl/xfrm_linux.go<|end_filename|>
package nl

import (
	"bytes"
	"net"
	"unsafe"
)

// Infinity for packet and byte counts
const (
	XFRM_INF = ^uint64(0)
)

// Message Types
const (
	XFRM_MSG_BASE        = 0x10
	XFRM_MSG_NEWSA       = 0x10
	XFRM_MSG_DELSA       = 0x11
	XFRM_MSG_GETSA       = 0x12
	XFRM_MSG_NEWPOLICY   = 0x13
	XFRM_MSG_DELPOLICY   = 0x14
	XFRM_MSG_GETPOLICY   = 0x15
	XFRM_MSG_ALLOCSPI    = 0x16
	XFRM_MSG_ACQUIRE     = 0x17
	XFRM_MSG_EXPIRE      = 0x18
	XFRM_MSG_UPDPOLICY   = 0x19
	XFRM_MSG_UPDSA       = 0x1a
	XFRM_MSG_POLEXPIRE   = 0x1b
	XFRM_MSG_FLUSHSA     = 0x1c
	XFRM_MSG_FLUSHPOLICY = 0x1d
	XFRM_MSG_NEWAE       = 0x1e
	XFRM_MSG_GETAE       = 0x1f
	XFRM_MSG_REPORT      = 0x20
	XFRM_MSG_MIGRATE     = 0x21
	XFRM_MSG_NEWSADINFO  = 0x22
	XFRM_MSG_GETSADINFO  = 0x23
	XFRM_MSG_NEWSPDINFO  = 0x24
	XFRM_MSG_GETSPDINFO  = 0x25
	XFRM_MSG_MAPPING     = 0x26
	XFRM_MSG_MAX         = 0x26
	XFRM_NR_MSGTYPES     = 0x17
)

// Attribute types
const (
	/* Netlink message attributes.  */
	XFRMA_UNSPEC         = 0x00
	XFRMA_ALG_AUTH       = 0x01 /* struct xfrm_algo */
	XFRMA_ALG_CRYPT      = 0x02 /* struct xfrm_algo */
	XFRMA_ALG_COMP       = 0x03 /* struct xfrm_algo */
	XFRMA_ENCAP          = 0x04 /* struct xfrm_algo + struct xfrm_encap_tmpl */
	XFRMA_TMPL           = 0x05 /* 1 or more struct xfrm_user_tmpl */
	XFRMA_SA             = 0x06 /* struct xfrm_usersa_info  */
	XFRMA_POLICY         = 0x07 /* struct xfrm_userpolicy_info */
	XFRMA_SEC_CTX        = 0x08 /* struct xfrm_sec_ctx */
	XFRMA_LTIME_VAL      = 0x09
	XFRMA_REPLAY_VAL     = 0x0a
	XFRMA_REPLAY_THRESH  = 0x0b
	XFRMA_ETIMER_THRESH  = 0x0c
	XFRMA_SRCADDR        = 0x0d /* xfrm_address_t */
	XFRMA_COADDR         = 0x0e /* xfrm_address_t */
	XFRMA_LASTUSED       = 0x0f /* unsigned long  */
	XFRMA_POLICY_TYPE    = 0x10 /* struct xfrm_userpolicy_type */
	XFRMA_MIGRATE        = 0x11
	XFRMA_ALG_AEAD       = 0x12 /* struct xfrm_algo_aead */
	XFRMA_KMADDRESS      = 0x13 /* struct xfrm_user_kmaddress */
	XFRMA_ALG_AUTH_TRUNC = 0x14 /* struct xfrm_algo_auth */
	XFRMA_MARK           = 0x15 /* struct xfrm_mark */
	XFRMA_TFCPAD         = 0x16 /* __u32 */
	XFRMA_REPLAY_ESN_VAL = 0x17 /* struct xfrm_replay_esn */
	XFRMA_SA_EXTRA_FLAGS = 0x18 /* __u32 */
	XFRMA_MAX            = 0x18
)

const (
	SizeofXfrmAddress     = 0x10
	SizeofXfrmSelector    = 0x38
	SizeofXfrmLifetimeCfg = 0x40
	SizeofXfrmLifetimeCur = 0x20
	SizeofXfrmId          = 0x18
)

// typedef union {
//   __be32    a4;
//   __be32    a6[4];
// } xfrm_address_t;

type XfrmAddress [SizeofXfrmAddress]byte

func (x *XfrmAddress) ToIP() net.IP {
	var empty = [12]byte{}
	ip := make(net.IP, net.IPv6len)
	if bytes.Equal(x[4:16], empty[:]) {
		ip[10] = 0xff
		ip[11] = 0xff
		copy(ip[12:16], x[0:4])
	} else {
		copy(ip[:], x[:])
	}
	return ip
}

func (x *XfrmAddress) ToIPNet(prefixlen uint8) *net.IPNet {
	ip := x.ToIP()
	if GetIPFamily(ip) == FAMILY_V4 {
		return &net.IPNet{ip, net.CIDRMask(int(prefixlen), 32)}
	} else {
		return &net.IPNet{ip, net.CIDRMask(int(prefixlen), 128)}
	}
}

func (x *XfrmAddress) FromIP(ip net.IP) {
	var empty = [16]byte{}
	if len(ip) < net.IPv4len {
		copy(x[4:16], empty[:])
	} else if GetIPFamily(ip) == FAMILY_V4 {
		copy(x[0:4], ip.To4()[0:4])
		copy(x[4:16], empty[:12])
	} else {
		copy(x[0:16], ip.To16()[0:16])
	}
}

func DeserializeXfrmAddress(b []byte) *XfrmAddress {
	return (*XfrmAddress)(unsafe.Pointer(&b[0:SizeofXfrmAddress][0]))
}

func (msg *XfrmAddress) Serialize() []byte {
	return (*(*[SizeofXfrmAddress]byte)(unsafe.Pointer(msg)))[:]
}

// struct xfrm_selector {
//   xfrm_address_t  daddr;
//   xfrm_address_t  saddr;
//   __be16  dport;
//   __be16  dport_mask;
//   __be16  sport;
//   __be16  sport_mask;
//   __u16 family;
//   __u8  prefixlen_d;
//   __u8  prefixlen_s;
//   __u8  proto;
//   int ifindex;
//   __kernel_uid32_t  user;
// };

type XfrmSelector struct {
	Daddr      XfrmAddress
	Saddr      XfrmAddress
	Dport      uint16 // big endian
	DportMask  uint16 // big endian
	Sport      uint16 // big endian
	SportMask  uint16 // big endian
	Family     uint16
	PrefixlenD uint8
	PrefixlenS uint8
	Proto      uint8
	Pad        [3]byte
	Ifindex    int32
	User       uint32
}

func (msg *XfrmSelector) Len() int {
	return SizeofXfrmSelector
}

func DeserializeXfrmSelector(b []byte) *XfrmSelector {
	return (*XfrmSelector)(unsafe.Pointer(&b[0:SizeofXfrmSelector][0]))
}

func (msg *XfrmSelector) Serialize() []byte {
	return (*(*[SizeofXfrmSelector]byte)(unsafe.Pointer(msg)))[:]
}

// struct xfrm_lifetime_cfg {
//   __u64 soft_byte_limit;
//   __u64 hard_byte_limit;
//   __u64 soft_packet_limit;
//   __u64 hard_packet_limit;
//   __u64 soft_add_expires_seconds;
//   __u64 hard_add_expires_seconds;
//   __u64 soft_use_expires_seconds;
//   __u64 hard_use_expires_seconds;
// };
//

type XfrmLifetimeCfg struct {
	SoftByteLimit         uint64
	HardByteLimit         uint64
	SoftPacketLimit       uint64
	HardPacketLimit       uint64
	SoftAddExpiresSeconds uint64
	HardAddExpiresSeconds uint64
	SoftUseExpiresSeconds uint64
	HardUseExpiresSeconds uint64
}

func (msg *XfrmLifetimeCfg) Len() int {
	return SizeofXfrmLifetimeCfg
}

func DeserializeXfrmLifetimeCfg(b []byte) *XfrmLifetimeCfg {
	return (*XfrmLifetimeCfg)(unsafe.Pointer(&b[0:SizeofXfrmLifetimeCfg][0]))
}

func (msg *XfrmLifetimeCfg) Serialize() []byte {
	return (*(*[SizeofXfrmLifetimeCfg]byte)(unsafe.Pointer(msg)))[:]
}

// struct xfrm_lifetime_cur {
//   __u64 bytes;
//   __u64 packets;
//   __u64 add_time;
//   __u64 use_time;
// };

type XfrmLifetimeCur struct {
	Bytes   uint64
	Packets uint64
	AddTime uint64
	UseTime uint64
}

func (msg *XfrmLifetimeCur) Len() int {
	return SizeofXfrmLifetimeCur
}

func DeserializeXfrmLifetimeCur(b []byte) *XfrmLifetimeCur {
	return (*XfrmLifetimeCur)(unsafe.Pointer(&b[0:SizeofXfrmLifetimeCur][0]))
}

func (msg *XfrmLifetimeCur) Serialize() []byte {
	return (*(*[SizeofXfrmLifetimeCur]byte)(unsafe.Pointer(msg)))[:]
}

// struct xfrm_id {
//   xfrm_address_t  daddr;
//   __be32    spi;
//   __u8    proto;
// };

type XfrmId struct {
	Daddr XfrmAddress
	Spi   uint32 // big endian
	Proto uint8
	Pad   [3]byte
}

func (msg *XfrmId) Len() int {
	return SizeofXfrmId
}

func DeserializeXfrmId(b []byte) *XfrmId {
	return (*XfrmId)(unsafe.Pointer(&b[0:SizeofXfrmId][0]))
}

func (msg *XfrmId) Serialize() []byte {
	return (*(*[SizeofXfrmId]byte)(unsafe.Pointer(msg)))[:]
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/command/members_test.go<|end_filename|>
package command

import (
	"fmt"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/mitchellh/cli"
	"strings"
	"testing"
)

func TestMembersCommand_implements(t *testing.T) {
	var _ cli.Command = &MembersCommand{}
}

func TestMembersCommandRun(t *testing.T) {
	a1 := testAgent(t)
	defer a1.Shutdown()

	ui := new(cli.MockUi)
	c := &MembersCommand{Ui: ui}
	args := []string{"-rpc-addr=" + a1.addr}

	code := c.Run(args)
	if code != 0 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}

	if !strings.Contains(ui.OutputWriter.String(), a1.config.NodeName) {
		t.Fatalf("bad: %#v", ui.OutputWriter.String())
	}
}

func TestMembersCommandRun_WAN(t *testing.T) {
	a1 := testAgent(t)
	defer a1.Shutdown()

	ui := new(cli.MockUi)
	c := &MembersCommand{Ui: ui}
	args := []string{"-rpc-addr=" + a1.addr, "-wan"}

	code := c.Run(args)
	if code != 0 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}

	if !strings.Contains(ui.OutputWriter.String(), fmt.Sprintf("%d", a1.config.Ports.SerfWan)) {
		t.Fatalf("bad: %#v", ui.OutputWriter.String())
	}
}

func TestMembersCommandRun_statusFilter(t *testing.T) {
	a1 := testAgent(t)
	defer a1.Shutdown()

	ui := new(cli.MockUi)
	c := &MembersCommand{Ui: ui}
	args := []string{
		"-rpc-addr=" + a1.addr,
		"-status=a.*e",
	}

	code := c.Run(args)
	if code != 0 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}

	if !strings.Contains(ui.OutputWriter.String(), a1.config.NodeName) {
		t.Fatalf("bad: %#v", ui.OutputWriter.String())
	}
}

func TestMembersCommandRun_statusFilter_failed(t *testing.T) {
	a1 := testAgent(t)
	defer a1.Shutdown()

	ui := new(cli.MockUi)
	c := &MembersCommand{Ui: ui}
	args := []string{
		"-rpc-addr=" + a1.addr,
		"-status=(fail|left)",
	}

	code := c.Run(args)
	if code == 1 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}

	if strings.Contains(ui.OutputWriter.String(), a1.config.NodeName) {
		t.Fatalf("bad: %#v", ui.OutputWriter.String())
	}

	if code != 2 {
		t.Fatalf("bad: %d", code)
	}
}


<|start_filename|>daemon/bridge_test.go<|end_filename|>
package daemon

import (
	"bytes"
	"net"
	"testing"
)

func TestGetAvailableGwAddress(t *testing.T) {
	addr, err := GetAvailableGwAddress("")
	if err != nil {
		t.Fatal("Could not get Gateway address:", err)
	}
	if addr == "" {
		t.Fatal("Address is nil")
	}

	addr, err = GetAvailableGwAddress("1.2.3.1/24")
	if err != nil {
		t.Fatal("Could not get Gateway address:", err)
	}
	if addr == "" {
		t.Fatal("Address is nil")
	}
}

func TestGetAvailableGwAddressError(t *testing.T) {
	_, err := GetAvailableGwAddress("socketplane")
	if err == nil {
		t.Fatal("socketplane is not a valid IP Address")
	}
}

func TestGetAvailableSubnet(t *testing.T) {
	subnet, err := GetAvailableSubnet()
	if err != nil {
		t.Fatal("Error finding available subnet:", err)
	}
	if subnet == nil {
		t.Fatal("Subnet should not be nil")
	}
}

func TestCreateBridge(t *testing.T) {
	err := CreateBridge()
	if err != nil {
		t.Fatal("Error creating bridge:", err)
	}
}

func TestAddPeer(t *testing.T) {
	err := AddPeer("1.1.1.1")
	if err != nil {
		t.Fatal("Could not add peer:", err)
	}

	exists, err := portExists(ovs, "vxlan-1.1.1.1")
	if err != nil {
		t.Fatal("Error finding port:", err)
	}

	if !exists {
		t.Fatal("Port does not exist")
	}
}

func TestDeletePeer(t *testing.T) {
	err := DeletePeer("1.1.1.1")
	if err != nil {
		t.Fatal("Could not delete peer")
	}

	exists, err := portExists(ovs, "vxlan-1.1.1.1")
	if err != nil {
		t.Fatal("Error finding port:", err)
	}

	if exists {
		t.Fatal("Port has not been deleted")
	}
}

func TestGenerateRandomName(t *testing.T) {
	results := make(map[string]bool)
	for i := 0; i <= 100; i++ {
		result, err := GenerateRandomName("foo", 12)
		if err != nil {
			t.Fatal(err)
		}
		if results[result] != false {
			t.Fatal("generated name not unique")
		}
		results[result] = true
	}
}

func TestGenerateMacAddress(t *testing.T) {
	ip := net.ParseIP("1.1.1.1")
	mac := generateMacAddr(ip)
	if mac[0] != 0x02 {
		t.Fatal("first byte should be 0x02")
	}
	if mac[1] != 0x42 {
		t.Fatal("second byte should be 0x42")
	}
	if !bytes.Equal(mac[2:], ip.To4()) {
		t.Fatal("remaning bytes should be ipv4 address")
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/vishvananda/netlink/route_test.go<|end_filename|>
package netlink

import (
	"net"
	"testing"
)

func TestRouteAddDel(t *testing.T) {
	tearDown := setUpNetlinkTest(t)
	defer tearDown()

	// get loopback interface
	link, err := LinkByName("lo")
	if err != nil {
		t.Fatal(err)
	}

	// bring the interface up
	if err = LinkSetUp(link); err != nil {
		t.Fatal(err)
	}

	// add a gateway route
	_, dst, err := net.ParseCIDR("192.168.0.0/24")

	ip := net.ParseIP("127.1.1.1")
	route := Route{LinkIndex: link.Attrs().Index, Dst: dst, Src: ip}
	err = RouteAdd(&route)
	if err != nil {
		t.Fatal(err)
	}
	routes, err := RouteList(link, FAMILY_V4)
	if err != nil {
		t.Fatal(err)
	}
	if len(routes) != 1 {
		t.Fatal("Link not added properly")
	}

	dstIP := net.ParseIP("192.168.0.42")
	routeToDstIP, err := RouteGet(dstIP)
	if err != nil {
		t.Fatal(err)
	}

	if len(routeToDstIP) == 0 {
		t.Fatal("Default route not present")
	}

	err = RouteDel(&route)
	if err != nil {
		t.Fatal(err)
	}

	routes, err = RouteList(link, FAMILY_V4)
	if err != nil {
		t.Fatal(err)
	}
	if len(routes) != 0 {
		t.Fatal("Route not removed properly")
	}

}


<|start_filename|>socketplane.go<|end_filename|>
package main

import (
	"log"
	"os"

	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/codegangsta/cli"
	"github.com/socketplane/socketplane/config"
	"github.com/socketplane/socketplane/daemon"
)

func init() {
	daemon.Initialize()
}

func main() {
	app := cli.NewApp()
	app.Name = "socketplane"
	app.Usage = "linux container networking"
	app.Version = "0.1.0"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  config.CFG_FILE,
			Value: "/etc/socketplane/socketplane.toml",
			Usage: "Name of the configuration file in TOML format",
		},
		cli.StringFlag{
			Name:  config.CFG_IFACE,
			Value: "auto",
			Usage: "Name of the interface to bind to. The default is to auto select",
		},
		cli.BoolFlag{
			Name:  config.CFG_BOOTSTRAP,
			Usage: "Set --bootstrap for the first socketplane instance being started",
		},
		cli.BoolFlag{
			Name:  config.CFG_DEBUG,
			Usage: "Provide debug level logging",
		},
	}
	app.Action = Run
	app.Run(os.Args)
}

func Run(ctx *cli.Context) {
	configFilename := ctx.String(config.CFG_FILE)
	err := config.Parse(configFilename)
	if err != nil {
		log.Fatal("Unable to parse configuration file " + configFilename)
		os.Exit(1)
	}
	d := daemon.NewDaemon()
	d.Run(ctx)
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/raft/stable.go<|end_filename|>
package raft

// StableStore is used to provide stable storage
// of key configurations to ensure safety.
type StableStore interface {
	Set(key []byte, val []byte) error
	Get(key []byte) ([]byte, error)

	SetUint64(key []byte, val uint64) error
	GetUint64(key []byte) (uint64, error)
}


<|start_filename|>Godeps/_workspace/src/github.com/armon/gomdb/cursor.go<|end_filename|>
package mdb

/*
#cgo freebsd CFLAGS: -DMDB_DSYNC=O_SYNC
#cgo openbsd CFLAGS: -DMDB_DSYNC=O_SYNC
#cgo netbsd CFLAGS: -DMDB_DSYNC=O_SYNC
#include <stdlib.h>
#include <stdio.h>
#include "lmdb.h"
*/
import "C"

import (
	"errors"
	"unsafe"
)

// MDB_cursor_op
const (
	FIRST = iota
	FIRST_DUP
	GET_BOTH
	GET_RANGE
	GET_CURRENT
	GET_MULTIPLE
	LAST
	LAST_DUP
	NEXT
	NEXT_DUP
	NEXT_MULTIPLE
	NEXT_NODUP
	PREV
	PREV_DUP
	PREV_NODUP
	SET
	SET_KEY
	SET_RANGE
)

func (cursor *Cursor) Close() error {
	if cursor._cursor == nil {
		return errors.New("Cursor already closed")
	}
	C.mdb_cursor_close(cursor._cursor)
	cursor._cursor = nil
	return nil
}

func (cursor *Cursor) Txn() *Txn {
	var _txn *C.MDB_txn
	_txn = C.mdb_cursor_txn(cursor._cursor)
	if _txn != nil {
		return &Txn{_txn}
	}
	return nil
}

func (cursor *Cursor) DBI() DBI {
	var _dbi C.MDB_dbi
	_dbi = C.mdb_cursor_dbi(cursor._cursor)
	return DBI(_dbi)
}

// Retrieves the low-level MDB cursor.
func (cursor *Cursor) MdbCursor() *C.MDB_cursor {
	return cursor._cursor
}

func (cursor *Cursor) Get(set_key []byte, op uint) (key, val []byte, err error) {
	var ckey C.MDB_val
	var cval C.MDB_val
	if set_key != nil && (op == SET || op == SET_KEY || op == SET_RANGE) {
		ckey.mv_size = C.size_t(len(set_key))
		ckey.mv_data = unsafe.Pointer(&set_key[0])
	}
	ret := C.mdb_cursor_get(cursor._cursor, &ckey, &cval, C.MDB_cursor_op(op))
	if ret != SUCCESS {
		err = Errno(ret)
		key = nil
		val = nil
		return
	}
	err = nil
	key = C.GoBytes(ckey.mv_data, C.int(ckey.mv_size))
	val = C.GoBytes(cval.mv_data, C.int(cval.mv_size))
	return
}

func (cursor *Cursor) Put(key, val []byte, flags uint) error {
	ckey := &C.MDB_val{mv_size: C.size_t(len(key)),
		mv_data: unsafe.Pointer(&key[0])}
	cval := &C.MDB_val{mv_size: C.size_t(len(val)),
		mv_data: unsafe.Pointer(&val[0])}
	ret := C.mdb_cursor_put(cursor._cursor, ckey, cval, C.uint(flags))
	if ret != SUCCESS {
		return Errno(ret)
	}
	return nil
}

func (cursor *Cursor) Del(flags uint) error {
	ret := C.mdb_cursor_del(cursor._cursor, C.uint(flags))
	if ret != SUCCESS {
		return Errno(ret)
	}
	return nil
}

func (cursor *Cursor) Count() (uint64, error) {
	var _size C.size_t
	ret := C.mdb_cursor_count(cursor._cursor, &_size)
	if ret != SUCCESS {
		return 0, Errno(ret)
	}
	return uint64(_size), nil
}


<|start_filename|>Godeps/_workspace/src/github.com/socketplane/bonjour/server.go<|end_filename|>
package bonjour

import (
	"fmt"
	"log"
	"math/rand"
	"net"
	"os"
	"strings"
	"sync"
	"time"

	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/miekg/dns"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/golang.org/x/net/ipv4"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/golang.org/x/net/ipv6"
)

var (
	// Multicast groups used by mDNS
	mdnsGroupIPv4 = net.IPv4(224, 0, 0, 251)
	mdnsGroupIPv6 = net.ParseIP("fd00:c2b6:b24b:be67:2827:688d:e6a1:6a3b")

	// mDNS wildcard addresses
	mdnsWildcardAddrIPv4 = &net.UDPAddr{
		IP:   net.ParseIP("192.168.3.11"),
		Port: 5353,
	}
	mdnsWildcardAddrIPv6 = &net.UDPAddr{
		IP:   net.ParseIP("[ff02::]"),
		Port: 5353,
	}

	// mDNS endpoint addresses
	ipv4Addr = &net.UDPAddr{
		IP:   mdnsGroupIPv4,
		Port: 5353,
	}
	ipv6Addr = &net.UDPAddr{
		IP:   mdnsGroupIPv6,
		Port: 5353,
	}

	serverCache = make(map[string]*server)
)

// Register a service by given arguments. This call will take the system's hostname
// and lookup IP by that hostname.
func Register(instance, service, domain string, port int, text []string, iface *net.Interface,
	bindToIntf bool) (chan<- bool, error) {
	entry := NewServiceEntry(instance, service, domain)
	entry.Port = port
	entry.Text = text

	if entry.Instance == "" {
		return nil, fmt.Errorf("Missing service instance name")
	}
	if entry.Service == "" {
		return nil, fmt.Errorf("Missing service name")
	}
	if entry.Domain == "" {
		entry.Domain = "local"
	}
	if entry.Port == 0 {
		return nil, fmt.Errorf("Missing port")
	}

	var err error
	if entry.HostName == "" {
		entry.HostName, err = os.Hostname()
		if err != nil {
			return nil, fmt.Errorf("Could not determine host")
		}
	}
	entry.HostName = fmt.Sprintf("%s.", trimDot(entry.HostName))

	if iface == nil && bindToIntf {
		iface = InterfaceToBind()
	}

	if iface == nil {
		addrs, err := net.LookupIP(entry.HostName)
		if err != nil {
			// Try appending the host domain suffix and lookup again
			// (required for Linux-based hosts)
			tmpHostName := fmt.Sprintf("%s%s.", entry.HostName, entry.Domain)
			addrs, err = net.LookupIP(tmpHostName)
			if err != nil {
				intAddrs, err := net.InterfaceAddrs()
				if err != nil {
					return nil, err
				}
				for _, a := range intAddrs {
					if ipnet, ok := a.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
						addrs = append(addrs, ipnet.IP)
					}
				}
				if len(addrs) == 0 {
					return nil, fmt.Errorf("Could not determine host IP addresses for %s", entry.HostName)
				}
			}
		}
		for i := 0; i < len(addrs); i++ {
			if ipv4 := addrs[i].To4(); ipv4 != nil {
				entry.AddrIPv4 = addrs[i]
			} else if ipv6 := addrs[i].To16(); ipv6 != nil {
				entry.AddrIPv6 = addrs[i]
			}
		}
	} else {
		addrs, err := iface.Addrs()
		if err == nil {
			for i := 0; i < len(addrs); i++ {
				addr := addrs[i].String()
				addr = strings.Split(addr, "/")[0]
				ip := net.ParseIP(addr)
				if ip != nil {
					if ip.To4() != nil {
						entry.AddrIPv4 = ip
					} else if ip.To16() != nil {
						entry.AddrIPv6 = ip
					}
				}
			}
		}
	}

	ifaceName := ""
	if iface != nil {
		ifaceName = iface.Name
	}
	s, ok := serverCache[ifaceName]
	if !ok {
		var err error
		s, err = newServer(iface)
		if err != nil {
			return nil, err
		}
		serverCache[ifaceName] = s
		go s.mainloop()
	}

	s.service = entry
	go s.probe()

	return s.shutdownCh, nil
}

// Register a service proxy by given argument. This call will skip the hostname/IP lookup and
// will use the provided values.
func RegisterProxy(instance, service, domain string, port int, host, ip string, text []string, iface *net.Interface) (chan<- bool, error) {
	entry := NewServiceEntry(instance, service, domain)
	entry.Port = port
	entry.Text = text
	entry.HostName = host

	if entry.Instance == "" {
		return nil, fmt.Errorf("Missing service instance name")
	}
	if entry.Service == "" {
		return nil, fmt.Errorf("Missing service name")
	}
	if entry.HostName == "" {
		return nil, fmt.Errorf("Missing host name")
	}
	if entry.Domain == "" {
		entry.Domain = "local"
	}
	if entry.Port == 0 {
		return nil, fmt.Errorf("Missing port")
	}

	if !strings.HasSuffix(trimDot(entry.HostName), entry.Domain) {
		entry.HostName = fmt.Sprintf("%s.%s.", trimDot(entry.HostName), trimDot(entry.Domain))
	}

	ipAddr := net.ParseIP(ip)
	if ipAddr == nil {
		return nil, fmt.Errorf("Failed to parse given IP: %v", ip)
	} else if ipv4 := ipAddr.To4(); ipv4 != nil {
		entry.AddrIPv4 = ipAddr
	} else if ipv6 := ipAddr.To16(); ipv6 != nil {
		entry.AddrIPv4 = ipAddr
	} else {
		return nil, fmt.Errorf("The IP is neither IPv4 nor IPv6: %#v", ipAddr)
	}

	s, err := newServer(iface)
	if err != nil {
		return nil, err
	}

	s.service = entry
	go s.mainloop()
	go s.probe()

	return s.shutdownCh, nil
}

// Server structure incapsulates both IPv4/IPv6 UDP connections
type server struct {
	service        *ServiceEntry
	ipv4conn       *net.UDPConn
	ipv6conn       *net.UDPConn
	shouldShutdown bool
	shutdownCh     chan bool
	shutdownLock   sync.Mutex
}

// Constructs server structure
func newServer(iface *net.Interface) (*server, error) {
	// Create wildcard connections (because :5353 can be already taken by other apps)
	ipv4conn, err := net.ListenMulticastUDP("udp4", iface, mdnsWildcardAddrIPv4)
	if err != nil {
		log.Printf("[ERR] bonjour: Failed to bind to udp4 port: %v", err)
	}
	ipv6conn, err := net.ListenMulticastUDP("udp6", iface, mdnsWildcardAddrIPv6)
	if ipv4conn == nil && ipv6conn == nil {
		return nil, fmt.Errorf("[ERR] bonjour: Failed to bind to any udp port!")
	}

	// Join multicast groups to receive announcements
	p1 := ipv4.NewPacketConn(ipv4conn)
	p2 := ipv6.NewPacketConn(ipv6conn)
	if iface != nil {
		errCount := 0
		if err := p1.JoinGroup(iface, &net.UDPAddr{IP: mdnsGroupIPv4}); err != nil {
			errCount++
		}
		if err := p2.JoinGroup(iface, &net.UDPAddr{IP: mdnsGroupIPv6}); err != nil {
			errCount++
		}
		if errCount == 2 {
			return nil, fmt.Errorf("Failed to join multicast group on both v4 and v6")
		}
	} else {
		ifaces, err := net.Interfaces()
		if err != nil {
			return nil, err
		}
		errCount1, errCount2 := 0, 0
		for _, iface := range ifaces {
			if err := p1.JoinGroup(&iface, &net.UDPAddr{IP: mdnsGroupIPv4}); err != nil {
				errCount1++
			}
			if err := p2.JoinGroup(&iface, &net.UDPAddr{IP: mdnsGroupIPv6}); err != nil {
				errCount2++
			}
		}
		if len(ifaces) == errCount1 && len(ifaces) == errCount2 {
			return nil, fmt.Errorf("Failed to join multicast group on all interfaces!")
		}
	}

	s := &server{
		ipv4conn:   ipv4conn,
		ipv6conn:   ipv6conn,
		shutdownCh: make(chan bool),
	}

	return s, nil
}

// Start listeners and waits for the shutdown signal from exit channel
func (s *server) mainloop() {
	if s.ipv4conn != nil {
		go s.recv(s.ipv4conn)
	}
	if s.ipv6conn != nil {
		go s.recv(s.ipv6conn)
	}
	for !s.shouldShutdown {
		select {
		case <-s.shutdownCh:
			s.shutdown()
		}
	}
}

// Shutdown server will close currently open connections & channel
func (s *server) shutdown() error {
	s.shutdownLock.Lock()
	defer s.shutdownLock.Unlock()

	s.unregister()

	if s.shouldShutdown {
		return nil
	}
	s.shouldShutdown = true
	close(s.shutdownCh)

	if s.ipv4conn != nil {
		s.ipv4conn.Close()
	}
	if s.ipv6conn != nil {
		s.ipv6conn.Close()
	}
	return nil
}

// recv is a long running routine to receive packets from an interface
func (s *server) recv(c *net.UDPConn) {
	if c == nil {
		return
	}
	buf := make([]byte, 65536)
	for !s.shouldShutdown {
		n, from, err := c.ReadFrom(buf)
		if err != nil {
			continue
		}
		if err := s.parsePacket(buf[:n], from); err != nil {
			log.Printf("[ERR] bonjour: Failed to handle query: %v", err)
		}
	}
}

// parsePacket is used to parse an incoming packet
func (s *server) parsePacket(packet []byte, from net.Addr) error {
	var msg dns.Msg
	if err := msg.Unpack(packet); err != nil {
		log.Printf("[ERR] bonjour: Failed to unpack packet: %v", err)
		return err
	}
	return s.handleQuery(&msg, from)
}

// handleQuery is used to handle an incoming query
func (s *server) handleQuery(query *dns.Msg, from net.Addr) error {
	// Ignore answer for now
	if len(query.Answer) > 0 {
		return nil
	}
	// Ignore questions with Authorative section for now
	if len(query.Ns) > 0 {
		return nil
	}

	// Handle each question
	var (
		resp dns.Msg
		err  error
	)
	if len(query.Question) > 0 {
		for i, _ := range query.Question {
			resp = dns.Msg{}
			resp.SetReply(query)
			resp.Answer = []dns.RR{}
			resp.Extra = []dns.RR{}
			if err = s.handleQuestion(query.Question[i], &resp); err != nil {
				log.Printf("[ERR] bonjour: failed to handle question %v: %v",
					query.Question[i], err)
				continue
			}
			// Check if there is an answer
			if len(resp.Answer) > 0 {
				//return s.sendResponse(&resp, from)
				//log.Println("====== BEGIN ======")
				//log.Println(resp.String())
				//log.Println("======= END =======")
				if e := s.multicastResponse(&resp); e != nil {
					err = e
				}
			}
		}
	}

	return err
}

// handleQuestion is used to handle an incoming question
func (s *server) handleQuestion(q dns.Question, resp *dns.Msg) error {
	if s.service == nil {
		return nil
	}

	switch q.Name {
	case s.service.ServiceName():
		s.composeBrowsingAnswers(resp, 3200)
	case s.service.ServiceInstanceName():
		s.composeLookupAnswers(resp, 3200)
	}

	return nil
}

func (s *server) composeBrowsingAnswers(resp *dns.Msg, ttl uint32) {
	ptr := &dns.PTR{
		Hdr: dns.RR_Header{
			Name:   s.service.ServiceName(),
			Rrtype: dns.TypePTR,
			Class:  dns.ClassINET,
			Ttl:    ttl,
		},
		Ptr: s.service.ServiceInstanceName(),
	}
	resp.Answer = append(resp.Answer, ptr)

	txt := &dns.TXT{
		Hdr: dns.RR_Header{
			Name:   s.service.ServiceInstanceName(),
			Rrtype: dns.TypeTXT,
			Class:  dns.ClassINET,
			Ttl:    ttl,
		},
		Txt: s.service.Text,
	}
	srv := &dns.SRV{
		Hdr: dns.RR_Header{
			Name:   s.service.ServiceInstanceName(),
			Rrtype: dns.TypeSRV,
			Class:  dns.ClassINET,
			Ttl:    ttl,
		},
		Priority: 0,
		Weight:   0,
		Port:     uint16(s.service.Port),
		Target:   s.service.HostName,
	}
	resp.Extra = append(resp.Extra, srv, txt)

	if s.service.AddrIPv4 != nil {
		a := &dns.A{
			Hdr: dns.RR_Header{
				Name:   s.service.HostName,
				Rrtype: dns.TypeA,
				Class:  dns.ClassINET,
				Ttl:    ttl,
			},
			A: s.service.AddrIPv4,
		}
		resp.Extra = append(resp.Extra, a)
	}
	if s.service.AddrIPv6 != nil {
		aaaa := &dns.AAAA{
			Hdr: dns.RR_Header{
				Name:   s.service.HostName,
				Rrtype: dns.TypeAAAA,
				Class:  dns.ClassINET,
				Ttl:    ttl,
			},
			AAAA: s.service.AddrIPv6,
		}
		resp.Extra = append(resp.Extra, aaaa)
	}
}

func (s *server) composeLookupAnswers(resp *dns.Msg, ttl uint32) {
	ptr := &dns.PTR{
		Hdr: dns.RR_Header{
			Name:   s.service.ServiceName(),
			Rrtype: dns.TypePTR,
			Class:  dns.ClassINET,
			Ttl:    ttl,
		},
		Ptr: s.service.ServiceInstanceName(),
	}
	srv := &dns.SRV{
		Hdr: dns.RR_Header{
			Name:   s.service.ServiceInstanceName(),
			Rrtype: dns.TypeSRV,
			Class:  dns.ClassINET,
			Ttl:    ttl,
		},
		Priority: 0,
		Weight:   0,
		Port:     uint16(s.service.Port),
		Target:   s.service.HostName,
	}
	txt := &dns.TXT{
		Hdr: dns.RR_Header{
			Name:   s.service.ServiceInstanceName(),
			Rrtype: dns.TypeTXT,
			Class:  dns.ClassINET,
			Ttl:    ttl,
		},
		Txt: s.service.Text,
	}
	dnssd := &dns.PTR{
		Hdr: dns.RR_Header{
			Name:   fmt.Sprintf("_services._dns-sd._udp.%s.", trimDot(s.service.Domain)),
			Rrtype: dns.TypePTR,
			Class:  dns.ClassINET,
			Ttl:    ttl,
		},
		Ptr: s.service.ServiceName(),
	}
	resp.Answer = append(resp.Answer, srv, txt, ptr, dnssd)

	if s.service.AddrIPv4 != nil {
		a := &dns.A{
			Hdr: dns.RR_Header{
				Name:   s.service.HostName,
				Rrtype: dns.TypeA,
				Class:  dns.ClassINET,
				Ttl:    120,
			},
			A: s.service.AddrIPv4,
		}
		resp.Extra = append(resp.Extra, a)
	}
	if s.service.AddrIPv6 != nil {
		aaaa := &dns.AAAA{
			Hdr: dns.RR_Header{
				Name:   s.service.HostName,
				Rrtype: dns.TypeAAAA,
				Class:  dns.ClassINET,
				Ttl:    120,
			},
			AAAA: s.service.AddrIPv6,
		}
		resp.Extra = append(resp.Extra, aaaa)
	}
}

// Perform probing & announcement
//TODO: implement a proper probing & conflict resolution
func (s *server) probe() {
	q := new(dns.Msg)
	q.SetQuestion(s.service.ServiceInstanceName(), dns.TypePTR)
	q.RecursionDesired = false

	srv := &dns.SRV{
		Hdr: dns.RR_Header{
			Name:   s.service.ServiceInstanceName(),
			Rrtype: dns.TypeSRV,
			Class:  dns.ClassINET,
			Ttl:    3200,
		},
		Priority: 0,
		Weight:   0,
		Port:     uint16(s.service.Port),
		Target:   s.service.HostName,
	}
	txt := &dns.TXT{
		Hdr: dns.RR_Header{
			Name:   s.service.ServiceInstanceName(),
			Rrtype: dns.TypeTXT,
			Class:  dns.ClassINET,
			Ttl:    3200,
		},
		Txt: s.service.Text,
	}
	q.Ns = []dns.RR{srv, txt}

	randomizer := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < 3; i++ {
		if err := s.multicastResponse(q); err != nil {
			log.Println("[ERR] bonjour: failed to send probe:", err.Error())
		}
		time.Sleep(time.Duration(randomizer.Intn(250)) * time.Millisecond)
	}

	resp := new(dns.Msg)
	resp.Answer = []dns.RR{}
	resp.Extra = []dns.RR{}
	s.composeLookupAnswers(resp, 3200)
	for i := 0; i < 3; i++ {
		if err := s.multicastResponse(resp); err != nil {
			log.Println("[ERR] bonjour: failed to send announcement:", err.Error())
		}
		time.Sleep(2 * time.Second)
	}
}

func (s *server) unregister() error {
	resp := new(dns.Msg)
	resp.Answer = []dns.RR{}
	resp.Extra = []dns.RR{}
	s.composeLookupAnswers(resp, 0)
	return s.multicastResponse(resp)
}

// sendResponse is used to send a unicast response packet
func (s *server) sendResponse(resp *dns.Msg, from net.Addr) error {
	buf, err := resp.Pack()
	if err != nil {
		return err
	}
	addr := from.(*net.UDPAddr)
	if addr.IP.To4() != nil {
		_, err = s.ipv4conn.WriteToUDP(buf, addr)
		return err
	} else {
		_, err = s.ipv6conn.WriteToUDP(buf, addr)
		return err
	}
}

// multicastResponse us used to send a multicast response packet
func (c *server) multicastResponse(msg *dns.Msg) error {
	buf, err := msg.Pack()
	if err != nil {
		log.Println("Failed to pack message!")
		return err
	}
	if c.ipv4conn != nil {
		c.ipv4conn.WriteTo(buf, ipv4Addr)
	}
	if c.ipv6conn != nil {
		c.ipv6conn.WriteTo(buf, ipv6Addr)
	}
	return nil
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/watch/plan_test.go<|end_filename|>
package watch

import (
	"testing"
	"time"
)

func init() {
	watchFuncFactory["noop"] = noopWatch
}

func noopWatch(params map[string]interface{}) (WatchFunc, error) {
	fn := func(p *WatchPlan) (uint64, interface{}, error) {
		idx := p.lastIndex + 1
		return idx, idx, nil
	}
	return fn, nil
}

func mustParse(t *testing.T, q string) *WatchPlan {
	params := makeParams(t, q)
	plan, err := Parse(params)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	return plan
}

func TestRun_Stop(t *testing.T) {
	plan := mustParse(t, `{"type":"noop"}`)
	var expect uint64 = 1
	plan.Handler = func(idx uint64, val interface{}) {
		if idx != expect {
			t.Fatalf("Bad: %d %d", expect, idx)
		}
		if val != expect {
			t.Fatalf("Bad: %d %d", expect, val)
		}
		expect++
	}

	time.AfterFunc(10*time.Millisecond, func() {
		plan.Stop()
	})

	err := plan.Run("127.0.0.1:8500")
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if expect == 1 {
		t.Fatalf("Bad: %d", expect)
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/serf/serf/delegate.go<|end_filename|>
package serf

import (
	"fmt"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/armon/go-metrics"
)

// delegate is the memberlist.Delegate implementation that Serf uses.
type delegate struct {
	serf *Serf
}

func (d *delegate) NodeMeta(limit int) []byte {
	roleBytes := d.serf.encodeTags(d.serf.config.Tags)
	if len(roleBytes) > limit {
		panic(fmt.Errorf("Node tags '%v' exceeds length limit of %d bytes", d.serf.config.Tags, limit))
	}

	return roleBytes
}

func (d *delegate) NotifyMsg(buf []byte) {
	// If we didn't actually receive any data, then ignore it.
	if len(buf) == 0 {
		return
	}
	metrics.AddSample([]string{"serf", "msgs", "received"}, float32(len(buf)))

	rebroadcast := false
	rebroadcastQueue := d.serf.broadcasts
	t := messageType(buf[0])
	switch t {
	case messageLeaveType:
		var leave messageLeave
		if err := decodeMessage(buf[1:], &leave); err != nil {
			d.serf.logger.Printf("[ERR] serf: Error decoding leave message: %s", err)
			break
		}

		d.serf.logger.Printf("[DEBUG] serf: messageLeaveType: %s", leave.Node)
		rebroadcast = d.serf.handleNodeLeaveIntent(&leave)

	case messageJoinType:
		var join messageJoin
		if err := decodeMessage(buf[1:], &join); err != nil {
			d.serf.logger.Printf("[ERR] serf: Error decoding join message: %s", err)
			break
		}

		d.serf.logger.Printf("[DEBUG] serf: messageJoinType: %s", join.Node)
		rebroadcast = d.serf.handleNodeJoinIntent(&join)

	case messageUserEventType:
		var event messageUserEvent
		if err := decodeMessage(buf[1:], &event); err != nil {
			d.serf.logger.Printf("[ERR] serf: Error decoding user event message: %s", err)
			break
		}

		d.serf.logger.Printf("[DEBUG] serf: messageUserEventType: %s", event.Name)
		rebroadcast = d.serf.handleUserEvent(&event)
		rebroadcastQueue = d.serf.eventBroadcasts

	case messageQueryType:
		var query messageQuery
		if err := decodeMessage(buf[1:], &query); err != nil {
			d.serf.logger.Printf("[ERR] serf: Error decoding query message: %s", err)
			break
		}

		d.serf.logger.Printf("[DEBUG] serf: messageQueryType: %s", query.Name)
		rebroadcast = d.serf.handleQuery(&query)
		rebroadcastQueue = d.serf.queryBroadcasts

	case messageQueryResponseType:
		var resp messageQueryResponse
		if err := decodeMessage(buf[1:], &resp); err != nil {
			d.serf.logger.Printf("[ERR] serf: Error decoding query response message: %s", err)
			break
		}

		d.serf.logger.Printf("[DEBUG] serf: messageQueryResponseType: %v", resp.From)
		d.serf.handleQueryResponse(&resp)

	default:
		d.serf.logger.Printf("[WARN] serf: Received message of unknown type: %d", t)
	}

	if rebroadcast {
		// Copy the buffer since it we cannot rely on the slice not changing
		newBuf := make([]byte, len(buf))
		copy(newBuf, buf)

		rebroadcastQueue.QueueBroadcast(&broadcast{
			msg:    newBuf,
			notify: nil,
		})
	}
}

func (d *delegate) GetBroadcasts(overhead, limit int) [][]byte {
	msgs := d.serf.broadcasts.GetBroadcasts(overhead, limit)

	// Determine the bytes used already
	bytesUsed := 0
	for _, msg := range msgs {
		lm := len(msg)
		bytesUsed += lm + overhead
		metrics.AddSample([]string{"serf", "msgs", "sent"}, float32(lm))
	}

	// Get any additional query broadcasts
	queryMsgs := d.serf.queryBroadcasts.GetBroadcasts(overhead, limit-bytesUsed)
	if queryMsgs != nil {
		for _, m := range queryMsgs {
			lm := len(m)
			bytesUsed += lm + overhead
			metrics.AddSample([]string{"serf", "msgs", "sent"}, float32(lm))
		}
		msgs = append(msgs, queryMsgs...)
	}

	// Get any additional event broadcasts
	eventMsgs := d.serf.eventBroadcasts.GetBroadcasts(overhead, limit-bytesUsed)
	if eventMsgs != nil {
		for _, m := range eventMsgs {
			lm := len(m)
			bytesUsed += lm + overhead
			metrics.AddSample([]string{"serf", "msgs", "sent"}, float32(lm))
		}
		msgs = append(msgs, eventMsgs...)
	}

	return msgs
}

func (d *delegate) LocalState(join bool) []byte {
	d.serf.memberLock.RLock()
	defer d.serf.memberLock.RUnlock()
	d.serf.eventLock.RLock()
	defer d.serf.eventLock.RUnlock()

	// Create the message to send
	pp := messagePushPull{
		LTime:        d.serf.clock.Time(),
		StatusLTimes: make(map[string]LamportTime, len(d.serf.members)),
		LeftMembers:  make([]string, 0, len(d.serf.leftMembers)),
		EventLTime:   d.serf.eventClock.Time(),
		Events:       d.serf.eventBuffer,
		QueryLTime:   d.serf.queryClock.Time(),
	}

	// Add all the join LTimes
	for name, member := range d.serf.members {
		pp.StatusLTimes[name] = member.statusLTime
	}

	// Add all the left nodes
	for _, member := range d.serf.leftMembers {
		pp.LeftMembers = append(pp.LeftMembers, member.Name)
	}

	// Encode the push pull state
	buf, err := encodeMessage(messagePushPullType, &pp)
	if err != nil {
		d.serf.logger.Printf("[ERR] serf: Failed to encode local state: %v", err)
		return nil
	}
	return buf
}

func (d *delegate) MergeRemoteState(buf []byte, isJoin bool) {
	// Check the message type
	if messageType(buf[0]) != messagePushPullType {
		d.serf.logger.Printf("[ERR] serf: Remote state has bad type prefix: %v", buf[0])
		return
	}

	// Attempt a decode
	pp := messagePushPull{}
	if err := decodeMessage(buf[1:], &pp); err != nil {
		d.serf.logger.Printf("[ERR] serf: Failed to decode remote state: %v", err)
		return
	}

	// Witness the Lamport clocks first.
	// We subtract 1 since no message with that clock has been sent yet
	if pp.LTime > 0 {
		d.serf.clock.Witness(pp.LTime - 1)
	}
	if pp.EventLTime > 0 {
		d.serf.eventClock.Witness(pp.EventLTime - 1)
	}
	if pp.QueryLTime > 0 {
		d.serf.queryClock.Witness(pp.QueryLTime - 1)
	}

	// Process the left nodes first to avoid the LTimes from being increment
	// in the wrong order
	leftMap := make(map[string]struct{}, len(pp.LeftMembers))
	leave := messageLeave{}
	for _, name := range pp.LeftMembers {
		leftMap[name] = struct{}{}
		leave.LTime = pp.StatusLTimes[name]
		leave.Node = name
		d.serf.handleNodeLeaveIntent(&leave)
	}

	// Update any other LTimes
	join := messageJoin{}
	for name, statusLTime := range pp.StatusLTimes {
		// Skip the left nodes
		if _, ok := leftMap[name]; ok {
			continue
		}

		// Create an artificial join message
		join.LTime = statusLTime
		join.Node = name
		d.serf.handleNodeJoinIntent(&join)
	}

	// If we are doing a join, and eventJoinIgnore is set
	// then we set the eventMinTime to the EventLTime. This
	// prevents any of the incoming events from being processed
	if isJoin && d.serf.eventJoinIgnore {
		d.serf.eventLock.Lock()
		if pp.EventLTime > d.serf.eventMinTime {
			d.serf.eventMinTime = pp.EventLTime
		}
		d.serf.eventLock.Unlock()
	}

	// Process all the events
	userEvent := messageUserEvent{}
	for _, events := range pp.Events {
		if events == nil {
			continue
		}
		userEvent.LTime = events.LTime
		for _, e := range events.Events {
			userEvent.Name = e.Name
			userEvent.Payload = e.Payload
			d.serf.handleUserEvent(&userEvent)
		}
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/cenkalti/hub/example_test.go<|end_filename|>
package hub

import "fmt"

// Different event kinds
const (
	happenedA = iota
	happenedB
	happenedC
)

// Our custom event type
type EventA struct {
	arg1, arg2 int
}

// Implement hub.Event interface
func (e EventA) Kind() int { return happenedA }

func Example() {
	Subscribe(happenedA, func(e Event) {
		a := e.(EventA) // Cast to concrete type
		fmt.Println(a.arg1 + a.arg2)
	})

	Publish(EventA{2, 3})
	// Output: 5
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/command/version_test.go<|end_filename|>
package command

import (
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/mitchellh/cli"
	"testing"
)

func TestVersionCommand_implements(t *testing.T) {
	var _ cli.Command = &VersionCommand{}
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/serf/serf/keymanager_test.go<|end_filename|>
package serf

import (
	"bytes"
	"encoding/base64"
	"github.com/hashicorp/serf/testutil"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/memberlist"
	"testing"
)

func testKeyring() (*memberlist.Keyring, error) {
	keys := []string{
		"enjTwAFRe4IE71bOFhirzQ==",
		"<KEY>
		"<KEY>
	}

	keysDecoded := make([][]byte, len(keys))
	for i, key := range keys {
		decoded, err := base64.StdEncoding.DecodeString(key)
		if err != nil {
			return nil, err
		}
		keysDecoded[i] = decoded
	}

	return memberlist.NewKeyring(keysDecoded, keysDecoded[0])
}

func testKeyringSerf() (*Serf, error) {
	config := testConfig()

	keyring, err := testKeyring()
	if err != nil {
		return nil, err
	}
	config.MemberlistConfig.Keyring = keyring

	s, err := Create(config)
	if err != nil {
		return nil, err
	}

	return s, nil
}

func keyExistsInRing(kr *memberlist.Keyring, key []byte) bool {
	for _, installedKey := range kr.GetKeys() {
		if bytes.Equal(key, installedKey) {
			return true
		}
	}
	return false
}

func TestSerf_InstallKey(t *testing.T) {
	s1, err := testKeyringSerf()
	if err != nil {
		t.Fatalf("%s", err)
	}
	defer s1.Shutdown()

	s2, err := testKeyringSerf()
	if err != nil {
		t.Fatalf("%s", err)
	}
	defer s2.Shutdown()

	primaryKey := s1.config.MemberlistConfig.Keyring.GetPrimaryKey()

	// Join s1 and s2
	_, err = s1.Join([]string{s2.config.MemberlistConfig.BindAddr}, false)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	testutil.Yield()

	// Begin tests
	newKey := "l4ZkaypGLT8AsB0LBldthw=="
	newKeyBytes, err := base64.StdEncoding.DecodeString(newKey)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	manager := s1.KeyManager()

	// Install a new key onto the existing ring. This is a blocking call, so no
	// need for a yield.
	_, err = manager.InstallKey(newKey)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	// Key installation did not affect the current primary key
	if !bytes.Equal(primaryKey, s1.config.MemberlistConfig.Keyring.GetPrimaryKey()) {
		t.Fatal("Unexpected primary key change on s1")
	}

	if !bytes.Equal(primaryKey, s2.config.MemberlistConfig.Keyring.GetPrimaryKey()) {
		t.Fatal("Unexpected primary key change on s2")
	}

	// New key was successfully broadcasted and installed on all members
	if !keyExistsInRing(s1.config.MemberlistConfig.Keyring, newKeyBytes) {
		t.Fatal("Newly-installed key not found in keyring on s1")
	}

	if !keyExistsInRing(s2.config.MemberlistConfig.Keyring, newKeyBytes) {
		t.Fatal("Newly-installed key not found in keyring on s2")
	}
}

func TestSerf_UseKey(t *testing.T) {
	s1, err := testKeyringSerf()
	if err != nil {
		t.Fatalf("%s", err)
	}
	defer s1.Shutdown()

	s2, err := testKeyringSerf()
	if err != nil {
		t.Fatalf("%s", err)
	}
	defer s2.Shutdown()

	// Join s1 and s2
	_, err = s1.Join([]string{s2.config.MemberlistConfig.BindAddr}, false)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	testutil.Yield()

	// Begin tests
	useKey := "<KEY>
	useKeyBytes, err := base64.StdEncoding.DecodeString(useKey)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	manager := s1.KeyManager()

	// Change the primary encryption key
	_, err = manager.UseKey(useKey)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	// First make sure that the primary key is what we expect it to be
	if !bytes.Equal(useKeyBytes, s1.config.MemberlistConfig.Keyring.GetPrimaryKey()) {
		t.Fatal("Unexpected primary key on s1")
	}

	if !bytes.Equal(useKeyBytes, s2.config.MemberlistConfig.Keyring.GetPrimaryKey()) {
		t.Fatal("Unexpected primary key on s2")
	}

	// Make sure an error is thrown if the key doesn't exist
	_, err = manager.UseKey("<KEY>)
	if err == nil {
		t.Fatalf("Expected error changing to non-existent primary key")
	}
}

func TestSerf_RemoveKey(t *testing.T) {
	s1, err := testKeyringSerf()
	if err != nil {
		t.Fatalf("%s", err)
	}
	defer s1.Shutdown()

	s2, err := testKeyringSerf()
	if err != nil {
		t.Fatalf("%s", err)
	}
	defer s2.Shutdown()

	// Join s1 and s2
	_, err = s1.Join([]string{s2.config.MemberlistConfig.BindAddr}, false)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	testutil.Yield()

	// Begin tests
	removeKey := "<KEY>
	removeKeyBytes, err := base64.StdEncoding.DecodeString(removeKey)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	manager := s1.KeyManager()

	// Remove a key from the ring
	_, err = manager.RemoveKey(removeKey)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	// Key was successfully removed from all members
	if keyExistsInRing(s1.config.MemberlistConfig.Keyring, removeKeyBytes) {
		t.Fatal("Key not removed from keyring on s1")
	}

	if keyExistsInRing(s2.config.MemberlistConfig.Keyring, removeKeyBytes) {
		t.Fatal("Key not removed from keyring on s2")
	}
}

func TestSerf_ListKeys(t *testing.T) {
	s1, err := testKeyringSerf()
	if err != nil {
		t.Fatalf("%s", err)
	}
	defer s1.Shutdown()

	s2, err := testKeyringSerf()
	if err != nil {
		t.Fatalf("%s", err)
	}
	defer s2.Shutdown()

	manager := s1.KeyManager()

	initialKeyringLen := len(s1.config.MemberlistConfig.Keyring.GetKeys())

	// Extra key on s2 to make sure we see it in the list
	extraKey := "<KEY>
	extraKeyBytes, err := base64.StdEncoding.DecodeString(extraKey)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	s2.config.MemberlistConfig.Keyring.AddKey(extraKeyBytes)

	// Join s1 and s2
	_, err = s1.Join([]string{s2.config.MemberlistConfig.BindAddr}, false)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	testutil.Yield()

	resp, err := manager.ListKeys()
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	// Found all keys in the list
	expected := initialKeyringLen + 1
	if expected != len(resp.Keys) {
		t.Fatalf("Expected %d keys in result, found %d", expected, len(resp.Keys))
	}

	found := false
	for key, _ := range resp.Keys {
		if key == extraKey {
			found = true
		}
	}
	if !found {
		t.Fatalf("Did not find expected key in list: %s", extraKey)
	}

	// Number of members with extra key installed should be 1
	for key, num := range resp.Keys {
		if key == extraKey && num != 1 {
			t.Fatalf("Expected 1 nodes with key %s but have %d", extraKey, num)
		}
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/consul/internal_endpoint_test.go<|end_filename|>
package consul

import (
	"encoding/base64"
	"fmt"
	"github.com/hashicorp/consul/testutil"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/consul/structs"
	"os"
	"testing"
)

func TestInternal_NodeInfo(t *testing.T) {
	dir1, s1 := testServer(t)
	defer os.RemoveAll(dir1)
	defer s1.Shutdown()
	client := rpcClient(t, s1)
	defer client.Close()

	testutil.WaitForLeader(t, client.Call, "dc1")

	arg := structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "foo",
		Address:    "127.0.0.1",
		Service: &structs.NodeService{
			ID:      "db",
			Service: "db",
			Tags:    []string{"master"},
		},
		Check: &structs.HealthCheck{
			Name:      "db connect",
			Status:    structs.HealthPassing,
			ServiceID: "db",
		},
	}
	var out struct{}
	if err := client.Call("Catalog.Register", &arg, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	var out2 structs.IndexedNodeDump
	req := structs.NodeSpecificRequest{
		Datacenter: "dc1",
		Node:       "foo",
	}
	if err := client.Call("Internal.NodeInfo", &req, &out2); err != nil {
		t.Fatalf("err: %v", err)
	}

	nodes := out2.Dump
	if len(nodes) != 1 {
		t.Fatalf("Bad: %v", nodes)
	}
	if nodes[0].Node != "foo" {
		t.Fatalf("Bad: %v", nodes[0])
	}
	if !strContains(nodes[0].Services[0].Tags, "master") {
		t.Fatalf("Bad: %v", nodes[0])
	}
	if nodes[0].Checks[0].Status != structs.HealthPassing {
		t.Fatalf("Bad: %v", nodes[0])
	}
}

func TestInternal_NodeDump(t *testing.T) {
	dir1, s1 := testServer(t)
	defer os.RemoveAll(dir1)
	defer s1.Shutdown()
	client := rpcClient(t, s1)
	defer client.Close()

	testutil.WaitForLeader(t, client.Call, "dc1")

	arg := structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "foo",
		Address:    "127.0.0.1",
		Service: &structs.NodeService{
			ID:      "db",
			Service: "db",
			Tags:    []string{"master"},
		},
		Check: &structs.HealthCheck{
			Name:      "db connect",
			Status:    structs.HealthPassing,
			ServiceID: "db",
		},
	}
	var out struct{}
	if err := client.Call("Catalog.Register", &arg, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	arg = structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "bar",
		Address:    "127.0.0.2",
		Service: &structs.NodeService{
			ID:      "db",
			Service: "db",
			Tags:    []string{"slave"},
		},
		Check: &structs.HealthCheck{
			Name:      "db connect",
			Status:    structs.HealthWarning,
			ServiceID: "db",
		},
	}
	if err := client.Call("Catalog.Register", &arg, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	var out2 structs.IndexedNodeDump
	req := structs.DCSpecificRequest{
		Datacenter: "dc1",
	}
	if err := client.Call("Internal.NodeDump", &req, &out2); err != nil {
		t.Fatalf("err: %v", err)
	}

	nodes := out2.Dump
	if len(nodes) != 3 {
		t.Fatalf("Bad: %v", nodes)
	}

	var foundFoo, foundBar bool
	for _, node := range nodes {
		switch node.Node {
		case "foo":
			foundFoo = true
			if !strContains(node.Services[0].Tags, "master") {
				t.Fatalf("Bad: %v", nodes[0])
			}
			if node.Checks[0].Status != structs.HealthPassing {
				t.Fatalf("Bad: %v", nodes[0])
			}

		case "bar":
			foundBar = true
			if !strContains(node.Services[0].Tags, "slave") {
				t.Fatalf("Bad: %v", nodes[1])
			}
			if node.Checks[0].Status != structs.HealthWarning {
				t.Fatalf("Bad: %v", nodes[1])
			}

		default:
			continue
		}
	}
	if !foundFoo || !foundBar {
		t.Fatalf("missing foo or bar")
	}
}

func TestInternal_KeyringOperation(t *testing.T) {
	key1 := "<KEY>
	keyBytes1, err := base64.StdEncoding.DecodeString(key1)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	dir1, s1 := testServerWithConfig(t, func(c *Config) {
		c.SerfLANConfig.MemberlistConfig.SecretKey = keyBytes1
		c.SerfWANConfig.MemberlistConfig.SecretKey = keyBytes1
	})
	defer os.RemoveAll(dir1)
	defer s1.Shutdown()
	client := rpcClient(t, s1)
	defer client.Close()

	testutil.WaitForLeader(t, client.Call, "dc1")

	var out structs.KeyringResponses
	req := structs.KeyringRequest{
		Operation:  structs.KeyringList,
		Datacenter: "dc1",
	}
	if err := client.Call("Internal.KeyringOperation", &req, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Two responses (local lan/wan pools) from single-node cluster
	if len(out.Responses) != 2 {
		t.Fatalf("bad: %#v", out)
	}
	if _, ok := out.Responses[0].Keys[key1]; !ok {
		t.Fatalf("bad: %#v", out)
	}
	wanResp, lanResp := 0, 0
	for _, resp := range out.Responses {
		if resp.WAN {
			wanResp++
		} else {
			lanResp++
		}
	}
	if lanResp != 1 || wanResp != 1 {
		t.Fatalf("should have one lan and one wan response")
	}

	// Start a second agent to test cross-dc queries
	dir2, s2 := testServerWithConfig(t, func(c *Config) {
		c.SerfLANConfig.MemberlistConfig.SecretKey = keyBytes1
		c.SerfWANConfig.MemberlistConfig.SecretKey = keyBytes1
		c.Datacenter = "dc2"
	})
	defer os.RemoveAll(dir2)
	defer s2.Shutdown()

	// Try to join
	addr := fmt.Sprintf("127.0.0.1:%d",
		s1.config.SerfWANConfig.MemberlistConfig.BindPort)
	if _, err := s2.JoinWAN([]string{addr}); err != nil {
		t.Fatalf("err: %v", err)
	}

	var out2 structs.KeyringResponses
	req2 := structs.KeyringRequest{
		Operation: structs.KeyringList,
	}
	if err := client.Call("Internal.KeyringOperation", &req2, &out2); err != nil {
		t.Fatalf("err: %v", err)
	}

	// 3 responses (one from each DC LAN, one from WAN) in two-node cluster
	if len(out2.Responses) != 3 {
		t.Fatalf("bad: %#v", out)
	}
	wanResp, lanResp = 0, 0
	for _, resp := range out2.Responses {
		if resp.WAN {
			wanResp++
		} else {
			lanResp++
		}
	}
	if lanResp != 2 || wanResp != 1 {
		t.Fatalf("should have two lan and one wan response")
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/socketplane/ecc/Makefile<|end_filename|>
all: build test test-all

build:
	        go build -v

test:
	        go test -covermode=count -test.short -coverprofile=coverage.out -v

test-all:
	        go test -covermode=count -coverprofile=coverage.out -v


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/command/agent/check_test.go<|end_filename|>
package agent

import (
	"fmt"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/consul/structs"
	"log"
	"net/http"
	"net/http/httptest"
	"os"
	"testing"
	"time"
)

type MockNotify struct {
	state   map[string]string
	updates map[string]int
	output  map[string]string
}

func (m *MockNotify) UpdateCheck(id, status, output string) {
	m.state[id] = status
	old := m.updates[id]
	m.updates[id] = old + 1
	m.output[id] = output
}

func expectStatus(t *testing.T, script, status string) {
	mock := &MockNotify{
		state:   make(map[string]string),
		updates: make(map[string]int),
		output:  make(map[string]string),
	}
	check := &CheckMonitor{
		Notify:   mock,
		CheckID:  "foo",
		Script:   script,
		Interval: 10 * time.Millisecond,
		Logger:   log.New(os.Stderr, "", log.LstdFlags),
	}
	check.Start()
	defer check.Stop()

	time.Sleep(50 * time.Millisecond)

	// Should have at least 2 updates
	if mock.updates["foo"] < 2 {
		t.Fatalf("should have 2 updates %v", mock.updates)
	}

	if mock.state["foo"] != status {
		t.Fatalf("should be %v %v", status, mock.state)
	}
}

func TestCheckMonitor_Passing(t *testing.T) {
	expectStatus(t, "exit 0", structs.HealthPassing)
}

func TestCheckMonitor_Warning(t *testing.T) {
	expectStatus(t, "exit 1", structs.HealthWarning)
}

func TestCheckMonitor_Critical(t *testing.T) {
	expectStatus(t, "exit 2", structs.HealthCritical)
}

func TestCheckMonitor_BadCmd(t *testing.T) {
	expectStatus(t, "foobarbaz", structs.HealthCritical)
}

func TestCheckMonitor_RandomStagger(t *testing.T) {
	mock := &MockNotify{
		state:   make(map[string]string),
		updates: make(map[string]int),
		output:  make(map[string]string),
	}
	check := &CheckMonitor{
		Notify:   mock,
		CheckID:  "foo",
		Script:   "exit 0",
		Interval: 25 * time.Millisecond,
		Logger:   log.New(os.Stderr, "", log.LstdFlags),
	}
	check.Start()
	defer check.Stop()

	time.Sleep(50 * time.Millisecond)

	// Should have at least 1 update
	if mock.updates["foo"] < 1 {
		t.Fatalf("should have 1 or more updates %v", mock.updates)
	}

	if mock.state["foo"] != structs.HealthPassing {
		t.Fatalf("should be %v %v", structs.HealthPassing, mock.state)
	}
}

func TestCheckMonitor_LimitOutput(t *testing.T) {
	mock := &MockNotify{
		state:   make(map[string]string),
		updates: make(map[string]int),
		output:  make(map[string]string),
	}
	check := &CheckMonitor{
		Notify:   mock,
		CheckID:  "foo",
		Script:   "od -N 81920 /dev/urandom",
		Interval: 25 * time.Millisecond,
		Logger:   log.New(os.Stderr, "", log.LstdFlags),
	}
	check.Start()
	defer check.Stop()

	time.Sleep(50 * time.Millisecond)

	// Allow for extra bytes for the truncation message
	if len(mock.output["foo"]) > CheckBufSize+100 {
		t.Fatalf("output size is too long")
	}
}

func TestCheckTTL(t *testing.T) {
	mock := &MockNotify{
		state:   make(map[string]string),
		updates: make(map[string]int),
		output:  make(map[string]string),
	}
	check := &CheckTTL{
		Notify:  mock,
		CheckID: "foo",
		TTL:     100 * time.Millisecond,
		Logger:  log.New(os.Stderr, "", log.LstdFlags),
	}
	check.Start()
	defer check.Stop()

	time.Sleep(50 * time.Millisecond)
	check.SetStatus(structs.HealthPassing, "")

	if mock.updates["foo"] != 1 {
		t.Fatalf("should have 1 updates %v", mock.updates)
	}

	if mock.state["foo"] != structs.HealthPassing {
		t.Fatalf("should be passing %v", mock.state)
	}

	// Ensure we don't fail early
	time.Sleep(75 * time.Millisecond)
	if mock.updates["foo"] != 1 {
		t.Fatalf("should have 1 updates %v", mock.updates)
	}

	// Wait for the TTL to expire
	time.Sleep(75 * time.Millisecond)

	if mock.updates["foo"] != 2 {
		t.Fatalf("should have 2 updates %v", mock.updates)
	}

	if mock.state["foo"] != structs.HealthCritical {
		t.Fatalf("should be critical %v", mock.state)
	}
}

func mockHTTPServer(responseCode int) *httptest.Server {
	mux := http.NewServeMux()
	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(responseCode)
		return
	})

	return httptest.NewServer(mux)
}

func expectHTTPStatus(t *testing.T, url string, status string) {
	mock := &MockNotify{
		state:   make(map[string]string),
		updates: make(map[string]int),
		output:  make(map[string]string),
	}
	check := &CheckHTTP{
		Notify:   mock,
		CheckID:  "foo",
		HTTP:     url,
		Interval: 10 * time.Millisecond,
		Logger:   log.New(os.Stderr, "", log.LstdFlags),
	}
	check.Start()
	defer check.Stop()

	time.Sleep(50 * time.Millisecond)

	// Should have at least 2 updates
	if mock.updates["foo"] < 2 {
		t.Fatalf("should have 2 updates %v", mock.updates)
	}

	if mock.state["foo"] != status {
		t.Fatalf("should be %v %v", status, mock.state)
	}
}

func TestCheckHTTPCritical(t *testing.T) {
	// var server *httptest.Server

	server := mockHTTPServer(150)
	fmt.Println(server.URL)
	expectHTTPStatus(t, server.URL, "critical")
	server.Close()

	// 2xx - 1
	server = mockHTTPServer(199)
	expectHTTPStatus(t, server.URL, "critical")
	server.Close()

	// 2xx + 1
	server = mockHTTPServer(300)
	expectHTTPStatus(t, server.URL, "critical")
	server.Close()

	server = mockHTTPServer(400)
	expectHTTPStatus(t, server.URL, "critical")
	server.Close()

	server = mockHTTPServer(500)
	expectHTTPStatus(t, server.URL, "critical")
	server.Close()
}

func TestCheckHTTPPassing(t *testing.T) {
	var server *httptest.Server

	server = mockHTTPServer(200)
	expectHTTPStatus(t, server.URL, "passing")
	server.Close()

	server = mockHTTPServer(201)
	expectHTTPStatus(t, server.URL, "passing")
	server.Close()

	server = mockHTTPServer(250)
	expectHTTPStatus(t, server.URL, "passing")
	server.Close()

	server = mockHTTPServer(299)
	expectHTTPStatus(t, server.URL, "passing")
	server.Close()
}

func TestCheckHTTPWarning(t *testing.T) {
	server := mockHTTPServer(429)
	expectHTTPStatus(t, server.URL, "warning")
	server.Close()
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/consul/acl.go<|end_filename|>
package consul

import (
	"errors"
	"strings"
	"time"

	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/armon/go-metrics"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/acl"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/consul/structs"
)

const (
	// aclNotFound indicates there is no matching ACL
	aclNotFound = "ACL not found"

	// rootDenied is returned when attempting to resolve a root ACL
	rootDenied = "Cannot resolve root ACL"

	// permissionDenied is returned when an ACL based rejection happens
	permissionDenied = "Permission denied"

	// aclDisabled is returned when ACL changes are not permitted
	// since they are disabled.
	aclDisabled = "ACL support disabled"

	// anonymousToken is the token ID we re-write to if there
	// is no token ID provided
	anonymousToken = "anonymous"
)

var (
	permissionDeniedErr = errors.New(permissionDenied)
)

// aclCacheEntry is used to cache non-authoritative ACL's
// If non-authoritative, then we must respect a TTL
type aclCacheEntry struct {
	ACL     acl.ACL
	Expires time.Time
	ETag    string
}

// aclFault is used to fault in the rules for an ACL if we take a miss
func (s *Server) aclFault(id string) (string, string, error) {
	defer metrics.MeasureSince([]string{"consul", "acl", "fault"}, time.Now())
	state := s.fsm.State()
	_, acl, err := state.ACLGet(id)
	if err != nil {
		return "", "", err
	}
	if acl == nil {
		return "", "", errors.New(aclNotFound)
	}

	// Management tokens have no policy and inherit from the
	// 'manage' root policy
	if acl.Type == structs.ACLTypeManagement {
		return "manage", "", nil
	}

	// Otherwise use the base policy
	return s.config.ACLDefaultPolicy, acl.Rules, nil
}

// resolveToken is used to resolve an ACL is any is appropriate
func (s *Server) resolveToken(id string) (acl.ACL, error) {
	// Check if there is no ACL datacenter (ACL's disabled)
	authDC := s.config.ACLDatacenter
	if len(authDC) == 0 {
		return nil, nil
	}
	defer metrics.MeasureSince([]string{"consul", "acl", "resolveToken"}, time.Now())

	// Handle the anonymous token
	if len(id) == 0 {
		id = anonymousToken
	} else if acl.RootACL(id) != nil {
		return nil, errors.New(rootDenied)
	}

	// Check if we are the ACL datacenter and the leader, use the
	// authoritative cache
	if s.config.Datacenter == authDC && s.IsLeader() {
		return s.aclAuthCache.GetACL(id)
	}

	// Use our non-authoritative cache
	return s.lookupACL(id, authDC)
}

// lookupACL is used when we are non-authoritative, and need
// to resolve an ACL
func (s *Server) lookupACL(id, authDC string) (acl.ACL, error) {
	// Check the cache for the ACL
	var cached *aclCacheEntry
	raw, ok := s.aclCache.Get(id)
	if ok {
		cached = raw.(*aclCacheEntry)
	}

	// Check for live cache
	if cached != nil && time.Now().Before(cached.Expires) {
		metrics.IncrCounter([]string{"consul", "acl", "cache_hit"}, 1)
		return cached.ACL, nil
	} else {
		metrics.IncrCounter([]string{"consul", "acl", "cache_miss"}, 1)
	}

	// Attempt to refresh the policy
	args := structs.ACLPolicyRequest{
		Datacenter: authDC,
		ACL:        id,
	}
	if cached != nil {
		args.ETag = cached.ETag
	}
	var out structs.ACLPolicy
	err := s.RPC("ACL.GetPolicy", &args, &out)

	// Handle the happy path
	if err == nil {
		return s.useACLPolicy(id, authDC, cached, &out)
	}

	// Check for not-found
	if strings.Contains(err.Error(), aclNotFound) {
		return nil, errors.New(aclNotFound)
	} else {
		s.logger.Printf("[ERR] consul.acl: Failed to get policy for '%s': %v", id, err)
	}

	// Unable to refresh, apply the down policy
	switch s.config.ACLDownPolicy {
	case "allow":
		return acl.AllowAll(), nil
	case "extend-cache":
		if cached != nil {
			return cached.ACL, nil
		}
		fallthrough
	default:
		return acl.DenyAll(), nil
	}
}

// useACLPolicy handles an ACLPolicy response
func (s *Server) useACLPolicy(id, authDC string, cached *aclCacheEntry, p *structs.ACLPolicy) (acl.ACL, error) {
	// Check if we can used the cached policy
	if cached != nil && cached.ETag == p.ETag {
		if p.TTL > 0 {
			cached.Expires = time.Now().Add(p.TTL)
		}
		return cached.ACL, nil
	}

	// Check for a cached compiled policy
	var compiled acl.ACL
	raw, ok := s.aclPolicyCache.Get(p.ETag)
	if ok {
		compiled = raw.(acl.ACL)
	} else {
		// Resolve the parent policy
		parent := acl.RootACL(p.Parent)
		if parent == nil {
			var err error
			parent, err = s.lookupACL(p.Parent, authDC)
			if err != nil {
				return nil, err
			}
		}

		// Compile the ACL
		acl, err := acl.New(parent, p.Policy)
		if err != nil {
			return nil, err
		}

		// Cache the policy
		s.aclPolicyCache.Add(p.ETag, acl)
		compiled = acl
	}

	// Cache the ACL
	cached = &aclCacheEntry{
		ACL:  compiled,
		ETag: p.ETag,
	}
	if p.TTL > 0 {
		cached.Expires = time.Now().Add(p.TTL)
	}
	s.aclCache.Add(id, cached)
	return compiled, nil
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/command/agent/util.go<|end_filename|>
package agent

import (
	"bytes"
	"crypto/md5"
	crand "crypto/rand"
	"fmt"
	"math"
	"math/rand"
	"os"
	"os/exec"
	"runtime"
	"time"

	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/go-msgpack/codec"
)

const (
	// This scale factor means we will add a minute after we
	// cross 128 nodes, another at 256, another at 512, etc.
	// By 8192 nodes, we will scale up by a factor of 8
	aeScaleThreshold = 128
)

// aeScale is used to scale the time interval at which anti-entropy
// take place. It is used to prevent saturation as the cluster size grows
func aeScale(interval time.Duration, n int) time.Duration {
	// Don't scale until we cross the threshold
	if n <= aeScaleThreshold {
		return interval
	}

	multiplier := math.Ceil(math.Log2(float64(n))-math.Log2(aeScaleThreshold)) + 1.0
	return time.Duration(multiplier) * interval
}

// Returns a random stagger interval between 0 and the duration
func randomStagger(intv time.Duration) time.Duration {
	return time.Duration(uint64(rand.Int63()) % uint64(intv))
}

// strContains checks if a list contains a string
func strContains(l []string, s string) bool {
	for _, v := range l {
		if v == s {
			return true
		}
	}
	return false
}

// ExecScript returns a command to execute a script
func ExecScript(script string) (*exec.Cmd, error) {
	var shell, flag string
	if runtime.GOOS == "windows" {
		shell = "cmd"
		flag = "/C"
	} else {
		shell = "/bin/sh"
		flag = "-c"
	}
	if other := os.Getenv("SHELL"); other != "" {
		shell = other
	}
	cmd := exec.Command(shell, flag, script)
	return cmd, nil
}

// generateUUID is used to generate a random UUID
func generateUUID() string {
	buf := make([]byte, 16)
	if _, err := crand.Read(buf); err != nil {
		panic(fmt.Errorf("failed to read random bytes: %v", err))
	}

	return fmt.Sprintf("%08x-%04x-%04x-%04x-%12x",
		buf[0:4],
		buf[4:6],
		buf[6:8],
		buf[8:10],
		buf[10:16])
}

// decodeMsgPack is used to decode a MsgPack encoded object
func decodeMsgPack(buf []byte, out interface{}) error {
	return codec.NewDecoder(bytes.NewReader(buf), msgpackHandle).Decode(out)
}

// encodeMsgPack is used to encode an object with msgpack
func encodeMsgPack(msg interface{}) ([]byte, error) {
	var buf bytes.Buffer
	err := codec.NewEncoder(&buf, msgpackHandle).Encode(msg)
	return buf.Bytes(), err
}

// stringHash returns a simple md5sum for a string.
func stringHash(s string) string {
	return fmt.Sprintf("%x", md5.Sum([]byte(s)))
}


<|start_filename|>daemon/ovs_driver.go<|end_filename|>
package daemon

import (
	"errors"
	"fmt"
	"reflect"
	"time"

	log "github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/Sirupsen/logrus"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/socketplane/libovsdb"
)

var quit chan bool
var update chan *libovsdb.TableUpdates
var cache map[string]map[string]libovsdb.Row

const CONTEXT_KEY = "container_id"
const CONTEXT_VALUE = "container_data"

func GetTableCache(tableName string) map[string]libovsdb.Row {
	return cache[tableName]
}

func monitorDockerBridge(ovs *libovsdb.OvsdbClient) {
	for {
		select {
		case currUpdate := <-update:
			for table, tableUpdate := range currUpdate.Updates {
				if table == "Bridge" {
					for _, row := range tableUpdate.Rows {
						empty := libovsdb.Row{}
						if !reflect.DeepEqual(row.New, empty) {
							oldRow := row.Old
							if _, ok := oldRow.Fields["name"]; ok {
								name := oldRow.Fields["name"].(string)
								if name == "docker0-ovs" {
									CreateOVSBridge(ovs, name)
								}
							}
						}
					}
				}
			}
		}
	}
}

func CreateOVSBridge(ovs *libovsdb.OvsdbClient, bridgeName string) error {
	namedBridgeUuid := "bridge"
	namedPortUuid := "port"
	namedIntfUuid := "intf"

	// intf row to insert
	intf := make(map[string]interface{})
	intf["name"] = bridgeName
	intf["type"] = `internal`

	insertIntfOp := libovsdb.Operation{
		Op:       "insert",
		Table:    "Interface",
		Row:      intf,
		UUIDName: namedIntfUuid,
	}

	// port row to insert
	port := make(map[string]interface{})
	port["name"] = bridgeName
	port["interfaces"] = libovsdb.UUID{namedIntfUuid}

	insertPortOp := libovsdb.Operation{
		Op:       "insert",
		Table:    "Port",
		Row:      port,
		UUIDName: namedPortUuid,
	}

	// bridge row to insert
	bridge := make(map[string]interface{})
	bridge["name"] = bridgeName
	bridge["stp_enable"] = true
	bridge["ports"] = libovsdb.UUID{namedPortUuid}

	insertBridgeOp := libovsdb.Operation{
		Op:       "insert",
		Table:    "Bridge",
		Row:      bridge,
		UUIDName: namedBridgeUuid,
	}
	// Inserting a Bridge row in Bridge table requires mutating the open_vswitch table.
	mutateUuid := []libovsdb.UUID{libovsdb.UUID{namedBridgeUuid}}
	mutateSet, _ := libovsdb.NewOvsSet(mutateUuid)
	mutation := libovsdb.NewMutation("bridges", "insert", mutateSet)
	condition := libovsdb.NewCondition("_uuid", "==", libovsdb.UUID{getRootUuid()})

	// simple mutate operation
	mutateOp := libovsdb.Operation{
		Op:        "mutate",
		Table:     "Open_vSwitch",
		Mutations: []interface{}{mutation},
		Where:     []interface{}{condition},
	}

	operations := []libovsdb.Operation{insertIntfOp, insertPortOp, insertBridgeOp, mutateOp}
	reply, _ := ovs.Transact("Open_vSwitch", operations...)

	if len(reply) < len(operations) {
		return errors.New("Number of Replies should be atleast equal to number of Operations")
	}
	for i, o := range reply {
		if o.Error != "" && i < len(operations) {
			return errors.New("Transaction Failed due to an error :" + o.Error + " details : " + o.Details)
		} else if o.Error != "" {
			return errors.New("Transaction Failed due to an error :" + o.Error + " details : " + o.Details)
		}
	}
	return nil
}

func getRootUuid() string {
	for uuid, _ := range cache["Open_vSwitch"] {
		return uuid
	}
	return ""
}

func addVxlanPort(ovs *libovsdb.OvsdbClient, bridgeName string, portName string, peerAddress string) {
	namedPortUuid := "port"
	namedIntfUuid := "intf"

	options := make(map[string]interface{})
	options["remote_ip"] = peerAddress
	// intf row to insert
	intf := make(map[string]interface{})
	intf["name"] = portName
	intf["type"] = `vxlan`
	intf["options"], _ = libovsdb.NewOvsMap(options)

	insertIntfOp := libovsdb.Operation{
		Op:       "insert",
		Table:    "Interface",
		Row:      intf,
		UUIDName: namedIntfUuid,
	}

	// port row to insert
	port := make(map[string]interface{})
	port["name"] = portName
	port["interfaces"] = libovsdb.UUID{namedIntfUuid}

	insertPortOp := libovsdb.Operation{
		Op:       "insert",
		Table:    "Port",
		Row:      port,
		UUIDName: namedPortUuid,
	}

	// Inserting a row in Port table requires mutating the bridge table.
	mutateUuid := []libovsdb.UUID{libovsdb.UUID{namedPortUuid}}
	mutateSet, _ := libovsdb.NewOvsSet(mutateUuid)
	mutation := libovsdb.NewMutation("ports", "insert", mutateSet)
	condition := libovsdb.NewCondition("name", "==", bridgeName)

	// simple mutate operation
	mutateOp := libovsdb.Operation{
		Op:        "mutate",
		Table:     "Bridge",
		Mutations: []interface{}{mutation},
		Where:     []interface{}{condition},
	}
	operations := []libovsdb.Operation{insertIntfOp, insertPortOp, mutateOp}
	reply, _ := ovs.Transact("Open_vSwitch", operations...)
	if len(reply) < len(operations) {
		fmt.Println("Number of Replies should be atleast equal to number of Operations")
	}
	for i, o := range reply {
		if o.Error != "" && i < len(operations) {
			fmt.Println("Transaction Failed due to an error :", o.Error, " details:", o.Details, " in ", operations[i])
		} else if o.Error != "" {
			fmt.Println("Transaction Failed due to an error :", o.Error)
		}
	}
}

func portUuidForName(portName string) string {
	portCache := cache["Port"]
	for key, val := range portCache {
		if val.Fields["name"] == portName {
			return key
		}
	}
	return ""
}

func portExists(ovs *libovsdb.OvsdbClient, portName string) (bool, error) {
	condition := libovsdb.NewCondition("name", "==", portName)
	selectOp := libovsdb.Operation{
		Op:    "select",
		Table: "Port",
		Where: []interface{}{condition},
	}
	operations := []libovsdb.Operation{selectOp}
	reply, _ := ovs.Transact("Open_vSwitch", operations...)

	if len(reply) < len(operations) {
		return false, errors.New("Number of Replies should be atleast equal to number of Operations")
	}

	if reply[0].Error != "" {
		errMsg := fmt.Sprintf("Transaction Failed due to an error: %v", reply[0].Error)
		return false, errors.New(errMsg)
	}

	if len(reply[0].Rows) == 0 {
		return false, nil
	}
	return true, nil
}

func deletePort(ovs *libovsdb.OvsdbClient, bridgeName string, portName string) {
	condition := libovsdb.NewCondition("name", "==", portName)
	deleteOp := libovsdb.Operation{
		Op:    "delete",
		Table: "Port",
		Where: []interface{}{condition},
	}

	portUuid := portUuidForName(portName)
	if portUuid == "" {
		log.Error("Unable to find a matching Port : ", portName)
		return
	}
	// Deleting a Bridge row in Bridge table requires mutating the open_vswitch table.
	mutateUuid := []libovsdb.UUID{libovsdb.UUID{portUuid}}
	mutateSet, _ := libovsdb.NewOvsSet(mutateUuid)
	mutation := libovsdb.NewMutation("ports", "delete", mutateSet)
	condition = libovsdb.NewCondition("name", "==", bridgeName)

	// simple mutate operation
	mutateOp := libovsdb.Operation{
		Op:        "mutate",
		Table:     "Bridge",
		Mutations: []interface{}{mutation},
		Where:     []interface{}{condition},
	}

	operations := []libovsdb.Operation{deleteOp, mutateOp}
	reply, _ := ovs.Transact("Open_vSwitch", operations...)

	if len(reply) < len(operations) {
		log.Error("Number of Replies should be atleast equal to number of Operations")
	}
	for i, o := range reply {
		if o.Error != "" && i < len(operations) {
			log.Error("Transaction Failed due to an error :", o.Error, " in ", operations[i])
		} else if o.Error != "" {
			log.Error("Transaction Failed due to an error :", o.Error)
		}
	}
}

func UpdatePortContext(ovs *libovsdb.OvsdbClient, portName string, key string, context string) error {
	config := make(map[string]string)
	config[CONTEXT_KEY] = key
	config[CONTEXT_VALUE] = context
	other_config, _ := libovsdb.NewOvsMap(config)

	mutation := libovsdb.NewMutation("other_config", "insert", other_config)
	condition := libovsdb.NewCondition("name", "==", portName)

	// simple mutate operation
	mutateOp := libovsdb.Operation{
		Op:        "mutate",
		Table:     "Interface",
		Mutations: []interface{}{mutation},
		Where:     []interface{}{condition},
	}

	operations := []libovsdb.Operation{mutateOp}
	reply, _ := ovs.Transact("Open_vSwitch", operations...)
	if len(reply) < len(operations) {
		return errors.New("Number of Replies should be atleast equal to number of Operations")
	}
	for i, o := range reply {
		if o.Error != "" && i < len(operations) {
			return errors.New(fmt.Sprintln("Transaction Failed due to an error :", o.Error, " details:", o.Details, " in ", operations[i]))
		} else if o.Error != "" {
			return errors.New(fmt.Sprintln("Transaction Failed due to an error :", o.Error))
		}
	}
	return nil
}

func AddInternalPort(ovs *libovsdb.OvsdbClient, bridgeName string, portName string, tag uint) error {
	namedPortUuid := "port"
	namedIntfUuid := "intf"

	// intf row to insert
	intf := make(map[string]interface{})
	intf["name"] = portName
	intf["type"] = `internal`

	insertIntfOp := libovsdb.Operation{
		Op:       "insert",
		Table:    "Interface",
		Row:      intf,
		UUIDName: namedIntfUuid,
	}

	// port row to insert
	port := make(map[string]interface{})
	port["name"] = portName
	port["interfaces"] = libovsdb.UUID{namedIntfUuid}

	if tag != 0 {
		port["tag"] = tag
	}

	insertPortOp := libovsdb.Operation{
		Op:       "insert",
		Table:    "Port",
		Row:      port,
		UUIDName: namedPortUuid,
	}

	// Inserting a row in Port table requires mutating the bridge table.
	mutateUuid := []libovsdb.UUID{libovsdb.UUID{namedPortUuid}}
	mutateSet, _ := libovsdb.NewOvsSet(mutateUuid)
	mutation := libovsdb.NewMutation("ports", "insert", mutateSet)
	condition := libovsdb.NewCondition("name", "==", bridgeName)

	// simple mutate operation
	mutateOp := libovsdb.Operation{
		Op:        "mutate",
		Table:     "Bridge",
		Mutations: []interface{}{mutation},
		Where:     []interface{}{condition},
	}

	operations := []libovsdb.Operation{insertIntfOp, insertPortOp, mutateOp}
	reply, _ := ovs.Transact("Open_vSwitch", operations...)
	if len(reply) < len(operations) {
		log.Error("Number of Replies should be atleast equal to number of Operations")
		return errors.New("Number of Replies should be atleast equal to number of Operations")
	}
	for i, o := range reply {
		if o.Error != "" && i < len(operations) {
			msg := fmt.Sprintf("Transaction Failed due to an error : %v details: %v in %v", o.Error, o.Details, operations[i])
			return errors.New(msg)
		} else if o.Error != "" {
			msg := fmt.Sprintf("Transaction Failed due to an error : %v", o.Error)
			return errors.New(msg)
		}
	}
	return nil
}

func populateCache(updates libovsdb.TableUpdates) {
	for table, tableUpdate := range updates.Updates {
		if _, ok := cache[table]; !ok {
			cache[table] = make(map[string]libovsdb.Row)

		}
		for uuid, row := range tableUpdate.Rows {
			empty := libovsdb.Row{}
			if !reflect.DeepEqual(row.New, empty) {
				cache[table][uuid] = row.New
			} else {
				delete(cache[table], uuid)
			}
		}
	}
}

func ovs_connect() (*libovsdb.OvsdbClient, error) {
	quit = make(chan bool)
	update = make(chan *libovsdb.TableUpdates)
	cache = make(map[string]map[string]libovsdb.Row)

	// By default libovsdb connects to 127.0.0.0:6400.
	var ovs *libovsdb.OvsdbClient
	var err error
	for {
		ovs, err = libovsdb.Connect("", 0)
		if err != nil {
			log.Errorf("Error(%s) connecting to OVS. Retrying...", err.Error())
			time.Sleep(time.Second * 2)
			continue
		}
		break
	}
	var notifier Notifier
	ovs.Register(notifier)

	initial, _ := ovs.MonitorAll("Open_vSwitch", "")
	populateCache(*initial)
	go monitorDockerBridge(ovs)
	for getRootUuid() == "" {
		time.Sleep(time.Second * 1)
	}
	log.Debug("Connected to OVS...")
	return ovs, nil
}

type Notifier struct {
}

func (n Notifier) Update(context interface{}, tableUpdates libovsdb.TableUpdates) {
	populateCache(tableUpdates)
	update <- &tableUpdates
}
func (n Notifier) Disconnected(ovsClient *libovsdb.OvsdbClient) {
}
func (n Notifier) Locked([]interface{}) {
}
func (n Notifier) Stolen([]interface{}) {
}
func (n Notifier) Echo([]interface{}) {
}


<|start_filename|>Dockerfile<|end_filename|>
FROM golang:1.3-onbuild
MAINTAINER <EMAIL>
RUN export DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y iptables


<|start_filename|>Godeps/_workspace/src/github.com/socketplane/ecc/ecc.go<|end_filename|>
package ecc

import (
	"bytes"
	b64 "encoding/base64"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"os"
	"reflect"
	"time"

	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/api"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/command"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/watch"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/mitchellh/cli"
)

// Embedded Consul Client
// Quick and Dirty way to embed Consul with any golang based application without the
// additional step of installing the Consul application in the host system

// Consul Agent related functions

var started bool
var OfflineSupport bool = true
var listener eccListener

func Start(serverMode bool, bootstrap bool, bindInterface string, dataDir string) error {
	bindAddress := ""
	if bindInterface != "" {
		intf, err := net.InterfaceByName(bindInterface)
		if err != nil {
			log.Printf("Error : %v", err)
			return err
		}
		addrs, err := intf.Addrs()
		if err == nil {
			for i := 0; i < len(addrs); i++ {
				addr := addrs[i].String()
				ip, _, _ := net.ParseCIDR(addr)
				if ip != nil && ip.To4() != nil {
					bindAddress = ip.To4().String()
				}
			}
		}
	}
	errCh := make(chan int)
	watchForExistingRegisteredUpdates()
	go RegisterForNodeUpdates(listener)
	go startConsul(serverMode, bootstrap, bindAddress, dataDir, errCh)

	select {
	case <-errCh:
		return errors.New("Error starting Consul Agent")
	case <-time.After(time.Second * 5):
	}
	return nil
}

func startConsul(serverMode bool, bootstrap bool, bindAddress string, dataDir string, eCh chan int) {
	args := []string{"agent", "-data-dir", dataDir}

	if serverMode {
		args = append(args, "-server")
	}

	if bootstrap {
		args = append(args, "-bootstrap")
	}

	if bindAddress != "" {
		args = append(args, "-bind")
		args = append(args, bindAddress)
		args = append(args, "-advertise")
		args = append(args, bindAddress)
	}

	ret := Execute(args...)

	eCh <- ret
}

func HasStarted() bool {
	return started
}

func Join(address string) error {
	ret := Execute("join", address)

	if ret != 0 {
		log.Println("Error (%d) joining %s with Consul peers", ret, address)
		return errors.New("Error adding member")
	}
	return nil
}

func Leave() error {
	stopWatches()
	ret := Execute("leave")
	if ret != 0 {
		log.Println("Error Leaving Consul membership")
		return errors.New("Error leaving Consul cluster")
	}
	return nil
}

// Execute function is borrowed from Consul's main.go
func Execute(args ...string) int {

	for _, arg := range args {
		if arg == "-v" || arg == "--version" {
			newArgs := make([]string, len(args)+1)
			newArgs[0] = "version"
			copy(newArgs[1:], args)
			args = newArgs
			break
		}
	}

	cli := &cli.CLI{
		Args:     args,
		Commands: Commands,
		HelpFunc: cli.BasicHelpFunc("consul"),
	}

	exitCode, err := cli.Run()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error executing CLI: %s\n", err.Error())
		return 1
	}

	return exitCode
}

const CONSUL_BASE_URL = "http://localhost:8500/v1/"

func ConsulGet(url string) (string, bool) {
	resp, err := http.Get(url)
	if err != nil {
		log.Printf("Error (%v) in Get for %s\n", err, url)
		return "", false
	}
	defer resp.Body.Close()
	log.Printf("Status of Get %s %d for %s", resp.Status, resp.StatusCode, url)
	if resp.StatusCode >= 200 && resp.StatusCode < 300 {
		var jsonBody []consulBody
		body, err := ioutil.ReadAll(resp.Body)
		err = json.Unmarshal(body, &jsonBody)
		existingValue, err := b64.StdEncoding.DecodeString(jsonBody[0].Value)
		if err != nil {
			return "", false
		}
		return string(existingValue[:]), true
	} else {
		return "", false
	}
}

// Consul KV Store related

const CONSUL_KV_BASE_URL = "http://localhost:8500/v1/kv/"

type consulBody struct {
	CreateIndex int    `json:"CreateIndex,omitempty"`
	ModifyIndex int    `json:"ModifyIndex,omitempty"`
	Key         string `json:"Key,omitempty"`
	Flags       int    `json:"Flags,omitempty"`
	Value       string `json:"Value,omitempty"`
}

func GetAll(store string) ([][]byte, []int, bool) {
	if OfflineSupport && !started {
		return getAllFromCache(store)
	}
	url := CONSUL_KV_BASE_URL + store + "?recurse"
	resp, err := http.Get(url)
	if err != nil {
		log.Printf("Error (%v) in Get for %s\n", err, url)
		return nil, nil, false
	}
	defer resp.Body.Close()
	log.Printf("Status of Get %s %d for %s", resp.Status, resp.StatusCode, url)
	if resp.StatusCode >= 400 && resp.StatusCode < 500 {
		return nil, nil, false
	} else if resp.StatusCode >= 200 && resp.StatusCode < 300 {
		var jsonBody []consulBody
		valueArr := make([][]byte, 0)
		indexArr := make([]int, 0)
		body, _ := ioutil.ReadAll(resp.Body)
		err = json.Unmarshal(body, &jsonBody)
		for _, body := range jsonBody {
			existingValue, _ := b64.StdEncoding.DecodeString(body.Value)
			valueArr = append(valueArr, existingValue)
			indexArr = append(indexArr, body.ModifyIndex)
		}
		return valueArr, indexArr, true
	} else {
		return nil, nil, false
	}
}

func Get(store string, key string) ([]byte, int, bool) {
	if OfflineSupport && !started {
		return getFromCache(store, key)
	}
	url := CONSUL_KV_BASE_URL + store + "/" + key
	resp, err := http.Get(url)
	if err != nil {
		log.Printf("Error (%v) in Get for %s\n", err, url)
		return nil, 0, false
	}
	defer resp.Body.Close()
	log.Printf("Status of Get %s %d for %s", resp.Status, resp.StatusCode, url)
	if resp.StatusCode >= 400 && resp.StatusCode < 500 {
		return nil, 0, false
	} else if resp.StatusCode >= 200 && resp.StatusCode < 300 {
		var jsonBody []consulBody
		body, err := ioutil.ReadAll(resp.Body)
		err = json.Unmarshal(body, &jsonBody)
		existingValue, err := b64.StdEncoding.DecodeString(jsonBody[0].Value)
		if err != nil {
			return nil, jsonBody[0].ModifyIndex, false
		}
		return existingValue, jsonBody[0].ModifyIndex, true
	} else {
		return nil, 0, false
	}
}

const (
	OK = iota
	OUTDATED
	ERROR
)

type eccerror int

func Put(store string, key string, value []byte, oldValue []byte) eccerror {
	if OfflineSupport && !started {
		return putInCache(store, key, value, oldValue)
	}
	existingValue, casIndex, ok := Get(store, key)
	if ok && !bytes.Equal(oldValue, existingValue) {
		return OUTDATED
	}
	url := fmt.Sprintf("%s%s/%s?cas=%d", CONSUL_KV_BASE_URL, store, key, casIndex)
	log.Printf("Updating KV pair for %s %s %s %d", url, key, value, casIndex)
	req, err := http.NewRequest("PUT", url, bytes.NewBuffer(value))

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		log.Println("Error creating KV pair for ", url, err)
		return ERROR
	}
	defer resp.Body.Close()

	body, _ := ioutil.ReadAll(resp.Body)
	if string(body) == "false" {
		// Let the application retry based on return value
		// return Put(store, key, value, oldValue)
		return OUTDATED
	}
	return OK
}

func Delete(store string, key string) eccerror {
	if OfflineSupport && !started {
		return deleteFromCache(store, key)
	}
	url := fmt.Sprintf("%s%s/%s", CONSUL_KV_BASE_URL, store, key)
	log.Printf("Deleting KV pair for %s", url)
	req, err := http.NewRequest("DELETE", url, nil)

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		log.Println("Error creating KV pair for ", url, err)
		return ERROR
	}
	defer resp.Body.Close()

	body, _ := ioutil.ReadAll(resp.Body)
	log.Println(string(body))
	return OK
}

type Store struct {
	cache map[string][]byte
}

// Local KV store cache for bootstrap node consul connection issues
var cache map[string]Store = make(map[string]Store)

func getAllFromCache(storeName string) ([][]byte, []int, bool) {
	store, ok := cache[storeName]
	if !ok {
		return nil, nil, false
	}
	vals := make([][]byte, 0)
	for _, val := range store.cache {
		vals = append(vals, val)
	}
	return vals, nil, true
}

func getFromCache(storeName string, key string) ([]byte, int, bool) {
	store, ok := cache[storeName]
	if !ok {
		return nil, 0, false
	}
	val, ok := store.cache[key]
	return val, 0, ok
}

func putInCache(storeName string, key string, value []byte, oldValue []byte) eccerror {
	store, ok := cache[storeName]
	if !ok {
		store = Store{make(map[string][]byte)}
		cache[storeName] = store
	}
	store.cache[key] = value
	return OK
}

func deleteFromCache(storeName string, key string) eccerror {
	store, ok := cache[storeName]
	if ok {
		delete(store.cache, key)
	}
	return OK
}

func populateKVStoreFromCache() {
	if !OfflineSupport || started {
		return
	}
	started = true
	for storeName, store := range cache {
		for key, val := range store.cache {
			go Put(storeName, key, val, nil)
		}
		delete(cache, storeName)
	}
}

// Watch related

const (
	NOTIFY_UPDATE_ADD = iota
	NOTIFY_UPDATE_MODIFY
	NOTIFY_UPDATE_DELETE
)

type NotifyUpdateType int

const (
	WATCH_TYPE_NODE = iota
	WATCH_TYPE_KEY
	WATCH_TYPE_STORE
	WATCH_TYPE_EVENT
)

type WatchType int

type watchData struct {
	listeners  map[string][]Listener
	watchPlans []*watch.WatchPlan
}

var watches map[WatchType]watchData = make(map[WatchType]watchData)

type Listener interface {
	NotifyNodeUpdate(NotifyUpdateType, string)
	NotifyKeyUpdate(NotifyUpdateType, string, []byte)
	NotifyStoreUpdate(NotifyUpdateType, string, map[string][]byte)
}

type eccListener struct {
}

func (e eccListener) NotifyNodeUpdate(nType NotifyUpdateType, nodeAddress string) {
	if nType == NOTIFY_UPDATE_ADD && !started {
		populateKVStoreFromCache()
	}
}

func (e eccListener) NotifyKeyUpdate(nType NotifyUpdateType, key string, data []byte) {
}
func (e eccListener) NotifyStoreUpdate(nType NotifyUpdateType, store string, data map[string][]byte) {
}

func contains(wtype WatchType, key string, elem interface{}) bool {
	ws, ok := watches[wtype]
	if !ok {
		return false
	}

	list, ok := ws.listeners[key]
	if !ok {
		return false
	}

	v := reflect.ValueOf(list)
	for i := 0; i < v.Len(); i++ {
		if v.Index(i).Interface() == elem {
			return true
		}
	}
	return false
}

type watchconsul bool

func addListener(wtype WatchType, key string, listener Listener) watchconsul {
	var wc watchconsul = false
	if !contains(WATCH_TYPE_NODE, key, listener) {
		ws, ok := watches[wtype]
		if !ok {
			watches[wtype] = watchData{make(map[string][]Listener), make([]*watch.WatchPlan, 0)}
			ws = watches[wtype]
		}

		listeners, ok := ws.listeners[key]
		if !ok {
			listeners = make([]Listener, 0)
			wc = true
		}
		ws.listeners[key] = append(listeners, listener)
	}
	return wc
}

func getListeners(wtype WatchType, key string) []Listener {
	ws, ok := watches[wtype]
	if !ok {
		return nil
	}

	list, ok := ws.listeners[key]
	if ok {
		return list
	}
	return nil
}

func addWatchPlan(wtype WatchType, wp *watch.WatchPlan) {
	ws, ok := watches[wtype]
	if !ok {
		return
	}

	ws.watchPlans = append(ws.watchPlans, wp)
	watches[wtype] = ws
}

func stopWatches() {
	for _, ws := range watches {
		for _, wp := range ws.watchPlans {
			wp.Stop()
		}
		ws.watchPlans = ws.watchPlans[:0]
	}
}

func register(wtype WatchType, params map[string]interface{}, handler watch.HandlerFunc) {
	// Create the watch
	wp, err := watch.Parse(params)
	if err != nil {
		fmt.Printf("Register error : %s", err)
		return
	}
	addWatchPlan(wtype, wp)
	wp.Handler = handler
	cmdFlags := flag.NewFlagSet("watch", flag.ContinueOnError)
	httpAddr := command.HTTPAddrFlag(cmdFlags)
	// Run the watch
	if err := wp.Run(*httpAddr); err != nil {
		fmt.Printf("Error querying Consul agent: %s", err)
	}
}

var nodeCache []*api.Node

func compare(X, Y []*api.Node) []*api.Node {
	m := make(map[string]bool)

	for _, y := range Y {
		m[y.Address] = true
	}

	var ret []*api.Node
	for _, x := range X {
		if m[x.Address] {
			continue
		}
		ret = append(ret, x)
	}

	return ret
}

func updateNodeListeners(clusterNodes []*api.Node) {
	toDelete := compare(nodeCache, clusterNodes)
	toAdd := compare(clusterNodes, nodeCache)
	nodeCache = clusterNodes
	listeners := getListeners(WATCH_TYPE_NODE, "")
	if listeners == nil {
		return
	}
	for _, deleteNode := range toDelete {
		for _, listener := range listeners {
			listener.NotifyNodeUpdate(NOTIFY_UPDATE_DELETE, deleteNode.Address)
		}
	}

	for _, addNode := range toAdd {
		for _, listener := range listeners {
			listener.NotifyNodeUpdate(NOTIFY_UPDATE_ADD, addNode.Address)
		}
	}
}

func updateKeyListeners(idx uint64, key string, data interface{}) {
	listeners := getListeners(WATCH_TYPE_KEY, key)
	if listeners == nil {
		return
	}

	var kv *api.KVPair = nil
	var val []byte = nil
	updateType := NOTIFY_UPDATE_MODIFY

	if data != nil {
		kv = data.(*api.KVPair)
	}

	if kv == nil {
		updateType = NOTIFY_UPDATE_DELETE
	} else {
		updateType = NOTIFY_UPDATE_MODIFY
		if idx == kv.CreateIndex {
			updateType = NOTIFY_UPDATE_ADD
		}
		val = kv.Value
	}

	for _, listener := range listeners {
		listener.NotifyKeyUpdate(NotifyUpdateType(updateType), key, val)
	}
}

func registerForNodeUpdates() {
	// Compile the watch parameters
	params := make(map[string]interface{})
	params["type"] = "nodes"
	handler := func(idx uint64, data interface{}) {
		updateNodeListeners(data.([]*api.Node))
	}
	register(WATCH_TYPE_NODE, params, handler)
}

func RegisterForNodeUpdates(listener Listener) {
	wc := addListener(WATCH_TYPE_NODE, "", listener)
	if wc {
		registerForNodeUpdates()
	}
}

func registerForKeyUpdates(absKey string) {
	params := make(map[string]interface{})
	params["type"] = "key"
	params["key"] = absKey
	handler := func(idx uint64, data interface{}) {
		updateKeyListeners(idx, absKey, data)
	}
	register(WATCH_TYPE_KEY, params, handler)
}

func RegisterForKeyUpdates(store string, key string, listener Listener) {
	absKey := store + "/" + key
	wc := addListener(WATCH_TYPE_KEY, absKey, listener)
	if wc {
		registerForKeyUpdates(absKey)
	}
}

func registerForStoreUpdates(store string) {
	// Compile the watch parameters
	params := make(map[string]interface{})
	params["type"] = "keyprefix"
	params["prefix"] = store + "/"
	handler := func(idx uint64, data interface{}) {
		fmt.Println("NOT IMPLEMENTED Store Update :", idx, data)
	}
	register(WATCH_TYPE_STORE, params, handler)
}

func RegisterForStoreUpdates(store string, listener Listener) {
	wc := addListener(WATCH_TYPE_STORE, store, listener)
	if wc {
		registerForStoreUpdates(store)
	}
}

func watchForExistingRegisteredUpdates() {
	for wType, ws := range watches {
		log.Println("watchForExistingRegisteredUpdates : ", wType)
		for key, _ := range ws.listeners {
			log.Println("key : ", key)
			switch wType {
			case WATCH_TYPE_NODE:
				go registerForNodeUpdates()
			case WATCH_TYPE_KEY:
				go registerForKeyUpdates(key)
			case WATCH_TYPE_STORE:
				go registerForStoreUpdates(key)
			}
		}
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/inconshreveable/muxado/server.go<|end_filename|>
package muxado

import (
	"crypto/tls"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/inconshreveable/muxado/proto"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/inconshreveable/muxado/proto/ext"
	"net"
)

// A Listener accepts new connections from its net.Listener
// and begins muxado server connections on them.
//
// It's API is very similar to a net.Listener, but it returns
// muxado.Sessions instead of net.Conn's.
type Listener struct {
	wrapped net.Listener
}

// Accept the next connection from the listener and begin
// a muxado session on it.
func (l *Listener) Accept() (Session, error) {
	conn, err := l.wrapped.Accept()
	if err != nil {
		return nil, err
	}

	return Server(conn), nil
}

// Addr returns the bound address of the wrapped net.Listener
func (l *Listener) Addr() net.Addr {
	return l.wrapped.Addr()
}

// Close closes the wrapped net.Listener
func (l *Listener) Close() error {
	return l.wrapped.Close()
}

// Server returns a muxado server session using conn as the transport.
func Server(conn net.Conn) Session {
	return &sessionAdaptor{proto.NewSession(conn, proto.NewStream, false, []proto.Extension{ext.NewDefaultHeartbeat()})}
}

// Listen binds to a network address and returns a Listener which accepts
// new connections and starts muxado server sessions on them.
func Listen(network, addr string) (*Listener, error) {
	l, err := net.Listen(network, addr)
	if err != nil {
		return nil, err
	}

	return &Listener{l}, nil
}

// ListenTLS binds to a network address and accepts new TLS-encrypted connections.
// It returns a Listener which starts new muxado server sessions on the connections.
func ListenTLS(network, addr string, tlsConfig *tls.Config) (*Listener, error) {
	l, err := tls.Listen(network, addr, tlsConfig)
	if err != nil {
		return nil, err
	}

	return &Listener{l}, nil
}

// NewListener creates a new muxado listener which creates new muxado server sessions
// by accepting connections from the given net.Listener
func NewListener(l net.Listener) *Listener {
	return &Listener{l}
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/command/exec.go<|end_filename|>
package command

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"os"
	"path"
	"regexp"
	"strconv"
	"strings"
	"time"
	"unicode"

	consulapi "github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/api"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/mitchellh/cli"
)

const (
	// rExecPrefix is the prefix in the KV store used to
	// store the remote exec data
	rExecPrefix = "_rexec"

	// rExecFileName is the name of the file we append to
	// the path, e.g. _rexec/session_id/job
	rExecFileName = "job"

	// rExecAck is the suffix added to an ack path
	rExecAckSuffix = "/ack"

	// rExecAck is the suffix added to an exit code
	rExecExitSuffix = "/exit"

	// rExecOutputDivider is used to namespace the output
	rExecOutputDivider = "/out/"

	// rExecReplicationWait is how long we wait for replication
	rExecReplicationWait = 200 * time.Millisecond

	// rExecQuietWait is how long we wait for no responses
	// before assuming the job is done.
	rExecQuietWait = 2 * time.Second

	// rExecTTL is how long we default the session TTL to
	rExecTTL = "15s"

	// rExecRenewInterval is how often we renew the session TTL
	// when doing an exec in a foreign DC.
	rExecRenewInterval = 5 * time.Second
)

// rExecConf is used to pass around configuration
type rExecConf struct {
	datacenter string
	prefix     string

	foreignDC bool
	localDC   string
	localNode string

	node    string
	service string
	tag     string

	wait     time.Duration
	replWait time.Duration

	cmd    string
	script []byte

	verbose bool
}

// rExecEvent is the event we broadcast using a user-event
type rExecEvent struct {
	Prefix  string
	Session string
}

// rExecSpec is the file we upload to specify the parameters
// of the remote execution.
type rExecSpec struct {
	// Command is a single command to run directly in the shell
	Command string `json:",omitempty"`

	// Script should be spilled to a file and executed
	Script []byte `json:",omitempty"`

	// Wait is how long we are waiting on a quiet period to terminate
	Wait time.Duration
}

// rExecAck is used to transmit an acknowledgement
type rExecAck struct {
	Node string
}

// rExecHeart is used to transmit a heartbeat
type rExecHeart struct {
	Node string
}

// rExecOutput is used to transmit a chunk of output
type rExecOutput struct {
	Node   string
	Output []byte
}

// rExecExit is used to transmit an exit code
type rExecExit struct {
	Node string
	Code int
}

// ExecCommand is a Command implementation that is used to
// do remote execution of commands
type ExecCommand struct {
	ShutdownCh <-chan struct{}
	Ui         cli.Ui
	conf       rExecConf
	client     *consulapi.Client
	sessionID  string
	stopCh     chan struct{}
}

func (c *ExecCommand) Run(args []string) int {
	cmdFlags := flag.NewFlagSet("exec", flag.ContinueOnError)
	cmdFlags.Usage = func() { c.Ui.Output(c.Help()) }
	cmdFlags.StringVar(&c.conf.datacenter, "datacenter", "", "")
	cmdFlags.StringVar(&c.conf.node, "node", "", "")
	cmdFlags.StringVar(&c.conf.service, "service", "", "")
	cmdFlags.StringVar(&c.conf.tag, "tag", "", "")
	cmdFlags.StringVar(&c.conf.prefix, "prefix", rExecPrefix, "")
	cmdFlags.DurationVar(&c.conf.replWait, "wait-repl", rExecReplicationWait, "")
	cmdFlags.DurationVar(&c.conf.wait, "wait", rExecQuietWait, "")
	cmdFlags.BoolVar(&c.conf.verbose, "verbose", false, "")
	httpAddr := HTTPAddrFlag(cmdFlags)
	if err := cmdFlags.Parse(args); err != nil {
		return 1
	}

	// Join the commands to execute
	c.conf.cmd = strings.Join(cmdFlags.Args(), " ")

	// If there is no command, read stdin for a script input
	if c.conf.cmd == "-" {
		c.conf.cmd = ""
		var buf bytes.Buffer
		_, err := io.Copy(&buf, os.Stdin)
		if err != nil {
			c.Ui.Error(fmt.Sprintf("Failed to read stdin: %v", err))
			c.Ui.Error("")
			c.Ui.Error(c.Help())
			return 1
		}
		c.conf.script = buf.Bytes()
	}

	// Ensure we have a command or script
	if c.conf.cmd == "" && len(c.conf.script) == 0 {
		c.Ui.Error("Must specify a command to execute")
		c.Ui.Error("")
		c.Ui.Error(c.Help())
		return 1
	}

	// Validate the configuration
	if err := c.conf.validate(); err != nil {
		c.Ui.Error(err.Error())
		return 1
	}

	// Create and test the HTTP client
	client, err := HTTPClientDC(*httpAddr, c.conf.datacenter)
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err))
		return 1
	}
	info, err := client.Agent().Self()
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Error querying Consul agent: %s", err))
		return 1
	}
	c.client = client

	// Check if this is a foreign datacenter
	if c.conf.datacenter != "" && c.conf.datacenter != info["Config"]["Datacenter"] {
		if c.conf.verbose {
			c.Ui.Info("Remote exec in foreign datacenter, using Session TTL")
		}
		c.conf.foreignDC = true
		c.conf.localDC = info["Config"]["Datacenter"].(string)
		c.conf.localNode = info["Config"]["NodeName"].(string)
	}

	// Create the job spec
	spec, err := c.makeRExecSpec()
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Failed to create job spec: %s", err))
		return 1
	}

	// Create a session for this
	c.sessionID, err = c.createSession()
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Failed to create session: %s", err))
		return 1
	}
	defer c.destroySession()
	if c.conf.verbose {
		c.Ui.Info(fmt.Sprintf("Created remote execution session: %s", c.sessionID))
	}

	// Upload the payload
	if err := c.uploadPayload(spec); err != nil {
		c.Ui.Error(fmt.Sprintf("Failed to create job file: %s", err))
		return 1
	}
	defer c.destroyData()
	if c.conf.verbose {
		c.Ui.Info(fmt.Sprintf("Uploaded remote execution spec"))
	}

	// Wait for replication. This is done so that when the event is
	// received, the job file can be read using a stale read. If the
	// stale read fails, we expect a consistent read to be done, so
	// largely this is a heuristic.
	select {
	case <-time.After(c.conf.replWait):
	case <-c.ShutdownCh:
		return 1
	}

	// Fire the event
	id, err := c.fireEvent()
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Failed to fire event: %s", err))
		return 1
	}
	if c.conf.verbose {
		c.Ui.Info(fmt.Sprintf("Fired remote execution event: %s", id))
	}

	// Wait for the job to finish now
	return c.waitForJob()
}

// waitForJob is used to poll for results and wait until the job is terminated
func (c *ExecCommand) waitForJob() int {
	// Although the session destroy is already deferred, we do it again here,
	// because invalidation of the session before destroyData() ensures there is
	// no race condition allowing an agent to upload data (the acquire will fail).
	defer c.destroySession()
	start := time.Now()
	ackCh := make(chan rExecAck, 128)
	heartCh := make(chan rExecHeart, 128)
	outputCh := make(chan rExecOutput, 128)
	exitCh := make(chan rExecExit, 128)
	doneCh := make(chan struct{})
	errCh := make(chan struct{}, 1)
	defer close(doneCh)
	go c.streamResults(doneCh, ackCh, heartCh, outputCh, exitCh, errCh)
	target := &TargettedUi{Ui: c.Ui}

	var ackCount, exitCount, badExit int
OUTER:
	for {
		// Determine wait time. We provide a larger window if we know about
		// nodes which are still working.
		waitIntv := c.conf.wait
		if ackCount > exitCount {
			waitIntv *= 2
		}

		select {
		case e := <-ackCh:
			ackCount++
			if c.conf.verbose {
				target.Target = e.Node
				target.Info("acknowledged")
			}

		case h := <-heartCh:
			if c.conf.verbose {
				target.Target = h.Node
				target.Info("heartbeat received")
			}

		case e := <-outputCh:
			target.Target = e.Node
			target.Output(string(e.Output))

		case e := <-exitCh:
			exitCount++
			target.Target = e.Node
			target.Info(fmt.Sprintf("finished with exit code %d", e.Code))
			if e.Code != 0 {
				badExit++
			}

		case <-time.After(waitIntv):
			c.Ui.Info(fmt.Sprintf("%d / %d node(s) completed / acknowledged", exitCount, ackCount))
			if c.conf.verbose {
				c.Ui.Info(fmt.Sprintf("Completed in %0.2f seconds",
					float64(time.Now().Sub(start))/float64(time.Second)))
			}
			break OUTER

		case <-errCh:
			return 1

		case <-c.ShutdownCh:
			return 1
		}
	}

	if badExit > 0 {
		return 2
	}
	return 0
}

// streamResults is used to perform blocking queries against the KV endpoint and stream in
// notice of various events into waitForJob
func (c *ExecCommand) streamResults(doneCh chan struct{}, ackCh chan rExecAck, heartCh chan rExecHeart,
	outputCh chan rExecOutput, exitCh chan rExecExit, errCh chan struct{}) {
	kv := c.client.KV()
	opts := consulapi.QueryOptions{WaitTime: c.conf.wait}
	dir := path.Join(c.conf.prefix, c.sessionID) + "/"
	seen := make(map[string]struct{})

	for {
		// Check if we've been signaled to exit
		select {
		case <-doneCh:
			return
		default:
		}

		// Block on waiting for new keys
		keys, qm, err := kv.Keys(dir, "", &opts)
		if err != nil {
			c.Ui.Error(fmt.Sprintf("Failed to read results: %s", err))
			goto ERR_EXIT
		}

		// Fast-path the no-change case
		if qm.LastIndex == opts.WaitIndex {
			continue
		}
		opts.WaitIndex = qm.LastIndex

		// Handle each key
		for _, key := range keys {
			// Ignore if we've seen it
			if _, ok := seen[key]; ok {
				continue
			}
			seen[key] = struct{}{}

			// Trim the directory
			full := key
			key = strings.TrimPrefix(key, dir)

			// Handle the key type
			switch {
			case key == rExecFileName:
				continue
			case strings.HasSuffix(key, rExecAckSuffix):
				ackCh <- rExecAck{Node: strings.TrimSuffix(key, rExecAckSuffix)}

			case strings.HasSuffix(key, rExecExitSuffix):
				pair, _, err := kv.Get(full, nil)
				if err != nil {
					c.Ui.Error(fmt.Sprintf("Failed to read key '%s': %v", full, err))
					continue
				}
				code, err := strconv.ParseInt(string(pair.Value), 10, 32)
				if err != nil {
					c.Ui.Error(fmt.Sprintf("Failed to parse exit code '%s': %v", pair.Value, err))
					continue
				}
				exitCh <- rExecExit{
					Node: strings.TrimSuffix(key, rExecExitSuffix),
					Code: int(code),
				}

			case strings.LastIndex(key, rExecOutputDivider) != -1:
				pair, _, err := kv.Get(full, nil)
				if err != nil {
					c.Ui.Error(fmt.Sprintf("Failed to read key '%s': %v", full, err))
					continue
				}
				idx := strings.LastIndex(key, rExecOutputDivider)
				node := key[:idx]
				if len(pair.Value) == 0 {
					heartCh <- rExecHeart{Node: node}
				} else {
					outputCh <- rExecOutput{Node: node, Output: pair.Value}
				}

			default:
				c.Ui.Error(fmt.Sprintf("Unknown key '%s', ignoring.", key))
			}
		}
	}

ERR_EXIT:
	select {
	case errCh <- struct{}{}:
	default:
	}
}

// validate checks that the configuration is sane
func (conf *rExecConf) validate() error {
	// Validate the filters
	if conf.node != "" {
		if _, err := regexp.Compile(conf.node); err != nil {
			return fmt.Errorf("Failed to compile node filter regexp: %v", err)
		}
	}
	if conf.service != "" {
		if _, err := regexp.Compile(conf.service); err != nil {
			return fmt.Errorf("Failed to compile service filter regexp: %v", err)
		}
	}
	if conf.tag != "" {
		if _, err := regexp.Compile(conf.tag); err != nil {
			return fmt.Errorf("Failed to compile tag filter regexp: %v", err)
		}
	}
	if conf.tag != "" && conf.service == "" {
		return fmt.Errorf("Cannot provide tag filter without service filter.")
	}
	return nil
}

// createSession is used to create a new session for this command
func (c *ExecCommand) createSession() (string, error) {
	var id string
	var err error
	if c.conf.foreignDC {
		id, err = c.createSessionForeign()
	} else {
		id, err = c.createSessionLocal()
	}
	if err == nil {
		c.stopCh = make(chan struct{})
		go c.renewSession(id, c.stopCh)
	}
	return id, err
}

// createSessionLocal is used to create a new session in a local datacenter
// This is simpler since we can use the local agent to create the session.
func (c *ExecCommand) createSessionLocal() (string, error) {
	session := c.client.Session()
	se := consulapi.SessionEntry{
		Name:     "Remote Exec",
		Behavior: consulapi.SessionBehaviorDelete,
		TTL:      rExecTTL,
	}
	id, _, err := session.Create(&se, nil)
	return id, err
}

// createSessionLocal is used to create a new session in a foreign datacenter
// This is more complex since the local agent cannot be used to create
// a session, and we must associate with a node in the remote datacenter.
func (c *ExecCommand) createSessionForeign() (string, error) {
	// Look for a remote node to bind to
	health := c.client.Health()
	services, _, err := health.Service("consul", "", true, nil)
	if err != nil {
		return "", fmt.Errorf("Failed to find Consul server in remote datacenter: %v", err)
	}
	if len(services) == 0 {
		return "", fmt.Errorf("Failed to find Consul server in remote datacenter")
	}
	node := services[0].Node.Node
	if c.conf.verbose {
		c.Ui.Info(fmt.Sprintf("Binding session to remote node %s@%s",
			node, c.conf.datacenter))
	}

	session := c.client.Session()
	se := consulapi.SessionEntry{
		Name:     fmt.Sprintf("Remote Exec via %s@%s", c.conf.localNode, c.conf.localDC),
		Node:     node,
		Checks:   []string{},
		Behavior: consulapi.SessionBehaviorDelete,
		TTL:      rExecTTL,
	}
	id, _, err := session.CreateNoChecks(&se, nil)
	return id, err
}

// renewSession is a long running routine that periodically renews
// the session TTL. This is used for foreign sessions where we depend
// on TTLs.
func (c *ExecCommand) renewSession(id string, stopCh chan struct{}) {
	session := c.client.Session()
	for {
		select {
		case <-time.After(rExecRenewInterval):
			_, _, err := session.Renew(id, nil)
			if err != nil {
				c.Ui.Error(fmt.Sprintf("Session renew failed: %v", err))
				return
			}
		case <-stopCh:
			return
		}
	}
}

// destroySession is used to destroy the associated session
func (c *ExecCommand) destroySession() error {
	// Stop the session renew if any
	if c.stopCh != nil {
		close(c.stopCh)
		c.stopCh = nil
	}

	// Destroy the session explicitly
	session := c.client.Session()
	_, err := session.Destroy(c.sessionID, nil)
	return err
}

// makeRExecSpec creates a serialized job specification
// that can be uploaded which will be parsed by agents to
// determine what to do.
func (c *ExecCommand) makeRExecSpec() ([]byte, error) {
	spec := &rExecSpec{
		Command: c.conf.cmd,
		Script:  c.conf.script,
		Wait:    c.conf.wait,
	}
	return json.Marshal(spec)
}

// uploadPayload is used to upload the request payload
func (c *ExecCommand) uploadPayload(payload []byte) error {
	kv := c.client.KV()
	pair := consulapi.KVPair{
		Key:     path.Join(c.conf.prefix, c.sessionID, rExecFileName),
		Value:   payload,
		Session: c.sessionID,
	}
	ok, _, err := kv.Acquire(&pair, nil)
	if err != nil {
		return err
	}
	if !ok {
		return fmt.Errorf("failed to acquire key %s", pair.Key)
	}
	return nil
}

// destroyData is used to nuke all the data associated with
// this remote exec. We just do a recursive delete of our
// data directory.
func (c *ExecCommand) destroyData() error {
	kv := c.client.KV()
	dir := path.Join(c.conf.prefix, c.sessionID)
	_, err := kv.DeleteTree(dir, nil)
	return err
}

// fireEvent is used to fire the event that will notify nodes
// about the remote execution. Returns the event ID or error
func (c *ExecCommand) fireEvent() (string, error) {
	// Create the user event payload
	msg := &rExecEvent{
		Prefix:  c.conf.prefix,
		Session: c.sessionID,
	}
	buf, err := json.Marshal(msg)
	if err != nil {
		return "", err
	}

	// Format the user event
	event := c.client.Event()
	params := &consulapi.UserEvent{
		Name:          "_rexec",
		Payload:       buf,
		NodeFilter:    c.conf.node,
		ServiceFilter: c.conf.service,
		TagFilter:     c.conf.tag,
	}

	// Fire the event
	id, _, err := event.Fire(params, nil)
	return id, err
}

func (c *ExecCommand) Synopsis() string {
	return "Executes a command on Consul nodes"
}

func (c *ExecCommand) Help() string {
	helpText := `
Usage: consul exec [options] [-|command...]

  Evaluates a command on remote Consul nodes. The nodes responding can
  be filtered using regular expressions on node name, service, and tag
  definitions. If a command is '-', stdin will be read until EOF
  and used as a script input.

Options:

  -http-addr=127.0.0.1:8500  HTTP address of the Consul agent.
  -datacenter=""             Datacenter to dispatch in. Defaults to that of agent.
  -prefix="_rexec"           Prefix in the KV store to use for request data
  -node=""					 Regular expression to filter on node names
  -service=""                Regular expression to filter on service instances
  -tag=""                    Regular expression to filter on service tags. Must be used
                             with -service.
  -wait=2s                   Period to wait with no responses before terminating execution.
  -wait-repl=200ms           Period to wait for replication before firing event. This is an
                             optimization to allow stale reads to be performed.
  -verbose                   Enables verbose output
`
	return strings.TrimSpace(helpText)
}

// TargettedUi is a UI that wraps another UI implementation and modifies
// the output to indicate a specific target. Specifically, all Say output
// is prefixed with the target name. Message output is not prefixed but
// is offset by the length of the target so that output is lined up properly
// with Say output. Machine-readable output has the proper target set.
type TargettedUi struct {
	Target string
	Ui     cli.Ui
}

func (u *TargettedUi) Ask(query string) (string, error) {
	return u.Ui.Ask(u.prefixLines(true, query))
}

func (u *TargettedUi) Info(message string) {
	u.Ui.Info(u.prefixLines(true, message))
}

func (u *TargettedUi) Output(message string) {
	u.Ui.Output(u.prefixLines(false, message))
}

func (u *TargettedUi) Error(message string) {
	u.Ui.Error(u.prefixLines(true, message))
}

func (u *TargettedUi) prefixLines(arrow bool, message string) string {
	arrowText := "==>"
	if !arrow {
		arrowText = strings.Repeat(" ", len(arrowText))
	}

	var result bytes.Buffer

	for _, line := range strings.Split(message, "\n") {
		result.WriteString(fmt.Sprintf("%s %s: %s\n", arrowText, u.Target, line))
	}

	return strings.TrimRightFunc(result.String(), unicode.IsSpace)
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/raft/inmem_transport.go<|end_filename|>
package raft

import (
	"fmt"
	"io"
	"net"
	"sync"
	"time"
)

// InmemAddr implements the net.Addr interface.
type InmemAddr struct {
	ID string
}

// NewInmemAddr returns a new in-memory addr with
// a randomly generate UUID as the ID
func NewInmemAddr() *InmemAddr {
	return &InmemAddr{generateUUID()}
}

// Network implements the net.Addr interface.
func (ia *InmemAddr) Network() string {
	return "inmem"
}

// String implements the net.Addr interface.
func (ia *InmemAddr) String() string {
	return ia.ID
}

// inmemPipeline is used to pipeline requests for the in-mem transport
type inmemPipeline struct {
	trans    *InmemTransport
	peer     *InmemTransport
	peerAddr string

	doneCh       chan AppendFuture
	inprogressCh chan *inmemPipelineInflight

	shutdown     bool
	shutdownCh   chan struct{}
	shutdownLock sync.Mutex
}

type inmemPipelineInflight struct {
	future *appendFuture
	respCh <-chan RPCResponse
}

// InmemTransport Implements the Transport interface, to allow Raft to be
// tested in-memory without going over a network.
type InmemTransport struct {
	sync.RWMutex
	consumerCh chan RPC
	localAddr  *InmemAddr
	peers      map[string]*InmemTransport
	pipelines  []*inmemPipeline
	timeout    time.Duration
}

// NewInmemTransport is used to initialize a new transport
// and generates a random local address.
func NewInmemTransport() (*InmemAddr, *InmemTransport) {
	addr := NewInmemAddr()
	trans := &InmemTransport{
		consumerCh: make(chan RPC, 16),
		localAddr:  addr,
		peers:      make(map[string]*InmemTransport),
		timeout:    50 * time.Millisecond,
	}
	return addr, trans
}

// SetHeartbeatHandler is used to set optional fast-path for
// heartbeats, not supported for this transport.
func (i *InmemTransport) SetHeartbeatHandler(cb func(RPC)) {
}

// Consumer implements the Transport interface.
func (i *InmemTransport) Consumer() <-chan RPC {
	return i.consumerCh
}

// LocalAddr implements the Transport interface.
func (i *InmemTransport) LocalAddr() net.Addr {
	return i.localAddr
}

// AppendEntriesPipeline returns an interface that can be used to pipeline
// AppendEntries requests.
func (i *InmemTransport) AppendEntriesPipeline(target net.Addr) (AppendPipeline, error) {
	i.RLock()
	peer, ok := i.peers[target.String()]
	i.RUnlock()
	if !ok {
		return nil, fmt.Errorf("failed to connect to peer: %v", target)
	}
	pipeline := newInmemPipeline(i, peer, target.String())
	i.Lock()
	i.pipelines = append(i.pipelines, pipeline)
	i.Unlock()
	return pipeline, nil
}

// AppendEntries implements the Transport interface.
func (i *InmemTransport) AppendEntries(target net.Addr, args *AppendEntriesRequest, resp *AppendEntriesResponse) error {
	rpcResp, err := i.makeRPC(target, args, nil, i.timeout)
	if err != nil {
		return err
	}

	// Copy the result back
	out := rpcResp.Response.(*AppendEntriesResponse)
	*resp = *out
	return nil
}

// RequestVote implements the Transport interface.
func (i *InmemTransport) RequestVote(target net.Addr, args *RequestVoteRequest, resp *RequestVoteResponse) error {
	rpcResp, err := i.makeRPC(target, args, nil, i.timeout)
	if err != nil {
		return err
	}

	// Copy the result back
	out := rpcResp.Response.(*RequestVoteResponse)
	*resp = *out
	return nil
}

// InstallSnapshot implements the Transport interface.
func (i *InmemTransport) InstallSnapshot(target net.Addr, args *InstallSnapshotRequest, resp *InstallSnapshotResponse, data io.Reader) error {
	rpcResp, err := i.makeRPC(target, args, data, 10*i.timeout)
	if err != nil {
		return err
	}

	// Copy the result back
	out := rpcResp.Response.(*InstallSnapshotResponse)
	*resp = *out
	return nil
}

func (i *InmemTransport) makeRPC(target net.Addr, args interface{}, r io.Reader, timeout time.Duration) (rpcResp RPCResponse, err error) {
	i.RLock()
	peer, ok := i.peers[target.String()]
	i.RUnlock()

	if !ok {
		err = fmt.Errorf("failed to connect to peer: %v", target)
		return
	}

	// Send the RPC over
	respCh := make(chan RPCResponse)
	peer.consumerCh <- RPC{
		Command:  args,
		Reader:   r,
		RespChan: respCh,
	}

	// Wait for a response
	select {
	case rpcResp = <-respCh:
		if rpcResp.Error != nil {
			err = rpcResp.Error
		}
	case <-time.After(timeout):
		err = fmt.Errorf("command timed out")
	}
	return
}

// EncodePeer implements the Transport interface. It uses the UUID as the
// address directly.
func (i *InmemTransport) EncodePeer(p net.Addr) []byte {
	return []byte(p.String())
}

// DecodePeer implements the Transport interface. It wraps the UUID in an
// InmemAddr.
func (i *InmemTransport) DecodePeer(buf []byte) net.Addr {
	return &InmemAddr{string(buf)}
}

// Connect is used to connect this transport to another transport for
// a given peer name. This allows for local routing.
func (i *InmemTransport) Connect(peer net.Addr, trans *InmemTransport) {
	i.Lock()
	defer i.Unlock()
	i.peers[peer.String()] = trans
}

// Disconnect is used to remove the ability to route to a given peer.
func (i *InmemTransport) Disconnect(peer net.Addr) {
	i.Lock()
	defer i.Unlock()
	delete(i.peers, peer.String())

	// Disconnect any pipelines
	n := len(i.pipelines)
	for idx := 0; idx < n; idx++ {
		if i.pipelines[idx].peerAddr == peer.String() {
			i.pipelines[idx].Close()
			i.pipelines[idx], i.pipelines[n-1] = i.pipelines[n-1], nil
			idx--
			n--
		}
	}
	i.pipelines = i.pipelines[:n]
}

// DisconnectAll is used to remove all routes to peers.
func (i *InmemTransport) DisconnectAll() {
	i.Lock()
	defer i.Unlock()
	i.peers = make(map[string]*InmemTransport)

	// Handle pipelines
	for _, pipeline := range i.pipelines {
		pipeline.Close()
	}
	i.pipelines = nil
}

func newInmemPipeline(trans *InmemTransport, peer *InmemTransport, addr string) *inmemPipeline {
	i := &inmemPipeline{
		trans:        trans,
		peer:         peer,
		peerAddr:     addr,
		doneCh:       make(chan AppendFuture, 16),
		inprogressCh: make(chan *inmemPipelineInflight, 16),
		shutdownCh:   make(chan struct{}),
	}
	go i.decodeResponses()
	return i
}

func (i *inmemPipeline) decodeResponses() {
	timeout := i.trans.timeout
	for {
		select {
		case inp := <-i.inprogressCh:
			var timeoutCh <-chan time.Time
			if timeout > 0 {
				timeoutCh = time.After(timeout)
			}

			select {
			case rpcResp := <-inp.respCh:
				// Copy the result back
				*inp.future.resp = *rpcResp.Response.(*AppendEntriesResponse)
				inp.future.respond(rpcResp.Error)

				select {
				case i.doneCh <- inp.future:
				case <-i.shutdownCh:
					return
				}

			case <-timeoutCh:
				inp.future.respond(fmt.Errorf("command timed out"))
				select {
				case i.doneCh <- inp.future:
				case <-i.shutdownCh:
					return
				}

			case <-i.shutdownCh:
				return
			}
		case <-i.shutdownCh:
			return
		}
	}
}

func (i *inmemPipeline) AppendEntries(args *AppendEntriesRequest, resp *AppendEntriesResponse) (AppendFuture, error) {
	// Create a new future
	future := &appendFuture{
		start: time.Now(),
		args:  args,
		resp:  resp,
	}
	future.init()

	// Handle a timeout
	var timeout <-chan time.Time
	if i.trans.timeout > 0 {
		timeout = time.After(i.trans.timeout)
	}

	// Send the RPC over
	respCh := make(chan RPCResponse, 1)
	rpc := RPC{
		Command:  args,
		RespChan: respCh,
	}
	select {
	case i.peer.consumerCh <- rpc:
	case <-timeout:
		return nil, fmt.Errorf("command enqueue timeout")
	case <-i.shutdownCh:
		return nil, ErrPipelineShutdown
	}

	// Send to be decoded
	select {
	case i.inprogressCh <- &inmemPipelineInflight{future, respCh}:
		return future, nil
	case <-i.shutdownCh:
		return nil, ErrPipelineShutdown
	}
}

func (i *inmemPipeline) Consumer() <-chan AppendFuture {
	return i.doneCh
}

func (i *inmemPipeline) Close() error {
	i.shutdownLock.Lock()
	defer i.shutdownLock.Unlock()
	if i.shutdown {
		return nil
	}

	i.shutdown = true
	close(i.shutdownCh)
	return nil
}


<|start_filename|>Godeps/_workspace/src/github.com/socketplane/bonjour/echo.go<|end_filename|>
package bonjour

import (
	"errors"
	"fmt"
	"net"
	"strings"
	"time"

	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/socketplane/go-fastping"
)

type response struct {
	addr *net.IPAddr
	rtt  time.Duration
}

const (
	ECHO_REPLY = iota
	NO_REPLY
	ERROR
)

func echo(address string, ip *net.IP) (int, error) {
	p := fastping.NewPinger()
	p.Debug = false
	netProto := "ip4:icmp"
	if strings.Index(address, ":") != -1 {
		netProto = "ip6:ipv6-icmp"
	}
	ra, err := net.ResolveIPAddr(netProto, address)
	if err != nil {
		return ERROR, err
	}

	if ip != nil && ip.To4() != nil {
		p.ListenAddr, _ = net.ResolveIPAddr("ip4", ip.To4().String())
	}

	results := make(map[string]*response)
	results[ra.String()] = nil
	p.AddIPAddr(ra)

	onRecv, onIdle, onErr := make(chan *response), make(chan bool), make(chan int)

	p.OnRecv = func(addr *net.IPAddr, t time.Duration) {
		onRecv <- &response{addr: addr, rtt: t}
	}
	p.OnIdle = func() {
		onIdle <- true
	}

	p.OnErr = func(addr *net.IPAddr, t int) {
		onErr <- t
	}

	p.MaxRTT = time.Second
	go p.Run()

	ret := NO_REPLY
	select {
	case <-onRecv:
		ret = ECHO_REPLY
	case <-onIdle:
		ret = NO_REPLY
	case res := <-onErr:
		errId := fmt.Sprintf("%d", res)
		err = errors.New(errId)
		ret = ERROR
	}

	p.Stop()
	return ret, err
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/serf/serf/merge_delegate.go<|end_filename|>
package serf

import (
	"net"

	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/memberlist"
)

type MergeDelegate interface {
	NotifyMerge([]*Member) (cancel bool)
}

type mergeDelegate struct {
	serf *Serf
}

func (m *mergeDelegate) NotifyMerge(nodes []*memberlist.Node) (cancel bool) {
	members := make([]*Member, len(nodes))
	for idx, n := range nodes {
		members[idx] = &Member{
			Name:        n.Name,
			Addr:        net.IP(n.Addr),
			Port:        n.Port,
			Tags:        m.serf.decodeTags(n.Meta),
			Status:      StatusNone,
			ProtocolMin: n.PMin,
			ProtocolMax: n.PMax,
			ProtocolCur: n.PCur,
			DelegateMin: n.DMin,
			DelegateMax: n.DMax,
			DelegateCur: n.DCur,
		}
	}
	return m.serf.config.Merge.NotifyMerge(members)
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/command/rpc_test.go<|end_filename|>
package command

import (
	"flag"
	"os"
	"testing"
)

const (
	defaultRPC  = "127.0.0.1:8400"
	defaultHTTP = "127.0.0.1:8500"
)

type flagFunc func(f *flag.FlagSet) *string

func getParsedAddr(t *testing.T, addrType, cliVal, envVal string) string {
	var cliFlag, envVar string
	var fn flagFunc
	args := []string{}

	switch addrType {
	case "rpc":
		fn = RPCAddrFlag
		envVar = RPCAddrEnvName
		cliFlag = "-rpc-addr"
	case "http":
		fn = HTTPAddrFlag
		envVar = HTTPAddrEnvName
		cliFlag = "-http-addr"
	default:
		t.Fatalf("unknown address type %s", addrType)
	}

	if cliVal != "" {
		args = append(args, cliFlag+"="+cliVal)
	}

	os.Clearenv()
	if envVal != "" {
		os.Setenv(envVar, envVal)
	}

	cmdFlags := flag.NewFlagSet(addrType, flag.ContinueOnError)
	result := fn(cmdFlags)

	if err := cmdFlags.Parse(args); err != nil {
		t.Fatal("Parse error", err)
	}

	return *result
}

func TestAddrFlag_default(t *testing.T) {
	for a, def := range map[string]string{
		"rpc":  defaultRPC,
		"http": defaultHTTP,
	} {
		res := getParsedAddr(t, a, "", "")

		if res != def {
			t.Fatalf("Expected %s addr: %s, got: %s", def, res)
		}
	}
}

func TestAddrFlag_onlyEnv(t *testing.T) {
	envAddr := "4.4.4.4:1234"
	for _, a := range []string{"rpc", "http"} {
		res := getParsedAddr(t, a, "", envAddr)

		if res != envAddr {
			t.Fatalf("Expected %s addr: %s, got: %s", a, envAddr, res)
		}
	}
}

func TestAddrFlag_precedence(t *testing.T) {
	cliAddr := "8.8.8.8:8400"
	envAddr := "4.4.4.4:8400"
	for _, a := range []string{"rpc", "http"} {
		res := getParsedAddr(t, a, cliAddr, envAddr)

		if res != cliAddr {
			t.Fatalf("Expected %s addr: %s, got: %s", a, cliAddr, res)
		}
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/command/rpc.go<|end_filename|>
package command

import (
	"flag"
	"os"

	consulapi "github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/api"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/command/agent"
)

const (
	// RPCAddrEnvName defines an environment variable name which sets
	// an RPC address if there is no -rpc-addr specified.
	RPCAddrEnvName = "CONSUL_RPC_ADDR"

	// HTTPAddrEnvName defines an environment variable name which sets
	// the HTTP address if there is no -http-addr specified.
	HTTPAddrEnvName = "CONSUL_HTTP_ADDR"
)

// RPCAddrFlag returns a pointer to a string that will be populated
// when the given flagset is parsed with the RPC address of the Consul.
func RPCAddrFlag(f *flag.FlagSet) *string {
	defaultRPCAddr := os.Getenv(RPCAddrEnvName)
	if defaultRPCAddr == "" {
		defaultRPCAddr = "127.0.0.1:8400"
	}
	return f.String("rpc-addr", defaultRPCAddr,
		"RPC address of the Consul agent")
}

// RPCClient returns a new Consul RPC client with the given address.
func RPCClient(addr string) (*agent.RPCClient, error) {
	return agent.NewRPCClient(addr)
}

// HTTPAddrFlag returns a pointer to a string that will be populated
// when the given flagset is parsed with the HTTP address of the Consul.
func HTTPAddrFlag(f *flag.FlagSet) *string {
	defaultHTTPAddr := os.Getenv(HTTPAddrEnvName)
	if defaultHTTPAddr == "" {
		defaultHTTPAddr = "127.0.0.1:8500"
	}
	return f.String("http-addr", defaultHTTPAddr,
		"HTTP address of the Consul agent")
}

// HTTPClient returns a new Consul HTTP client with the given address.
func HTTPClient(addr string) (*consulapi.Client, error) {
	return HTTPClientDC(addr, "")
}

// HTTPClientDC returns a new Consul HTTP client with the given address and datacenter
func HTTPClientDC(addr, dc string) (*consulapi.Client, error) {
	conf := consulapi.DefaultConfig()
	if envAddr := os.Getenv(HTTPAddrEnvName); addr == "" && envAddr != "" {
		addr = envAddr
	}
	conf.Address = addr
	conf.Datacenter = dc
	return consulapi.NewClient(conf)
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/logutils/level.go<|end_filename|>
package logutils

import (
	"bytes"
	"io"
	"sync"
)

type LogLevel string

// LevelFilter is an io.Writer that can be used with a logger that
// will filter out log messages that aren't at least a certain level.
//
// Once the filter is in use somewhere, it is not safe to modify
// the structure.
type LevelFilter struct {
	// Levels is the list of log levels, in increasing order of
	// severity. Example might be: {"DEBUG", "WARN", "ERROR"}.
	Levels []LogLevel

	// MinLevel is the minimum level allowed through
	MinLevel LogLevel

	// The underlying io.Writer where log messages that pass the filter
	// will be set.
	Writer io.Writer

	badLevels map[LogLevel]struct{}
	once      sync.Once
}

// Check will check a given line if it would be included in the level
// filter.
func (f *LevelFilter) Check(line []byte) bool {
	f.once.Do(f.init)

	// Check for a log level
	var level LogLevel
	x := bytes.IndexByte(line, '[')
	if x >= 0 {
		y := bytes.IndexByte(line[x:], ']')
		if y >= 0 {
			level = LogLevel(line[x+1 : x+y])
		}
	}

	_, ok := f.badLevels[level]
	return !ok
}

func (f *LevelFilter) Write(p []byte) (n int, err error) {
	// Note in general that io.Writer can receive any byte sequence
	// to write, but the "log" package always guarantees that we only
	// get a single line. We use that as a slight optimization within
	// this method, assuming we're dealing with a single, complete line
	// of log data.

	if !f.Check(p) {
		return len(p), nil
	}

	return f.Writer.Write(p)
}

// SetMinLevel is used to update the minimum log level
func (f *LevelFilter) SetMinLevel(min LogLevel) {
	f.MinLevel = min
	f.init()
}

func (f *LevelFilter) init() {
	badLevels := make(map[LogLevel]struct{})
	for _, level := range f.Levels {
		if level == f.MinLevel {
			break
		}
		badLevels[level] = struct{}{}
	}
	f.badLevels = badLevels
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/hcl/json/y.go<|end_filename|>
//line parse.y:3
package json

import __yyfmt__ "fmt"

//line parse.y:5
import (
	"fmt"
	"strconv"

	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/hcl/hcl"
)

//line parse.y:15
type jsonSymType struct {
	yys     int
	f       float64
	num     int
	str     string
	obj     *hcl.Object
	objlist []*hcl.Object
}

const FLOAT = 57346
const NUMBER = 57347
const COLON = 57348
const COMMA = 57349
const IDENTIFIER = 57350
const EQUAL = 57351
const NEWLINE = 57352
const STRING = 57353
const LEFTBRACE = 57354
const RIGHTBRACE = 57355
const LEFTBRACKET = 57356
const RIGHTBRACKET = 57357
const TRUE = 57358
const FALSE = 57359
const NULL = 57360
const MINUS = 57361
const PERIOD = 57362
const EPLUS = 57363
const EMINUS = 57364

var jsonToknames = []string{
	"FLOAT",
	"NUMBER",
	"COLON",
	"COMMA",
	"IDENTIFIER",
	"EQUAL",
	"NEWLINE",
	"STRING",
	"LEFTBRACE",
	"RIGHTBRACE",
	"LEFTBRACKET",
	"RIGHTBRACKET",
	"TRUE",
	"FALSE",
	"NULL",
	"MINUS",
	"PERIOD",
	"EPLUS",
	"EMINUS",
}
var jsonStatenames = []string{}

const jsonEofCode = 1
const jsonErrCode = 2
const jsonMaxDepth = 200

//line parse.y:210

//line yacctab:1
var jsonExca = []int{
	-1, 1,
	1, -1,
	-2, 0,
}

const jsonNprod = 28
const jsonPrivate = 57344

var jsonTokenNames []string
var jsonStates []string

const jsonLast = 53

var jsonAct = []int{

	12, 25, 24, 3, 20, 27, 28, 7, 13, 3,
	21, 22, 30, 17, 18, 19, 23, 25, 24, 26,
	25, 24, 36, 32, 13, 3, 10, 22, 33, 17,
	18, 19, 23, 35, 34, 23, 38, 9, 7, 39,
	5, 29, 6, 8, 37, 15, 2, 1, 4, 31,
	16, 14, 11,
}
var jsonPact = []int{

	-9, -1000, -1000, 27, 30, -1000, -1000, 20, -1000, -4,
	13, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
	-16, -16, -3, 16, -1000, -1000, -1000, 28, 17, -1000,
	-1000, 29, -1000, -1000, -1000, -1000, -1000, -1000, 13, -1000,
}
var jsonPgo = []int{

	0, 10, 4, 51, 45, 42, 0, 50, 49, 48,
	19, 47,
}
var jsonR1 = []int{

	0, 11, 4, 4, 9, 9, 5, 6, 6, 6,
	6, 6, 6, 6, 7, 7, 8, 8, 3, 3,
	3, 3, 2, 2, 1, 1, 10, 10,
}
var jsonR2 = []int{

	0, 1, 3, 2, 1, 3, 3, 1, 1, 1,
	1, 1, 1, 1, 2, 3, 1, 3, 1, 1,
	2, 2, 2, 1, 2, 1, 2, 2,
}
var jsonChk = []int{

	-1000, -11, -4, 12, -9, 13, -5, 11, 13, 7,
	6, -5, -6, 11, -3, -4, -7, 16, 17, 18,
	-2, -1, 14, 19, 5, 4, -10, 21, 22, -10,
	15, -8, -6, -2, -1, 5, 5, 15, 7, -6,
}
var jsonDef = []int{

	0, -2, 1, 0, 0, 3, 4, 0, 2, 0,
	0, 5, 6, 7, 8, 9, 10, 11, 12, 13,
	18, 19, 0, 0, 23, 25, 20, 0, 0, 21,
	14, 0, 16, 22, 24, 26, 27, 15, 0, 17,
}
var jsonTok1 = []int{

	1,
}
var jsonTok2 = []int{

	2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
	12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
	22,
}
var jsonTok3 = []int{
	0,
}

//line yaccpar:1

/*	parser for yacc output	*/

var jsonDebug = 0

type jsonLexer interface {
	Lex(lval *jsonSymType) int
	Error(s string)
}

const jsonFlag = -1000

func jsonTokname(c int) string {
	// 4 is TOKSTART above
	if c >= 4 && c-4 < len(jsonToknames) {
		if jsonToknames[c-4] != "" {
			return jsonToknames[c-4]
		}
	}
	return __yyfmt__.Sprintf("tok-%v", c)
}

func jsonStatname(s int) string {
	if s >= 0 && s < len(jsonStatenames) {
		if jsonStatenames[s] != "" {
			return jsonStatenames[s]
		}
	}
	return __yyfmt__.Sprintf("state-%v", s)
}

func jsonlex1(lex jsonLexer, lval *jsonSymType) int {
	c := 0
	char := lex.Lex(lval)
	if char <= 0 {
		c = jsonTok1[0]
		goto out
	}
	if char < len(jsonTok1) {
		c = jsonTok1[char]
		goto out
	}
	if char >= jsonPrivate {
		if char < jsonPrivate+len(jsonTok2) {
			c = jsonTok2[char-jsonPrivate]
			goto out
		}
	}
	for i := 0; i < len(jsonTok3); i += 2 {
		c = jsonTok3[i+0]
		if c == char {
			c = jsonTok3[i+1]
			goto out
		}
	}

out:
	if c == 0 {
		c = jsonTok2[1] /* unknown char */
	}
	if jsonDebug >= 3 {
		__yyfmt__.Printf("lex %s(%d)\n", jsonTokname(c), uint(char))
	}
	return c
}

func jsonParse(jsonlex jsonLexer) int {
	var jsonn int
	var jsonlval jsonSymType
	var jsonVAL jsonSymType
	jsonS := make([]jsonSymType, jsonMaxDepth)

	Nerrs := 0   /* number of errors */
	Errflag := 0 /* error recovery flag */
	jsonstate := 0
	jsonchar := -1
	jsonp := -1
	goto jsonstack

ret0:
	return 0

ret1:
	return 1

jsonstack:
	/* put a state and value onto the stack */
	if jsonDebug >= 4 {
		__yyfmt__.Printf("char %v in %v\n", jsonTokname(jsonchar), jsonStatname(jsonstate))
	}

	jsonp++
	if jsonp >= len(jsonS) {
		nyys := make([]jsonSymType, len(jsonS)*2)
		copy(nyys, jsonS)
		jsonS = nyys
	}
	jsonS[jsonp] = jsonVAL
	jsonS[jsonp].yys = jsonstate

jsonnewstate:
	jsonn = jsonPact[jsonstate]
	if jsonn <= jsonFlag {
		goto jsondefault /* simple state */
	}
	if jsonchar < 0 {
		jsonchar = jsonlex1(jsonlex, &jsonlval)
	}
	jsonn += jsonchar
	if jsonn < 0 || jsonn >= jsonLast {
		goto jsondefault
	}
	jsonn = jsonAct[jsonn]
	if jsonChk[jsonn] == jsonchar { /* valid shift */
		jsonchar = -1
		jsonVAL = jsonlval
		jsonstate = jsonn
		if Errflag > 0 {
			Errflag--
		}
		goto jsonstack
	}

jsondefault:
	/* default state action */
	jsonn = jsonDef[jsonstate]
	if jsonn == -2 {
		if jsonchar < 0 {
			jsonchar = jsonlex1(jsonlex, &jsonlval)
		}

		/* look through exception table */
		xi := 0
		for {
			if jsonExca[xi+0] == -1 && jsonExca[xi+1] == jsonstate {
				break
			}
			xi += 2
		}
		for xi += 2; ; xi += 2 {
			jsonn = jsonExca[xi+0]
			if jsonn < 0 || jsonn == jsonchar {
				break
			}
		}
		jsonn = jsonExca[xi+1]
		if jsonn < 0 {
			goto ret0
		}
	}
	if jsonn == 0 {
		/* error ... attempt to resume parsing */
		switch Errflag {
		case 0: /* brand new error */
			jsonlex.Error("syntax error")
			Nerrs++
			if jsonDebug >= 1 {
				__yyfmt__.Printf("%s", jsonStatname(jsonstate))
				__yyfmt__.Printf(" saw %s\n", jsonTokname(jsonchar))
			}
			fallthrough

		case 1, 2: /* incompletely recovered error ... try again */
			Errflag = 3

			/* find a state where "error" is a legal shift action */
			for jsonp >= 0 {
				jsonn = jsonPact[jsonS[jsonp].yys] + jsonErrCode
				if jsonn >= 0 && jsonn < jsonLast {
					jsonstate = jsonAct[jsonn] /* simulate a shift of "error" */
					if jsonChk[jsonstate] == jsonErrCode {
						goto jsonstack
					}
				}

				/* the current p has no shift on "error", pop stack */
				if jsonDebug >= 2 {
					__yyfmt__.Printf("error recovery pops state %d\n", jsonS[jsonp].yys)
				}
				jsonp--
			}
			/* there is no state on the stack with an error shift ... abort */
			goto ret1

		case 3: /* no shift yet; clobber input char */
			if jsonDebug >= 2 {
				__yyfmt__.Printf("error recovery discards %s\n", jsonTokname(jsonchar))
			}
			if jsonchar == jsonEofCode {
				goto ret1
			}
			jsonchar = -1
			goto jsonnewstate /* try again in the same state */
		}
	}

	/* reduction by production jsonn */
	if jsonDebug >= 2 {
		__yyfmt__.Printf("reduce %v in:\n\t%v\n", jsonn, jsonStatname(jsonstate))
	}

	jsonnt := jsonn
	jsonpt := jsonp
	_ = jsonpt // guard against "declared and not used"

	jsonp -= jsonR2[jsonn]
	jsonVAL = jsonS[jsonp+1]

	/* consult goto table to find next state */
	jsonn = jsonR1[jsonn]
	jsong := jsonPgo[jsonn]
	jsonj := jsong + jsonS[jsonp].yys + 1

	if jsonj >= jsonLast {
		jsonstate = jsonAct[jsong]
	} else {
		jsonstate = jsonAct[jsonj]
		if jsonChk[jsonstate] != -jsonn {
			jsonstate = jsonAct[jsong]
		}
	}
	// dummy call; replaced with literal code
	switch jsonnt {

	case 1:
		//line parse.y:39
		{
			jsonResult = jsonS[jsonpt-0].obj
		}
	case 2:
		//line parse.y:45
		{
			jsonVAL.obj = &hcl.Object{
				Type:  hcl.ValueTypeObject,
				Value: hcl.ObjectList(jsonS[jsonpt-1].objlist).Flat(),
			}
		}
	case 3:
		//line parse.y:52
		{
			jsonVAL.obj = &hcl.Object{Type: hcl.ValueTypeObject}
		}
	case 4:
		//line parse.y:58
		{
			jsonVAL.objlist = []*hcl.Object{jsonS[jsonpt-0].obj}
		}
	case 5:
		//line parse.y:62
		{
			jsonVAL.objlist = append(jsonS[jsonpt-2].objlist, jsonS[jsonpt-0].obj)
		}
	case 6:
		//line parse.y:68
		{
			jsonS[jsonpt-0].obj.Key = jsonS[jsonpt-2].str
			jsonVAL.obj = jsonS[jsonpt-0].obj
		}
	case 7:
		//line parse.y:75
		{
			jsonVAL.obj = &hcl.Object{
				Type:  hcl.ValueTypeString,
				Value: jsonS[jsonpt-0].str,
			}
		}
	case 8:
		//line parse.y:82
		{
			jsonVAL.obj = jsonS[jsonpt-0].obj
		}
	case 9:
		//line parse.y:86
		{
			jsonVAL.obj = jsonS[jsonpt-0].obj
		}
	case 10:
		//line parse.y:90
		{
			jsonVAL.obj = &hcl.Object{
				Type:  hcl.ValueTypeList,
				Value: jsonS[jsonpt-0].objlist,
			}
		}
	case 11:
		//line parse.y:97
		{
			jsonVAL.obj = &hcl.Object{
				Type:  hcl.ValueTypeBool,
				Value: true,
			}
		}
	case 12:
		//line parse.y:104
		{
			jsonVAL.obj = &hcl.Object{
				Type:  hcl.ValueTypeBool,
				Value: false,
			}
		}
	case 13:
		//line parse.y:111
		{
			jsonVAL.obj = &hcl.Object{
				Type:  hcl.ValueTypeNil,
				Value: nil,
			}
		}
	case 14:
		//line parse.y:120
		{
			jsonVAL.objlist = nil
		}
	case 15:
		//line parse.y:124
		{
			jsonVAL.objlist = jsonS[jsonpt-1].objlist
		}
	case 16:
		//line parse.y:130
		{
			jsonVAL.objlist = []*hcl.Object{jsonS[jsonpt-0].obj}
		}
	case 17:
		//line parse.y:134
		{
			jsonVAL.objlist = append(jsonS[jsonpt-2].objlist, jsonS[jsonpt-0].obj)
		}
	case 18:
		//line parse.y:140
		{
			jsonVAL.obj = &hcl.Object{
				Type:  hcl.ValueTypeInt,
				Value: jsonS[jsonpt-0].num,
			}
		}
	case 19:
		//line parse.y:147
		{
			jsonVAL.obj = &hcl.Object{
				Type:  hcl.ValueTypeFloat,
				Value: jsonS[jsonpt-0].f,
			}
		}
	case 20:
		//line parse.y:154
		{
			fs := fmt.Sprintf("%d%s", jsonS[jsonpt-1].num, jsonS[jsonpt-0].str)
			f, err := strconv.ParseFloat(fs, 64)
			if err != nil {
				panic(err)
			}

			jsonVAL.obj = &hcl.Object{
				Type:  hcl.ValueTypeFloat,
				Value: f,
			}
		}
	case 21:
		//line parse.y:167
		{
			fs := fmt.Sprintf("%f%s", jsonS[jsonpt-1].f, jsonS[jsonpt-0].str)
			f, err := strconv.ParseFloat(fs, 64)
			if err != nil {
				panic(err)
			}

			jsonVAL.obj = &hcl.Object{
				Type:  hcl.ValueTypeFloat,
				Value: f,
			}
		}
	case 22:
		//line parse.y:182
		{
			jsonVAL.num = jsonS[jsonpt-0].num * -1
		}
	case 23:
		//line parse.y:186
		{
			jsonVAL.num = jsonS[jsonpt-0].num
		}
	case 24:
		//line parse.y:192
		{
			jsonVAL.f = jsonS[jsonpt-0].f * -1
		}
	case 25:
		//line parse.y:196
		{
			jsonVAL.f = jsonS[jsonpt-0].f
		}
	case 26:
		//line parse.y:202
		{
			jsonVAL.str = "e" + strconv.FormatInt(int64(jsonS[jsonpt-0].num), 10)
		}
	case 27:
		//line parse.y:206
		{
			jsonVAL.str = "e-" + strconv.FormatInt(int64(jsonS[jsonpt-0].num), 10)
		}
	}
	goto jsonstack /* stack new state and value */
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/api/api_test.go<|end_filename|>
package api

import (
	crand "crypto/rand"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"testing"
	"time"

	"github.com/hashicorp/consul/testutil"
)

type testServer struct {
	pid        int
	dataDir    string
	configFile string
}

type testPortConfig struct {
	DNS     int `json:"dns,omitempty"`
	HTTP    int `json:"http,omitempty"`
	RPC     int `json:"rpc,omitempty"`
	SerfLan int `json:"serf_lan,omitempty"`
	SerfWan int `json:"serf_wan,omitempty"`
	Server  int `json:"server,omitempty"`
}

type testAddressConfig struct {
	HTTP string `json:"http,omitempty"`
}

type testServerConfig struct {
	Bootstrap bool               `json:"bootstrap,omitempty"`
	Server    bool               `json:"server,omitempty"`
	DataDir   string             `json:"data_dir,omitempty"`
	LogLevel  string             `json:"log_level,omitempty"`
	Addresses *testAddressConfig `json:"addresses,omitempty"`
	Ports     testPortConfig     `json:"ports,omitempty"`
}

// Callback functions for modifying config
type configCallback func(c *Config)
type serverConfigCallback func(c *testServerConfig)

func defaultConfig() *testServerConfig {
	return &testServerConfig{
		Bootstrap: true,
		Server:    true,
		LogLevel:  "debug",
		Ports: testPortConfig{
			DNS:     19000,
			HTTP:    18800,
			RPC:     18600,
			SerfLan: 18200,
			SerfWan: 18400,
			Server:  18000,
		},
	}
}

func (s *testServer) stop() {
	defer os.RemoveAll(s.dataDir)
	defer os.RemoveAll(s.configFile)

	cmd := exec.Command("kill", "-9", fmt.Sprintf("%d", s.pid))
	if err := cmd.Run(); err != nil {
		panic(err)
	}
}

func newTestServer(t *testing.T) *testServer {
	return newTestServerWithConfig(t, func(c *testServerConfig) {})
}

func newTestServerWithConfig(t *testing.T, cb serverConfigCallback) *testServer {
	if path, err := exec.LookPath("consul"); err != nil || path == "" {
		t.Log("consul not found on $PATH, skipping")
		t.SkipNow()
	}

	pidFile, err := ioutil.TempFile("", "consul")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	pidFile.Close()
	os.Remove(pidFile.Name())

	dataDir, err := ioutil.TempDir("", "consul")
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	configFile, err := ioutil.TempFile("", "consul")
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	consulConfig := defaultConfig()
	consulConfig.DataDir = dataDir

	cb(consulConfig)

	configContent, err := json.Marshal(consulConfig)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	if _, err := configFile.Write(configContent); err != nil {
		t.Fatalf("err: %s", err)
	}
	configFile.Close()

	// Start the server
	cmd := exec.Command("consul", "agent", "-config-file", configFile.Name())
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Start(); err != nil {
		t.Fatalf("err: %s", err)
	}

	return &testServer{
		pid:        cmd.Process.Pid,
		dataDir:    dataDir,
		configFile: configFile.Name(),
	}
}

func makeClient(t *testing.T) (*Client, *testServer) {
	return makeClientWithConfig(t, func(c *Config) {
		c.Address = "127.0.0.1:18800"
	}, func(c *testServerConfig) {})
}

func makeClientWithConfig(t *testing.T, cb1 configCallback, cb2 serverConfigCallback) (*Client, *testServer) {
	// Make client config
	conf := DefaultConfig()
	cb1(conf)

	// Create client
	client, err := NewClient(conf)
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	// Create server
	server := newTestServerWithConfig(t, cb2)

	// Allow the server some time to start, and verify we have a leader.
	testutil.WaitForResult(func() (bool, error) {
		req := client.newRequest("GET", "/v1/catalog/nodes")
		_, resp, err := client.doRequest(req)
		if err != nil {
			return false, err
		}
		resp.Body.Close()

		// Ensure we have a leader and a node registeration
		if leader := resp.Header.Get("X-Consul-KnownLeader"); leader != "true" {
			return false, fmt.Errorf("Consul leader status: %#v", leader)
		}
		if resp.Header.Get("X-Consul-Index") == "0" {
			return false, fmt.Errorf("Consul index is 0")
		}

		return true, nil
	}, func(err error) {
		t.Fatalf("err: %s", err)
	})

	return client, server
}

func testKey() string {
	buf := make([]byte, 16)
	if _, err := crand.Read(buf); err != nil {
		panic(fmt.Errorf("Failed to read random bytes: %v", err))
	}

	return fmt.Sprintf("%08x-%04x-%04x-%04x-%12x",
		buf[0:4],
		buf[4:6],
		buf[6:8],
		buf[8:10],
		buf[10:16])
}

func TestSetQueryOptions(t *testing.T) {
	c, s := makeClient(t)
	defer s.stop()

	r := c.newRequest("GET", "/v1/kv/foo")
	q := &QueryOptions{
		Datacenter:        "foo",
		AllowStale:        true,
		RequireConsistent: true,
		WaitIndex:         1000,
		WaitTime:          100 * time.Second,
		Token:             "<PASSWORD>",
	}
	r.setQueryOptions(q)

	if r.params.Get("dc") != "foo" {
		t.Fatalf("bad: %v", r.params)
	}
	if _, ok := r.params["stale"]; !ok {
		t.Fatalf("bad: %v", r.params)
	}
	if _, ok := r.params["consistent"]; !ok {
		t.Fatalf("bad: %v", r.params)
	}
	if r.params.Get("index") != "1000" {
		t.Fatalf("bad: %v", r.params)
	}
	if r.params.Get("wait") != "100000ms" {
		t.Fatalf("bad: %v", r.params)
	}
	if r.params.Get("token") != "<PASSWORD>" {
		t.Fatalf("bad: %v", r.params)
	}
}

func TestSetWriteOptions(t *testing.T) {
	c, s := makeClient(t)
	defer s.stop()

	r := c.newRequest("GET", "/v1/kv/foo")
	q := &WriteOptions{
		Datacenter: "foo",
		Token:      "<PASSWORD>",
	}
	r.setWriteOptions(q)

	if r.params.Get("dc") != "foo" {
		t.Fatalf("bad: %v", r.params)
	}
	if r.params.Get("token") != "<PASSWORD>" {
		t.Fatalf("bad: %v", r.params)
	}
}

func TestRequestToHTTP(t *testing.T) {
	c, s := makeClient(t)
	defer s.stop()

	r := c.newRequest("DELETE", "/v1/kv/foo")
	q := &QueryOptions{
		Datacenter: "foo",
	}
	r.setQueryOptions(q)
	req, err := r.toHTTP()
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if req.Method != "DELETE" {
		t.Fatalf("bad: %v", req)
	}
	if req.URL.RequestURI() != "/v1/kv/foo?dc=foo" {
		t.Fatalf("bad: %v", req)
	}
}

func TestParseQueryMeta(t *testing.T) {
	resp := &http.Response{
		Header: make(map[string][]string),
	}
	resp.Header.Set("X-Consul-Index", "12345")
	resp.Header.Set("X-Consul-LastContact", "80")
	resp.Header.Set("X-Consul-KnownLeader", "true")

	qm := &QueryMeta{}
	if err := parseQueryMeta(resp, qm); err != nil {
		t.Fatalf("err: %v", err)
	}

	if qm.LastIndex != 12345 {
		t.Fatalf("Bad: %v", qm)
	}
	if qm.LastContact != 80*time.Millisecond {
		t.Fatalf("Bad: %v", qm)
	}
	if !qm.KnownLeader {
		t.Fatalf("Bad: %v", qm)
	}
}

func TestAPI_UnixSocket(t *testing.T) {
	if runtime.GOOS == "windows" {
		t.SkipNow()
	}

	tempDir, err := ioutil.TempDir("", "consul")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer os.RemoveAll(tempDir)
	socket := filepath.Join(tempDir, "test.sock")

	c, s := makeClientWithConfig(t, func(c *Config) {
		c.Address = "unix://" + socket
	}, func(c *testServerConfig) {
		c.Addresses = &testAddressConfig{
			HTTP: "unix://" + socket,
		}
	})
	defer s.stop()

	agent := c.Agent()

	info, err := agent.Self()
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	if info["Config"]["NodeName"] == "" {
		t.Fatalf("bad: %v", info)
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/armon/gomdb/env.go<|end_filename|>
package mdb

/*
#cgo freebsd CFLAGS: -DMDB_DSYNC=O_SYNC
#cgo openbsd CFLAGS: -DMDB_DSYNC=O_SYNC
#cgo netbsd CFLAGS: -DMDB_DSYNC=O_SYNC
#include <stdlib.h>
#include <stdio.h>
#include "lmdb.h"
*/
import "C"

import (
	"errors"
	"unsafe"
)

const (
	SUCCESS = 0
)

// mdb_env Environment Flags
const (
	FIXEDMAP   = C.MDB_FIXEDMAP   // mmap at a fixed address (experimental)
	NOSUBDIR   = C.MDB_NOSUBDIR   // no environment directory
	NOSYNC     = C.MDB_NOSYNC     // don't fsync after commit
	RDONLY     = C.MDB_RDONLY     // read only
	NOMETASYNC = C.MDB_NOMETASYNC // don't fsync metapage after commit
	WRITEMAP   = C.MDB_WRITEMAP   // use writable mmap
	MAPASYNC   = C.MDB_MAPASYNC   // use asynchronous msync when MDB_WRITEMAP is use
	NOTLS      = C.MDB_NOTLS      // tie reader locktable slots to Txn objects instead of threads
)

type DBI uint
type Errno int

func (e Errno) Error() string {
	return C.GoString(C.mdb_strerror(C.int(e)))
}

// error codes
var (
	KeyExist        error = Errno(-30799)
	NotFound        error = Errno(-30798)
	PageNotFound    error = Errno(-30797)
	Corrupted       error = Errno(-30796)
	Panic           error = Errno(-30795)
	VersionMismatch error = Errno(-30794)
	Invalid         error = Errno(-30793)
	MapFull         error = Errno(-30792)
	DbsFull         error = Errno(-30791)
	ReadersFull     error = Errno(-30790)
	TlsFull         error = Errno(-30789)
	TxnFull         error = Errno(-30788)
	CursorFull      error = Errno(-30787)
	PageFull        error = Errno(-30786)
	MapResized      error = Errno(-30785)
	Incompatibile   error = Errno(-30784)
)

func Version() string {
	var major, minor, patch *C.int
	ver_str := C.mdb_version(major, minor, patch)
	return C.GoString(ver_str)
}

// Env is opaque structure for a database environment.
// A DB environment supports multiple databases, all residing in the
// same shared-memory map.
type Env struct {
	_env *C.MDB_env
}

// Create an MDB environment handle.
func NewEnv() (*Env, error) {
	var _env *C.MDB_env
	ret := C.mdb_env_create(&_env)
	if ret != SUCCESS {
		return nil, Errno(ret)
	}
	return &Env{_env}, nil
}

// Open an environment handle. If this function fails Close() must be called to discard the Env handle.
func (env *Env) Open(path string, flags uint, mode uint) error {
	cpath := C.CString(path)
	defer C.free(unsafe.Pointer(cpath))
	ret := C.mdb_env_open(env._env, cpath, C.uint(NOTLS|flags), C.mdb_mode_t(mode))
	if ret != SUCCESS {
		return Errno(ret)
	}
	return nil
}

func (env *Env) Close() error {
	if env._env == nil {
		return errors.New("Environment already closed")
	}
	C.mdb_env_close(env._env)
	env._env = nil
	return nil
}

func (env *Env) Copy(path string) error {
	cpath := C.CString(path)
	defer C.free(unsafe.Pointer(cpath))
	ret := C.mdb_env_copy(env._env, cpath)
	if ret != SUCCESS {
		return Errno(ret)
	}
	return nil
}

// Statistics for a database in the environment
type Stat struct {
	PSize         uint   // Size of a database page. This is currently the same for all databases.
	Depth         uint   // Depth (height) of the B-tree
	BranchPages   uint64 // Number of internal (non-leaf) pages
	LeafPages     uint64 // Number of leaf pages
	OwerflowPages uint64 // Number of overflow pages
	Entries       uint64 // Number of data items
}

func (env *Env) Stat() (*Stat, error) {
	var _stat C.MDB_stat
	ret := C.mdb_env_stat(env._env, &_stat)
	if ret != SUCCESS {
		return nil, Errno(ret)
	}
	stat := Stat{PSize: uint(_stat.ms_psize),
		Depth:         uint(_stat.ms_depth),
		BranchPages:   uint64(_stat.ms_branch_pages),
		LeafPages:     uint64(_stat.ms_leaf_pages),
		OwerflowPages: uint64(_stat.ms_overflow_pages),
		Entries:       uint64(_stat.ms_entries)}
	return &stat, nil
}

type Info struct {
	MapSize    uint64 // Size of the data memory map
	LastPNO    uint64 // ID of the last used page
	LastTxnID  uint64 // ID of the last committed transaction
	MaxReaders uint   // maximum number of threads for the environment
	NumReaders uint   // maximum number of threads used in the environment
}

func (env *Env) Info() (*Info, error) {
	var _info C.MDB_envinfo
	ret := C.mdb_env_info(env._env, &_info)
	if ret != SUCCESS {
		return nil, Errno(ret)
	}
	info := Info{MapSize: uint64(_info.me_mapsize),
		LastPNO:    uint64(_info.me_last_pgno),
		LastTxnID:  uint64(_info.me_last_txnid),
		MaxReaders: uint(_info.me_maxreaders),
		NumReaders: uint(_info.me_numreaders)}
	return &info, nil
}

func (env *Env) Sync(force int) error {
	ret := C.mdb_env_sync(env._env, C.int(force))
	if ret != SUCCESS {
		return Errno(ret)
	}
	return nil
}

func (env *Env) SetFlags(flags uint, onoff int) error {
	ret := C.mdb_env_set_flags(env._env, C.uint(flags), C.int(onoff))
	if ret != SUCCESS {
		return Errno(ret)
	}
	return nil
}

func (env *Env) Flags() (uint, error) {
	var _flags C.uint
	ret := C.mdb_env_get_flags(env._env, &_flags)
	if ret != SUCCESS {
		return 0, Errno(ret)
	}
	return uint(_flags), nil
}

func (env *Env) Path() (string, error) {
	var path string
	cpath := C.CString(path)
	defer C.free(unsafe.Pointer(cpath))
	ret := C.mdb_env_get_path(env._env, &cpath)
	if ret != SUCCESS {
		return "", Errno(ret)
	}
	return C.GoString(cpath), nil
}

func (env *Env) SetMapSize(size uint64) error {
	ret := C.mdb_env_set_mapsize(env._env, C.size_t(size))
	if ret != SUCCESS {
		return Errno(ret)
	}
	return nil
}

func (env *Env) SetMaxReaders(size uint) error {
	ret := C.mdb_env_set_maxreaders(env._env, C.uint(size))
	if ret != SUCCESS {
		return Errno(ret)
	}
	return nil
}

func (env *Env) SetMaxDBs(size DBI) error {
	ret := C.mdb_env_set_maxdbs(env._env, C.MDB_dbi(size))
	if ret != SUCCESS {
		return Errno(ret)
	}
	return nil
}

func (env *Env) DBIClose(dbi DBI) {
	C.mdb_dbi_close(env._env, C.MDB_dbi(dbi))
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/acl/policy_test.go<|end_filename|>
package acl

import (
	"reflect"
	"testing"
)

func TestParse(t *testing.T) {
	inp := `
key "" {
	policy = "read"
}
key "foo/" {
	policy = "write"
}
key "foo/bar/" {
	policy = "read"
}
key "foo/bar/baz" {
	policy = "deny"
}
service "" {
	policy = "write"
}
service "foo" {
	policy = "read"
}
	`
	exp := &Policy{
		Keys: []*KeyPolicy{
			&KeyPolicy{
				Prefix: "",
				Policy: KeyPolicyRead,
			},
			&KeyPolicy{
				Prefix: "foo/",
				Policy: KeyPolicyWrite,
			},
			&KeyPolicy{
				Prefix: "foo/bar/",
				Policy: KeyPolicyRead,
			},
			&KeyPolicy{
				Prefix: "foo/bar/baz",
				Policy: KeyPolicyDeny,
			},
		},
		Services: []*ServicePolicy{
			&ServicePolicy{
				Name:   "",
				Policy: ServicePolicyWrite,
			},
			&ServicePolicy{
				Name:   "foo",
				Policy: ServicePolicyRead,
			},
		},
	}

	out, err := Parse(inp)
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if !reflect.DeepEqual(out, exp) {
		t.Fatalf("bad: %#v %#v", out, exp)
	}
}

func TestParse_JSON(t *testing.T) {
	inp := `{
	"key": {
		"": {
			"policy": "read"
		},
		"foo/": {
			"policy": "write"
		},
		"foo/bar/": {
			"policy": "read"
		},
		"foo/bar/baz": {
			"policy": "deny"
		}
	},
	"service": {
		"": {
			"policy": "write"
		},
		"foo": {
			"policy": "read"
		}
	}
}`
	exp := &Policy{
		Keys: []*KeyPolicy{
			&KeyPolicy{
				Prefix: "",
				Policy: KeyPolicyRead,
			},
			&KeyPolicy{
				Prefix: "foo/",
				Policy: KeyPolicyWrite,
			},
			&KeyPolicy{
				Prefix: "foo/bar/",
				Policy: KeyPolicyRead,
			},
			&KeyPolicy{
				Prefix: "foo/bar/baz",
				Policy: KeyPolicyDeny,
			},
		},
		Services: []*ServicePolicy{
			&ServicePolicy{
				Name:   "",
				Policy: ServicePolicyWrite,
			},
			&ServicePolicy{
				Name:   "foo",
				Policy: ServicePolicyRead,
			},
		},
	}

	out, err := Parse(inp)
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if !reflect.DeepEqual(out, exp) {
		t.Fatalf("bad: %#v %#v", out, exp)
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/socketplane/bonjour/Godeps/Godeps/Godeps.json<|end_filename|>
{
	"ImportPath": "github.com/socketplane/bonjour/Godeps",
	"GoVersion": "go1.2.1",
	"Packages": [
		"./..."
	],
	"Deps": []
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/raft/inflight_test.go<|end_filename|>
package raft

import (
	"fmt"
	"testing"
)

func TestInflight_StartCommit(t *testing.T) {
	commitCh := make(chan struct{}, 1)
	in := newInflight(commitCh)

	// Commit a transaction as being in flight
	l := &logFuture{log: Log{Index: 1}}
	l.policy = newMajorityQuorum(5)
	in.Start(l)

	// Commit 3 times
	in.Commit(1)
	if in.Committed().Len() != 0 {
		t.Fatalf("should not be commited")
	}

	in.Commit(1)
	if in.Committed().Len() != 1 {
		t.Fatalf("should be commited")
	}

	// Already commited but should work anyways
	in.Commit(1)
}

func TestInflight_Cancel(t *testing.T) {
	commitCh := make(chan struct{}, 1)
	in := newInflight(commitCh)

	// Commit a transaction as being in flight
	l := &logFuture{
		log: Log{Index: 1},
	}
	l.init()
	l.policy = newMajorityQuorum(3)
	in.Start(l)

	// Cancel with an error
	err := fmt.Errorf("error 1")
	in.Cancel(err)

	// Should get an error return
	if l.Error() != err {
		t.Fatalf("expected error")
	}
}

func TestInflight_StartAll(t *testing.T) {
	commitCh := make(chan struct{}, 1)
	in := newInflight(commitCh)

	// Commit a few transaction as being in flight
	l1 := &logFuture{log: Log{Index: 2}}
	l1.policy = newMajorityQuorum(5)
	l2 := &logFuture{log: Log{Index: 3}}
	l2.policy = newMajorityQuorum(5)
	l3 := &logFuture{log: Log{Index: 4}}
	l3.policy = newMajorityQuorum(5)

	// Start all the entries
	in.StartAll([]*logFuture{l1, l2, l3})

	// Commit ranges
	in.CommitRange(1, 5)
	in.CommitRange(1, 4)
	in.CommitRange(1, 10)

	// Should get 3 back
	if in.Committed().Len() != 3 {
		t.Fatalf("expected all 3 to commit")
	}
}

func TestInflight_CommitRange(t *testing.T) {
	commitCh := make(chan struct{}, 1)
	in := newInflight(commitCh)

	// Commit a few transaction as being in flight
	l1 := &logFuture{log: Log{Index: 2}}
	l1.policy = newMajorityQuorum(5)
	in.Start(l1)

	l2 := &logFuture{log: Log{Index: 3}}
	l2.policy = newMajorityQuorum(5)
	in.Start(l2)

	l3 := &logFuture{log: Log{Index: 4}}
	l3.policy = newMajorityQuorum(5)
	in.Start(l3)

	// Commit ranges
	in.CommitRange(1, 5)
	in.CommitRange(1, 4)
	in.CommitRange(1, 10)

	// Should get 3 back
	if in.Committed().Len() != 3 {
		t.Fatalf("expected all 3 to commit")
	}
}

// Should panic if we commit non contiguously!
func TestInflight_NonContiguous(t *testing.T) {
	commitCh := make(chan struct{}, 1)
	in := newInflight(commitCh)

	// Commit a few transaction as being in flight
	l1 := &logFuture{log: Log{Index: 2}}
	l1.policy = newMajorityQuorum(5)
	in.Start(l1)

	l2 := &logFuture{log: Log{Index: 3}}
	l2.policy = newMajorityQuorum(5)
	in.Start(l2)

	in.Commit(3)
	in.Commit(3)
	in.Commit(3) // panic!

	if in.Committed().Len() != 0 {
		t.Fatalf("should not commit")
	}

	in.Commit(2)
	in.Commit(2)
	in.Commit(2) // panic!

	committed := in.Committed()
	if committed.Len() != 2 {
		t.Fatalf("should commit both")
	}

	current := committed.Front()
	l := current.Value.(*logFuture)
	if l.log.Index != 2 {
		t.Fatalf("bad: %v", *l)
	}

	current = current.Next()
	l = current.Value.(*logFuture)
	if l.log.Index != 3 {
		t.Fatalf("bad: %v", *l)
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/socketplane/bonjour/service.go<|end_filename|>
package bonjour

import (
	"fmt"
	"net"
)

// ServiceRecord contains the basic description of a service, which contains instance name, service type & domain
type ServiceRecord struct {
	Instance string `json:"name"`   // Instance name (e.g. "My web page")
	Service  string `json:"type"`   // Service name (e.g. _http._tcp.)
	Domain   string `json:"domain"` // If blank, assumes "local"

	// private variable populated on the first call to ServiceName()/ServiceInstanceName()
	serviceName         string `json:"-"`
	serviceInstanceName string `json:"-"`
}

// Returns complete service name (e.g. _foobar._tcp.local.), which is composed
// from a service name (also referred as service type) and a domain.
func (s *ServiceRecord) ServiceName() string {
	if s.serviceName == "" {
		s.serviceName = fmt.Sprintf("%s.%s.", trimDot(s.Service), trimDot(s.Domain))
	}
	return s.serviceName
}

// Returns complete service instance name (e.g. MyDemo\ Service._foobar._tcp.local.),
// which is composed from service instance name, service name and a domain.
func (s *ServiceRecord) ServiceInstanceName() string {
	// If no instance name provided we cannot compose service instance name
	if s.Instance == "" {
		return ""
	}
	// If not cached - compose and cache
	if s.serviceInstanceName == "" {
		s.serviceInstanceName = fmt.Sprintf("%s.%s", trimDot(s.Instance), s.ServiceName())
	}
	return s.serviceInstanceName
}

// Constructs a ServiceRecord structure by given arguments
func NewServiceRecord(instance, service, domain string) *ServiceRecord {
	return &ServiceRecord{instance, service, domain, "", ""}
}

// LookupParams contains configurable properties to create a service discovery request
type LookupParams struct {
	ServiceRecord
	Entries chan<- *ServiceEntry // Entries Channel
}

// Constructs a LookupParams structure by given arguments
func NewLookupParams(instance, service, domain string, entries chan<- *ServiceEntry) *LookupParams {
	return &LookupParams{
		*NewServiceRecord(instance, service, domain),
		entries,
	}
}

// ServiceEntry represents a browse/lookup result for client API.
// It is also used to configure service registration (server API), which is
// used to answer multicast queries.
type ServiceEntry struct {
	ServiceRecord
	HostName string   `json:"hostname"` // Host machine DNS name
	Port     int      `json:"port"`     // Service Port
	Text     []string `json:"text"`     // Service info served as a TXT record
	TTL      uint32   `json:"ttl"`      // TTL of the service record
	AddrIPv4 net.IP   `json:"-"`        // Host machine IPv4 address
	AddrIPv6 net.IP   `json:"-"`        // Host machine IPv6 address
}

// Constructs a ServiceEntry structure by given arguments
func NewServiceEntry(instance, service, domain string) *ServiceEntry {
	return &ServiceEntry{
		*NewServiceRecord(instance, service, domain),
		"",
		0,
		[]string{},
		0,
		nil,
		nil,
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/samalba/dockerclient/examples/events.go<|end_filename|>
package main

import (
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/samalba/dockerclient"
	"log"
	"os"
	"os/signal"
	"syscall"
)

func eventCallback(e *dockerclient.Event, ec chan error, args ...interface{}) {
	log.Println(e)
}

func waitForInterrupt() {
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)
	for _ = range sigChan {
		os.Exit(0)
	}
}

func main() {
	docker, err := dockerclient.NewDockerClient(os.Getenv("DOCKER_HOST"), nil)
	if err != nil {
		log.Fatal(err)
	}

	docker.StartMonitorEvents(eventCallback, nil)

	waitForInterrupt()
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/command/agent/structs.go<|end_filename|>
package agent

import (
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/consul/structs"
)

// ServiceDefinition is used to JSON decode the Service definitions
type ServiceDefinition struct {
	ID      string
	Name    string
	Tags    []string
	Address string
	Port    int
	Check   CheckType
}

func (s *ServiceDefinition) NodeService() *structs.NodeService {
	ns := &structs.NodeService{
		ID:      s.ID,
		Service: s.Name,
		Tags:    s.Tags,
		Address: s.Address,
		Port:    s.Port,
	}
	if ns.ID == "" && ns.Service != "" {
		ns.ID = ns.Service
	}
	return ns
}

func (s *ServiceDefinition) CheckType() *CheckType {
	if s.Check.Script == "" && s.Check.Interval == 0 && s.Check.TTL == 0 {
		return nil
	}
	return &s.Check
}

// ChecKDefinition is used to JSON decode the Check definitions
type CheckDefinition struct {
	ID        string
	Name      string
	Notes     string
	CheckType `mapstructure:",squash"`
}

func (c *CheckDefinition) HealthCheck(node string) *structs.HealthCheck {
	health := &structs.HealthCheck{
		Node:    node,
		CheckID: c.ID,
		Name:    c.Name,
		Status:  structs.HealthCritical,
		Notes:   c.Notes,
	}
	if health.CheckID == "" && health.Name != "" {
		health.CheckID = health.Name
	}
	return health
}


<|start_filename|>Godeps/_workspace/src/github.com/samalba/dockerclient/mockclient/mock.go<|end_filename|>
package mockclient

import (
	"io"

	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/samalba/dockerclient"
	"github.com/stretchr/testify/mock"
)

type MockClient struct {
	mock.Mock
}

func NewMockClient() *MockClient {
	return &MockClient{}
}

func (client *MockClient) Info() (*dockerclient.Info, error) {
	args := client.Mock.Called()
	return args.Get(0).(*dockerclient.Info), args.Error(1)
}

func (client *MockClient) ListContainers(all bool, size bool, filters string) ([]dockerclient.Container, error) {
	args := client.Mock.Called(all, size, filters)
	return args.Get(0).([]dockerclient.Container), args.Error(1)
}

func (client *MockClient) InspectContainer(id string) (*dockerclient.ContainerInfo, error) {
	args := client.Mock.Called(id)
	return args.Get(0).(*dockerclient.ContainerInfo), args.Error(1)
}

func (client *MockClient) CreateContainer(config *dockerclient.ContainerConfig, name string) (string, error) {
	args := client.Mock.Called(config, name)
	return args.String(0), args.Error(1)
}

func (client *MockClient) ContainerLogs(id string, options *dockerclient.LogOptions) (io.ReadCloser, error) {
	args := client.Mock.Called(id, options)
	return args.Get(0).(io.ReadCloser), args.Error(1)
}

func (client *MockClient) StartContainer(id string, config *dockerclient.HostConfig) error {
	args := client.Mock.Called(id, config)
	return args.Error(0)
}

func (client *MockClient) StopContainer(id string, timeout int) error {
	args := client.Mock.Called(id, timeout)
	return args.Error(0)
}

func (client *MockClient) RestartContainer(id string, timeout int) error {
	args := client.Mock.Called(id, timeout)
	return args.Error(0)
}

func (client *MockClient) KillContainer(id, signal string) error {
	args := client.Mock.Called(id, signal)
	return args.Error(0)
}

func (client *MockClient) StartMonitorEvents(cb dockerclient.Callback, ec chan error, args ...interface{}) {
	client.Mock.Called(cb, ec, args)
}

func (client *MockClient) StopAllMonitorEvents() {
	client.Mock.Called()
}

func (client *MockClient) Version() (*dockerclient.Version, error) {
	args := client.Mock.Called()
	return args.Get(0).(*dockerclient.Version), args.Error(1)
}

func (client *MockClient) PullImage(name string, auth *dockerclient.AuthConfig) error {
	args := client.Mock.Called(name, auth)
	return args.Error(0)
}

func (client *MockClient) RemoveContainer(id string, force bool) error {
	args := client.Mock.Called(id, force)
	return args.Error(0)
}

func (client *MockClient) ListImages() ([]*dockerclient.Image, error) {
	args := client.Mock.Called()
	return args.Get(0).([]*dockerclient.Image), args.Error(1)
}

func (client *MockClient) RemoveImage(name string) error {
	args := client.Mock.Called(name)
	return args.Error(0)
}

func (client *MockClient) PauseContainer(name string) error {
	args := client.Mock.Called(name)
	return args.Error(0)
}

func (client *MockClient) UnpauseContainer(name string) error {
	args := client.Mock.Called(name)
	return args.Error(0)
}

func (client *MockClient) Exec(config *dockerclient.ExecConfig) (string, error) {
	args := client.Mock.Called(config)
	return args.String(0), args.Error(1)
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/consul/server_test.go<|end_filename|>
package consul

import (
	"errors"
	"fmt"
	"io/ioutil"
	"net"
	"os"
	"strings"
	"testing"
	"time"

	"github.com/hashicorp/consul/testutil"
)

var nextPort = 15000

func getPort() int {
	p := nextPort
	nextPort++
	return p
}

func tmpDir(t *testing.T) string {
	dir, err := ioutil.TempDir("", "consul")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	return dir
}

func configureTLS(config *Config) {
	config.CAFile = "../test/ca/root.cer"
	config.CertFile = "../test/key/ourdomain.cer"
	config.KeyFile = "../test/key/ourdomain.key"
}

func testServerConfig(t *testing.T, NodeName string) (string, *Config) {
	dir := tmpDir(t)
	config := DefaultConfig()

	config.NodeName = NodeName
	config.Bootstrap = true
	config.Datacenter = "dc1"
	config.DataDir = dir
	config.RPCAddr = &net.TCPAddr{
		IP:   []byte{127, 0, 0, 1},
		Port: getPort(),
	}
	config.SerfLANConfig.MemberlistConfig.BindAddr = "127.0.0.1"
	config.SerfLANConfig.MemberlistConfig.BindPort = getPort()
	config.SerfLANConfig.MemberlistConfig.SuspicionMult = 2
	config.SerfLANConfig.MemberlistConfig.ProbeTimeout = 50 * time.Millisecond
	config.SerfLANConfig.MemberlistConfig.ProbeInterval = 100 * time.Millisecond
	config.SerfLANConfig.MemberlistConfig.GossipInterval = 100 * time.Millisecond

	config.SerfWANConfig.MemberlistConfig.BindAddr = "127.0.0.1"
	config.SerfWANConfig.MemberlistConfig.BindPort = getPort()
	config.SerfWANConfig.MemberlistConfig.SuspicionMult = 2
	config.SerfWANConfig.MemberlistConfig.ProbeTimeout = 50 * time.Millisecond
	config.SerfWANConfig.MemberlistConfig.ProbeInterval = 100 * time.Millisecond
	config.SerfWANConfig.MemberlistConfig.GossipInterval = 100 * time.Millisecond

	config.RaftConfig.LeaderLeaseTimeout = 20 * time.Millisecond
	config.RaftConfig.HeartbeatTimeout = 40 * time.Millisecond
	config.RaftConfig.ElectionTimeout = 40 * time.Millisecond

	config.ReconcileInterval = 100 * time.Millisecond
	return dir, config
}

func testServer(t *testing.T) (string, *Server) {
	return testServerDC(t, "dc1")
}

func testServerDC(t *testing.T, dc string) (string, *Server) {
	return testServerDCBootstrap(t, dc, true)
}

func testServerDCBootstrap(t *testing.T, dc string, bootstrap bool) (string, *Server) {
	name := fmt.Sprintf("Node %d", getPort())
	dir, config := testServerConfig(t, name)
	config.Datacenter = dc
	config.Bootstrap = bootstrap
	server, err := NewServer(config)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	return dir, server
}

func testServerDCExpect(t *testing.T, dc string, expect int) (string, *Server) {
	name := fmt.Sprintf("Node %d", getPort())
	dir, config := testServerConfig(t, name)
	config.Datacenter = dc
	config.Bootstrap = false
	config.BootstrapExpect = expect
	server, err := NewServer(config)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	return dir, server
}

func testServerWithConfig(t *testing.T, cb func(c *Config)) (string, *Server) {
	name := fmt.Sprintf("Node %d", getPort())
	dir, config := testServerConfig(t, name)
	cb(config)
	server, err := NewServer(config)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	return dir, server
}

func TestServer_StartStop(t *testing.T) {
	dir := tmpDir(t)
	defer os.RemoveAll(dir)

	config := DefaultConfig()
	config.DataDir = dir

	private, err := GetPrivateIP()
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	config.RPCAdvertise = &net.TCPAddr{
		IP:   private,
		Port: 8300,
	}

	server, err := NewServer(config)
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := server.Shutdown(); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Idempotent
	if err := server.Shutdown(); err != nil {
		t.Fatalf("err: %v", err)
	}
}

func TestServer_JoinLAN(t *testing.T) {
	dir1, s1 := testServer(t)
	defer os.RemoveAll(dir1)
	defer s1.Shutdown()

	dir2, s2 := testServer(t)
	defer os.RemoveAll(dir2)
	defer s2.Shutdown()

	// Try to join
	addr := fmt.Sprintf("127.0.0.1:%d",
		s1.config.SerfLANConfig.MemberlistConfig.BindPort)
	if _, err := s2.JoinLAN([]string{addr}); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Check the members
	testutil.WaitForResult(func() (bool, error) {
		return len(s1.LANMembers()) == 2, nil
	}, func(err error) {
		t.Fatalf("bad len")
	})

	testutil.WaitForResult(func() (bool, error) {
		return len(s2.LANMembers()) == 2, nil
	}, func(err error) {
		t.Fatalf("bad len")
	})
}

func TestServer_JoinWAN(t *testing.T) {
	dir1, s1 := testServer(t)
	defer os.RemoveAll(dir1)
	defer s1.Shutdown()

	dir2, s2 := testServerDC(t, "dc2")
	defer os.RemoveAll(dir2)
	defer s2.Shutdown()

	// Try to join
	addr := fmt.Sprintf("127.0.0.1:%d",
		s1.config.SerfWANConfig.MemberlistConfig.BindPort)
	if _, err := s2.JoinWAN([]string{addr}); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Check the members
	testutil.WaitForResult(func() (bool, error) {
		return len(s1.WANMembers()) == 2, nil
	}, func(err error) {
		t.Fatalf("bad len")
	})

	testutil.WaitForResult(func() (bool, error) {
		return len(s2.WANMembers()) == 2, nil
	}, func(err error) {
		t.Fatalf("bad len")
	})

	// Check the remoteConsuls has both
	if len(s1.remoteConsuls) != 2 {
		t.Fatalf("remote consul missing")
	}

	testutil.WaitForResult(func() (bool, error) {
		return len(s2.remoteConsuls) == 2, nil
	}, func(err error) {
		t.Fatalf("remote consul missing")
	})
}

func TestServer_Leave(t *testing.T) {
	dir1, s1 := testServer(t)
	defer os.RemoveAll(dir1)
	defer s1.Shutdown()

	// Second server not in bootstrap mode
	dir2, s2 := testServerDCBootstrap(t, "dc1", false)
	defer os.RemoveAll(dir2)
	defer s2.Shutdown()

	// Try to join
	addr := fmt.Sprintf("127.0.0.1:%d",
		s1.config.SerfLANConfig.MemberlistConfig.BindPort)
	if _, err := s2.JoinLAN([]string{addr}); err != nil {
		t.Fatalf("err: %v", err)
	}

	var p1 []net.Addr
	var p2 []net.Addr

	testutil.WaitForResult(func() (bool, error) {
		p1, _ = s1.raftPeers.Peers()
		return len(p1) == 2, errors.New(fmt.Sprintf("%v", p1))
	}, func(err error) {
		t.Fatalf("should have 2 peers: %v", err)
	})

	testutil.WaitForResult(func() (bool, error) {
		p2, _ = s2.raftPeers.Peers()
		return len(p2) == 2, errors.New(fmt.Sprintf("%v", p1))
	}, func(err error) {
		t.Fatalf("should have 2 peers: %v", err)
	})

	// Issue a leave
	if err := s2.Leave(); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Should lose a peer
	testutil.WaitForResult(func() (bool, error) {
		p1, _ = s1.raftPeers.Peers()
		return len(p1) == 1, nil
	}, func(err error) {
		t.Fatalf("should have 1 peer: %v", p1)
	})
}

func TestServer_RPC(t *testing.T) {
	dir1, s1 := testServer(t)
	defer os.RemoveAll(dir1)
	defer s1.Shutdown()

	var out struct{}
	if err := s1.RPC("Status.Ping", struct{}{}, &out); err != nil {
		t.Fatalf("err: %v", err)
	}
}

func TestServer_JoinLAN_TLS(t *testing.T) {
	dir1, conf1 := testServerConfig(t, "a.testco.internal")
	conf1.VerifyIncoming = true
	conf1.VerifyOutgoing = true
	configureTLS(conf1)
	s1, err := NewServer(conf1)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer os.RemoveAll(dir1)
	defer s1.Shutdown()

	dir2, conf2 := testServerConfig(t, "b.testco.internal")
	conf2.Bootstrap = false
	conf2.VerifyIncoming = true
	conf2.VerifyOutgoing = true
	configureTLS(conf2)
	s2, err := NewServer(conf2)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer os.RemoveAll(dir2)
	defer s2.Shutdown()

	// Try to join
	addr := fmt.Sprintf("127.0.0.1:%d",
		s1.config.SerfLANConfig.MemberlistConfig.BindPort)
	if _, err := s2.JoinLAN([]string{addr}); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Check the members
	testutil.WaitForResult(func() (bool, error) {
		return len(s1.LANMembers()) == 2, nil
	}, func(err error) {
		t.Fatalf("bad len")
	})

	testutil.WaitForResult(func() (bool, error) {
		return len(s2.LANMembers()) == 2, nil
	}, func(err error) {
		t.Fatalf("bad len")
	})

	// Verify Raft has established a peer
	testutil.WaitForResult(func() (bool, error) {
		return s1.Stats()["raft"]["num_peers"] == "1", nil
	}, func(err error) {
		t.Fatalf("no peer established")
	})

	testutil.WaitForResult(func() (bool, error) {
		return s2.Stats()["raft"]["num_peers"] == "1", nil
	}, func(err error) {
		t.Fatalf("no peer established")
	})
}

func TestServer_Expect(t *testing.T) {
	// all test servers should be in expect=3 mode
	dir1, s1 := testServerDCExpect(t, "dc1", 3)
	defer os.RemoveAll(dir1)
	defer s1.Shutdown()

	dir2, s2 := testServerDCExpect(t, "dc1", 3)
	defer os.RemoveAll(dir2)
	defer s2.Shutdown()

	dir3, s3 := testServerDCExpect(t, "dc1", 0)
	defer os.RemoveAll(dir3)
	defer s3.Shutdown()

	// Try to join
	addr := fmt.Sprintf("127.0.0.1:%d",
		s1.config.SerfLANConfig.MemberlistConfig.BindPort)
	if _, err := s2.JoinLAN([]string{addr}); err != nil {
		t.Fatalf("err: %v", err)
	}

	var p1 []net.Addr
	var p2 []net.Addr

	// should have no peers yet
	testutil.WaitForResult(func() (bool, error) {
		p1, _ = s1.raftPeers.Peers()
		return len(p1) == 0, errors.New(fmt.Sprintf("%v", p1))
	}, func(err error) {
		t.Fatalf("should have 0 peers: %v", err)
	})

	testutil.WaitForResult(func() (bool, error) {
		p2, _ = s2.raftPeers.Peers()
		return len(p2) == 0, errors.New(fmt.Sprintf("%v", p2))
	}, func(err error) {
		t.Fatalf("should have 0 peers: %v", err)
	})

	// join the third node
	if _, err := s3.JoinLAN([]string{addr}); err != nil {
		t.Fatalf("err: %v", err)
	}

	var p3 []net.Addr

	// should now have all three peers
	testutil.WaitForResult(func() (bool, error) {
		p1, _ = s1.raftPeers.Peers()
		return len(p1) == 3, errors.New(fmt.Sprintf("%v", p1))
	}, func(err error) {
		t.Fatalf("should have 3 peers: %v", err)
	})

	testutil.WaitForResult(func() (bool, error) {
		p2, _ = s2.raftPeers.Peers()
		return len(p2) == 3, errors.New(fmt.Sprintf("%v", p2))
	}, func(err error) {
		t.Fatalf("should have 3 peers: %v", err)
	})

	testutil.WaitForResult(func() (bool, error) {
		p3, _ = s3.raftPeers.Peers()
		return len(p3) == 3, errors.New(fmt.Sprintf("%v", p3))
	}, func(err error) {
		t.Fatalf("should have 3 peers: %v", err)
	})

	// check if there is one leader now
	testutil.WaitForLeader(t, s1.RPC, "dc1")
}

func TestServer_BadExpect(t *testing.T) {
	// this one is in expect=3 mode
	dir1, s1 := testServerDCExpect(t, "dc1", 3)
	defer os.RemoveAll(dir1)
	defer s1.Shutdown()

	// this one is in expect=2 mode
	dir2, s2 := testServerDCExpect(t, "dc1", 2)
	defer os.RemoveAll(dir2)
	defer s2.Shutdown()

	// and this one is in expect=3 mode
	dir3, s3 := testServerDCExpect(t, "dc1", 3)
	defer os.RemoveAll(dir3)
	defer s3.Shutdown()

	// Try to join
	addr := fmt.Sprintf("127.0.0.1:%d",
		s1.config.SerfLANConfig.MemberlistConfig.BindPort)
	if _, err := s2.JoinLAN([]string{addr}); err != nil {
		t.Fatalf("err: %v", err)
	}

	var p1 []net.Addr
	var p2 []net.Addr

	// should have no peers yet
	testutil.WaitForResult(func() (bool, error) {
		p1, _ = s1.raftPeers.Peers()
		return len(p1) == 0, errors.New(fmt.Sprintf("%v", p1))
	}, func(err error) {
		t.Fatalf("should have 0 peers: %v", err)
	})

	testutil.WaitForResult(func() (bool, error) {
		p2, _ = s2.raftPeers.Peers()
		return len(p2) == 0, errors.New(fmt.Sprintf("%v", p2))
	}, func(err error) {
		t.Fatalf("should have 0 peers: %v", err)
	})

	// join the third node
	if _, err := s3.JoinLAN([]string{addr}); err != nil {
		t.Fatalf("err: %v", err)
	}

	var p3 []net.Addr

	// should still have no peers (because s2 is in expect=2 mode)
	testutil.WaitForResult(func() (bool, error) {
		p1, _ = s1.raftPeers.Peers()
		return len(p1) == 0, errors.New(fmt.Sprintf("%v", p1))
	}, func(err error) {
		t.Fatalf("should have 0 peers: %v", err)
	})

	testutil.WaitForResult(func() (bool, error) {
		p2, _ = s2.raftPeers.Peers()
		return len(p2) == 0, errors.New(fmt.Sprintf("%v", p2))
	}, func(err error) {
		t.Fatalf("should have 0 peers: %v", err)
	})

	testutil.WaitForResult(func() (bool, error) {
		p3, _ = s3.raftPeers.Peers()
		return len(p3) == 0, errors.New(fmt.Sprintf("%v", p3))
	}, func(err error) {
		t.Fatalf("should have 0 peers: %v", err)
	})
}

type fakeGlobalResp struct{}

func (r *fakeGlobalResp) Add(interface{}) {
	return
}

func (r *fakeGlobalResp) New() interface{} {
	return struct{}{}
}

func TestServer_globalRPCErrors(t *testing.T) {
	dir1, s1 := testServerDC(t, "dc1")
	defer os.RemoveAll(dir1)
	defer s1.Shutdown()

	testutil.WaitForResult(func() (bool, error) {
		return len(s1.remoteConsuls) == 1, nil
	}, func(err error) {
		t.Fatalf("Server did not join LAN successfully")
	})

	// Check that an error from a remote DC is returned
	err := s1.globalRPC("Bad.Method", nil, &fakeGlobalResp{})
	if err == nil {
		t.Fatalf("should have errored")
	}
	if !strings.Contains(err.Error(), "Bad.Method") {
		t.Fatalf("unexpcted error: %s", err)
	}
}

func TestServer_Encrypted(t *testing.T) {
	dir1, s1 := testServer(t)
	defer os.RemoveAll(dir1)
	defer s1.Shutdown()

	key := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
	dir2, s2 := testServerWithConfig(t, func(c *Config) {
		c.SerfLANConfig.MemberlistConfig.SecretKey = key
		c.SerfWANConfig.MemberlistConfig.SecretKey = key
	})
	defer os.RemoveAll(dir2)
	defer s2.Shutdown()

	if s1.Encrypted() {
		t.Fatalf("should not be encrypted")
	}
	if !s2.Encrypted() {
		t.Fatalf("should be encrypted")
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/command/agent/check.go<|end_filename|>
package agent

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os/exec"
	"sync"
	"syscall"
	"time"

	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/armon/circbuf"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/consul/structs"
)

const (
	// Do not allow for a interval below this value.
	// Otherwise we risk fork bombing a system.
	MinInterval = time.Second

	// Limit the size of a check's output to the
	// last CheckBufSize. Prevents an enormous buffer
	// from being captured
	CheckBufSize = 4 * 1024 // 4KB
)

// CheckType is used to create either the CheckMonitor
// or the CheckTTL.
// Three types are supported: Script, HTTP, and TTL
// Script and HTTP both require Interval
// Only one of the types needs to be provided
//  TTL or Script/Interval or HTTP/Interval
type CheckType struct {
	Script   string
	HTTP     string
	Interval time.Duration

	TTL time.Duration

	Notes string
}

// Valid checks if the CheckType is valid
func (c *CheckType) Valid() bool {
	return c.IsTTL() || c.IsMonitor() || c.IsHTTP()
}

// IsTTL checks if this is a TTL type
func (c *CheckType) IsTTL() bool {
	return c.TTL != 0
}

// IsMonitor checks if this is a Monitor type
func (c *CheckType) IsMonitor() bool {
	return c.Script != "" && c.Interval != 0
}

// IsHTTP checks if this is a HTTP type
func (c *CheckType) IsHTTP() bool {
	return c.HTTP != "" && c.Interval != 0
}

// CheckNotifier interface is used by the CheckMonitor
// to notify when a check has a status update. The update
// should take care to be idempotent.
type CheckNotifier interface {
	UpdateCheck(checkID, status, output string)
}

// CheckMonitor is used to periodically invoke a script to
// determine the health of a given check. It is compatible with
// nagios plugins and expects the output in the same format.
type CheckMonitor struct {
	Notify   CheckNotifier
	CheckID  string
	Script   string
	Interval time.Duration
	Logger   *log.Logger

	stop     bool
	stopCh   chan struct{}
	stopLock sync.Mutex
}

// Start is used to start a check monitor.
// Monitor runs until stop is called
func (c *CheckMonitor) Start() {
	c.stopLock.Lock()
	defer c.stopLock.Unlock()
	c.stop = false
	c.stopCh = make(chan struct{})
	go c.run()
}

// Stop is used to stop a check monitor.
func (c *CheckMonitor) Stop() {
	c.stopLock.Lock()
	defer c.stopLock.Unlock()
	if !c.stop {
		c.stop = true
		close(c.stopCh)
	}
}

// run is invoked by a goroutine to run until Stop() is called
func (c *CheckMonitor) run() {
	// Get the randomized initial pause time
	initialPauseTime := randomStagger(c.Interval)
	c.Logger.Printf("[DEBUG] agent: pausing %v before first invocation of %s", initialPauseTime, c.Script)
	next := time.After(initialPauseTime)
	for {
		select {
		case <-next:
			c.check()
			next = time.After(c.Interval)
		case <-c.stopCh:
			return
		}
	}
}

// check is invoked periodically to perform the script check
func (c *CheckMonitor) check() {
	// Create the command
	cmd, err := ExecScript(c.Script)
	if err != nil {
		c.Logger.Printf("[ERR] agent: failed to setup invoke '%s': %s", c.Script, err)
		c.Notify.UpdateCheck(c.CheckID, structs.HealthCritical, err.Error())
		return
	}

	// Collect the output
	output, _ := circbuf.NewBuffer(CheckBufSize)
	cmd.Stdout = output
	cmd.Stderr = output

	// Start the check
	if err := cmd.Start(); err != nil {
		c.Logger.Printf("[ERR] agent: failed to invoke '%s': %s", c.Script, err)
		c.Notify.UpdateCheck(c.CheckID, structs.HealthCritical, err.Error())
		return
	}

	// Wait for the check to complete
	errCh := make(chan error, 2)
	go func() {
		errCh <- cmd.Wait()
	}()
	go func() {
		time.Sleep(30 * time.Second)
		errCh <- fmt.Errorf("Timed out running check '%s'", c.Script)
	}()
	err = <-errCh

	// Get the output, add a message about truncation
	outputStr := string(output.Bytes())
	if output.TotalWritten() > output.Size() {
		outputStr = fmt.Sprintf("Captured %d of %d bytes\n...\n%s",
			output.Size(), output.TotalWritten(), outputStr)
	}

	c.Logger.Printf("[DEBUG] agent: check '%s' script '%s' output: %s",
		c.CheckID, c.Script, outputStr)

	// Check if the check passed
	if err == nil {
		c.Logger.Printf("[DEBUG] agent: Check '%v' is passing", c.CheckID)
		c.Notify.UpdateCheck(c.CheckID, structs.HealthPassing, outputStr)
		return
	}

	// If the exit code is 1, set check as warning
	exitErr, ok := err.(*exec.ExitError)
	if ok {
		if status, ok := exitErr.Sys().(syscall.WaitStatus); ok {
			code := status.ExitStatus()
			if code == 1 {
				c.Logger.Printf("[WARN] agent: Check '%v' is now warning", c.CheckID)
				c.Notify.UpdateCheck(c.CheckID, structs.HealthWarning, outputStr)
				return
			}
		}
	}

	// Set the health as critical
	c.Logger.Printf("[WARN] agent: Check '%v' is now critical", c.CheckID)
	c.Notify.UpdateCheck(c.CheckID, structs.HealthCritical, outputStr)
}

// CheckTTL is used to apply a TTL to check status,
// and enables clients to set the status of a check
// but upon the TTL expiring, the check status is
// automatically set to critical.
type CheckTTL struct {
	Notify  CheckNotifier
	CheckID string
	TTL     time.Duration
	Logger  *log.Logger

	timer *time.Timer

	stop     bool
	stopCh   chan struct{}
	stopLock sync.Mutex
}

// Start is used to start a check ttl, runs until Stop()
func (c *CheckTTL) Start() {
	c.stopLock.Lock()
	defer c.stopLock.Unlock()
	c.stop = false
	c.stopCh = make(chan struct{})
	c.timer = time.NewTimer(c.TTL)
	go c.run()
}

// Stop is used to stop a check ttl.
func (c *CheckTTL) Stop() {
	c.stopLock.Lock()
	defer c.stopLock.Unlock()
	if !c.stop {
		c.timer.Stop()
		c.stop = true
		close(c.stopCh)
	}
}

// run is used to handle TTL expiration and to update the check status
func (c *CheckTTL) run() {
	for {
		select {
		case <-c.timer.C:
			c.Logger.Printf("[WARN] agent: Check '%v' missed TTL, is now critical",
				c.CheckID)
			c.Notify.UpdateCheck(c.CheckID, structs.HealthCritical, "TTL expired")

		case <-c.stopCh:
			return
		}
	}
}

// SetStatus is used to update the status of the check,
// and to renew the TTL. If expired, TTL is restarted.
func (c *CheckTTL) SetStatus(status, output string) {
	c.Logger.Printf("[DEBUG] agent: Check '%v' status is now %v",
		c.CheckID, status)
	c.Notify.UpdateCheck(c.CheckID, status, output)
	c.timer.Reset(c.TTL)
}

// persistedCheck is used to serialize a check and write it to disk
// so that it may be restored later on.
type persistedCheck struct {
	Check   *structs.HealthCheck
	ChkType *CheckType
}

// CheckHTTP is used to periodically make an HTTP request to
// determine the health of a given check.
// The check is passing if the response code is 2XX.
// The check is warning if the response code is 429.
// The check is critical if the response code is anything else
// or if the request returns an error
type CheckHTTP struct {
	Notify   CheckNotifier
	CheckID  string
	HTTP     string
	Interval time.Duration
	Logger   *log.Logger

	httpClient *http.Client
	stop       bool
	stopCh     chan struct{}
	stopLock   sync.Mutex
}

// Start is used to start an HTTP check.
// The check runs until stop is called
func (c *CheckHTTP) Start() {
	c.stopLock.Lock()
	defer c.stopLock.Unlock()

	if c.httpClient == nil {
		// For long (>10s) interval checks the http timeout is 10s, otherwise the
		// timeout is the interval. This means that a check *should* return
		// before the next check begins.
		if c.Interval < 10*time.Second {
			c.httpClient = &http.Client{Timeout: c.Interval}
		} else {
			c.httpClient = &http.Client{Timeout: 10 * time.Second}
		}
	}

	c.stop = false
	c.stopCh = make(chan struct{})
	go c.run()
}

// Stop is used to stop an HTTP check.
func (c *CheckHTTP) Stop() {
	c.stopLock.Lock()
	defer c.stopLock.Unlock()
	if !c.stop {
		c.stop = true
		close(c.stopCh)
	}
}

// run is invoked by a goroutine to run until Stop() is called
func (c *CheckHTTP) run() {
	// Get the randomized initial pause time
	initialPauseTime := randomStagger(c.Interval)
	c.Logger.Printf("[DEBUG] agent: pausing %v before first HTTP request of %s", initialPauseTime, c.HTTP)
	next := time.After(initialPauseTime)
	for {
		select {
		case <-next:
			c.check()
			next = time.After(c.Interval)
		case <-c.stopCh:
			return
		}
	}
}

// check is invoked periodically to perform the HTTP check
func (c *CheckHTTP) check() {
	resp, err := c.httpClient.Get(c.HTTP)
	if err != nil {
		c.Logger.Printf("[WARN] agent: http request failed '%s': %s", c.HTTP, err)
		c.Notify.UpdateCheck(c.CheckID, structs.HealthCritical, err.Error())
		return
	}
	defer resp.Body.Close()

	// Format the response body
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		c.Logger.Printf("[WARN] agent: check '%v': Get error while reading body: %s", c.CheckID, err)
		body = []byte{}
	}
	result := fmt.Sprintf("HTTP GET %s: %s Output: %s", c.HTTP, resp.Status, body)

	if resp.StatusCode >= 200 && resp.StatusCode <= 299 {
		// PASSING (2xx)
		c.Logger.Printf("[DEBUG] agent: check '%v' is passing", c.CheckID)
		c.Notify.UpdateCheck(c.CheckID, structs.HealthPassing, result)

	} else if resp.StatusCode == 429 {
		// WARNING
		// 429 Too Many Requests (RFC 6585)
		// The user has sent too many requests in a given amount of time.
		c.Logger.Printf("[WARN] agent: check '%v' is now warning", c.CheckID)
		c.Notify.UpdateCheck(c.CheckID, structs.HealthWarning, result)

	} else {
		// CRITICAL
		c.Logger.Printf("[WARN] agent: check '%v' is now critical", c.CheckID)
		c.Notify.UpdateCheck(c.CheckID, structs.HealthCritical, result)
	}
}


<|start_filename|>config/configuration.go<|end_filename|>
package config

import "github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/BurntSushi/toml"

const (
	CFG_DEBUG     = "debug"
	CFG_BOOTSTRAP = "bootstrap"
	CFG_FILE      = "config-file"
	CFG_IFACE     = "iface"
)

type config struct {
	Daemon DaemonCfg
	// Add more Configs such as ClusterCfg, OvsCfg, etc.
}

type DaemonCfg struct {
	Bootstrap bool
	Debug     bool
}

var spConfig config
var Daemon DaemonCfg

func Parse(tomlCfgFile string) error {
	if _, err := toml.DecodeFile(tomlCfgFile, &spConfig); err != nil {
		return err
	}
	Daemon = spConfig.Daemon
	return nil
}


<|start_filename|>Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_state.go<|end_filename|>
package netlink

import (
	"net"
)

// XfrmStateAlgo represents the algorithm to use for the ipsec encryption.
type XfrmStateAlgo struct {
	Name        string
	Key         []byte
	TruncateLen int // Auth only
}

// EncapType is an enum representing an ipsec template direction.
type EncapType uint8

const (
	_                                    = iota
	XFRM_ENCAP_ESPINUDP_NONIKE EncapType = iota
	XFRM_ENCAP_ESPINUDP        EncapType = iota
)

func (e EncapType) String() string {
	switch e {
	case XFRM_ENCAP_ESPINUDP_NONIKE:
		return "espinudp-nonike"
	case XFRM_ENCAP_ESPINUDP:
		return "espinudp"
	}
	return "unknown"
}

// XfrmEncap represents the encapsulation to use for the ipsec encryption.
type XfrmStateEncap struct {
	Type            EncapType
	SrcPort         int
	DstPort         int
	OriginalAddress net.IP
}

// XfrmState represents the state of an ipsec policy. It optionally
// contains an XfrmStateAlgo for encryption and one for authentication.
type XfrmState struct {
	Dst          net.IP
	Src          net.IP
	Proto        Proto
	Mode         Mode
	Spi          int
	Reqid        int
	ReplayWindow int
	Auth         *XfrmStateAlgo
	Crypt        *XfrmStateAlgo
	Encap        *XfrmStateEncap
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/hcl/hcl/y.go<|end_filename|>
//line parse.y:4
package hcl

import __yyfmt__ "fmt"

//line parse.y:4
import (
	"fmt"
	"strconv"
)

//line parse.y:13
type hclSymType struct {
	yys     int
	b       bool
	f       float64
	num     int
	str     string
	obj     *Object
	objlist []*Object
}

const BOOL = 57346
const FLOAT = 57347
const NUMBER = 57348
const COMMA = 57349
const COMMAEND = 57350
const IDENTIFIER = 57351
const EQUAL = 57352
const NEWLINE = 57353
const STRING = 57354
const MINUS = 57355
const LEFTBRACE = 57356
const RIGHTBRACE = 57357
const LEFTBRACKET = 57358
const RIGHTBRACKET = 57359
const PERIOD = 57360
const EPLUS = 57361
const EMINUS = 57362

var hclToknames = []string{
	"BOOL",
	"FLOAT",
	"NUMBER",
	"COMMA",
	"COMMAEND",
	"IDENTIFIER",
	"EQUAL",
	"NEWLINE",
	"STRING",
	"MINUS",
	"LEFTBRACE",
	"RIGHTBRACE",
	"LEFTBRACKET",
	"RIGHTBRACKET",
	"PERIOD",
	"EPLUS",
	"EMINUS",
}
var hclStatenames = []string{}

const hclEofCode = 1
const hclErrCode = 2
const hclMaxDepth = 200

//line parse.y:259

//line yacctab:1
var hclExca = []int{
	-1, 1,
	1, -1,
	-2, 0,
	-1, 6,
	10, 7,
	-2, 17,
	-1, 7,
	10, 8,
	-2, 18,
}

const hclNprod = 36
const hclPrivate = 57344

var hclTokenNames []string
var hclStates []string

const hclLast = 62

var hclAct = []int{

	35, 3, 21, 22, 9, 30, 31, 29, 17, 26,
	25, 26, 25, 10, 26, 25, 18, 24, 13, 24,
	23, 37, 24, 44, 45, 42, 34, 38, 39, 9,
	32, 6, 6, 43, 7, 7, 2, 40, 28, 26,
	25, 6, 41, 11, 7, 46, 37, 24, 14, 36,
	27, 15, 5, 13, 19, 1, 4, 8, 33, 20,
	16, 12,
}
var hclPact = []int{

	32, -1000, 32, -1000, 3, -1000, -1000, -1000, 39, -1000,
	4, -1000, -1000, 23, -1000, -1000, -1000, -1000, -1000, -1000,
	-1000, -14, -14, 9, 6, -1000, -1000, 22, -1000, -1000,
	36, 19, -1000, 16, -1000, -1000, -1000, -1000, -1000, -1000,
	-1000, -1000, -1000, -1000, 34, -1000, -1000,
}
var hclPgo = []int{

	0, 3, 2, 59, 58, 36, 52, 49, 43, 1,
	0, 57, 7, 56, 55,
}
var hclR1 = []int{

	0, 14, 14, 5, 5, 8, 8, 13, 13, 9,
	9, 9, 9, 9, 9, 6, 6, 11, 11, 3,
	3, 4, 4, 4, 10, 10, 7, 7, 7, 7,
	2, 2, 1, 1, 12, 12,
}
var hclR2 = []int{

	0, 0, 1, 1, 2, 3, 2, 1, 1, 3,
	3, 3, 3, 3, 1, 2, 2, 1, 1, 3,
	2, 1, 3, 2, 1, 1, 1, 1, 2, 2,
	2, 1, 2, 1, 2, 2,
}
var hclChk = []int{

	-1000, -14, -5, -9, -13, -6, 9, 12, -11, -9,
	10, -8, -6, 14, 9, 12, -7, 4, 12, -8,
	-3, -2, -1, 16, 13, 6, 5, -5, 15, -12,
	19, 20, -12, -4, 17, -10, -7, 12, -2, -1,
	15, 6, 6, 17, 7, 8, -10,
}
var hclDef = []int{

	1, -2, 2, 3, 0, 14, -2, -2, 0, 4,
	0, 15, 16, 0, 17, 18, 9, 10, 11, 12,
	13, 26, 27, 0, 0, 31, 33, 0, 6, 28,
	0, 0, 29, 0, 20, 21, 24, 25, 30, 32,
	5, 34, 35, 19, 0, 23, 22,
}
var hclTok1 = []int{

	1,
}
var hclTok2 = []int{

	2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
	12, 13, 14, 15, 16, 17, 18, 19, 20,
}
var hclTok3 = []int{
	0,
}

//line yaccpar:1

/*	parser for yacc output	*/

var hclDebug = 0

type hclLexer interface {
	Lex(lval *hclSymType) int
	Error(s string)
}

const hclFlag = -1000

func hclTokname(c int) string {
	// 4 is TOKSTART above
	if c >= 4 && c-4 < len(hclToknames) {
		if hclToknames[c-4] != "" {
			return hclToknames[c-4]
		}
	}
	return __yyfmt__.Sprintf("tok-%v", c)
}

func hclStatname(s int) string {
	if s >= 0 && s < len(hclStatenames) {
		if hclStatenames[s] != "" {
			return hclStatenames[s]
		}
	}
	return __yyfmt__.Sprintf("state-%v", s)
}

func hcllex1(lex hclLexer, lval *hclSymType) int {
	c := 0
	char := lex.Lex(lval)
	if char <= 0 {
		c = hclTok1[0]
		goto out
	}
	if char < len(hclTok1) {
		c = hclTok1[char]
		goto out
	}
	if char >= hclPrivate {
		if char < hclPrivate+len(hclTok2) {
			c = hclTok2[char-hclPrivate]
			goto out
		}
	}
	for i := 0; i < len(hclTok3); i += 2 {
		c = hclTok3[i+0]
		if c == char {
			c = hclTok3[i+1]
			goto out
		}
	}

out:
	if c == 0 {
		c = hclTok2[1] /* unknown char */
	}
	if hclDebug >= 3 {
		__yyfmt__.Printf("lex %s(%d)\n", hclTokname(c), uint(char))
	}
	return c
}

func hclParse(hcllex hclLexer) int {
	var hcln int
	var hcllval hclSymType
	var hclVAL hclSymType
	hclS := make([]hclSymType, hclMaxDepth)

	Nerrs := 0   /* number of errors */
	Errflag := 0 /* error recovery flag */
	hclstate := 0
	hclchar := -1
	hclp := -1
	goto hclstack

ret0:
	return 0

ret1:
	return 1

hclstack:
	/* put a state and value onto the stack */
	if hclDebug >= 4 {
		__yyfmt__.Printf("char %v in %v\n", hclTokname(hclchar), hclStatname(hclstate))
	}

	hclp++
	if hclp >= len(hclS) {
		nyys := make([]hclSymType, len(hclS)*2)
		copy(nyys, hclS)
		hclS = nyys
	}
	hclS[hclp] = hclVAL
	hclS[hclp].yys = hclstate

hclnewstate:
	hcln = hclPact[hclstate]
	if hcln <= hclFlag {
		goto hcldefault /* simple state */
	}
	if hclchar < 0 {
		hclchar = hcllex1(hcllex, &hcllval)
	}
	hcln += hclchar
	if hcln < 0 || hcln >= hclLast {
		goto hcldefault
	}
	hcln = hclAct[hcln]
	if hclChk[hcln] == hclchar { /* valid shift */
		hclchar = -1
		hclVAL = hcllval
		hclstate = hcln
		if Errflag > 0 {
			Errflag--
		}
		goto hclstack
	}

hcldefault:
	/* default state action */
	hcln = hclDef[hclstate]
	if hcln == -2 {
		if hclchar < 0 {
			hclchar = hcllex1(hcllex, &hcllval)
		}

		/* look through exception table */
		xi := 0
		for {
			if hclExca[xi+0] == -1 && hclExca[xi+1] == hclstate {
				break
			}
			xi += 2
		}
		for xi += 2; ; xi += 2 {
			hcln = hclExca[xi+0]
			if hcln < 0 || hcln == hclchar {
				break
			}
		}
		hcln = hclExca[xi+1]
		if hcln < 0 {
			goto ret0
		}
	}
	if hcln == 0 {
		/* error ... attempt to resume parsing */
		switch Errflag {
		case 0: /* brand new error */
			hcllex.Error("syntax error")
			Nerrs++
			if hclDebug >= 1 {
				__yyfmt__.Printf("%s", hclStatname(hclstate))
				__yyfmt__.Printf(" saw %s\n", hclTokname(hclchar))
			}
			fallthrough

		case 1, 2: /* incompletely recovered error ... try again */
			Errflag = 3

			/* find a state where "error" is a legal shift action */
			for hclp >= 0 {
				hcln = hclPact[hclS[hclp].yys] + hclErrCode
				if hcln >= 0 && hcln < hclLast {
					hclstate = hclAct[hcln] /* simulate a shift of "error" */
					if hclChk[hclstate] == hclErrCode {
						goto hclstack
					}
				}

				/* the current p has no shift on "error", pop stack */
				if hclDebug >= 2 {
					__yyfmt__.Printf("error recovery pops state %d\n", hclS[hclp].yys)
				}
				hclp--
			}
			/* there is no state on the stack with an error shift ... abort */
			goto ret1

		case 3: /* no shift yet; clobber input char */
			if hclDebug >= 2 {
				__yyfmt__.Printf("error recovery discards %s\n", hclTokname(hclchar))
			}
			if hclchar == hclEofCode {
				goto ret1
			}
			hclchar = -1
			goto hclnewstate /* try again in the same state */
		}
	}

	/* reduction by production hcln */
	if hclDebug >= 2 {
		__yyfmt__.Printf("reduce %v in:\n\t%v\n", hcln, hclStatname(hclstate))
	}

	hclnt := hcln
	hclpt := hclp
	_ = hclpt // guard against "declared and not used"

	hclp -= hclR2[hcln]
	hclVAL = hclS[hclp+1]

	/* consult goto table to find next state */
	hcln = hclR1[hcln]
	hclg := hclPgo[hcln]
	hclj := hclg + hclS[hclp].yys + 1

	if hclj >= hclLast {
		hclstate = hclAct[hclg]
	} else {
		hclstate = hclAct[hclj]
		if hclChk[hclstate] != -hcln {
			hclstate = hclAct[hclg]
		}
	}
	// dummy call; replaced with literal code
	switch hclnt {

	case 1:
		//line parse.y:39
		{
			hclResult = &Object{Type: ValueTypeObject}
		}
	case 2:
		//line parse.y:43
		{
			hclResult = &Object{
				Type:  ValueTypeObject,
				Value: ObjectList(hclS[hclpt-0].objlist).Flat(),
			}
		}
	case 3:
		//line parse.y:52
		{
			hclVAL.objlist = []*Object{hclS[hclpt-0].obj}
		}
	case 4:
		//line parse.y:56
		{
			hclVAL.objlist = append(hclS[hclpt-1].objlist, hclS[hclpt-0].obj)
		}
	case 5:
		//line parse.y:62
		{
			hclVAL.obj = &Object{
				Type:  ValueTypeObject,
				Value: ObjectList(hclS[hclpt-1].objlist).Flat(),
			}
		}
	case 6:
		//line parse.y:69
		{
			hclVAL.obj = &Object{
				Type: ValueTypeObject,
			}
		}
	case 7:
		//line parse.y:77
		{
			hclVAL.str = hclS[hclpt-0].str
		}
	case 8:
		//line parse.y:81
		{
			hclVAL.str = hclS[hclpt-0].str
		}
	case 9:
		//line parse.y:87
		{
			hclVAL.obj = hclS[hclpt-0].obj
			hclVAL.obj.Key = hclS[hclpt-2].str
		}
	case 10:
		//line parse.y:92
		{
			hclVAL.obj = &Object{
				Key:   hclS[hclpt-2].str,
				Type:  ValueTypeBool,
				Value: hclS[hclpt-0].b,
			}
		}
	case 11:
		//line parse.y:100
		{
			hclVAL.obj = &Object{
				Key:   hclS[hclpt-2].str,
				Type:  ValueTypeString,
				Value: hclS[hclpt-0].str,
			}
		}
	case 12:
		//line parse.y:108
		{
			hclS[hclpt-0].obj.Key = hclS[hclpt-2].str
			hclVAL.obj = hclS[hclpt-0].obj
		}
	case 13:
		//line parse.y:113
		{
			hclVAL.obj = &Object{
				Key:   hclS[hclpt-2].str,
				Type:  ValueTypeList,
				Value: hclS[hclpt-0].objlist,
			}
		}
	case 14:
		//line parse.y:121
		{
			hclVAL.obj = hclS[hclpt-0].obj
		}
	case 15:
		//line parse.y:127
		{
			hclS[hclpt-0].obj.Key = hclS[hclpt-1].str
			hclVAL.obj = hclS[hclpt-0].obj
		}
	case 16:
		//line parse.y:132
		{
			hclVAL.obj = &Object{
				Key:   hclS[hclpt-1].str,
				Type:  ValueTypeObject,
				Value: []*Object{hclS[hclpt-0].obj},
			}
		}
	case 17:
		//line parse.y:142
		{
			hclVAL.str = hclS[hclpt-0].str
		}
	case 18:
		//line parse.y:146
		{
			hclVAL.str = hclS[hclpt-0].str
		}
	case 19:
		//line parse.y:152
		{
			hclVAL.objlist = hclS[hclpt-1].objlist
		}
	case 20:
		//line parse.y:156
		{
			hclVAL.objlist = nil
		}
	case 21:
		//line parse.y:162
		{
			hclVAL.objlist = []*Object{hclS[hclpt-0].obj}
		}
	case 22:
		//line parse.y:166
		{
			hclVAL.objlist = append(hclS[hclpt-2].objlist, hclS[hclpt-0].obj)
		}
	case 23:
		//line parse.y:170
		{
			hclVAL.objlist = hclS[hclpt-1].objlist
		}
	case 24:
		//line parse.y:176
		{
			hclVAL.obj = hclS[hclpt-0].obj
		}
	case 25:
		//line parse.y:180
		{
			hclVAL.obj = &Object{
				Type:  ValueTypeString,
				Value: hclS[hclpt-0].str,
			}
		}
	case 26:
		//line parse.y:189
		{
			hclVAL.obj = &Object{
				Type:  ValueTypeInt,
				Value: hclS[hclpt-0].num,
			}
		}
	case 27:
		//line parse.y:196
		{
			hclVAL.obj = &Object{
				Type:  ValueTypeFloat,
				Value: hclS[hclpt-0].f,
			}
		}
	case 28:
		//line parse.y:203
		{
			fs := fmt.Sprintf("%d%s", hclS[hclpt-1].num, hclS[hclpt-0].str)
			f, err := strconv.ParseFloat(fs, 64)
			if err != nil {
				panic(err)
			}

			hclVAL.obj = &Object{
				Type:  ValueTypeFloat,
				Value: f,
			}
		}
	case 29:
		//line parse.y:216
		{
			fs := fmt.Sprintf("%f%s", hclS[hclpt-1].f, hclS[hclpt-0].str)
			f, err := strconv.ParseFloat(fs, 64)
			if err != nil {
				panic(err)
			}

			hclVAL.obj = &Object{
				Type:  ValueTypeFloat,
				Value: f,
			}
		}
	case 30:
		//line parse.y:231
		{
			hclVAL.num = hclS[hclpt-0].num * -1
		}
	case 31:
		//line parse.y:235
		{
			hclVAL.num = hclS[hclpt-0].num
		}
	case 32:
		//line parse.y:241
		{
			hclVAL.f = hclS[hclpt-0].f * -1
		}
	case 33:
		//line parse.y:245
		{
			hclVAL.f = hclS[hclpt-0].f
		}
	case 34:
		//line parse.y:251
		{
			hclVAL.str = "e" + strconv.FormatInt(int64(hclS[hclpt-0].num), 10)
		}
	case 35:
		//line parse.y:255
		{
			hclVAL.str = "e-" + strconv.FormatInt(int64(hclS[hclpt-0].num), 10)
		}
	}
	goto hclstack /* stack new state and value */
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/raft/inflight.go<|end_filename|>
package raft

import (
	"container/list"
	"sync"
)

// QuorumPolicy allows individual logFutures to have different
// commitment rules while still using the inflight mechanism
type quorumPolicy interface {
	// Checks if a commit from a given peer is enough to
	// satisfy the commitment rules
	Commit() bool

	// Checks if a commit is committed
	IsCommitted() bool
}

// MajorityQuorum is used by Apply transactions and requires
// a simple majority of nodes
type majorityQuorum struct {
	count       int
	votesNeeded int
}

func newMajorityQuorum(clusterSize int) *majorityQuorum {
	votesNeeded := (clusterSize / 2) + 1
	return &majorityQuorum{count: 0, votesNeeded: votesNeeded}
}

func (m *majorityQuorum) Commit() bool {
	m.count++
	return m.count >= m.votesNeeded
}

func (m *majorityQuorum) IsCommitted() bool {
	return m.count >= m.votesNeeded
}

// Inflight is used to track operations that are still in-flight
type inflight struct {
	sync.Mutex
	committed  *list.List
	commitCh   chan struct{}
	minCommit  uint64
	maxCommit  uint64
	operations map[uint64]*logFuture
	stopCh     chan struct{}
}

// NewInflight returns an inflight struct that notifies
// the provided channel when logs are finished commiting.
func newInflight(commitCh chan struct{}) *inflight {
	return &inflight{
		committed:  list.New(),
		commitCh:   commitCh,
		minCommit:  0,
		maxCommit:  0,
		operations: make(map[uint64]*logFuture),
		stopCh:     make(chan struct{}),
	}
}

// Start is used to mark a logFuture as being inflight. It
// also commits the entry, as it is assumed the leader is
// starting.
func (i *inflight) Start(l *logFuture) {
	i.Lock()
	defer i.Unlock()
	i.start(l)
}

// StartAll is used to mark a list of logFuture's as being
// inflight. It also commits each entry as the leader is
// assumed to be starting.
func (i *inflight) StartAll(logs []*logFuture) {
	i.Lock()
	defer i.Unlock()
	for _, l := range logs {
		i.start(l)
	}
}

// start is used to mark a single entry as inflight,
// must be invoked with the lock held
func (i *inflight) start(l *logFuture) {
	idx := l.log.Index
	i.operations[idx] = l

	if idx > i.maxCommit {
		i.maxCommit = idx
	}
	if i.minCommit == 0 {
		i.minCommit = idx
	}
	i.commit(idx)
}

// Cancel is used to cancel all in-flight operations.
// This is done when the leader steps down, and all futures
// are sent the given error.
func (i *inflight) Cancel(err error) {
	// Close the channel first to unblock any pending commits
	close(i.stopCh)

	// Lock after close to avoid deadlock
	i.Lock()
	defer i.Unlock()

	// Respond to all inflight operations
	for _, op := range i.operations {
		op.respond(err)
	}

	// Clear all the committed but not processed
	for e := i.committed.Front(); e != nil; e = e.Next() {
		e.Value.(*logFuture).respond(err)
	}

	// Clear the map
	i.operations = make(map[uint64]*logFuture)

	// Clear the list of committed
	i.committed = list.New()

	// Close the commmitCh
	close(i.commitCh)

	// Reset indexes
	i.minCommit = 0
	i.maxCommit = 0
}

// Committed returns all the committed operations in order
func (i *inflight) Committed() (l *list.List) {
	i.Lock()
	l, i.committed = i.committed, list.New()
	i.Unlock()
	return l
}

// Commit is used by leader replication routines to indicate that
// a follower was finished commiting a log to disk.
func (i *inflight) Commit(index uint64) {
	i.Lock()
	defer i.Unlock()
	i.commit(index)
}

// CommitRange is used to commit a range of indexes inclusively
// It optimized to avoid commits for indexes that are not tracked
func (i *inflight) CommitRange(minIndex, maxIndex uint64) {
	i.Lock()
	defer i.Unlock()

	// Update the minimum index
	minIndex = max(i.minCommit, minIndex)

	// Commit each index
	for idx := minIndex; idx <= maxIndex; idx++ {
		i.commit(idx)
	}
}

// commit is used to commit a single index. Must be called with the lock held.
func (i *inflight) commit(index uint64) {
	op, ok := i.operations[index]
	if !ok {
		// Ignore if not in the map, as it may be commited already
		return
	}

	// Check if we've satisfied the commit
	if !op.policy.Commit() {
		return
	}

	// Cannot commit if this is not the minimum inflight. This can happen
	// if the quorum size changes, meaning a previous commit requires a larger
	// quorum that this commit. We MUST block until the previous log is committed,
	// otherwise logs will be applied out of order.
	if index != i.minCommit {
		return
	}

NOTIFY:
	// Add the operation to the committed list
	i.committed.PushBack(op)

	// Stop tracking since it is committed
	delete(i.operations, index)

	// Update the indexes
	if index == i.maxCommit {
		i.minCommit = 0
		i.maxCommit = 0

	} else {
		i.minCommit++
	}

	// Check if the next in-flight operation is ready
	if i.minCommit != 0 {
		op = i.operations[i.minCommit]
		if op.policy.IsCommitted() {
			index = i.minCommit
			goto NOTIFY
		}
	}

	// Async notify of ready operations
	asyncNotifyCh(i.commitCh)
}


<|start_filename|>Godeps/_workspace/src/github.com/cenkalti/hub/hub_test.go<|end_filename|>
package hub

import "testing"

const testKind = 1
const testValue = "foo"

type testEvent string

func (e testEvent) Kind() int {
	return testKind
}

func TestPubSub(t *testing.T) {
	var h Hub
	var s string

	h.Subscribe(testKind, func(e Event) { s = string(e.(testEvent)) })
	h.Publish(testEvent(testValue))

	if s != testValue {
		t.Errorf("invalid value: %s", s)
	}
}

func TestCancel(t *testing.T) {
	var h Hub
	var called bool

	cancel := h.Subscribe(testKind, func(e Event) { called = true })
	cancel()
	h.Publish(testEvent(testValue))

	if called {
		t.Error("unexpected call")
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/consul/fsm.go<|end_filename|>
package consul

import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"time"

	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/armon/go-metrics"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/consul/structs"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/go-msgpack/codec"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/raft"
)

// consulFSM implements a finite state machine that is used
// along with Raft to provide strong consistency. We implement
// this outside the Server to avoid exposing this outside the package.
type consulFSM struct {
	logOutput io.Writer
	logger    *log.Logger
	path      string
	state     *StateStore
	gc        *TombstoneGC
}

// consulSnapshot is used to provide a snapshot of the current
// state in a way that can be accessed concurrently with operations
// that may modify the live state.
type consulSnapshot struct {
	state *StateSnapshot
}

// snapshotHeader is the first entry in our snapshot
type snapshotHeader struct {
	// LastIndex is the last index that affects the data.
	// This is used when we do the restore for watchers.
	LastIndex uint64
}

// NewFSMPath is used to construct a new FSM with a blank state
func NewFSM(gc *TombstoneGC, path string, logOutput io.Writer) (*consulFSM, error) {
	// Create a temporary path for the state store
	tmpPath, err := ioutil.TempDir(path, "state")
	if err != nil {
		return nil, err
	}

	// Create a state store
	state, err := NewStateStorePath(gc, tmpPath, logOutput)
	if err != nil {
		return nil, err
	}

	fsm := &consulFSM{
		logOutput: logOutput,
		logger:    log.New(logOutput, "", log.LstdFlags),
		path:      path,
		state:     state,
		gc:        gc,
	}
	return fsm, nil
}

// Close is used to cleanup resources associated with the FSM
func (c *consulFSM) Close() error {
	return c.state.Close()
}

// State is used to return a handle to the current state
func (c *consulFSM) State() *StateStore {
	return c.state
}

func (c *consulFSM) Apply(log *raft.Log) interface{} {
	buf := log.Data
	switch structs.MessageType(buf[0]) {
	case structs.RegisterRequestType:
		return c.decodeRegister(buf[1:], log.Index)
	case structs.DeregisterRequestType:
		return c.applyDeregister(buf[1:], log.Index)
	case structs.KVSRequestType:
		return c.applyKVSOperation(buf[1:], log.Index)
	case structs.SessionRequestType:
		return c.applySessionOperation(buf[1:], log.Index)
	case structs.ACLRequestType:
		return c.applyACLOperation(buf[1:], log.Index)
	case structs.TombstoneRequestType:
		return c.applyTombstoneOperation(buf[1:], log.Index)
	default:
		panic(fmt.Errorf("failed to apply request: %#v", buf))
	}
}

func (c *consulFSM) decodeRegister(buf []byte, index uint64) interface{} {
	var req structs.RegisterRequest
	if err := structs.Decode(buf, &req); err != nil {
		panic(fmt.Errorf("failed to decode request: %v", err))
	}
	return c.applyRegister(&req, index)
}

func (c *consulFSM) applyRegister(req *structs.RegisterRequest, index uint64) interface{} {
	defer metrics.MeasureSince([]string{"consul", "fsm", "register"}, time.Now())
	// Apply all updates in a single transaction
	if err := c.state.EnsureRegistration(index, req); err != nil {
		c.logger.Printf("[INFO] consul.fsm: EnsureRegistration failed: %v", err)
		return err
	}
	return nil
}

func (c *consulFSM) applyDeregister(buf []byte, index uint64) interface{} {
	defer metrics.MeasureSince([]string{"consul", "fsm", "deregister"}, time.Now())
	var req structs.DeregisterRequest
	if err := structs.Decode(buf, &req); err != nil {
		panic(fmt.Errorf("failed to decode request: %v", err))
	}

	// Either remove the service entry or the whole node
	if req.ServiceID != "" {
		if err := c.state.DeleteNodeService(index, req.Node, req.ServiceID); err != nil {
			c.logger.Printf("[INFO] consul.fsm: DeleteNodeService failed: %v", err)
			return err
		}
	} else if req.CheckID != "" {
		if err := c.state.DeleteNodeCheck(index, req.Node, req.CheckID); err != nil {
			c.logger.Printf("[INFO] consul.fsm: DeleteNodeCheck failed: %v", err)
			return err
		}
	} else {
		if err := c.state.DeleteNode(index, req.Node); err != nil {
			c.logger.Printf("[INFO] consul.fsm: DeleteNode failed: %v", err)
			return err
		}
	}
	return nil
}

func (c *consulFSM) applyKVSOperation(buf []byte, index uint64) interface{} {
	var req structs.KVSRequest
	if err := structs.Decode(buf, &req); err != nil {
		panic(fmt.Errorf("failed to decode request: %v", err))
	}
	defer metrics.MeasureSince([]string{"consul", "fsm", "kvs", string(req.Op)}, time.Now())
	switch req.Op {
	case structs.KVSSet:
		return c.state.KVSSet(index, &req.DirEnt)
	case structs.KVSDelete:
		return c.state.KVSDelete(index, req.DirEnt.Key)
	case structs.KVSDeleteCAS:
		act, err := c.state.KVSDeleteCheckAndSet(index, req.DirEnt.Key, req.DirEnt.ModifyIndex)
		if err != nil {
			return err
		} else {
			return act
		}
	case structs.KVSDeleteTree:
		return c.state.KVSDeleteTree(index, req.DirEnt.Key)
	case structs.KVSCAS:
		act, err := c.state.KVSCheckAndSet(index, &req.DirEnt)
		if err != nil {
			return err
		} else {
			return act
		}
	case structs.KVSLock:
		act, err := c.state.KVSLock(index, &req.DirEnt)
		if err != nil {
			return err
		} else {
			return act
		}
	case structs.KVSUnlock:
		act, err := c.state.KVSUnlock(index, &req.DirEnt)
		if err != nil {
			return err
		} else {
			return act
		}
	default:
		err := errors.New(fmt.Sprintf("Invalid KVS operation '%s'", req.Op))
		c.logger.Printf("[WARN] consul.fsm: %v", err)
		return err
	}
}

func (c *consulFSM) applySessionOperation(buf []byte, index uint64) interface{} {
	var req structs.SessionRequest
	if err := structs.Decode(buf, &req); err != nil {
		panic(fmt.Errorf("failed to decode request: %v", err))
	}
	defer metrics.MeasureSince([]string{"consul", "fsm", "session", string(req.Op)}, time.Now())
	switch req.Op {
	case structs.SessionCreate:
		if err := c.state.SessionCreate(index, &req.Session); err != nil {
			return err
		} else {
			return req.Session.ID
		}
	case structs.SessionDestroy:
		return c.state.SessionDestroy(index, req.Session.ID)
	default:
		c.logger.Printf("[WARN] consul.fsm: Invalid Session operation '%s'", req.Op)
		return fmt.Errorf("Invalid Session operation '%s'", req.Op)
	}
}

func (c *consulFSM) applyACLOperation(buf []byte, index uint64) interface{} {
	var req structs.ACLRequest
	if err := structs.Decode(buf, &req); err != nil {
		panic(fmt.Errorf("failed to decode request: %v", err))
	}
	defer metrics.MeasureSince([]string{"consul", "fsm", "acl", string(req.Op)}, time.Now())
	switch req.Op {
	case structs.ACLForceSet:
		fallthrough
	case structs.ACLSet:
		if err := c.state.ACLSet(index, &req.ACL); err != nil {
			return err
		} else {
			return req.ACL.ID
		}
	case structs.ACLDelete:
		return c.state.ACLDelete(index, req.ACL.ID)
	default:
		c.logger.Printf("[WARN] consul.fsm: Invalid ACL operation '%s'", req.Op)
		return fmt.Errorf("Invalid ACL operation '%s'", req.Op)
	}
}

func (c *consulFSM) applyTombstoneOperation(buf []byte, index uint64) interface{} {
	var req structs.TombstoneRequest
	if err := structs.Decode(buf, &req); err != nil {
		panic(fmt.Errorf("failed to decode request: %v", err))
	}
	defer metrics.MeasureSince([]string{"consul", "fsm", "tombstone", string(req.Op)}, time.Now())
	switch req.Op {
	case structs.TombstoneReap:
		return c.state.ReapTombstones(req.ReapIndex)
	default:
		c.logger.Printf("[WARN] consul.fsm: Invalid Tombstone operation '%s'", req.Op)
		return fmt.Errorf("Invalid Tombstone operation '%s'", req.Op)
	}
}

func (c *consulFSM) Snapshot() (raft.FSMSnapshot, error) {
	defer func(start time.Time) {
		c.logger.Printf("[INFO] consul.fsm: snapshot created in %v", time.Now().Sub(start))
	}(time.Now())

	// Create a new snapshot
	snap, err := c.state.Snapshot()
	if err != nil {
		return nil, err
	}
	return &consulSnapshot{snap}, nil
}

func (c *consulFSM) Restore(old io.ReadCloser) error {
	defer old.Close()

	// Create a temporary path for the state store
	tmpPath, err := ioutil.TempDir(c.path, "state")
	if err != nil {
		return err
	}

	// Create a new state store
	state, err := NewStateStorePath(c.gc, tmpPath, c.logOutput)
	if err != nil {
		return err
	}
	c.state.Close()
	c.state = state

	// Create a decoder
	dec := codec.NewDecoder(old, msgpackHandle)

	// Read in the header
	var header snapshotHeader
	if err := dec.Decode(&header); err != nil {
		return err
	}

	// Populate the new state
	msgType := make([]byte, 1)
	for {
		// Read the message type
		_, err := old.Read(msgType)
		if err == io.EOF {
			break
		} else if err != nil {
			return err
		}

		// Decode
		switch structs.MessageType(msgType[0]) {
		case structs.RegisterRequestType:
			var req structs.RegisterRequest
			if err := dec.Decode(&req); err != nil {
				return err
			}
			c.applyRegister(&req, header.LastIndex)

		case structs.KVSRequestType:
			var req structs.DirEntry
			if err := dec.Decode(&req); err != nil {
				return err
			}
			if err := c.state.KVSRestore(&req); err != nil {
				return err
			}

		case structs.SessionRequestType:
			var req structs.Session
			if err := dec.Decode(&req); err != nil {
				return err
			}
			if err := c.state.SessionRestore(&req); err != nil {
				return err
			}

		case structs.ACLRequestType:
			var req structs.ACL
			if err := dec.Decode(&req); err != nil {
				return err
			}
			if err := c.state.ACLRestore(&req); err != nil {
				return err
			}

		case structs.TombstoneRequestType:
			var req structs.DirEntry
			if err := dec.Decode(&req); err != nil {
				return err
			}
			if err := c.state.TombstoneRestore(&req); err != nil {
				return err
			}

		default:
			return fmt.Errorf("Unrecognized msg type: %v", msgType)
		}
	}

	return nil
}

func (s *consulSnapshot) Persist(sink raft.SnapshotSink) error {
	defer metrics.MeasureSince([]string{"consul", "fsm", "persist"}, time.Now())
	// Register the nodes
	encoder := codec.NewEncoder(sink, msgpackHandle)

	// Write the header
	header := snapshotHeader{
		LastIndex: s.state.LastIndex(),
	}
	if err := encoder.Encode(&header); err != nil {
		sink.Cancel()
		return err
	}

	if err := s.persistNodes(sink, encoder); err != nil {
		sink.Cancel()
		return err
	}

	if err := s.persistSessions(sink, encoder); err != nil {
		sink.Cancel()
		return err
	}

	if err := s.persistACLs(sink, encoder); err != nil {
		sink.Cancel()
		return err
	}

	if err := s.persistKV(sink, encoder); err != nil {
		sink.Cancel()
		return err
	}

	if err := s.persistTombstones(sink, encoder); err != nil {
		sink.Cancel()
		return err
	}
	return nil
}

func (s *consulSnapshot) persistNodes(sink raft.SnapshotSink,
	encoder *codec.Encoder) error {
	// Get all the nodes
	nodes := s.state.Nodes()

	// Register each node
	var req structs.RegisterRequest
	for i := 0; i < len(nodes); i++ {
		req = structs.RegisterRequest{
			Node:    nodes[i].Node,
			Address: nodes[i].Address,
		}

		// Register the node itself
		sink.Write([]byte{byte(structs.RegisterRequestType)})
		if err := encoder.Encode(&req); err != nil {
			return err
		}

		// Register each service this node has
		services := s.state.NodeServices(nodes[i].Node)
		for _, srv := range services.Services {
			req.Service = srv
			sink.Write([]byte{byte(structs.RegisterRequestType)})
			if err := encoder.Encode(&req); err != nil {
				return err
			}
		}

		// Register each check this node has
		req.Service = nil
		checks := s.state.NodeChecks(nodes[i].Node)
		for _, check := range checks {
			req.Check = check
			sink.Write([]byte{byte(structs.RegisterRequestType)})
			if err := encoder.Encode(&req); err != nil {
				return err
			}
		}
	}
	return nil
}

func (s *consulSnapshot) persistSessions(sink raft.SnapshotSink,
	encoder *codec.Encoder) error {
	sessions, err := s.state.SessionList()
	if err != nil {
		return err
	}

	for _, s := range sessions {
		sink.Write([]byte{byte(structs.SessionRequestType)})
		if err := encoder.Encode(s); err != nil {
			return err
		}
	}
	return nil
}

func (s *consulSnapshot) persistACLs(sink raft.SnapshotSink,
	encoder *codec.Encoder) error {
	acls, err := s.state.ACLList()
	if err != nil {
		return err
	}

	for _, s := range acls {
		sink.Write([]byte{byte(structs.ACLRequestType)})
		if err := encoder.Encode(s); err != nil {
			return err
		}
	}
	return nil
}

func (s *consulSnapshot) persistKV(sink raft.SnapshotSink,
	encoder *codec.Encoder) error {
	streamCh := make(chan interface{}, 256)
	errorCh := make(chan error)
	go func() {
		if err := s.state.KVSDump(streamCh); err != nil {
			errorCh <- err
		}
	}()

	for {
		select {
		case raw := <-streamCh:
			if raw == nil {
				return nil
			}
			sink.Write([]byte{byte(structs.KVSRequestType)})
			if err := encoder.Encode(raw); err != nil {
				return err
			}

		case err := <-errorCh:
			return err
		}
	}
}

func (s *consulSnapshot) persistTombstones(sink raft.SnapshotSink,
	encoder *codec.Encoder) error {
	streamCh := make(chan interface{}, 256)
	errorCh := make(chan error)
	go func() {
		if err := s.state.TombstoneDump(streamCh); err != nil {
			errorCh <- err
		}
	}()

	for {
		select {
		case raw := <-streamCh:
			if raw == nil {
				return nil
			}
			sink.Write([]byte{byte(structs.TombstoneRequestType)})
			if err := encoder.Encode(raw); err != nil {
				return err
			}

		case err := <-errorCh:
			return err
		}
	}
}

func (s *consulSnapshot) Release() {
	s.state.Close()
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/raft/peer.go<|end_filename|>
package raft

import (
	"bytes"
	"encoding/json"
	"io/ioutil"
	"net"
	"os"
	"path/filepath"
	"sync"
)

const (
	jsonPeerPath = "peers.json"
)

// PeerStore provides an interface for persistent storage and
// retrieval of peers. We use a seperate interface than StableStore
// since the peers may need to be editted by a human operator. For example,
// in a two node cluster, the failure of either node requires human intervention
// since consensus is impossible.
type PeerStore interface {
	// Peers returns the list of known peers.
	Peers() ([]net.Addr, error)

	// SetPeers sets the list of known peers. This is invoked when a peer is
	// added or removed.
	SetPeers([]net.Addr) error
}

// StaticPeers is used to provide a static list of peers.
type StaticPeers struct {
	StaticPeers []net.Addr
	l           sync.Mutex
}

// Peers implements the PeerStore interface.
func (s *StaticPeers) Peers() ([]net.Addr, error) {
	s.l.Lock()
	peers := s.StaticPeers
	s.l.Unlock()
	return peers, nil
}

// SetPeers implements the PeerStore interface.
func (s *StaticPeers) SetPeers(p []net.Addr) error {
	s.l.Lock()
	s.StaticPeers = p
	s.l.Unlock()
	return nil
}

// JSONPeers is used to provide peer persistence on disk in the form
// of a JSON file. This allows human operators to manipulate the file.
type JSONPeers struct {
	l     sync.Mutex
	path  string
	trans Transport
}

// NewJSONPeers creates a new JSONPeers store. Requires a transport
// to handle the serialization of network addresses
func NewJSONPeers(base string, trans Transport) *JSONPeers {
	path := filepath.Join(base, jsonPeerPath)
	store := &JSONPeers{
		path:  path,
		trans: trans,
	}
	return store
}

// Peers implements the PeerStore interface.
func (j *JSONPeers) Peers() ([]net.Addr, error) {
	j.l.Lock()
	defer j.l.Unlock()

	// Read the file
	buf, err := ioutil.ReadFile(j.path)
	if err != nil && !os.IsNotExist(err) {
		return nil, err
	}

	// Check for no peers
	if len(buf) == 0 {
		return nil, nil
	}

	// Decode the peers
	var peerSet []string
	dec := json.NewDecoder(bytes.NewReader(buf))
	if err := dec.Decode(&peerSet); err != nil {
		return nil, err
	}

	// Deserialize each peer
	var peers []net.Addr
	for _, p := range peerSet {
		peers = append(peers, j.trans.DecodePeer([]byte(p)))
	}
	return peers, nil
}

// SetPeers implements the PeerStore interface.
func (j *JSONPeers) SetPeers(peers []net.Addr) error {
	j.l.Lock()
	defer j.l.Unlock()

	// Encode each peer
	var peerSet []string
	for _, p := range peers {
		peerSet = append(peerSet, string(j.trans.EncodePeer(p)))
	}

	// Convert to JSON
	var buf bytes.Buffer
	enc := json.NewEncoder(&buf)
	if err := enc.Encode(peerSet); err != nil {
		return err
	}

	// Write out as JSON
	return ioutil.WriteFile(j.path, buf.Bytes(), 0755)
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/consul/state_store_test.go<|end_filename|>
package consul

import (
	"os"
	"reflect"
	"sort"
	"testing"
	"time"

	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/consul/structs"
)

func testStateStore() (*StateStore, error) {
	return NewStateStore(nil, os.Stderr)
}

func TestEnsureRegistration(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	reg := &structs.RegisterRequest{
		Node:    "foo",
		Address: "127.0.0.1",
		Service: &structs.NodeService{"api", "api", nil, "", 5000},
		Check: &structs.HealthCheck{
			Node:      "foo",
			CheckID:   "api",
			Name:      "Can connect",
			Status:    structs.HealthPassing,
			ServiceID: "api",
		},
	}

	if err := store.EnsureRegistration(13, reg); err != nil {
		t.Fatalf("err: %v", err)
	}

	idx, found, addr := store.GetNode("foo")
	if idx != 13 || !found || addr != "127.0.0.1" {
		t.Fatalf("Bad: %v %v %v", idx, found, addr)
	}

	idx, services := store.NodeServices("foo")
	if idx != 13 {
		t.Fatalf("bad: %v", idx)
	}

	entry, ok := services.Services["api"]
	if !ok {
		t.Fatalf("missing api: %#v", services)
	}
	if len(entry.Tags) != 0 || entry.Port != 5000 {
		t.Fatalf("Bad entry: %#v", entry)
	}

	idx, checks := store.NodeChecks("foo")
	if idx != 13 {
		t.Fatalf("bad: %v", idx)
	}
	if len(checks) != 1 {
		t.Fatalf("check: %#v", checks)
	}
}

func TestEnsureNode(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(3, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}

	idx, found, addr := store.GetNode("foo")
	if idx != 3 || !found || addr != "127.0.0.1" {
		t.Fatalf("Bad: %v %v %v", idx, found, addr)
	}

	if err := store.EnsureNode(4, structs.Node{"foo", "127.0.0.2"}); err != nil {
		t.Fatalf("err: %v", err)
	}

	idx, found, addr = store.GetNode("foo")
	if idx != 4 || !found || addr != "127.0.0.2" {
		t.Fatalf("Bad: %v %v %v", idx, found, addr)
	}
}

func TestGetNodes(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(40, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureNode(41, structs.Node{"bar", "127.0.0.2"}); err != nil {
		t.Fatalf("err: %v", err)
	}

	idx, nodes := store.Nodes()
	if idx != 41 {
		t.Fatalf("idx: %v", idx)
	}
	if len(nodes) != 2 {
		t.Fatalf("Bad: %v", nodes)
	}
	if nodes[1].Node != "foo" && nodes[0].Node != "bar" {
		t.Fatalf("Bad: %v", nodes)
	}
}

func BenchmarkGetNodes(b *testing.B) {
	store, err := testStateStore()
	if err != nil {
		b.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(100, structs.Node{"foo", "127.0.0.1"}); err != nil {
		b.Fatalf("err: %v", err)
	}

	if err := store.EnsureNode(101, structs.Node{"bar", "127.0.0.2"}); err != nil {
		b.Fatalf("err: %v", err)
	}

	for i := 0; i < b.N; i++ {
		store.Nodes()
	}
}

func TestEnsureService(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(10, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(11, "foo", &structs.NodeService{"api", "api", nil, "", 5000}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(12, "foo", &structs.NodeService{"api", "api", nil, "", 5001}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(13, "foo", &structs.NodeService{"db", "db", []string{"master"}, "", 8000}); err != nil {
		t.Fatalf("err: %v", err)
	}

	idx, services := store.NodeServices("foo")
	if idx != 13 {
		t.Fatalf("bad: %v", idx)
	}

	entry, ok := services.Services["api"]
	if !ok {
		t.Fatalf("missing api: %#v", services)
	}
	if len(entry.Tags) != 0 || entry.Port != 5001 {
		t.Fatalf("Bad entry: %#v", entry)
	}

	entry, ok = services.Services["db"]
	if !ok {
		t.Fatalf("missing db: %#v", services)
	}
	if !strContains(entry.Tags, "master") || entry.Port != 8000 {
		t.Fatalf("Bad entry: %#v", entry)
	}
}

func TestEnsureService_DuplicateNode(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(10, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(11, "foo", &structs.NodeService{"api1", "api", nil, "", 5000}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(12, "foo", &structs.NodeService{"api2", "api", nil, "", 5001}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(13, "foo", &structs.NodeService{"api3", "api", nil, "", 5002}); err != nil {
		t.Fatalf("err: %v", err)
	}

	idx, services := store.NodeServices("foo")
	if idx != 13 {
		t.Fatalf("bad: %v", idx)
	}

	entry, ok := services.Services["api1"]
	if !ok {
		t.Fatalf("missing api: %#v", services)
	}
	if len(entry.Tags) != 0 || entry.Port != 5000 {
		t.Fatalf("Bad entry: %#v", entry)
	}

	entry, ok = services.Services["api2"]
	if !ok {
		t.Fatalf("missing api: %#v", services)
	}
	if len(entry.Tags) != 0 || entry.Port != 5001 {
		t.Fatalf("Bad entry: %#v", entry)
	}

	entry, ok = services.Services["api3"]
	if !ok {
		t.Fatalf("missing api: %#v", services)
	}
	if len(entry.Tags) != 0 || entry.Port != 5002 {
		t.Fatalf("Bad entry: %#v", entry)
	}
}

func TestDeleteNodeService(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(11, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(12, "foo", &structs.NodeService{"api", "api", nil, "", 5000}); err != nil {
		t.Fatalf("err: %v", err)
	}

	check := &structs.HealthCheck{
		Node:      "foo",
		CheckID:   "api",
		Name:      "Can connect",
		Status:    structs.HealthPassing,
		ServiceID: "api",
	}
	if err := store.EnsureCheck(13, check); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.DeleteNodeService(14, "foo", "api"); err != nil {
		t.Fatalf("err: %v", err)
	}

	idx, services := store.NodeServices("foo")
	if idx != 14 {
		t.Fatalf("bad: %v", idx)
	}
	_, ok := services.Services["api"]
	if ok {
		t.Fatalf("has api: %#v", services)
	}

	idx, checks := store.NodeChecks("foo")
	if idx != 14 {
		t.Fatalf("bad: %v", idx)
	}
	if len(checks) != 0 {
		t.Fatalf("has check: %#v", checks)
	}
}

func TestDeleteNodeService_One(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(11, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(12, "foo", &structs.NodeService{"api", "api", nil, "", 5000}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(13, "foo", &structs.NodeService{"api2", "api", nil, "", 5001}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.DeleteNodeService(14, "foo", "api"); err != nil {
		t.Fatalf("err: %v", err)
	}

	idx, services := store.NodeServices("foo")
	if idx != 14 {
		t.Fatalf("bad: %v", idx)
	}
	_, ok := services.Services["api"]
	if ok {
		t.Fatalf("has api: %#v", services)
	}
	_, ok = services.Services["api2"]
	if !ok {
		t.Fatalf("does not have api2: %#v", services)
	}
}

func TestDeleteNode(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(20, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(21, "foo", &structs.NodeService{"api", "api", nil, "", 5000}); err != nil {
		t.Fatalf("err: %v", err)
	}

	check := &structs.HealthCheck{
		Node:      "foo",
		CheckID:   "db",
		Name:      "Can connect",
		Status:    structs.HealthPassing,
		ServiceID: "api",
	}
	if err := store.EnsureCheck(22, check); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.DeleteNode(23, "foo"); err != nil {
		t.Fatalf("err: %v", err)
	}

	idx, services := store.NodeServices("foo")
	if idx != 23 {
		t.Fatalf("bad: %v", idx)
	}
	if services != nil {
		t.Fatalf("has services: %#v", services)
	}

	idx, checks := store.NodeChecks("foo")
	if idx != 23 {
		t.Fatalf("bad: %v", idx)
	}
	if len(checks) > 0 {
		t.Fatalf("has checks: %v", checks)
	}

	idx, found, _ := store.GetNode("foo")
	if idx != 23 {
		t.Fatalf("bad: %v", idx)
	}
	if found {
		t.Fatalf("found node")
	}
}

func TestGetServices(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(30, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureNode(31, structs.Node{"bar", "127.0.0.2"}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(32, "foo", &structs.NodeService{"api", "api", nil, "", 5000}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(33, "foo", &structs.NodeService{"db", "db", []string{"master"}, "", 8000}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(34, "bar", &structs.NodeService{"db", "db", []string{"slave"}, "", 8000}); err != nil {
		t.Fatalf("err: %v", err)
	}

	idx, services := store.Services()
	if idx != 34 {
		t.Fatalf("bad: %v", idx)
	}

	tags, ok := services["api"]
	if !ok {
		t.Fatalf("missing api: %#v", services)
	}
	if len(tags) != 0 {
		t.Fatalf("Bad entry: %#v", tags)
	}

	tags, ok = services["db"]
	sort.Strings(tags)
	if !ok {
		t.Fatalf("missing db: %#v", services)
	}
	if len(tags) != 2 || tags[0] != "master" || tags[1] != "slave" {
		t.Fatalf("Bad entry: %#v", tags)
	}
}

func TestServiceNodes(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(10, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureNode(11, structs.Node{"bar", "127.0.0.2"}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(12, "foo", &structs.NodeService{"api", "api", nil, "", 5000}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(13, "bar", &structs.NodeService{"api", "api", nil, "", 5000}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(14, "foo", &structs.NodeService{"db", "db", []string{"master"}, "", 8000}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(15, "bar", &structs.NodeService{"db", "db", []string{"slave"}, "", 8000}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(16, "bar", &structs.NodeService{"db2", "db", []string{"slave"}, "", 8001}); err != nil {
		t.Fatalf("err: %v", err)
	}

	idx, nodes := store.ServiceNodes("db")
	if idx != 16 {
		t.Fatalf("bad: %v", 16)
	}
	if len(nodes) != 3 {
		t.Fatalf("bad: %v", nodes)
	}
	if nodes[0].Node != "foo" {
		t.Fatalf("bad: %v", nodes)
	}
	if nodes[0].Address != "127.0.0.1" {
		t.Fatalf("bad: %v", nodes)
	}
	if nodes[0].ServiceID != "db" {
		t.Fatalf("bad: %v", nodes)
	}
	if !strContains(nodes[0].ServiceTags, "master") {
		t.Fatalf("bad: %v", nodes)
	}
	if nodes[0].ServicePort != 8000 {
		t.Fatalf("bad: %v", nodes)
	}

	if nodes[1].Node != "bar" {
		t.Fatalf("bad: %v", nodes)
	}
	if nodes[1].Address != "127.0.0.2" {
		t.Fatalf("bad: %v", nodes)
	}
	if nodes[1].ServiceID != "db" {
		t.Fatalf("bad: %v", nodes)
	}
	if !strContains(nodes[1].ServiceTags, "slave") {
		t.Fatalf("bad: %v", nodes)
	}
	if nodes[1].ServicePort != 8000 {
		t.Fatalf("bad: %v", nodes)
	}

	if nodes[2].Node != "bar" {
		t.Fatalf("bad: %v", nodes)
	}
	if nodes[2].Address != "127.0.0.2" {
		t.Fatalf("bad: %v", nodes)
	}
	if nodes[2].ServiceID != "db2" {
		t.Fatalf("bad: %v", nodes)
	}
	if !strContains(nodes[2].ServiceTags, "slave") {
		t.Fatalf("bad: %v", nodes)
	}
	if nodes[2].ServicePort != 8001 {
		t.Fatalf("bad: %v", nodes)
	}
}

func TestServiceTagNodes(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(15, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureNode(16, structs.Node{"bar", "127.0.0.2"}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(17, "foo", &structs.NodeService{"db", "db", []string{"master"}, "", 8000}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(18, "foo", &structs.NodeService{"db2", "db", []string{"slave"}, "", 8001}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(19, "bar", &structs.NodeService{"db", "db", []string{"slave"}, "", 8000}); err != nil {
		t.Fatalf("err: %v", err)
	}

	idx, nodes := store.ServiceTagNodes("db", "master")
	if idx != 19 {
		t.Fatalf("bad: %v", idx)
	}
	if len(nodes) != 1 {
		t.Fatalf("bad: %v", nodes)
	}
	if nodes[0].Node != "foo" {
		t.Fatalf("bad: %v", nodes)
	}
	if nodes[0].Address != "127.0.0.1" {
		t.Fatalf("bad: %v", nodes)
	}
	if !strContains(nodes[0].ServiceTags, "master") {
		t.Fatalf("bad: %v", nodes)
	}
	if nodes[0].ServicePort != 8000 {
		t.Fatalf("bad: %v", nodes)
	}
}

func TestServiceTagNodes_MultipleTags(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(15, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureNode(16, structs.Node{"bar", "127.0.0.2"}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(17, "foo", &structs.NodeService{"db", "db", []string{"master", "v2"}, "", 8000}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(18, "foo", &structs.NodeService{"db2", "db", []string{"slave", "v2", "dev"}, "", 8001}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(19, "bar", &structs.NodeService{"db", "db", []string{"slave", "v2"}, "", 8000}); err != nil {
		t.Fatalf("err: %v", err)
	}

	idx, nodes := store.ServiceTagNodes("db", "master")
	if idx != 19 {
		t.Fatalf("bad: %v", idx)
	}
	if len(nodes) != 1 {
		t.Fatalf("bad: %v", nodes)
	}
	if nodes[0].Node != "foo" {
		t.Fatalf("bad: %v", nodes)
	}
	if nodes[0].Address != "127.0.0.1" {
		t.Fatalf("bad: %v", nodes)
	}
	if !strContains(nodes[0].ServiceTags, "master") {
		t.Fatalf("bad: %v", nodes)
	}
	if nodes[0].ServicePort != 8000 {
		t.Fatalf("bad: %v", nodes)
	}

	idx, nodes = store.ServiceTagNodes("db", "v2")
	if idx != 19 {
		t.Fatalf("bad: %v", idx)
	}
	if len(nodes) != 3 {
		t.Fatalf("bad: %v", nodes)
	}

	idx, nodes = store.ServiceTagNodes("db", "dev")
	if idx != 19 {
		t.Fatalf("bad: %v", idx)
	}
	if len(nodes) != 1 {
		t.Fatalf("bad: %v", nodes)
	}
	if nodes[0].Node != "foo" {
		t.Fatalf("bad: %v", nodes)
	}
	if nodes[0].Address != "127.0.0.1" {
		t.Fatalf("bad: %v", nodes)
	}
	if !strContains(nodes[0].ServiceTags, "dev") {
		t.Fatalf("bad: %v", nodes)
	}
	if nodes[0].ServicePort != 8001 {
		t.Fatalf("bad: %v", nodes)
	}
}

func TestStoreSnapshot(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(8, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureNode(9, structs.Node{"bar", "127.0.0.2"}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(10, "foo", &structs.NodeService{"db", "db", []string{"master"}, "", 8000}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(11, "foo", &structs.NodeService{"db2", "db", []string{"slave"}, "", 8001}); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.EnsureService(12, "bar", &structs.NodeService{"db", "db", []string{"slave"}, "", 8000}); err != nil {
		t.Fatalf("err: %v", err)
	}

	check := &structs.HealthCheck{
		Node:      "foo",
		CheckID:   "db",
		Name:      "Can connect",
		Status:    structs.HealthPassing,
		ServiceID: "db",
	}
	if err := store.EnsureCheck(13, check); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Add some KVS entries
	d := &structs.DirEntry{Key: "/web/a", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(14, d); err != nil {
		t.Fatalf("err: %v", err)
	}
	d = &structs.DirEntry{Key: "/web/b", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(15, d); err != nil {
		t.Fatalf("err: %v", err)
	}
	d = &structs.DirEntry{Key: "/web/c", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(16, d); err != nil {
		t.Fatalf("err: %v", err)
	}
	// Create a tombstone
	// TODO: Change to /web/c causes failure?
	if err := store.KVSDelete(17, "/web/a"); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Add some sessions
	session := &structs.Session{ID: generateUUID(), Node: "foo"}
	if err := store.SessionCreate(18, session); err != nil {
		t.Fatalf("err: %v", err)
	}

	session = &structs.Session{ID: generateUUID(), Node: "bar"}
	if err := store.SessionCreate(19, session); err != nil {
		t.Fatalf("err: %v", err)
	}
	d.Session = session.ID
	if ok, err := store.KVSLock(20, d); err != nil || !ok {
		t.Fatalf("err: %v", err)
	}
	session = &structs.Session{ID: generateUUID(), Node: "bar", TTL: "60s"}
	if err := store.SessionCreate(21, session); err != nil {
		t.Fatalf("err: %v", err)
	}

	a1 := &structs.ACL{
		ID:   generateUUID(),
		Name: "User token",
		Type: structs.ACLTypeClient,
	}
	if err := store.ACLSet(21, a1); err != nil {
		t.Fatalf("err: %v", err)
	}

	a2 := &structs.ACL{
		ID:   generateUUID(),
		Name: "User token",
		Type: structs.ACLTypeClient,
	}
	if err := store.ACLSet(22, a2); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Take a snapshot
	snap, err := store.Snapshot()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer snap.Close()

	// Check the last nodes
	if idx := snap.LastIndex(); idx != 22 {
		t.Fatalf("bad: %v", idx)
	}

	// Check snapshot has old values
	nodes := snap.Nodes()
	if len(nodes) != 2 {
		t.Fatalf("bad: %v", nodes)
	}

	// Ensure we get the service entries
	services := snap.NodeServices("foo")
	if !strContains(services.Services["db"].Tags, "master") {
		t.Fatalf("bad: %v", services)
	}
	if !strContains(services.Services["db2"].Tags, "slave") {
		t.Fatalf("bad: %v", services)
	}

	services = snap.NodeServices("bar")
	if !strContains(services.Services["db"].Tags, "slave") {
		t.Fatalf("bad: %v", services)
	}

	// Ensure we get the checks
	checks := snap.NodeChecks("foo")
	if len(checks) != 1 {
		t.Fatalf("bad: %v", checks)
	}
	if !reflect.DeepEqual(checks[0], check) {
		t.Fatalf("bad: %v", checks[0])
	}

	// Check we have the entries
	streamCh := make(chan interface{}, 64)
	doneCh := make(chan struct{})
	var ents []*structs.DirEntry
	go func() {
		for {
			obj := <-streamCh
			if obj == nil {
				close(doneCh)
				return
			}
			ents = append(ents, obj.(*structs.DirEntry))
		}
	}()
	if err := snap.KVSDump(streamCh); err != nil {
		t.Fatalf("err: %v", err)
	}
	<-doneCh
	if len(ents) != 2 {
		t.Fatalf("missing KVS entries! %#v", ents)
	}

	// Check we have the tombstone entries
	streamCh = make(chan interface{}, 64)
	doneCh = make(chan struct{})
	ents = nil
	go func() {
		for {
			obj := <-streamCh
			if obj == nil {
				close(doneCh)
				return
			}
			ents = append(ents, obj.(*structs.DirEntry))
		}
	}()
	if err := snap.TombstoneDump(streamCh); err != nil {
		t.Fatalf("err: %v", err)
	}
	<-doneCh
	if len(ents) != 1 {
		t.Fatalf("missing tombstone entries!")
	}

	// Check there are 3 sessions
	sessions, err := snap.SessionList()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if len(sessions) != 3 {
		t.Fatalf("missing sessions")
	}

	ttls := 0
	for _, session := range sessions {
		if session.TTL != "" {
			ttls++
		}
	}
	if ttls != 1 {
		t.Fatalf("Wrong number of sessions with TTL")
	}

	// Check for an acl
	acls, err := snap.ACLList()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if len(acls) != 2 {
		t.Fatalf("missing acls")
	}

	// Make some changes!
	if err := store.EnsureService(23, "foo", &structs.NodeService{"db", "db", []string{"slave"}, "", 8000}); err != nil {
		t.Fatalf("err: %v", err)
	}
	if err := store.EnsureService(24, "bar", &structs.NodeService{"db", "db", []string{"master"}, "", 8000}); err != nil {
		t.Fatalf("err: %v", err)
	}
	if err := store.EnsureNode(25, structs.Node{"baz", "127.0.0.3"}); err != nil {
		t.Fatalf("err: %v", err)
	}
	checkAfter := &structs.HealthCheck{
		Node:      "foo",
		CheckID:   "db",
		Name:      "Can connect",
		Status:    structs.HealthCritical,
		ServiceID: "db",
	}
	if err := store.EnsureCheck(27, checkAfter); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.KVSDelete(28, "/web/b"); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Nuke an ACL
	if err := store.ACLDelete(29, a1.ID); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Check snapshot has old values
	nodes = snap.Nodes()
	if len(nodes) != 2 {
		t.Fatalf("bad: %v", nodes)
	}

	// Ensure old service entries
	services = snap.NodeServices("foo")
	if !strContains(services.Services["db"].Tags, "master") {
		t.Fatalf("bad: %v", services)
	}
	if !strContains(services.Services["db2"].Tags, "slave") {
		t.Fatalf("bad: %v", services)
	}

	services = snap.NodeServices("bar")
	if !strContains(services.Services["db"].Tags, "slave") {
		t.Fatalf("bad: %v", services)
	}

	checks = snap.NodeChecks("foo")
	if len(checks) != 1 {
		t.Fatalf("bad: %v", checks)
	}
	if !reflect.DeepEqual(checks[0], check) {
		t.Fatalf("bad: %v", checks[0])
	}

	// Check we have the entries
	streamCh = make(chan interface{}, 64)
	doneCh = make(chan struct{})
	ents = nil
	go func() {
		for {
			obj := <-streamCh
			if obj == nil {
				close(doneCh)
				return
			}
			ents = append(ents, obj.(*structs.DirEntry))
		}
	}()
	if err := snap.KVSDump(streamCh); err != nil {
		t.Fatalf("err: %v", err)
	}
	<-doneCh
	if len(ents) != 2 {
		t.Fatalf("missing KVS entries!")
	}

	// Check we have the tombstone entries
	streamCh = make(chan interface{}, 64)
	doneCh = make(chan struct{})
	ents = nil
	go func() {
		for {
			obj := <-streamCh
			if obj == nil {
				close(doneCh)
				return
			}
			ents = append(ents, obj.(*structs.DirEntry))
		}
	}()
	if err := snap.TombstoneDump(streamCh); err != nil {
		t.Fatalf("err: %v", err)
	}
	<-doneCh
	if len(ents) != 1 {
		t.Fatalf("missing tombstone entries!")
	}

	// Check there are 3 sessions
	sessions, err = snap.SessionList()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if len(sessions) != 3 {
		t.Fatalf("missing sessions")
	}

	// Check for an acl
	acls, err = snap.ACLList()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if len(acls) != 2 {
		t.Fatalf("missing acls")
	}
}

func TestEnsureCheck(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(1, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}
	if err := store.EnsureService(2, "foo", &structs.NodeService{"db1", "db", []string{"master"}, "", 8000}); err != nil {
		t.Fatalf("err: %v", err)
	}
	check := &structs.HealthCheck{
		Node:      "foo",
		CheckID:   "db",
		Name:      "Can connect",
		Status:    structs.HealthPassing,
		ServiceID: "db1",
	}
	if err := store.EnsureCheck(3, check); err != nil {
		t.Fatalf("err: %v", err)
	}

	check2 := &structs.HealthCheck{
		Node:    "foo",
		CheckID: "memory",
		Name:    "memory utilization",
		Status:  structs.HealthWarning,
	}
	if err := store.EnsureCheck(4, check2); err != nil {
		t.Fatalf("err: %v", err)
	}

	idx, checks := store.NodeChecks("foo")
	if idx != 4 {
		t.Fatalf("bad: %v", idx)
	}
	if len(checks) != 2 {
		t.Fatalf("bad: %v", checks)
	}
	if !reflect.DeepEqual(checks[0], check) {
		t.Fatalf("bad: %v", checks[0])
	}
	if !reflect.DeepEqual(checks[1], check2) {
		t.Fatalf("bad: %v", checks[1])
	}

	idx, checks = store.ServiceChecks("db")
	if idx != 4 {
		t.Fatalf("bad: %v", idx)
	}
	if len(checks) != 1 {
		t.Fatalf("bad: %v", checks)
	}
	if !reflect.DeepEqual(checks[0], check) {
		t.Fatalf("bad: %v", checks[0])
	}

	idx, checks = store.ChecksInState(structs.HealthPassing)
	if idx != 4 {
		t.Fatalf("bad: %v", idx)
	}
	if len(checks) != 1 {
		t.Fatalf("bad: %v", checks)
	}
	if !reflect.DeepEqual(checks[0], check) {
		t.Fatalf("bad: %v", checks[0])
	}

	idx, checks = store.ChecksInState(structs.HealthWarning)
	if idx != 4 {
		t.Fatalf("bad: %v", idx)
	}
	if len(checks) != 1 {
		t.Fatalf("bad: %v", checks)
	}
	if !reflect.DeepEqual(checks[0], check2) {
		t.Fatalf("bad: %v", checks[0])
	}

	idx, checks = store.ChecksInState(structs.HealthAny)
	if idx != 4 {
		t.Fatalf("bad: %v", idx)
	}
	if len(checks) != 2 {
		t.Fatalf("bad: %v", checks)
	}
	if !reflect.DeepEqual(checks[0], check) {
		t.Fatalf("bad: %v", checks[0])
	}
	if !reflect.DeepEqual(checks[1], check2) {
		t.Fatalf("bad: %v", checks[1])
	}
}

func TestDeleteNodeCheck(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(1, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}
	if err := store.EnsureService(2, "foo", &structs.NodeService{"db1", "db", []string{"master"}, "", 8000}); err != nil {
		t.Fatalf("err: %v", err)
	}
	check := &structs.HealthCheck{
		Node:      "foo",
		CheckID:   "db",
		Name:      "Can connect",
		Status:    structs.HealthPassing,
		ServiceID: "db1",
	}
	if err := store.EnsureCheck(3, check); err != nil {
		t.Fatalf("err: %v", err)
	}

	check2 := &structs.HealthCheck{
		Node:    "foo",
		CheckID: "memory",
		Name:    "memory utilization",
		Status:  structs.HealthWarning,
	}
	if err := store.EnsureCheck(4, check2); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.DeleteNodeCheck(5, "foo", "db"); err != nil {
		t.Fatalf("err: %v", err)
	}

	idx, checks := store.NodeChecks("foo")
	if idx != 5 {
		t.Fatalf("bad: %v", idx)
	}
	if len(checks) != 1 {
		t.Fatalf("bad: %v", checks)
	}
	if !reflect.DeepEqual(checks[0], check2) {
		t.Fatalf("bad: %v", checks[0])
	}
}

func TestCheckServiceNodes(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(1, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}
	if err := store.EnsureService(2, "foo", &structs.NodeService{"db1", "db", []string{"master"}, "", 8000}); err != nil {
		t.Fatalf("err: %v", err)
	}
	check := &structs.HealthCheck{
		Node:      "foo",
		CheckID:   "db",
		Name:      "Can connect",
		Status:    structs.HealthPassing,
		ServiceID: "db1",
	}
	if err := store.EnsureCheck(3, check); err != nil {
		t.Fatalf("err: %v", err)
	}
	check = &structs.HealthCheck{
		Node:    "foo",
		CheckID: SerfCheckID,
		Name:    SerfCheckName,
		Status:  structs.HealthPassing,
	}
	if err := store.EnsureCheck(4, check); err != nil {
		t.Fatalf("err: %v", err)
	}

	idx, nodes := store.CheckServiceNodes("db")
	if idx != 4 {
		t.Fatalf("bad: %v", idx)
	}
	if len(nodes) != 1 {
		t.Fatalf("Bad: %v", nodes)
	}

	if nodes[0].Node.Node != "foo" {
		t.Fatalf("Bad: %v", nodes[0])
	}
	if nodes[0].Service.ID != "db1" {
		t.Fatalf("Bad: %v", nodes[0])
	}
	if len(nodes[0].Checks) != 2 {
		t.Fatalf("Bad: %v", nodes[0])
	}
	if nodes[0].Checks[0].CheckID != "db" {
		t.Fatalf("Bad: %v", nodes[0])
	}
	if nodes[0].Checks[1].CheckID != SerfCheckID {
		t.Fatalf("Bad: %v", nodes[0])
	}

	idx, nodes = store.CheckServiceTagNodes("db", "master")
	if idx != 4 {
		t.Fatalf("bad: %v", idx)
	}
	if len(nodes) != 1 {
		t.Fatalf("Bad: %v", nodes)
	}

	if nodes[0].Node.Node != "foo" {
		t.Fatalf("Bad: %v", nodes[0])
	}
	if nodes[0].Service.ID != "db1" {
		t.Fatalf("Bad: %v", nodes[0])
	}
	if len(nodes[0].Checks) != 2 {
		t.Fatalf("Bad: %v", nodes[0])
	}
	if nodes[0].Checks[0].CheckID != "db" {
		t.Fatalf("Bad: %v", nodes[0])
	}
	if nodes[0].Checks[1].CheckID != SerfCheckID {
		t.Fatalf("Bad: %v", nodes[0])
	}
}
func BenchmarkCheckServiceNodes(t *testing.B) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(1, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}
	if err := store.EnsureService(2, "foo", &structs.NodeService{"db1", "db", []string{"master"}, "", 8000}); err != nil {
		t.Fatalf("err: %v", err)
	}
	check := &structs.HealthCheck{
		Node:      "foo",
		CheckID:   "db",
		Name:      "Can connect",
		Status:    structs.HealthPassing,
		ServiceID: "db1",
	}
	if err := store.EnsureCheck(3, check); err != nil {
		t.Fatalf("err: %v", err)
	}
	check = &structs.HealthCheck{
		Node:    "foo",
		CheckID: SerfCheckID,
		Name:    SerfCheckName,
		Status:  structs.HealthPassing,
	}
	if err := store.EnsureCheck(4, check); err != nil {
		t.Fatalf("err: %v", err)
	}

	for i := 0; i < t.N; i++ {
		store.CheckServiceNodes("db")
	}
}

func TestSS_Register_Deregister_Query(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(1, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}

	srv := &structs.NodeService{
		"statsite-box-stats",
		"statsite-box-stats",
		nil,
		"",
		0}
	if err := store.EnsureService(2, "foo", srv); err != nil {
		t.Fatalf("err: %v", err)
	}

	srv = &structs.NodeService{
		"statsite-share-stats",
		"statsite-share-stats",
		nil,
		"",
		0}
	if err := store.EnsureService(3, "foo", srv); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.DeleteNode(4, "foo"); err != nil {
		t.Fatalf("err: %v", err)
	}

	idx, nodes := store.CheckServiceNodes("statsite-share-stats")
	if idx != 4 {
		t.Fatalf("bad: %v", idx)
	}
	if len(nodes) != 0 {
		t.Fatalf("Bad: %v", nodes)
	}
}

func TestNodeInfo(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(1, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}
	if err := store.EnsureService(2, "foo", &structs.NodeService{"db1", "db", []string{"master"}, "", 8000}); err != nil {
		t.Fatalf("err: %v", err)
	}
	check := &structs.HealthCheck{
		Node:      "foo",
		CheckID:   "db",
		Name:      "Can connect",
		Status:    structs.HealthPassing,
		ServiceID: "db1",
	}
	if err := store.EnsureCheck(3, check); err != nil {
		t.Fatalf("err: %v", err)
	}
	check = &structs.HealthCheck{
		Node:    "foo",
		CheckID: SerfCheckID,
		Name:    SerfCheckName,
		Status:  structs.HealthPassing,
	}
	if err := store.EnsureCheck(4, check); err != nil {
		t.Fatalf("err: %v", err)
	}

	idx, dump := store.NodeInfo("foo")
	if idx != 4 {
		t.Fatalf("bad: %v", idx)
	}
	if len(dump) != 1 {
		t.Fatalf("Bad: %v", dump)
	}

	info := dump[0]
	if info.Node != "foo" {
		t.Fatalf("Bad: %v", info)
	}
	if info.Services[0].ID != "db1" {
		t.Fatalf("Bad: %v", info)
	}
	if len(info.Checks) != 2 {
		t.Fatalf("Bad: %v", info)
	}
	if info.Checks[0].CheckID != "db" {
		t.Fatalf("Bad: %v", info)
	}
	if info.Checks[1].CheckID != SerfCheckID {
		t.Fatalf("Bad: %v", info)
	}
}

func TestNodeDump(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(1, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}
	if err := store.EnsureService(2, "foo", &structs.NodeService{"db1", "db", []string{"master"}, "", 8000}); err != nil {
		t.Fatalf("err: %v", err)
	}
	if err := store.EnsureNode(3, structs.Node{"baz", "127.0.0.2"}); err != nil {
		t.Fatalf("err: %v", err)
	}
	if err := store.EnsureService(4, "baz", &structs.NodeService{"db1", "db", []string{"master"}, "", 8000}); err != nil {
		t.Fatalf("err: %v", err)
	}

	idx, dump := store.NodeDump()
	if idx != 4 {
		t.Fatalf("bad: %v", idx)
	}
	if len(dump) != 2 {
		t.Fatalf("Bad: %v", dump)
	}

	info := dump[0]
	if info.Node != "baz" {
		t.Fatalf("Bad: %v", info)
	}
	if info.Services[0].ID != "db1" {
		t.Fatalf("Bad: %v", info)
	}
	info = dump[1]
	if info.Node != "foo" {
		t.Fatalf("Bad: %v", info)
	}
	if info.Services[0].ID != "db1" {
		t.Fatalf("Bad: %v", info)
	}
}

func TestKVSSet_Watch(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	notify1 := make(chan struct{}, 1)
	notify2 := make(chan struct{}, 1)
	notify3 := make(chan struct{}, 1)

	store.WatchKV("", notify1)
	store.WatchKV("foo/", notify2)
	store.WatchKV("foo/bar", notify3)

	// Create the entry
	d := &structs.DirEntry{Key: "foo/baz", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(1000, d); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Check that we've fired notify1 and notify2
	select {
	case <-notify1:
	default:
		t.Fatalf("should notify root")
	}
	select {
	case <-notify2:
	default:
		t.Fatalf("should notify foo/")
	}
	select {
	case <-notify3:
		t.Fatalf("should not notify foo/bar")
	default:
	}
}

func TestKVSSet_Get(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	// Should not exist
	idx, d, err := store.KVSGet("/foo")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 0 {
		t.Fatalf("bad: %v", idx)
	}
	if d != nil {
		t.Fatalf("bad: %v", d)
	}

	// Create the entry
	d = &structs.DirEntry{Key: "/foo", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(1000, d); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Should exist exist
	idx, d, err = store.KVSGet("/foo")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 1000 {
		t.Fatalf("bad: %v", idx)
	}
	if d.CreateIndex != 1000 {
		t.Fatalf("bad: %v", d)
	}
	if d.ModifyIndex != 1000 {
		t.Fatalf("bad: %v", d)
	}
	if d.Key != "/foo" {
		t.Fatalf("bad: %v", d)
	}
	if d.Flags != 42 {
		t.Fatalf("bad: %v", d)
	}
	if string(d.Value) != "test" {
		t.Fatalf("bad: %v", d)
	}

	// Update the entry
	d = &structs.DirEntry{Key: "/foo", Flags: 43, Value: []byte("zip")}
	if err := store.KVSSet(1010, d); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Should update
	idx, d, err = store.KVSGet("/foo")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 1010 {
		t.Fatalf("bad: %v", idx)
	}
	if d.CreateIndex != 1000 {
		t.Fatalf("bad: %v", d)
	}
	if d.ModifyIndex != 1010 {
		t.Fatalf("bad: %v", d)
	}
	if d.Key != "/foo" {
		t.Fatalf("bad: %v", d)
	}
	if d.Flags != 43 {
		t.Fatalf("bad: %v", d)
	}
	if string(d.Value) != "zip" {
		t.Fatalf("bad: %v", d)
	}
}

func TestKVSDelete(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	ttl := 10 * time.Millisecond
	gran := 5 * time.Millisecond
	gc, err := NewTombstoneGC(ttl, gran)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	gc.SetEnabled(true)
	store.gc = gc

	// Create the entry
	d := &structs.DirEntry{Key: "/foo", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(1000, d); err != nil {
		t.Fatalf("err: %v", err)
	}

	notify1 := make(chan struct{}, 1)
	store.WatchKV("/", notify1)

	// Delete the entry
	if err := store.KVSDelete(1020, "/foo"); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Check that we've fired notify1
	select {
	case <-notify1:
	default:
		t.Fatalf("should notify /")
	}

	// Should not exist
	idx, d, err := store.KVSGet("/foo")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 1020 {
		t.Fatalf("bad: %v", idx)
	}
	if d != nil {
		t.Fatalf("bad: %v", d)
	}

	// Check tombstone exists
	_, res, err := store.tombstoneTable.Get("id", "/foo")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if res == nil || res[0].(*structs.DirEntry).ModifyIndex != 1020 {
		t.Fatalf("bad: %#v", d)
	}

	// Check that we get a delete
	select {
	case idx := <-gc.ExpireCh():
		if idx != 1020 {
			t.Fatalf("bad %d", idx)
		}
	case <-time.After(20 * time.Millisecond):
		t.Fatalf("should expire")
	}
}

func TestKVSDeleteCheckAndSet(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	// CAS should fail, no entry
	ok, err := store.KVSDeleteCheckAndSet(1000, "/foo", 100)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if ok {
		t.Fatalf("unexpected commit")
	}

	// CAS should work, no entry
	ok, err = store.KVSDeleteCheckAndSet(1000, "/foo", 0)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if !ok {
		t.Fatalf("unexpected failure")
	}

	// Make an entry
	d := &structs.DirEntry{Key: "/foo"}
	if err := store.KVSSet(1000, d); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Constrain on a wrong modify time
	ok, err = store.KVSDeleteCheckAndSet(1001, "/foo", 42)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if ok {
		t.Fatalf("unexpected commit")
	}

	// Constrain on a correct modify time
	ok, err = store.KVSDeleteCheckAndSet(1002, "/foo", 1000)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if !ok {
		t.Fatalf("expected commit")
	}
}

func TestKVSCheckAndSet(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	// CAS should fail, no entry
	d := &structs.DirEntry{
		ModifyIndex: 100,
		Key:         "/foo",
		Flags:       42,
		Value:       []byte("test"),
	}
	ok, err := store.KVSCheckAndSet(1000, d)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if ok {
		t.Fatalf("unexpected commit")
	}

	// Constrain on not-exist, should work
	d.ModifyIndex = 0
	ok, err = store.KVSCheckAndSet(1001, d)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if !ok {
		t.Fatalf("expected commit")
	}

	// Constrain on not-exist, should fail
	d.ModifyIndex = 0
	ok, err = store.KVSCheckAndSet(1002, d)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if ok {
		t.Fatalf("unexpected commit")
	}

	// Constrain on a wrong modify time
	d.ModifyIndex = 1000
	ok, err = store.KVSCheckAndSet(1003, d)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if ok {
		t.Fatalf("unexpected commit")
	}

	// Constrain on a correct modify time
	d.ModifyIndex = 1001
	ok, err = store.KVSCheckAndSet(1004, d)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if !ok {
		t.Fatalf("expected commit")
	}
}

func TestKVS_List(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	// Should not exist
	_, idx, ents, err := store.KVSList("/web")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 0 {
		t.Fatalf("bad: %v", idx)
	}
	if len(ents) != 0 {
		t.Fatalf("bad: %v", ents)
	}

	// Create the entries
	d := &structs.DirEntry{Key: "/web/a", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(1000, d); err != nil {
		t.Fatalf("err: %v", err)
	}
	d = &structs.DirEntry{Key: "/web/b", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(1001, d); err != nil {
		t.Fatalf("err: %v", err)
	}
	d = &structs.DirEntry{Key: "/web/sub/c", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(1002, d); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Should list
	_, idx, ents, err = store.KVSList("/web")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 1002 {
		t.Fatalf("bad: %v", idx)
	}
	if len(ents) != 3 {
		t.Fatalf("bad: %v", ents)
	}

	if ents[0].Key != "/web/a" {
		t.Fatalf("bad: %v", ents[0])
	}
	if ents[1].Key != "/web/b" {
		t.Fatalf("bad: %v", ents[1])
	}
	if ents[2].Key != "/web/sub/c" {
		t.Fatalf("bad: %v", ents[2])
	}
}

func TestKVSList_TombstoneIndex(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	// Create the entries
	d := &structs.DirEntry{Key: "/web/a", Value: []byte("test")}
	if err := store.KVSSet(1000, d); err != nil {
		t.Fatalf("err: %v", err)
	}
	d = &structs.DirEntry{Key: "/web/b", Value: []byte("test")}
	if err := store.KVSSet(1001, d); err != nil {
		t.Fatalf("err: %v", err)
	}
	d = &structs.DirEntry{Key: "/web/c", Value: []byte("test")}
	if err := store.KVSSet(1002, d); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Nuke the last node
	err = store.KVSDeleteTree(1003, "/web/c")
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	// Add another node
	d = &structs.DirEntry{Key: "/other", Value: []byte("test")}
	if err := store.KVSSet(1004, d); err != nil {
		t.Fatalf("err: %v", err)
	}

	// List should properly reflect tombstoned value
	tombIdx, idx, ents, err := store.KVSList("/web")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 1004 {
		t.Fatalf("bad: %v", idx)
	}
	if tombIdx != 1003 {
		t.Fatalf("bad: %v", idx)
	}
	if len(ents) != 2 {
		t.Fatalf("bad: %v", ents)
	}
}

func TestKVS_ListKeys(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	// Should not exist
	idx, keys, err := store.KVSListKeys("", "/")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 1 {
		t.Fatalf("bad: %v", idx)
	}
	if len(keys) != 0 {
		t.Fatalf("bad: %v", keys)
	}

	// Create the entries
	d := &structs.DirEntry{Key: "/web/a", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(1000, d); err != nil {
		t.Fatalf("err: %v", err)
	}
	d = &structs.DirEntry{Key: "/web/b", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(1001, d); err != nil {
		t.Fatalf("err: %v", err)
	}
	d = &structs.DirEntry{Key: "/web/sub/c", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(1002, d); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Should list
	idx, keys, err = store.KVSListKeys("", "/")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 1002 {
		t.Fatalf("bad: %v", idx)
	}
	if len(keys) != 1 {
		t.Fatalf("bad: %v", keys)
	}
	if keys[0] != "/" {
		t.Fatalf("bad: %v", keys)
	}

	// Should list just web
	idx, keys, err = store.KVSListKeys("/", "/")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 1002 {
		t.Fatalf("bad: %v", idx)
	}
	if len(keys) != 1 {
		t.Fatalf("bad: %v", keys)
	}
	if keys[0] != "/web/" {
		t.Fatalf("bad: %v", keys)
	}

	// Should list a, b, sub/
	idx, keys, err = store.KVSListKeys("/web/", "/")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 1002 {
		t.Fatalf("bad: %v", idx)
	}
	if len(keys) != 3 {
		t.Fatalf("bad: %v", keys)
	}
	if keys[0] != "/web/a" {
		t.Fatalf("bad: %v", keys)
	}
	if keys[1] != "/web/b" {
		t.Fatalf("bad: %v", keys)
	}
	if keys[2] != "/web/sub/" {
		t.Fatalf("bad: %v", keys)
	}

	// Should list c
	idx, keys, err = store.KVSListKeys("/web/sub/", "/")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 1002 {
		t.Fatalf("bad: %v", idx)
	}
	if len(keys) != 1 {
		t.Fatalf("bad: %v", keys)
	}
	if keys[0] != "/web/sub/c" {
		t.Fatalf("bad: %v", keys)
	}

	// Should list all
	idx, keys, err = store.KVSListKeys("/web/", "")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 1002 {
		t.Fatalf("bad: %v", idx)
	}
	if len(keys) != 3 {
		t.Fatalf("bad: %v", keys)
	}
	if keys[2] != "/web/sub/c" {
		t.Fatalf("bad: %v", keys)
	}
}

func TestKVS_ListKeys_Index(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	// Create the entries
	d := &structs.DirEntry{Key: "/foo/a", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(1000, d); err != nil {
		t.Fatalf("err: %v", err)
	}
	d = &structs.DirEntry{Key: "/bar/b", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(1001, d); err != nil {
		t.Fatalf("err: %v", err)
	}
	d = &structs.DirEntry{Key: "/baz/c", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(1002, d); err != nil {
		t.Fatalf("err: %v", err)
	}
	d = &structs.DirEntry{Key: "/other/d", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(1003, d); err != nil {
		t.Fatalf("err: %v", err)
	}

	idx, keys, err := store.KVSListKeys("/foo", "")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 1000 {
		t.Fatalf("bad: %v", idx)
	}
	if len(keys) != 1 {
		t.Fatalf("bad: %v", keys)
	}

	idx, keys, err = store.KVSListKeys("/ba", "")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 1002 {
		t.Fatalf("bad: %v", idx)
	}
	if len(keys) != 2 {
		t.Fatalf("bad: %v", keys)
	}

	idx, keys, err = store.KVSListKeys("/nope", "")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 1003 {
		t.Fatalf("bad: %v", idx)
	}
	if len(keys) != 0 {
		t.Fatalf("bad: %v", keys)
	}
}

func TestKVS_ListKeys_TombstoneIndex(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	// Create the entries
	d := &structs.DirEntry{Key: "/foo/a", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(1000, d); err != nil {
		t.Fatalf("err: %v", err)
	}
	d = &structs.DirEntry{Key: "/bar/b", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(1001, d); err != nil {
		t.Fatalf("err: %v", err)
	}
	d = &structs.DirEntry{Key: "/baz/c", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(1002, d); err != nil {
		t.Fatalf("err: %v", err)
	}
	d = &structs.DirEntry{Key: "/other/d", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(1003, d); err != nil {
		t.Fatalf("err: %v", err)
	}
	if err := store.KVSDelete(1004, "/baz/c"); err != nil {
		t.Fatalf("err: %v", err)
	}

	idx, keys, err := store.KVSListKeys("/foo", "")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 1000 {
		t.Fatalf("bad: %v", idx)
	}
	if len(keys) != 1 {
		t.Fatalf("bad: %v", keys)
	}

	idx, keys, err = store.KVSListKeys("/ba", "")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 1004 {
		t.Fatalf("bad: %v", idx)
	}
	if len(keys) != 1 {
		t.Fatalf("bad: %v", keys)
	}

	idx, keys, err = store.KVSListKeys("/nope", "")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 1004 {
		t.Fatalf("bad: %v", idx)
	}
	if len(keys) != 0 {
		t.Fatalf("bad: %v", keys)
	}
}

func TestKVSDeleteTree(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	ttl := 10 * time.Millisecond
	gran := 5 * time.Millisecond
	gc, err := NewTombstoneGC(ttl, gran)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	gc.SetEnabled(true)
	store.gc = gc

	notify1 := make(chan struct{}, 1)
	notify2 := make(chan struct{}, 1)
	notify3 := make(chan struct{}, 1)

	store.WatchKV("", notify1)
	store.WatchKV("/web/sub", notify2)
	store.WatchKV("/other", notify3)

	// Should not exist
	err = store.KVSDeleteTree(1000, "/web")
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	// Create the entries
	d := &structs.DirEntry{Key: "/web/a", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(1000, d); err != nil {
		t.Fatalf("err: %v", err)
	}
	d = &structs.DirEntry{Key: "/web/b", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(1001, d); err != nil {
		t.Fatalf("err: %v", err)
	}
	d = &structs.DirEntry{Key: "/web/sub/c", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(1002, d); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Nuke the web tree
	err = store.KVSDeleteTree(1010, "/web")
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	// Nothing should list
	tombIdx, idx, ents, err := store.KVSList("/web")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 1010 {
		t.Fatalf("bad: %v", idx)
	}
	if tombIdx != 1010 {
		t.Fatalf("bad: %v", idx)
	}
	if len(ents) != 0 {
		t.Fatalf("bad: %v", ents)
	}

	// Check tombstones exists
	_, res, err := store.tombstoneTable.Get("id_prefix", "/web")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if len(res) != 3 {
		t.Fatalf("bad: %#v", d)
	}
	for _, r := range res {
		if r.(*structs.DirEntry).ModifyIndex != 1010 {
			t.Fatalf("bad: %#v", r)
		}
	}

	// Check that we've fired notify1 and notify2
	select {
	case <-notify1:
	default:
		t.Fatalf("should notify root")
	}
	select {
	case <-notify2:
	default:
		t.Fatalf("should notify /web/sub")
	}
	select {
	case <-notify3:
		t.Fatalf("should not notify /other")
	default:
	}

	// Check that we get a delete
	select {
	case idx := <-gc.ExpireCh():
		if idx != 1010 {
			t.Fatalf("bad %d", idx)
		}
	case <-time.After(20 * time.Millisecond):
		t.Fatalf("should expire")
	}
}

func TestReapTombstones(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	ttl := 10 * time.Millisecond
	gran := 5 * time.Millisecond
	gc, err := NewTombstoneGC(ttl, gran)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	gc.SetEnabled(true)
	store.gc = gc

	// Should not exist
	err = store.KVSDeleteTree(1000, "/web")
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	// Create the entries
	d := &structs.DirEntry{Key: "/web/a", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(1000, d); err != nil {
		t.Fatalf("err: %v", err)
	}
	d = &structs.DirEntry{Key: "/web/b", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(1001, d); err != nil {
		t.Fatalf("err: %v", err)
	}
	d = &structs.DirEntry{Key: "/web/sub/c", Flags: 42, Value: []byte("test")}
	if err := store.KVSSet(1002, d); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Nuke just a
	err = store.KVSDelete(1010, "/web/a")
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	// Nuke the web tree
	err = store.KVSDeleteTree(1020, "/web")
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	// Do a reap, should be a noop
	if err := store.ReapTombstones(1000); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Check tombstones exists
	_, res, err := store.tombstoneTable.Get("id_prefix", "/web")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if len(res) != 3 {
		t.Fatalf("bad: %#v", d)
	}

	// Do a reap, should remove just /web/a
	if err := store.ReapTombstones(1010); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Check tombstones exists
	_, res, err = store.tombstoneTable.Get("id_prefix", "/web")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if len(res) != 2 {
		t.Fatalf("bad: %#v", d)
	}

	// Do a reap, should remove them all
	if err := store.ReapTombstones(1025); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Check no tombstones exists
	_, res, err = store.tombstoneTable.Get("id_prefix", "/web")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if len(res) != 0 {
		t.Fatalf("bad: %#v", d)
	}
}

func TestSessionCreate(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(3, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}
	check := &structs.HealthCheck{
		Node:    "foo",
		CheckID: "bar",
		Status:  structs.HealthPassing,
	}
	if err := store.EnsureCheck(13, check); err != nil {
		t.Fatalf("err: %v", err)
	}

	session := &structs.Session{
		ID:     generateUUID(),
		Node:   "foo",
		Checks: []string{"bar"},
	}

	if err := store.SessionCreate(1000, session); err != nil {
		t.Fatalf("err: %v", err)
	}

	if session.CreateIndex != 1000 {
		t.Fatalf("bad: %v", session)
	}
}

func TestSessionCreate_Invalid(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	// No node registered
	session := &structs.Session{
		ID:     generateUUID(),
		Node:   "foo",
		Checks: []string{"bar"},
	}
	if err := store.SessionCreate(1000, session); err.Error() != "Missing node registration" {
		t.Fatalf("err: %v", err)
	}

	// Check not registered
	if err := store.EnsureNode(3, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}
	if err := store.SessionCreate(1000, session); err.Error() != "Missing check 'bar' registration" {
		t.Fatalf("err: %v", err)
	}

	// Unhealthy check
	check := &structs.HealthCheck{
		Node:    "foo",
		CheckID: "bar",
		Status:  structs.HealthCritical,
	}
	if err := store.EnsureCheck(13, check); err != nil {
		t.Fatalf("err: %v", err)
	}
	if err := store.SessionCreate(1000, session); err.Error() != "Check 'bar' is in critical state" {
		t.Fatalf("err: %v", err)
	}
}

func TestSession_Lookups(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	// Create a session
	if err := store.EnsureNode(3, structs.Node{"foo", "1172.16.31.10"}); err != nil {
		t.Fatalf("err: %v", err)
	}
	session := &structs.Session{
		ID:     generateUUID(),
		Node:   "foo",
		Checks: []string{},
	}
	if err := store.SessionCreate(1000, session); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Lookup by ID
	idx, s2, err := store.SessionGet(session.ID)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 1000 {
		t.Fatalf("bad: %v", idx)
	}
	if !reflect.DeepEqual(s2, session) {
		t.Fatalf("bad: %#v %#v", s2, session)
	}

	// Create many sessions
	ids := []string{session.ID}
	for i := 0; i < 10; i++ {
		session := &structs.Session{
			ID:   generateUUID(),
			Node: "foo",
		}
		if err := store.SessionCreate(uint64(1000+i), session); err != nil {
			t.Fatalf("err: %v", err)
		}
		ids = append(ids, session.ID)
	}

	// List all
	idx, all, err := store.SessionList()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 1009 {
		t.Fatalf("bad: %v", idx)
	}

	// Retrieve the ids
	var out []string
	for _, s := range all {
		out = append(out, s.ID)
	}

	sort.Strings(ids)
	sort.Strings(out)
	if !reflect.DeepEqual(ids, out) {
		t.Fatalf("bad: %v %v", ids, out)
	}

	// List by node
	idx, nodes, err := store.NodeSessions("foo")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 1009 {
		t.Fatalf("bad: %v", idx)
	}

	// Check again for the node list
	out = nil
	for _, s := range nodes {
		out = append(out, s.ID)
	}
	sort.Strings(out)
	if !reflect.DeepEqual(ids, out) {
		t.Fatalf("bad: %v %v", ids, out)
	}
}

func TestSessionInvalidate_CriticalHealthCheck(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(3, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}
	check := &structs.HealthCheck{
		Node:    "foo",
		CheckID: "bar",
		Status:  structs.HealthPassing,
	}
	if err := store.EnsureCheck(13, check); err != nil {
		t.Fatalf("err: %v", err)
	}

	session := &structs.Session{
		ID:     generateUUID(),
		Node:   "foo",
		Checks: []string{"bar"},
	}
	if err := store.SessionCreate(14, session); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Invalidate the check
	check.Status = structs.HealthCritical
	if err := store.EnsureCheck(15, check); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Lookup by ID, should be nil
	_, s2, err := store.SessionGet(session.ID)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if s2 != nil {
		t.Fatalf("session should be invalidated")
	}
}

func TestSessionInvalidate_DeleteHealthCheck(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(3, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}
	check := &structs.HealthCheck{
		Node:    "foo",
		CheckID: "bar",
		Status:  structs.HealthPassing,
	}
	if err := store.EnsureCheck(13, check); err != nil {
		t.Fatalf("err: %v", err)
	}

	session := &structs.Session{
		ID:     generateUUID(),
		Node:   "foo",
		Checks: []string{"bar"},
	}
	if err := store.SessionCreate(14, session); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Delete the check
	if err := store.DeleteNodeCheck(15, "foo", "bar"); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Lookup by ID, should be nil
	_, s2, err := store.SessionGet(session.ID)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if s2 != nil {
		t.Fatalf("session should be invalidated")
	}
}

func TestSessionInvalidate_DeleteNode(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(3, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}

	session := &structs.Session{
		ID:   generateUUID(),
		Node: "foo",
	}
	if err := store.SessionCreate(14, session); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Delete the node
	if err := store.DeleteNode(15, "foo"); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Lookup by ID, should be nil
	_, s2, err := store.SessionGet(session.ID)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if s2 != nil {
		t.Fatalf("session should be invalidated")
	}
}

func TestSessionInvalidate_DeleteNodeService(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(11, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}
	if err := store.EnsureService(12, "foo", &structs.NodeService{"api", "api", nil, "", 5000}); err != nil {
		t.Fatalf("err: %v", err)
	}
	check := &structs.HealthCheck{
		Node:      "foo",
		CheckID:   "api",
		Name:      "Can connect",
		Status:    structs.HealthPassing,
		ServiceID: "api",
	}
	if err := store.EnsureCheck(13, check); err != nil {
		t.Fatalf("err: %v", err)
	}

	session := &structs.Session{
		ID:     generateUUID(),
		Node:   "foo",
		Checks: []string{"api"},
	}
	if err := store.SessionCreate(14, session); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Should invalidate the session
	if err := store.DeleteNodeService(15, "foo", "api"); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Lookup by ID, should be nil
	_, s2, err := store.SessionGet(session.ID)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if s2 != nil {
		t.Fatalf("session should be invalidated")
	}
}

func TestKVSLock(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(3, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}
	session := &structs.Session{ID: generateUUID(), Node: "foo"}
	if err := store.SessionCreate(4, session); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Lock with a non-existing keys should work
	d := &structs.DirEntry{
		Key:     "/foo",
		Flags:   42,
		Value:   []byte("test"),
		Session: session.ID,
	}
	ok, err := store.KVSLock(5, d)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if !ok {
		t.Fatalf("unexpected fail")
	}
	if d.LockIndex != 1 {
		t.Fatalf("bad: %v", d)
	}

	// Re-locking should fail
	ok, err = store.KVSLock(6, d)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if ok {
		t.Fatalf("expected fail")
	}

	// Set a normal key
	k1 := &structs.DirEntry{
		Key:   "/bar",
		Flags: 0,
		Value: []byte("asdf"),
	}
	if err := store.KVSSet(7, k1); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Should acquire the lock
	k1.Session = session.ID
	ok, err = store.KVSLock(8, k1)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if !ok {
		t.Fatalf("unexpected fail")
	}

	// Re-acquire should fail
	ok, err = store.KVSLock(9, k1)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if ok {
		t.Fatalf("expected fail")
	}

}

func TestKVSUnlock(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(3, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}
	session := &structs.Session{ID: generateUUID(), Node: "foo"}
	if err := store.SessionCreate(4, session); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Unlock with a non-existing keys should fail
	d := &structs.DirEntry{
		Key:     "/foo",
		Flags:   42,
		Value:   []byte("test"),
		Session: session.ID,
	}
	ok, err := store.KVSUnlock(5, d)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if ok {
		t.Fatalf("expected fail")
	}

	// Lock should work
	d.Session = session.ID
	if ok, _ := store.KVSLock(6, d); !ok {
		t.Fatalf("expected lock")
	}

	// Unlock should work
	d.Session = session.ID
	ok, err = store.KVSUnlock(7, d)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if !ok {
		t.Fatalf("unexpected fail")
	}

	// Re-lock should work
	d.Session = session.ID
	if ok, err := store.KVSLock(8, d); err != nil {
		t.Fatalf("err: %v", err)
	} else if !ok {
		t.Fatalf("expected lock")
	}
	if d.LockIndex != 2 {
		t.Fatalf("bad: %v", d)
	}
}

func TestSessionInvalidate_KeyUnlock(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()
	if err := store.EnsureNode(3, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}
	session := &structs.Session{
		ID:        generateUUID(),
		Node:      "foo",
		LockDelay: 50 * time.Millisecond,
	}
	if err := store.SessionCreate(4, session); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Lock a key with the session
	d := &structs.DirEntry{
		Key:     "/foo",
		Flags:   42,
		Value:   []byte("test"),
		Session: session.ID,
	}
	ok, err := store.KVSLock(5, d)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if !ok {
		t.Fatalf("unexpected fail")
	}

	notify1 := make(chan struct{}, 1)
	store.WatchKV("/f", notify1)

	// Delete the node
	if err := store.DeleteNode(6, "foo"); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Key should be unlocked
	idx, d2, err := store.KVSGet("/foo")
	if idx != 6 {
		t.Fatalf("bad: %v", idx)
	}
	if d2.LockIndex != 1 {
		t.Fatalf("bad: %v", *d2)
	}
	if d2.Session != "" {
		t.Fatalf("bad: %v", *d2)
	}

	// Should notify of update
	select {
	case <-notify1:
	default:
		t.Fatalf("should notify /f")
	}

	// Key should have a lock delay
	expires := store.KVSLockDelay("/foo")
	if expires.Before(time.Now().Add(30 * time.Millisecond)) {
		t.Fatalf("Bad: %v", expires)
	}
}

func TestSessionInvalidate_KeyDelete(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	if err := store.EnsureNode(3, structs.Node{"foo", "127.0.0.1"}); err != nil {
		t.Fatalf("err: %v", err)
	}
	session := &structs.Session{
		ID:        generateUUID(),
		Node:      "foo",
		LockDelay: 50 * time.Millisecond,
		Behavior:  structs.SessionKeysDelete,
	}
	if err := store.SessionCreate(4, session); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Lock a key with the session
	d := &structs.DirEntry{
		Key:     "/bar",
		Flags:   42,
		Value:   []byte("test"),
		Session: session.ID,
	}
	ok, err := store.KVSLock(5, d)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if !ok {
		t.Fatalf("unexpected fail")
	}

	notify1 := make(chan struct{}, 1)
	store.WatchKV("/b", notify1)

	// Delete the node
	if err := store.DeleteNode(6, "foo"); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Key should be deleted
	_, d2, err := store.KVSGet("/bar")
	if d2 != nil {
		t.Fatalf("unexpected undeleted key")
	}

	// Should notify of update
	select {
	case <-notify1:
	default:
		t.Fatalf("should notify /b")
	}

	// Key should have a lock delay
	expires := store.KVSLockDelay("/bar")
	if expires.Before(time.Now().Add(30 * time.Millisecond)) {
		t.Fatalf("Bad: %v", expires)
	}
}

func TestACLSet_Get(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	idx, out, err := store.ACLGet("1234")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 0 {
		t.Fatalf("bad: %v", idx)
	}
	if out != nil {
		t.Fatalf("bad: %v", out)
	}

	a := &structs.ACL{
		ID:    generateUUID(),
		Name:  "<NAME>",
		Type:  structs.ACLTypeClient,
		Rules: "",
	}
	if err := store.ACLSet(50, a); err != nil {
		t.Fatalf("err: %v", err)
	}
	if a.CreateIndex != 50 {
		t.Fatalf("Bad: %v", a)
	}
	if a.ModifyIndex != 50 {
		t.Fatalf("Bad: %v", a)
	}
	if a.ID == "" {
		t.Fatalf("Bad: %v", a)
	}

	idx, out, err = store.ACLGet(a.ID)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 50 {
		t.Fatalf("bad: %v", idx)
	}
	if !reflect.DeepEqual(out, a) {
		t.Fatalf("bad: %v", out)
	}

	// Update
	a.Rules = "foo bar baz"
	if err := store.ACLSet(52, a); err != nil {
		t.Fatalf("err: %v", err)
	}
	if a.CreateIndex != 50 {
		t.Fatalf("Bad: %v", a)
	}
	if a.ModifyIndex != 52 {
		t.Fatalf("Bad: %v", a)
	}

	idx, out, err = store.ACLGet(a.ID)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 52 {
		t.Fatalf("bad: %v", idx)
	}
	if !reflect.DeepEqual(out, a) {
		t.Fatalf("bad: %v", out)
	}
}

func TestACLDelete(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	a := &structs.ACL{
		ID:    generateUUID(),
		Name:  "<NAME>",
		Type:  structs.ACLTypeClient,
		Rules: "",
	}
	if err := store.ACLSet(50, a); err != nil {
		t.Fatalf("err: %v", err)
	}

	if err := store.ACLDelete(52, a.ID); err != nil {
		t.Fatalf("err: %v", err)
	}
	if err := store.ACLDelete(53, a.ID); err != nil {
		t.Fatalf("err: %v", err)
	}

	idx, out, err := store.ACLGet(a.ID)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 52 {
		t.Fatalf("bad: %v", idx)
	}
	if out != nil {
		t.Fatalf("bad: %v", out)
	}
}

func TestACLList(t *testing.T) {
	store, err := testStateStore()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	defer store.Close()

	a1 := &structs.ACL{
		ID:   generateUUID(),
		Name: "User token",
		Type: structs.ACLTypeClient,
	}
	if err := store.ACLSet(50, a1); err != nil {
		t.Fatalf("err: %v", err)
	}

	a2 := &structs.ACL{
		ID:   generateUUID(),
		Name: "User token",
		Type: structs.ACLTypeClient,
	}
	if err := store.ACLSet(51, a2); err != nil {
		t.Fatalf("err: %v", err)
	}

	idx, out, err := store.ACLList()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if idx != 51 {
		t.Fatalf("bad: %v", idx)
	}
	if len(out) != 2 {
		t.Fatalf("bad: %v", out)
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/command/join.go<|end_filename|>
package command

import (
	"flag"
	"fmt"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/mitchellh/cli"
	"strings"
)

// JoinCommand is a Command implementation that tells a running Consul
// agent to join another.
type JoinCommand struct {
	Ui cli.Ui
}

func (c *JoinCommand) Help() string {
	helpText := `
Usage: consul join [options] address ...

  Tells a running Consul agent (with "consul agent") to join the cluster
  by specifying at least one existing member.

Options:

  -rpc-addr=127.0.0.1:8400  RPC address of the Consul agent.
  -wan                      Joins a server to another server in the WAN pool
`
	return strings.TrimSpace(helpText)
}

func (c *JoinCommand) Run(args []string) int {
	var wan bool

	cmdFlags := flag.NewFlagSet("join", flag.ContinueOnError)
	cmdFlags.Usage = func() { c.Ui.Output(c.Help()) }
	cmdFlags.BoolVar(&wan, "wan", false, "wan")
	rpcAddr := RPCAddrFlag(cmdFlags)
	if err := cmdFlags.Parse(args); err != nil {
		return 1
	}

	addrs := cmdFlags.Args()
	if len(addrs) == 0 {
		c.Ui.Error("At least one address to join must be specified.")
		c.Ui.Error("")
		c.Ui.Error(c.Help())
		return 1
	}

	client, err := RPCClient(*rpcAddr)
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err))
		return 1
	}
	defer client.Close()

	n, err := client.Join(addrs, wan)
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Error joining the cluster: %s", err))
		return 1
	}

	c.Ui.Output(fmt.Sprintf(
		"Successfully joined cluster by contacting %d nodes.", n))
	return 0
}

func (c *JoinCommand) Synopsis() string {
	return "Tell Consul agent to join cluster"
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/serf/serf/serf_internals_test.go<|end_filename|>
package serf

import (
	"github.com/hashicorp/serf/testutil"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/memberlist"
	"testing"
)

func TestSerf_joinLeave_ltime(t *testing.T) {
	s1Config := testConfig()
	s2Config := testConfig()

	s1, err := Create(s1Config)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer s1.Shutdown()

	s2, err := Create(s2Config)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer s2.Shutdown()

	testutil.Yield()

	_, err = s1.Join([]string{s2Config.MemberlistConfig.BindAddr}, false)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	testutil.Yield()

	if s2.members[s1.config.NodeName].statusLTime != 1 {
		t.Fatalf("join time is not valid %d",
			s2.members[s1.config.NodeName].statusLTime)
	}

	if s2.clock.Time() <= s2.members[s1.config.NodeName].statusLTime {
		t.Fatalf("join should increment")
	}
	oldClock := s2.clock.Time()

	err = s1.Leave()
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	testutil.Yield()

	// s1 clock should exceed s2 due to leave
	if s2.clock.Time() <= oldClock {
		t.Fatalf("leave should increment (%d / %d)",
			s2.clock.Time(), oldClock)
	}
}

func TestSerf_join_pendingIntent(t *testing.T) {
	c := testConfig()
	s, err := Create(c)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer s.Shutdown()

	s.recentJoin[0] = nodeIntent{5, "test"}

	n := memberlist.Node{Name: "test",
		Addr: nil,
		Meta: []byte("test"),
	}

	s.handleNodeJoin(&n)

	mem := s.members["test"]
	if mem.statusLTime != 5 {
		t.Fatalf("bad join time")
	}
	if mem.Status != StatusAlive {
		t.Fatalf("bad status")
	}
}

func TestSerf_join_pendingIntents(t *testing.T) {
	c := testConfig()
	s, err := Create(c)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer s.Shutdown()

	s.recentJoin[0] = nodeIntent{5, "test"}
	s.recentLeave[0] = nodeIntent{6, "test"}

	n := memberlist.Node{Name: "test",
		Addr: nil,
		Meta: []byte("test"),
	}

	s.handleNodeJoin(&n)

	mem := s.members["test"]
	if mem.statusLTime != 6 {
		t.Fatalf("bad join time")
	}
	if mem.Status != StatusLeaving {
		t.Fatalf("bad status")
	}
}

func TestSerf_leaveIntent_bufferEarly(t *testing.T) {
	c := testConfig()
	s, err := Create(c)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer s.Shutdown()

	// Deliver a leave intent message early
	j := messageLeave{LTime: 10, Node: "test"}
	if !s.handleNodeLeaveIntent(&j) {
		t.Fatalf("should rebroadcast")
	}
	if s.handleNodeLeaveIntent(&j) {
		t.Fatalf("should not rebroadcast")
	}

	// Check that we buffered
	if s.recentLeaveIndex != 1 {
		t.Fatalf("bad index")
	}
	if s.recentLeave[0].Node != "test" || s.recentLeave[0].LTime != 10 {
		t.Fatalf("bad buffer")
	}
}

func TestSerf_leaveIntent_oldMessage(t *testing.T) {
	c := testConfig()
	s, err := Create(c)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer s.Shutdown()

	s.members["test"] = &memberState{
		Member: Member{
			Status: StatusAlive,
		},
		statusLTime: 12,
	}

	j := messageLeave{LTime: 10, Node: "test"}
	if s.handleNodeLeaveIntent(&j) {
		t.Fatalf("should not rebroadcast")
	}

	if s.recentLeaveIndex != 0 {
		t.Fatalf("bad index")
	}
}

func TestSerf_leaveIntent_newer(t *testing.T) {
	c := testConfig()
	s, err := Create(c)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer s.Shutdown()

	s.members["test"] = &memberState{
		Member: Member{
			Status: StatusAlive,
		},
		statusLTime: 12,
	}

	j := messageLeave{LTime: 14, Node: "test"}
	if !s.handleNodeLeaveIntent(&j) {
		t.Fatalf("should rebroadcast")
	}

	if s.recentLeaveIndex != 0 {
		t.Fatalf("bad index")
	}

	if s.members["test"].Status != StatusLeaving {
		t.Fatalf("should update status")
	}

	if s.clock.Time() != 15 {
		t.Fatalf("should update clock")
	}
}

func TestSerf_joinIntent_bufferEarly(t *testing.T) {
	c := testConfig()
	s, err := Create(c)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer s.Shutdown()

	// Deliver a join intent message early
	j := messageJoin{LTime: 10, Node: "test"}
	if !s.handleNodeJoinIntent(&j) {
		t.Fatalf("should rebroadcast")
	}
	if s.handleNodeJoinIntent(&j) {
		t.Fatalf("should not rebroadcast")
	}

	// Check that we buffered
	if s.recentJoinIndex != 1 {
		t.Fatalf("bad index")
	}
	if s.recentJoin[0].Node != "test" || s.recentJoin[0].LTime != 10 {
		t.Fatalf("bad buffer")
	}
}

func TestSerf_joinIntent_oldMessage(t *testing.T) {
	c := testConfig()
	s, err := Create(c)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer s.Shutdown()

	s.members["test"] = &memberState{
		statusLTime: 12,
	}

	j := messageJoin{LTime: 10, Node: "test"}
	if s.handleNodeJoinIntent(&j) {
		t.Fatalf("should not rebroadcast")
	}

	if s.recentJoinIndex != 0 {
		t.Fatalf("bad index")
	}
}

func TestSerf_joinIntent_newer(t *testing.T) {
	c := testConfig()
	s, err := Create(c)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer s.Shutdown()

	s.members["test"] = &memberState{
		statusLTime: 12,
	}

	// Deliver a join intent message early
	j := messageJoin{LTime: 14, Node: "test"}
	if !s.handleNodeJoinIntent(&j) {
		t.Fatalf("should rebroadcast")
	}

	if s.recentJoinIndex != 0 {
		t.Fatalf("bad index")
	}

	if s.members["test"].statusLTime != 14 {
		t.Fatalf("should update join time")
	}

	if s.clock.Time() != 15 {
		t.Fatalf("should update clock")
	}
}

func TestSerf_joinIntent_resetLeaving(t *testing.T) {
	c := testConfig()
	s, err := Create(c)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer s.Shutdown()

	s.members["test"] = &memberState{
		Member: Member{
			Status: StatusLeaving,
		},
		statusLTime: 12,
	}

	j := messageJoin{LTime: 14, Node: "test"}
	if !s.handleNodeJoinIntent(&j) {
		t.Fatalf("should rebroadcast")
	}

	if s.recentJoinIndex != 0 {
		t.Fatalf("bad index")
	}

	if s.members["test"].statusLTime != 14 {
		t.Fatalf("should update join time")
	}
	if s.members["test"].Status != StatusAlive {
		t.Fatalf("should update status")
	}

	if s.clock.Time() != 15 {
		t.Fatalf("should update clock")
	}
}

func TestSerf_userEvent_oldMessage(t *testing.T) {
	c := testConfig()
	s, err := Create(c)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer s.Shutdown()

	// increase the ltime artificially
	s.eventClock.Witness(LamportTime(c.EventBuffer + 1000))

	msg := messageUserEvent{
		LTime:   1,
		Name:    "old",
		Payload: nil,
	}
	if s.handleUserEvent(&msg) {
		t.Fatalf("should not rebroadcast")
	}
}

func TestSerf_userEvent_sameClock(t *testing.T) {
	eventCh := make(chan Event, 4)
	c := testConfig()
	c.EventCh = eventCh
	s, err := Create(c)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer s.Shutdown()

	msg := messageUserEvent{
		LTime:   1,
		Name:    "first",
		Payload: []byte("test"),
	}
	if !s.handleUserEvent(&msg) {
		t.Fatalf("should rebroadcast")
	}
	msg = messageUserEvent{
		LTime:   1,
		Name:    "first",
		Payload: []byte("newpayload"),
	}
	if !s.handleUserEvent(&msg) {
		t.Fatalf("should rebroadcast")
	}
	msg = messageUserEvent{
		LTime:   1,
		Name:    "second",
		Payload: []byte("other"),
	}
	if !s.handleUserEvent(&msg) {
		t.Fatalf("should rebroadcast")
	}

	testUserEvents(t, eventCh,
		[]string{"first", "first", "second"},
		[][]byte{[]byte("test"), []byte("newpayload"), []byte("other")})
}

func TestSerf_query_oldMessage(t *testing.T) {
	c := testConfig()
	s, err := Create(c)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer s.Shutdown()

	// increase the ltime artificially
	s.queryClock.Witness(LamportTime(c.QueryBuffer + 1000))

	msg := messageQuery{
		LTime:   1,
		Name:    "old",
		Payload: nil,
	}
	if s.handleQuery(&msg) {
		t.Fatalf("should not rebroadcast")
	}
}

func TestSerf_query_sameClock(t *testing.T) {
	eventCh := make(chan Event, 4)
	c := testConfig()
	c.EventCh = eventCh
	s, err := Create(c)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer s.Shutdown()

	msg := messageQuery{
		LTime:   1,
		ID:      1,
		Name:    "foo",
		Payload: []byte("test"),
	}
	if !s.handleQuery(&msg) {
		t.Fatalf("should rebroadcast")
	}
	if s.handleQuery(&msg) {
		t.Fatalf("should not rebroadcast")
	}
	msg = messageQuery{
		LTime:   1,
		ID:      2,
		Name:    "bar",
		Payload: []byte("newpayload"),
	}
	if !s.handleQuery(&msg) {
		t.Fatalf("should rebroadcast")
	}
	if s.handleQuery(&msg) {
		t.Fatalf("should not rebroadcast")
	}
	msg = messageQuery{
		LTime:   1,
		ID:      3,
		Name:    "baz",
		Payload: []byte("other"),
	}
	if !s.handleQuery(&msg) {
		t.Fatalf("should rebroadcast")
	}
	if s.handleQuery(&msg) {
		t.Fatalf("should not rebroadcast")
	}

	testQueryEvents(t, eventCh,
		[]string{"foo", "bar", "baz"},
		[][]byte{[]byte("test"), []byte("newpayload"), []byte("other")})
}


<|start_filename|>Godeps/_workspace/src/github.com/socketplane/ecc/ecc_test.go<|end_filename|>
package ecc

import (
	"bytes"
	"testing"
)

func TestStart(t *testing.T) {
	err := Start(true, true, "", "data-dir")
	if err != nil {
		t.Error("Error starting Consul ", err)
	}
}

func TestJoin(t *testing.T) {
	err := Join("1.1.1.1")
	if err == nil {
		t.Error("Join to unknown peer must fail")
	}
}

func TestGet(t *testing.T) {
	existingValue, _, ok := Get("ipam", "test")
	if ok {
		t.Fatal("Please cleanup the existing database and restart the test :", string(existingValue[:]))
	}
}

func TestPut(t *testing.T) {
	existingValue, _, ok := Get("ipam", "test")
	if ok {
		t.Fatal("Please cleanup the existing database and restart the test")
	}

	eccerr := Put("ipam", "test", []byte("192.168.56.1"), existingValue)
	if eccerr != OK {
		t.Fatal("Error putting value into ipam store")
	}

	// Test with Old existingValue
	eccerr = Put("ipam", "test", []byte("192.168.56.1"), existingValue)
	if eccerr == OK {
		t.Fatal("Put must fail if the existingValue is NOT in sync with the db")
	}

	// Test with New existingValue
	existingValue, _, ok = Get("ipam", "test")
	if !ok {
		t.Fatal("test key is missing in ipam store")
	}

	eccerr = Put("ipam", "test", []byte("192.168.56.2"), existingValue)
	if eccerr != OK {
		t.Error("Error putting value into ipam store")
	}

	existingValue, _, ok = Get("ipam", "test")
	if !ok {
		t.Fatal("test key is missing in ipam store")
	}
	if !bytes.Equal(existingValue, []byte("192.168.56.2")) {
		t.Fatal("Value for test key is not updated in DB")
	}
}

func TestCleanup(t *testing.T) {
	Delete("ipam", "test")
	Leave()
}

func TestRestart(t *testing.T) {
	err := Start(true, true, "", "data-dir")
	if err != nil {
		t.Error("Error starting Consul ", err)
	}
	Leave()
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/command/event.go<|end_filename|>
package command

import (
	"flag"
	"fmt"
	"regexp"
	"strings"

	consulapi "github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/api"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/mitchellh/cli"
)

// EventCommand is a Command implementation that is used to
// fire new events
type EventCommand struct {
	Ui cli.Ui
}

func (c *EventCommand) Help() string {
	helpText := `
Usage: consul event [options] [payload]

  Dispatches a custom user event across a datacenter. An event must provide
  a name, but a payload is optional. Events support filtering using
  regular expressions on node name, service, and tag definitions.

Options:

  -http-addr=127.0.0.1:8500  HTTP address of the Consul agent.
  -datacenter=""             Datacenter to dispatch in. Defaults to that of agent.
  -name=""                   Name of the event.
  -node=""                   Regular expression to filter on node names
  -service=""                Regular expression to filter on service instances
  -tag=""                    Regular expression to filter on service tags. Must be used
                             with -service.
`
	return strings.TrimSpace(helpText)
}

func (c *EventCommand) Run(args []string) int {
	var datacenter, name, node, service, tag string
	cmdFlags := flag.NewFlagSet("event", flag.ContinueOnError)
	cmdFlags.Usage = func() { c.Ui.Output(c.Help()) }
	cmdFlags.StringVar(&datacenter, "datacenter", "", "")
	cmdFlags.StringVar(&name, "name", "", "")
	cmdFlags.StringVar(&node, "node", "", "")
	cmdFlags.StringVar(&service, "service", "", "")
	cmdFlags.StringVar(&tag, "tag", "", "")
	httpAddr := HTTPAddrFlag(cmdFlags)
	if err := cmdFlags.Parse(args); err != nil {
		return 1
	}

	// Check for a name
	if name == "" {
		c.Ui.Error("Event name must be specified")
		c.Ui.Error("")
		c.Ui.Error(c.Help())
		return 1
	}

	// Validate the filters
	if node != "" {
		if _, err := regexp.Compile(node); err != nil {
			c.Ui.Error(fmt.Sprintf("Failed to compile node filter regexp: %v", err))
			return 1
		}
	}
	if service != "" {
		if _, err := regexp.Compile(service); err != nil {
			c.Ui.Error(fmt.Sprintf("Failed to compile service filter regexp: %v", err))
			return 1
		}
	}
	if tag != "" {
		if _, err := regexp.Compile(tag); err != nil {
			c.Ui.Error(fmt.Sprintf("Failed to compile tag filter regexp: %v", err))
			return 1
		}
	}
	if tag != "" && service == "" {
		c.Ui.Error("Cannot provide tag filter without service filter.")
		return 1
	}

	// Check for a payload
	var payload []byte
	args = cmdFlags.Args()
	switch len(args) {
	case 0:
	case 1:
		payload = []byte(args[0])
	default:
		c.Ui.Error("Too many command line arguments.")
		c.Ui.Error("")
		c.Ui.Error(c.Help())
		return 1
	}

	// Create and test the HTTP client
	client, err := HTTPClient(*httpAddr)
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err))
		return 1
	}
	_, err = client.Agent().NodeName()
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Error querying Consul agent: %s", err))
		return 1
	}

	// Prepare the request
	event := client.Event()
	params := &consulapi.UserEvent{
		Name:          name,
		Payload:       payload,
		NodeFilter:    node,
		ServiceFilter: service,
		TagFilter:     tag,
	}
	opts := &consulapi.WriteOptions{
		Datacenter: datacenter,
	}

	// Fire the event
	id, _, err := event.Fire(params, opts)
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Error firing event: %s", err))
		return 1
	}

	// Write out the ID
	c.Ui.Output(fmt.Sprintf("Event ID: %s", id))
	return 0
}

func (c *EventCommand) Synopsis() string {
	return "Fire a new event"
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/serf/serf/messages.go<|end_filename|>
package serf

import (
	"bytes"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/go-msgpack/codec"
	"time"
)

// messageType are the types of gossip messages Serf will send along
// memberlist.
type messageType uint8

const (
	messageLeaveType messageType = iota
	messageJoinType
	messagePushPullType
	messageUserEventType
	messageQueryType
	messageQueryResponseType
	messageConflictResponseType
	messageKeyRequestType
	messageKeyResponseType
)

const (
	// Ack flag is used to force receiver to send an ack back
	queryFlagAck uint32 = 1 << iota

	// NoBroadcast is used to prevent re-broadcast of a query.
	// this can be used to selectively send queries to individual members
	queryFlagNoBroadcast
)

// filterType is used with a queryFilter to specify the type of
// filter we are sending
type filterType uint8

const (
	filterNodeType filterType = iota
	filterTagType
)

// messageJoin is the message broadcasted after we join to
// associated the node with a lamport clock
type messageJoin struct {
	LTime LamportTime
	Node  string
}

// messageLeave is the message broadcasted to signal the intentional to
// leave.
type messageLeave struct {
	LTime LamportTime
	Node  string
}

// messagePushPullType is used when doing a state exchange. This
// is a relatively large message, but is sent infrequently
type messagePushPull struct {
	LTime        LamportTime            // Current node lamport time
	StatusLTimes map[string]LamportTime // Maps the node to its status time
	LeftMembers  []string               // List of left nodes
	EventLTime   LamportTime            // Lamport time for event clock
	Events       []*userEvents          // Recent events
	QueryLTime   LamportTime            // Lamport time for query clock
}

// messageUserEvent is used for user-generated events
type messageUserEvent struct {
	LTime   LamportTime
	Name    string
	Payload []byte
	CC      bool // "Can Coalesce". Zero value is compatible with Serf 0.1
}

// messageQuery is used for query events
type messageQuery struct {
	LTime   LamportTime   // Event lamport time
	ID      uint32        // Query ID, randomly generated
	Addr    []byte        // Source address, used for a direct reply
	Port    uint16        // Source port, used for a direct reply
	Filters [][]byte      // Potential query filters
	Flags   uint32        // Used to provide various flags
	Timeout time.Duration // Maximum time between delivery and response
	Name    string        // Query name
	Payload []byte        // Query payload
}

// Ack checks if the ack flag is set
func (m *messageQuery) Ack() bool {
	return (m.Flags & queryFlagAck) != 0
}

// NoBroadcast checks if the no broadcast flag is set
func (m *messageQuery) NoBroadcast() bool {
	return (m.Flags & queryFlagNoBroadcast) != 0
}

// filterNode is used with the filterNodeType, and is a list
// of node names
type filterNode []string

// filterTag is used with the filterTagType and is a regular
// expression to apply to a tag
type filterTag struct {
	Tag  string
	Expr string
}

// messageQueryResponse is used to respond to a query
type messageQueryResponse struct {
	LTime   LamportTime // Event lamport time
	ID      uint32      // Query ID
	From    string      // Node name
	Flags   uint32      // Used to provide various flags
	Payload []byte      // Optional response payload
}

// Ack checks if the ack flag is set
func (m *messageQueryResponse) Ack() bool {
	return (m.Flags & queryFlagAck) != 0
}

func decodeMessage(buf []byte, out interface{}) error {
	var handle codec.MsgpackHandle
	return codec.NewDecoder(bytes.NewReader(buf), &handle).Decode(out)
}

func encodeMessage(t messageType, msg interface{}) ([]byte, error) {
	buf := bytes.NewBuffer(nil)
	buf.WriteByte(uint8(t))

	handle := codec.MsgpackHandle{}
	encoder := codec.NewEncoder(buf, &handle)
	err := encoder.Encode(msg)
	return buf.Bytes(), err
}

func encodeFilter(f filterType, filt interface{}) ([]byte, error) {
	buf := bytes.NewBuffer(nil)
	buf.WriteByte(uint8(f))

	handle := codec.MsgpackHandle{}
	encoder := codec.NewEncoder(buf, &handle)
	err := encoder.Encode(filt)
	return buf.Bytes(), err
}


<|start_filename|>daemon/api.go<|end_filename|>
package daemon

import (
	"encoding/json"
	"fmt"
	"net"
	"net/http"
	"net/url"

	log "github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/Sirupsen/logrus"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/gorilla/mux"
)

const API_VERSION string = "/v0.1"

type Response struct {
	Status  string
	Message string
}

type Configuration struct {
	BridgeIP   string `json:"bridge_ip"`
	BridgeName string `json:"bridge_name"`
	BridgeCIDR string `json:"bridge_cidr"`
	BridgeMTU  int    `json:"bridge_mtu"`
}

type Connection struct {
	ContainerID       string        `json:"container_id"`
	ContainerName     string        `json:"container_name"`
	ContainerPID      string        `json:"container_pid"`
	Network           string        `json:"network"`
	OvsPortID         string        `json:"ovs_port_id"`
	ConnectionDetails OvsConnection `json:"connection_details"`
}

type apiError struct {
	Code    int
	Message string
}

type HttpApiFunc func(d *Daemon, w http.ResponseWriter, r *http.Request) *apiError

type appHandler struct {
	*Daemon
	h HttpApiFunc
}

func (ah appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	err := ah.h(ah.Daemon, w, r)
	if err != nil {
		http.Error(w, err.Message, err.Code)
	}
}

func ServeAPI(d *Daemon) {
	r := createRouter(d)
	server := &http.Server{
		Addr:    "0.0.0.0:6675",
		Handler: r,
	}
	server.ListenAndServe()
}

func createRouter(d *Daemon) *mux.Router {
	r := mux.NewRouter()
	m := map[string]map[string]HttpApiFunc{
		"GET": {
			"/configuration":       getConfiguration,
			"/connections":         getConnections,
			"/connections/{id:.*}": getConnection,
			"/networks":            getNetworks,
			"/networks/{id:.*}":    getNetwork,
		},
		"POST": {
			"/configuration": setConfiguration,
			"/connections":   createConnection,
			"/networks":      createNetwork,
			"/cluster/bind":  clusterBind,
			"/cluster/join":  clusterJoin,
			"/cluster/leave": clusterLeave,
			"/adapter":       psAdapter,
		},
		"DELETE": {
			"/connections/{id:.*}": deleteConnection,
			"/networks/{id:.*}":    deleteNetwork,
		},
	}

	for method, routes := range m {
		for route, fct := range routes {
			handler := appHandler{d, fct}
			r.Path(API_VERSION + route).Methods(method).Handler(handler)
			if route == "/adapter" {
				r.Path(route).Methods(method).Handler(handler)
			}
		}
	}

	return r
}

func getConfiguration(d *Daemon, w http.ResponseWriter, r *http.Request) *apiError {
	data, _ := json.Marshal(d.Configuration)
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	w.Write(data)
	return nil
}

func setConfiguration(d *Daemon, w http.ResponseWriter, r *http.Request) *apiError {
	if r.Body == nil {
		return &apiError{http.StatusBadRequest, "Request body is empty"}
	}
	cfg := &Configuration{}
	decoder := json.NewDecoder(r.Body)
	err := decoder.Decode(cfg)
	if err != nil {
		return &apiError{http.StatusInternalServerError, err.Error()}
	}
	d.Configuration = cfg
	return nil
}

func getConnections(d *Daemon, w http.ResponseWriter, r *http.Request) *apiError {
	data, _ := json.Marshal(d.Connections)
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	w.Write(data)
	return nil
}

func getConnection(d *Daemon, w http.ResponseWriter, r *http.Request) *apiError {
	vars := mux.Vars(r)
	containerID := vars["id"]
	connection := d.Connections[containerID]

	if connection == nil {
		msg := fmt.Sprintf("Connection for container %v not found", containerID)
		return &apiError{http.StatusNotFound, msg}
	}

	data, _ := json.Marshal(connection)
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	w.Write(data)
	return nil
}

func createConnection(d *Daemon, w http.ResponseWriter, r *http.Request) *apiError {
	if r.Body == nil {
		return &apiError{http.StatusBadRequest, "Request body is empty"}
	}
	cfg := &Connection{}
	decoder := json.NewDecoder(r.Body)
	err := decoder.Decode(cfg)
	if err != nil {
		return &apiError{http.StatusInternalServerError, err.Error()}
	}

	if cfg.Network == "" {
		cfg.Network = DefaultNetworkName
	}

	context := &ConnectionContext{
		ConnectionAdd,
		cfg,
		make(chan *Connection),
	}
	d.cC <- context

	result := <-context.Result

	location := fmt.Sprintf("%s/%s", r.URL.String(), cfg.ContainerID)
	data, _ := json.Marshal(result)
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	w.Header().Set("Content-Location", location)
	w.Write(data)
	return nil
}

func deleteConnection(d *Daemon, w http.ResponseWriter, r *http.Request) *apiError {
	vars := mux.Vars(r)
	containerID := vars["id"]

	connection, ok := d.Connections[containerID]
	if !ok {
		return &apiError{http.StatusNotFound, "Container Not Found"}
	}

	context := &ConnectionContext{
		ConnectionDelete,
		connection,
		make(chan *Connection),
	}
	d.cC <- context
	<-context.Result
	return nil
}

func getNetworks(d *Daemon, w http.ResponseWriter, r *http.Request) *apiError {
	networks, err := GetNetworks()
	if err != nil {
		return &apiError{http.StatusInternalServerError, err.Error()}
	}
	data, err := json.Marshal(networks)
	if err != nil {
		return &apiError{http.StatusInternalServerError, err.Error()}
	}
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	w.Write(data)
	return nil
}

func getNetwork(d *Daemon, w http.ResponseWriter, r *http.Request) *apiError {
	vars := mux.Vars(r)
	networkID := vars["id"]

	networks, err := GetNetwork(networkID)
	if err != nil {
		return &apiError{http.StatusInternalServerError, err.Error()}
	}
	data, err := json.Marshal(networks)
	if err != nil {
		return &apiError{http.StatusInternalServerError, err.Error()}
	}
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	w.Write(data)
	return nil
}

func createNetwork(d *Daemon, w http.ResponseWriter, r *http.Request) *apiError {
	if r.Body == nil {
		return &apiError{http.StatusBadRequest, "Request body is empty"}
	}
	networkRequest := &Network{}
	decoder := json.NewDecoder(r.Body)
	err := decoder.Decode(networkRequest)
	if err != nil {
		return &apiError{http.StatusInternalServerError, err.Error()}
	}
	_, cidr, err := net.ParseCIDR(networkRequest.Subnet)
	if err != nil {
		return &apiError{http.StatusInternalServerError, err.Error()}
	}

	newNetwork, err := CreateNetwork(networkRequest.ID, cidr)
	if err != nil {
		return &apiError{http.StatusInternalServerError, err.Error()}
	}

	data, _ := json.Marshal(newNetwork)
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	w.Write(data)
	return nil
}

func deleteNetwork(d *Daemon, w http.ResponseWriter, r *http.Request) *apiError {
	vars := mux.Vars(r)
	networkID := vars["id"]

	err := DeleteNetwork(networkID)
	if err != nil {
		return &apiError{http.StatusInternalServerError, err.Error()}
	}
	return nil
}

func clusterBind(d *Daemon, w http.ResponseWriter, r *http.Request) *apiError {
	if r.URL.RawQuery == "" {
		return &apiError{http.StatusBadRequest, "Please provide the interface parameter"}
	}
	values, err := url.ParseQuery(r.URL.RawQuery)
	if err != nil {
		return &apiError{http.StatusBadRequest, "Could not decode query parameters"}
	}
	iface, ok := values["iface"]
	if !ok || iface[0] == "" {
		return &apiError{http.StatusBadRequest, "Please provide the interface parameter"}
	}
	log.Debugf("Request Received. Change Cluster Interface to %s", iface[0])
	err = d.ConfigureClusterListenerPort(iface[0])
	if err != nil {
		return &apiError{http.StatusInternalServerError, err.Error()}
	}
	return nil
}

func clusterJoin(d *Daemon, w http.ResponseWriter, r *http.Request) *apiError {
	if r.URL.RawQuery == "" {
		return &apiError{http.StatusBadRequest, "Please provide the address parameter"}
	}
	values, err := url.ParseQuery(r.URL.RawQuery)
	if err != nil {
		return &apiError{http.StatusBadRequest, "Could not decode query parameters"}
	}
	addr, ok := values["address"]
	if !ok || addr[0] == "" {
		return &apiError{http.StatusBadRequest, "Please provide the address parameter"}
	}
	log.Debugf("Request Received. Join Cluster  %s", addr[0])
	err = d.JoinCluster(addr[0])
	if err != nil {
		return &apiError{http.StatusInternalServerError, err.Error()}
	}
	return nil
}

func clusterLeave(d *Daemon, w http.ResponseWriter, r *http.Request) *apiError {
	//ToDo: Needs implementing
	return nil
}


<|start_filename|>Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_policy.go<|end_filename|>
package netlink

import (
	"fmt"
	"net"
)

// Dir is an enum representing an ipsec template direction.
type Dir uint8

const (
	XFRM_DIR_IN     Dir = iota
	XFRM_DIR_OUT    Dir = iota
	XFRM_DIR_FWD    Dir = iota
	XFRM_SOCKET_IN  Dir = iota
	XFRM_SOCKET_OUT Dir = iota
	XFRM_SOCKET_FWD Dir = iota
)

func (d Dir) String() string {
	switch d {
	case XFRM_DIR_IN:
		return "dir in"
	case XFRM_DIR_OUT:
		return "dir out"
	case XFRM_DIR_FWD:
		return "dir fwd"
	case XFRM_SOCKET_IN:
		return "socket in"
	case XFRM_SOCKET_OUT:
		return "socket out"
	case XFRM_SOCKET_FWD:
		return "socket fwd"
	}
	return fmt.Sprintf("socket %d", d-XFRM_SOCKET_IN)
}

// XfrmPolicyTmpl encapsulates a rule for the base addresses of an ipsec
// policy. These rules are matched with XfrmState to determine encryption
// and authentication algorithms.
type XfrmPolicyTmpl struct {
	Dst   net.IP
	Src   net.IP
	Proto Proto
	Mode  Mode
	Reqid int
}

// XfrmPolicy represents an ipsec policy. It represents the overlay network
// and has a list of XfrmPolicyTmpls representing the base addresses of
// the policy.
type XfrmPolicy struct {
	Dst      *net.IPNet
	Src      *net.IPNet
	Dir      Dir
	Priority int
	Index    int
	Tmpls    []XfrmPolicyTmpl
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/command/agent/kvs_endpoint.go<|end_filename|>
package agent

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
	"strconv"
	"strings"

	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/consul/structs"
)

const (
	// maxKVSize is used to limit the maximum payload length
	// of a KV entry. If it exceeds this amount, the client is
	// likely abusing the KV store.
	maxKVSize = 512 * 1024
)

func (s *HTTPServer) KVSEndpoint(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Set default DC
	args := structs.KeyRequest{}
	if done := s.parse(resp, req, &args.Datacenter, &args.QueryOptions); done {
		return nil, nil
	}

	// Pull out the key name, validation left to each sub-handler
	args.Key = strings.TrimPrefix(req.URL.Path, "/v1/kv/")

	// Check for a key list
	keyList := false
	params := req.URL.Query()
	if _, ok := params["keys"]; ok {
		keyList = true
	}

	// Switch on the method
	switch req.Method {
	case "GET":
		if keyList {
			return s.KVSGetKeys(resp, req, &args)
		} else {
			return s.KVSGet(resp, req, &args)
		}
	case "PUT":
		return s.KVSPut(resp, req, &args)
	case "DELETE":
		return s.KVSDelete(resp, req, &args)
	default:
		resp.WriteHeader(405)
		return nil, nil
	}
}

// KVSGet handles a GET request
func (s *HTTPServer) KVSGet(resp http.ResponseWriter, req *http.Request, args *structs.KeyRequest) (interface{}, error) {
	// Check for recurse
	method := "KVS.Get"
	params := req.URL.Query()
	if _, ok := params["recurse"]; ok {
		method = "KVS.List"
	} else if missingKey(resp, args) {
		return nil, nil
	}

	// Make the RPC
	var out structs.IndexedDirEntries
	if err := s.agent.RPC(method, &args, &out); err != nil {
		return nil, err
	}
	setMeta(resp, &out.QueryMeta)

	// Check if we get a not found
	if len(out.Entries) == 0 {
		resp.WriteHeader(404)
		return nil, nil
	}

	// Check if we are in raw mode with a normal get, write out
	// the raw body
	if _, ok := params["raw"]; ok && method == "KVS.Get" {
		body := out.Entries[0].Value
		resp.Header().Set("Content-Length", strconv.FormatInt(int64(len(body)), 10))
		resp.Write(body)
		return nil, nil
	}

	return out.Entries, nil
}

// KVSGetKeys handles a GET request for keys
func (s *HTTPServer) KVSGetKeys(resp http.ResponseWriter, req *http.Request, args *structs.KeyRequest) (interface{}, error) {
	// Check for a seperator, due to historic spelling error,
	// we now are forced to check for both spellings
	var sep string
	params := req.URL.Query()
	if _, ok := params["seperator"]; ok {
		sep = params.Get("seperator")
	}
	if _, ok := params["separator"]; ok {
		sep = params.Get("separator")
	}

	// Construct the args
	listArgs := structs.KeyListRequest{
		Datacenter:   args.Datacenter,
		Prefix:       args.Key,
		Seperator:    sep,
		QueryOptions: args.QueryOptions,
	}

	// Make the RPC
	var out structs.IndexedKeyList
	if err := s.agent.RPC("KVS.ListKeys", &listArgs, &out); err != nil {
		return nil, err
	}
	setMeta(resp, &out.QueryMeta)

	// Check if we get a not found. We do not generate
	// not found for the root, but just provide the empty list
	if len(out.Keys) == 0 && listArgs.Prefix != "" {
		resp.WriteHeader(404)
		return nil, nil
	}

	// Use empty list instead of null
	if out.Keys == nil {
		out.Keys = []string{}
	}
	return out.Keys, nil
}

// KVSPut handles a PUT request
func (s *HTTPServer) KVSPut(resp http.ResponseWriter, req *http.Request, args *structs.KeyRequest) (interface{}, error) {
	if missingKey(resp, args) {
		return nil, nil
	}
	applyReq := structs.KVSRequest{
		Datacenter: args.Datacenter,
		Op:         structs.KVSSet,
		DirEnt: structs.DirEntry{
			Key:   args.Key,
			Flags: 0,
			Value: nil,
		},
	}
	applyReq.Token = args.Token

	// Check for flags
	params := req.URL.Query()
	if _, ok := params["flags"]; ok {
		flagVal, err := strconv.ParseUint(params.Get("flags"), 10, 64)
		if err != nil {
			return nil, err
		}
		applyReq.DirEnt.Flags = flagVal
	}

	// Check for cas value
	if _, ok := params["cas"]; ok {
		casVal, err := strconv.ParseUint(params.Get("cas"), 10, 64)
		if err != nil {
			return nil, err
		}
		applyReq.DirEnt.ModifyIndex = casVal
		applyReq.Op = structs.KVSCAS
	}

	// Check for lock acquisition
	if _, ok := params["acquire"]; ok {
		applyReq.DirEnt.Session = params.Get("acquire")
		applyReq.Op = structs.KVSLock
	}

	// Check for lock release
	if _, ok := params["release"]; ok {
		applyReq.DirEnt.Session = params.Get("release")
		applyReq.Op = structs.KVSUnlock
	}

	// Check the content-length
	if req.ContentLength > maxKVSize {
		resp.WriteHeader(413)
		resp.Write([]byte(fmt.Sprintf("Value exceeds %d byte limit", maxKVSize)))
		return nil, nil
	}

	// Copy the value
	buf := bytes.NewBuffer(nil)
	if _, err := io.Copy(buf, req.Body); err != nil {
		return nil, err
	}
	applyReq.DirEnt.Value = buf.Bytes()

	// Make the RPC
	var out bool
	if err := s.agent.RPC("KVS.Apply", &applyReq, &out); err != nil {
		return nil, err
	}

	// Only use the out value if this was a CAS
	if applyReq.Op == structs.KVSSet {
		return true, nil
	} else {
		return out, nil
	}
}

// KVSPut handles a DELETE request
func (s *HTTPServer) KVSDelete(resp http.ResponseWriter, req *http.Request, args *structs.KeyRequest) (interface{}, error) {
	applyReq := structs.KVSRequest{
		Datacenter: args.Datacenter,
		Op:         structs.KVSDelete,
		DirEnt: structs.DirEntry{
			Key: args.Key,
		},
	}
	applyReq.Token = args.Token

	// Check for recurse
	params := req.URL.Query()
	if _, ok := params["recurse"]; ok {
		applyReq.Op = structs.KVSDeleteTree
	} else if missingKey(resp, args) {
		return nil, nil
	}

	// Check for cas value
	if _, ok := params["cas"]; ok {
		casVal, err := strconv.ParseUint(params.Get("cas"), 10, 64)
		if err != nil {
			return nil, err
		}
		applyReq.DirEnt.ModifyIndex = casVal
		applyReq.Op = structs.KVSDeleteCAS
	}

	// Make the RPC
	var out bool
	if err := s.agent.RPC("KVS.Apply", &applyReq, &out); err != nil {
		return nil, err
	}

	// Only use the out value if this was a CAS
	if applyReq.Op == structs.KVSDeleteCAS {
		return out, nil
	} else {
		return true, nil
	}
}

// missingKey checks if the key is missing
func missingKey(resp http.ResponseWriter, args *structs.KeyRequest) bool {
	if args.Key == "" {
		resp.WriteHeader(400)
		resp.Write([]byte("Missing key name"))
		return true
	}
	return false
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/command/agent/dns_test.go<|end_filename|>
package agent

import (
	"fmt"
	"os"
	"strings"
	"testing"
	"time"

	"github.com/hashicorp/consul/testutil"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/consul/structs"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/miekg/dns"
)

func makeDNSServer(t *testing.T) (string, *DNSServer) {
	config := &DNSConfig{}
	return makeDNSServerConfig(t, config)
}

func makeDNSServerConfig(t *testing.T, config *DNSConfig) (string, *DNSServer) {
	conf := nextConfig()
	addr, _ := conf.ClientListener(conf.Addresses.DNS, conf.Ports.DNS)
	dir, agent := makeAgent(t, conf)
	server, err := NewDNSServer(agent, config, agent.logOutput,
		conf.Domain, addr.String(), []string{"8.8.8.8:53"})
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	return dir, server
}

func TestRecursorAddr(t *testing.T) {
	addr, err := recursorAddr("8.8.8.8")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if addr != "8.8.8.8:53" {
		t.Fatalf("bad: %v", addr)
	}
}

func TestDNS_IsAlive(t *testing.T) {
	dir, srv := makeDNSServer(t)
	defer os.RemoveAll(dir)
	defer srv.agent.Shutdown()

	m := new(dns.Msg)
	m.SetQuestion("_test.consul.", dns.TypeANY)

	c := new(dns.Client)
	addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
	in, _, err := c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if len(in.Answer) != 1 {
		t.Fatalf("Bad: %#v", in)
	}

	txt, ok := in.Answer[0].(*dns.TXT)
	if !ok {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if txt.Txt[0] != "ok" {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
}

func TestDNS_NodeLookup(t *testing.T) {
	dir, srv := makeDNSServer(t)
	defer os.RemoveAll(dir)
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	// Register node
	args := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "foo",
		Address:    "127.0.0.1",
	}

	var out struct{}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	m := new(dns.Msg)
	m.SetQuestion("foo.node.consul.", dns.TypeANY)

	c := new(dns.Client)
	addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
	in, _, err := c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if len(in.Answer) != 1 {
		t.Fatalf("Bad: %#v", in)
	}

	aRec, ok := in.Answer[0].(*dns.A)
	if !ok {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if aRec.A.String() != "127.0.0.1" {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if aRec.Hdr.Ttl != 0 {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}

	// Re-do the query, but specify the DC
	m = new(dns.Msg)
	m.SetQuestion("foo.node.dc1.consul.", dns.TypeANY)

	c = new(dns.Client)
	in, _, err = c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if len(in.Answer) != 1 {
		t.Fatalf("Bad: %#v", in)
	}

	aRec, ok = in.Answer[0].(*dns.A)
	if !ok {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if aRec.A.String() != "127.0.0.1" {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if aRec.Hdr.Ttl != 0 {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
}

func TestDNS_CaseInsensitiveNodeLookup(t *testing.T) {
	dir, srv := makeDNSServer(t)
	defer os.RemoveAll(dir)
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	// Register node
	args := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "Foo",
		Address:    "127.0.0.1",
	}

	var out struct{}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	m := new(dns.Msg)
	m.SetQuestion("fOO.node.dc1.consul.", dns.TypeANY)

	c := new(dns.Client)
	addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
	in, _, err := c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if len(in.Answer) != 1 {
		t.Fatalf("empty lookup: %#v", in)
	}
}

func TestDNS_NodeLookup_PeriodName(t *testing.T) {
	dir, srv := makeDNSServer(t)
	defer os.RemoveAll(dir)
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	// Register node with period in name
	args := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "foo.bar",
		Address:    "127.0.0.1",
	}

	var out struct{}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	m := new(dns.Msg)
	m.SetQuestion("foo.bar.node.consul.", dns.TypeANY)

	c := new(dns.Client)
	addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
	in, _, err := c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if len(in.Answer) != 1 {
		t.Fatalf("Bad: %#v", in)
	}

	aRec, ok := in.Answer[0].(*dns.A)
	if !ok {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if aRec.A.String() != "127.0.0.1" {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
}

func TestDNS_NodeLookup_AAAA(t *testing.T) {
	dir, srv := makeDNSServer(t)
	defer os.RemoveAll(dir)
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	// Register node
	args := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "bar",
		Address:    "::4242:4242",
	}

	var out struct{}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	m := new(dns.Msg)
	m.SetQuestion("bar.node.consul.", dns.TypeANY)

	c := new(dns.Client)
	addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
	in, _, err := c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if len(in.Answer) != 1 {
		t.Fatalf("Bad: %#v", in)
	}

	aRec, ok := in.Answer[0].(*dns.AAAA)
	if !ok {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if aRec.AAAA.String() != "::4242:4242" {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if aRec.Hdr.Ttl != 0 {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
}

func TestDNS_NodeLookup_CNAME(t *testing.T) {
	dir, srv := makeDNSServer(t)
	defer os.RemoveAll(dir)
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	// Register node
	args := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "google",
		Address:    "www.google.com",
	}

	var out struct{}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	m := new(dns.Msg)
	m.SetQuestion("google.node.consul.", dns.TypeANY)

	c := new(dns.Client)
	addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
	in, _, err := c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	// Should have the CNAME record + a few A records
	if len(in.Answer) < 2 {
		t.Fatalf("Bad: %#v", in)
	}

	cnRec, ok := in.Answer[0].(*dns.CNAME)
	if !ok {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if cnRec.Target != "www.google.com." {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if cnRec.Hdr.Ttl != 0 {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
}

func TestDNS_ReverseLookup(t *testing.T) {
	dir, srv := makeDNSServer(t)
	defer os.RemoveAll(dir)
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	// Register node
	args := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "foo2",
		Address:    "127.0.0.2",
	}

	var out struct{}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	m := new(dns.Msg)
	m.SetQuestion("172.16.31.10.in-addr.arpa.", dns.TypeANY)

	c := new(dns.Client)
	addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
	in, _, err := c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if len(in.Answer) != 1 {
		t.Fatalf("Bad: %#v", in)
	}

	ptrRec, ok := in.Answer[0].(*dns.PTR)
	if !ok {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if ptrRec.Ptr != "foo2.node.dc1.consul." {
		t.Fatalf("Bad: %#v", ptrRec)
	}
}

func TestDNS_ReverseLookup_CustomDomain(t *testing.T) {
	dir, srv := makeDNSServer(t)
	defer os.RemoveAll(dir)
	defer srv.agent.Shutdown()
	srv.domain = dns.Fqdn("custom")

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	// Register node
	args := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "foo2",
		Address:    "127.0.0.2",
	}

	var out struct{}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	m := new(dns.Msg)
	m.SetQuestion("172.16.31.10.in-addr.arpa.", dns.TypeANY)

	c := new(dns.Client)
	addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
	in, _, err := c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if len(in.Answer) != 1 {
		t.Fatalf("Bad: %#v", in)
	}

	ptrRec, ok := in.Answer[0].(*dns.PTR)
	if !ok {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if ptrRec.Ptr != "foo2.node.dc1.custom." {
		t.Fatalf("Bad: %#v", ptrRec)
	}
}

func TestDNS_ReverseLookup_IPV6(t *testing.T) {
	dir, srv := makeDNSServer(t)
	defer os.RemoveAll(dir)
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	// Register node
	args := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "bar",
		Address:    "::4242:4242",
	}

	var out struct{}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	m := new(dns.Msg)
	m.SetQuestion("2.4.2.4.2.4.2.4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", dns.TypeANY)

	c := new(dns.Client)
	addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
	in, _, err := c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if len(in.Answer) != 1 {
		t.Fatalf("Bad: %#v", in)
	}

	ptrRec, ok := in.Answer[0].(*dns.PTR)
	if !ok {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if ptrRec.Ptr != "bar.node.dc1.consul." {
		t.Fatalf("Bad: %#v", ptrRec)
	}
}

func TestDNS_ServiceLookup(t *testing.T) {
	dir, srv := makeDNSServer(t)
	defer os.RemoveAll(dir)
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	// Register node
	args := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "foo",
		Address:    "127.0.0.1",
		Service: &structs.NodeService{
			Service: "db",
			Tags:    []string{"master"},
			Port:    12345,
		},
	}

	var out struct{}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	m := new(dns.Msg)
	m.SetQuestion("db.service.consul.", dns.TypeSRV)

	c := new(dns.Client)
	addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
	in, _, err := c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if len(in.Answer) != 1 {
		t.Fatalf("Bad: %#v", in)
	}

	srvRec, ok := in.Answer[0].(*dns.SRV)
	if !ok {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if srvRec.Port != 12345 {
		t.Fatalf("Bad: %#v", srvRec)
	}
	if srvRec.Target != "foo.node.dc1.consul." {
		t.Fatalf("Bad: %#v", srvRec)
	}
	if srvRec.Hdr.Ttl != 0 {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}

	aRec, ok := in.Extra[0].(*dns.A)
	if !ok {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
	if aRec.Hdr.Name != "foo.node.dc1.consul." {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
	if aRec.A.String() != "127.0.0.1" {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
	if aRec.Hdr.Ttl != 0 {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
}

func TestDNS_ServiceLookup_ServiceAddress(t *testing.T) {
	dir, srv := makeDNSServer(t)
	defer os.RemoveAll(dir)
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	// Register node
	args := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "foo",
		Address:    "127.0.0.1",
		Service: &structs.NodeService{
			Service: "db",
			Tags:    []string{"master"},
			Address: "127.0.0.2",
			Port:    12345,
		},
	}

	var out struct{}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	m := new(dns.Msg)
	m.SetQuestion("db.service.consul.", dns.TypeSRV)

	c := new(dns.Client)
	addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
	in, _, err := c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if len(in.Answer) != 1 {
		t.Fatalf("Bad: %#v", in)
	}

	srvRec, ok := in.Answer[0].(*dns.SRV)
	if !ok {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if srvRec.Port != 12345 {
		t.Fatalf("Bad: %#v", srvRec)
	}
	if srvRec.Target != "foo.node.dc1.consul." {
		t.Fatalf("Bad: %#v", srvRec)
	}
	if srvRec.Hdr.Ttl != 0 {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}

	aRec, ok := in.Extra[0].(*dns.A)
	if !ok {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
	if aRec.Hdr.Name != "foo.node.dc1.consul." {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
	if aRec.A.String() != "127.0.0.2" {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
	if aRec.Hdr.Ttl != 0 {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
}

func TestDNS_CaseInsensitiveServiceLookup(t *testing.T) {
	dir, srv := makeDNSServer(t)
	defer os.RemoveAll(dir)
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	// Register node
	args := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "foo",
		Address:    "127.0.0.1",
		Service: &structs.NodeService{
			Service: "Db",
			Tags:    []string{"Master"},
			Port:    12345,
		},
	}

	var out struct{}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	m := new(dns.Msg)
	m.SetQuestion("mASTER.dB.service.consul.", dns.TypeSRV)

	c := new(dns.Client)
	addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
	in, _, err := c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if len(in.Answer) != 1 {
		t.Fatalf("empty lookup: %#v", in)
	}
}

func TestDNS_ServiceLookup_TagPeriod(t *testing.T) {
	dir, srv := makeDNSServer(t)
	defer os.RemoveAll(dir)
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	// Register node
	args := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "foo",
		Address:    "127.0.0.1",
		Service: &structs.NodeService{
			Service: "db",
			Tags:    []string{"v1.master"},
			Port:    12345,
		},
	}

	var out struct{}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	m := new(dns.Msg)
	m.SetQuestion("v1.master.db.service.consul.", dns.TypeSRV)

	c := new(dns.Client)
	addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
	in, _, err := c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if len(in.Answer) != 1 {
		t.Fatalf("Bad: %#v", in)
	}

	srvRec, ok := in.Answer[0].(*dns.SRV)
	if !ok {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if srvRec.Port != 12345 {
		t.Fatalf("Bad: %#v", srvRec)
	}
	if srvRec.Target != "foo.node.dc1.consul." {
		t.Fatalf("Bad: %#v", srvRec)
	}

	aRec, ok := in.Extra[0].(*dns.A)
	if !ok {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
	if aRec.Hdr.Name != "foo.node.dc1.consul." {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
	if aRec.A.String() != "127.0.0.1" {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
}

func TestDNS_ServiceLookup_Dedup(t *testing.T) {
	dir, srv := makeDNSServer(t)
	defer os.RemoveAll(dir)
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	// Register node
	args := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "foo",
		Address:    "127.0.0.1",
		Service: &structs.NodeService{
			Service: "db",
			Tags:    []string{"master"},
			Port:    12345,
		},
	}

	var out struct{}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	args = &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "foo",
		Address:    "127.0.0.1",
		Service: &structs.NodeService{
			ID:      "db2",
			Service: "db",
			Tags:    []string{"slave"},
			Port:    12345,
		},
	}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	args = &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "foo",
		Address:    "127.0.0.1",
		Service: &structs.NodeService{
			ID:      "db3",
			Service: "db",
			Tags:    []string{"slave"},
			Port:    12346,
		},
	}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	m := new(dns.Msg)
	m.SetQuestion("db.service.consul.", dns.TypeANY)

	c := new(dns.Client)
	addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
	in, _, err := c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if len(in.Answer) != 1 {
		t.Fatalf("Bad: %#v", in)
	}

	aRec, ok := in.Answer[0].(*dns.A)
	if !ok {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if aRec.A.String() != "127.0.0.1" {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
}

func TestDNS_ServiceLookup_Dedup_SRV(t *testing.T) {
	dir, srv := makeDNSServer(t)
	defer os.RemoveAll(dir)
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	// Register node
	args := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "foo",
		Address:    "127.0.0.1",
		Service: &structs.NodeService{
			Service: "db",
			Tags:    []string{"master"},
			Port:    12345,
		},
	}

	var out struct{}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	args = &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "foo",
		Address:    "127.0.0.1",
		Service: &structs.NodeService{
			ID:      "db2",
			Service: "db",
			Tags:    []string{"slave"},
			Port:    12345,
		},
	}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	args = &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "foo",
		Address:    "127.0.0.1",
		Service: &structs.NodeService{
			ID:      "db3",
			Service: "db",
			Tags:    []string{"slave"},
			Port:    12346,
		},
	}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	m := new(dns.Msg)
	m.SetQuestion("db.service.consul.", dns.TypeSRV)

	c := new(dns.Client)
	addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
	in, _, err := c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if len(in.Answer) != 2 {
		t.Fatalf("Bad: %#v", in)
	}

	srvRec, ok := in.Answer[0].(*dns.SRV)
	if !ok {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if srvRec.Port != 12345 && srvRec.Port != 12346 {
		t.Fatalf("Bad: %#v", srvRec)
	}
	if srvRec.Target != "foo.node.dc1.consul." {
		t.Fatalf("Bad: %#v", srvRec)
	}

	srvRec, ok = in.Answer[1].(*dns.SRV)
	if !ok {
		t.Fatalf("Bad: %#v", in.Answer[1])
	}
	if srvRec.Port != 12346 && srvRec.Port != 12345 {
		t.Fatalf("Bad: %#v", srvRec)
	}
	if srvRec.Port == in.Answer[0].(*dns.SRV).Port {
		t.Fatalf("should be a different port")
	}
	if srvRec.Target != "foo.node.dc1.consul." {
		t.Fatalf("Bad: %#v", srvRec)
	}

	aRec, ok := in.Extra[0].(*dns.A)
	if !ok {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
	if aRec.Hdr.Name != "foo.node.dc1.consul." {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
	if aRec.A.String() != "127.0.0.1" {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
}

func TestDNS_Recurse(t *testing.T) {
	dir, srv := makeDNSServer(t)
	defer os.RemoveAll(dir)
	defer srv.agent.Shutdown()

	m := new(dns.Msg)
	m.SetQuestion("apple.com.", dns.TypeANY)

	c := new(dns.Client)
	c.Net = "tcp"
	addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
	in, _, err := c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if len(in.Answer) == 0 {
		t.Fatalf("Bad: %#v", in)
	}
	if in.Rcode != dns.RcodeSuccess {
		t.Fatalf("Bad: %#v", in)
	}
}

func TestDNS_ServiceLookup_FilterCritical(t *testing.T) {
	dir, srv := makeDNSServer(t)
	defer os.RemoveAll(dir)
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	// Register nodes
	args := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "foo",
		Address:    "127.0.0.1",
		Service: &structs.NodeService{
			Service: "db",
			Tags:    []string{"master"},
			Port:    12345,
		},
		Check: &structs.HealthCheck{
			CheckID: "serf",
			Name:    "serf",
			Status:  structs.HealthCritical,
		},
	}

	var out struct{}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	args2 := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "bar",
		Address:    "127.0.0.2",
		Service: &structs.NodeService{
			Service: "db",
			Tags:    []string{"master"},
			Port:    12345,
		},
		Check: &structs.HealthCheck{
			CheckID: "serf",
			Name:    "serf",
			Status:  structs.HealthCritical,
		},
	}
	if err := srv.agent.RPC("Catalog.Register", args2, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	args3 := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "bar",
		Address:    "127.0.0.2",
		Service: &structs.NodeService{
			Service: "db",
			Tags:    []string{"master"},
			Port:    12345,
		},
		Check: &structs.HealthCheck{
			CheckID:   "db",
			Name:      "db",
			ServiceID: "db",
			Status:    structs.HealthCritical,
		},
	}
	if err := srv.agent.RPC("Catalog.Register", args3, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	args4 := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "baz",
		Address:    "127.0.0.3",
		Service: &structs.NodeService{
			Service: "db",
			Tags:    []string{"master"},
			Port:    12345,
		},
	}
	if err := srv.agent.RPC("Catalog.Register", args4, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	args5 := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "quux",
		Address:    "127.0.0.4",
		Service: &structs.NodeService{
			Service: "db",
			Tags:    []string{"master"},
			Port:    12345,
		},
		Check: &structs.HealthCheck{
			CheckID:   "db",
			Name:      "db",
			ServiceID: "db",
			Status:    structs.HealthWarning,
		},
	}
	if err := srv.agent.RPC("Catalog.Register", args5, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	m := new(dns.Msg)
	m.SetQuestion("db.service.consul.", dns.TypeANY)

	c := new(dns.Client)
	addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
	in, _, err := c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	// Only 4 and 5 are not failing, so we should get 2 answers
	if len(in.Answer) != 2 {
		t.Fatalf("Bad: %#v", in)
	}

	ips := make(map[string]bool)
	for _, resp := range in.Answer {
		aRec := resp.(*dns.A)
		ips[aRec.A.String()] = true
	}

	if !ips["127.0.0.3"] {
		t.Fatalf("Bad: %#v should contain 127.0.0.3 (state healthy)", in)
	}
	if !ips["127.0.0.4"] {
		t.Fatalf("Bad: %#v should contain 127.0.0.4 (state warning)", in)
	}
}

func TestDNS_ServiceLookup_OnlyPassing(t *testing.T) {
	dir, srv := makeDNSServerConfig(t, &DNSConfig{OnlyPassing: true})
	defer os.RemoveAll(dir)
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	// Register nodes
	args := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "foo",
		Address:    "127.0.0.1",
		Service: &structs.NodeService{
			Service: "db",
			Tags:    []string{"master"},
			Port:    12345,
		},
		Check: &structs.HealthCheck{
			CheckID:   "db",
			Name:      "db",
			ServiceID: "db",
			Status:    structs.HealthPassing,
		},
	}

	var out struct{}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	args2 := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "bar",
		Address:    "127.0.0.2",
		Service: &structs.NodeService{
			Service: "db",
			Tags:    []string{"master"},
			Port:    12345,
		},
		Check: &structs.HealthCheck{
			CheckID:   "db",
			Name:      "db",
			ServiceID: "db",
			Status:    structs.HealthWarning,
		},
	}

	if err := srv.agent.RPC("Catalog.Register", args2, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	args3 := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "baz",
		Address:    "127.0.0.3",
		Service: &structs.NodeService{
			Service: "db",
			Tags:    []string{"master"},
			Port:    12345,
		},
		Check: &structs.HealthCheck{
			CheckID:   "db",
			Name:      "db",
			ServiceID: "db",
			Status:    structs.HealthCritical,
		},
	}

	if err := srv.agent.RPC("Catalog.Register", args3, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	args4 := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "quux",
		Address:    "127.0.0.4",
		Service: &structs.NodeService{
			Service: "db",
			Tags:    []string{"master"},
			Port:    12345,
		},
		Check: &structs.HealthCheck{
			CheckID:   "db",
			Name:      "db",
			ServiceID: "db",
			Status:    structs.HealthUnknown,
		},
	}

	if err := srv.agent.RPC("Catalog.Register", args4, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	m := new(dns.Msg)
	m.SetQuestion("db.service.consul.", dns.TypeANY)

	c := new(dns.Client)
	addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
	in, _, err := c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	// Only 1 is passing, so we should only get 1 answer
	if len(in.Answer) != 1 {
		t.Fatalf("Bad: %#v", in)
	}

	resp := in.Answer[0]
	aRec := resp.(*dns.A)

	if aRec.A.String() != "127.0.0.1" {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
}

func TestDNS_ServiceLookup_Randomize(t *testing.T) {
	dir, srv := makeDNSServer(t)
	defer os.RemoveAll(dir)
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	// Register nodes
	for i := 0; i < 3*maxServiceResponses; i++ {
		args := &structs.RegisterRequest{
			Datacenter: "dc1",
			Node:       fmt.Sprintf("foo%d", i),
			Address:    fmt.Sprintf("127.0.0.%d", i+1),
			Service: &structs.NodeService{
				Service: "web",
				Port:    8000,
			},
		}

		var out struct{}
		if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
			t.Fatalf("err: %v", err)
		}
	}

	// Ensure the response is randomized each time.
	loops := 5
	uniques := map[string]struct{}{}
	addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
	for i := 0; i < loops; i++ {
		m := new(dns.Msg)
		m.SetQuestion("web.service.consul.", dns.TypeANY)

		c := new(dns.Client)
		in, _, err := c.Exchange(m, addr.String())
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		// Response length should be truncated
		// We should get an A record for each response
		if len(in.Answer) != maxServiceResponses {
			t.Fatalf("Bad: %#v", len(in.Answer))
		}

		// Collect all the names
		var names []string
		for _, rec := range in.Answer {
			switch v := rec.(type) {
			case *dns.SRV:
				names = append(names, v.Target)
			case *dns.A:
				names = append(names, v.A.String())
			}
		}
		nameS := strings.Join(names, "|")

		// Tally the results
		uniques[nameS] = struct{}{}
	}

	// Give some wiggle room. Since the responses are randomized and there
	// is a finite number of combinations, requiring 0 duplicates every
	// test run eventually gives us failures.
	if len(uniques) < (loops - 1) {
		t.Fatalf("unique response ratio too low: %d/%d\n%v",
			len(uniques), loops, uniques)
	}
}

func TestDNS_ServiceLookup_CNAME(t *testing.T) {
	dir, srv := makeDNSServer(t)
	defer os.RemoveAll(dir)
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	// Register node
	args := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "google",
		Address:    "www.google.com",
		Service: &structs.NodeService{
			Service: "search",
			Port:    80,
		},
	}

	var out struct{}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	m := new(dns.Msg)
	m.SetQuestion("search.service.consul.", dns.TypeANY)

	c := new(dns.Client)
	addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
	in, _, err := c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if len(in.Answer) != 4 {
		t.Fatalf("Bad: %#v", in)
	}

	// Should have google CNAME
	cnRec, ok := in.Answer[0].(*dns.CNAME)
	if !ok {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if cnRec.Target != "www.google.com." {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}

	// Check we recursively resolve
	for i := 1; i < 4; i++ {
		if _, ok := in.Answer[i].(*dns.A); !ok {
			t.Fatalf("Bad: %#v", in.Answer[i])
		}
	}
}

func TestDNS_NodeLookup_TTL(t *testing.T) {
	config := &DNSConfig{
		NodeTTL:    10 * time.Second,
		AllowStale: true,
		MaxStale:   time.Second,
	}

	dir, srv := makeDNSServerConfig(t, config)
	defer os.RemoveAll(dir)
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	// Register node
	args := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "foo",
		Address:    "127.0.0.1",
	}

	var out struct{}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	m := new(dns.Msg)
	m.SetQuestion("foo.node.consul.", dns.TypeANY)

	c := new(dns.Client)
	addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
	in, _, err := c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if len(in.Answer) != 1 {
		t.Fatalf("Bad: %#v", in)
	}

	aRec, ok := in.Answer[0].(*dns.A)
	if !ok {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if aRec.A.String() != "127.0.0.1" {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if aRec.Hdr.Ttl != 10 {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}

	// Register node with IPv6
	args = &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "bar",
		Address:    "::4242:4242",
	}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	// Check an IPv6 record
	m = new(dns.Msg)
	m.SetQuestion("bar.node.consul.", dns.TypeANY)

	in, _, err = c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if len(in.Answer) != 1 {
		t.Fatalf("Bad: %#v", in)
	}

	aaaaRec, ok := in.Answer[0].(*dns.AAAA)
	if !ok {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if aaaaRec.AAAA.String() != "::4242:4242" {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if aaaaRec.Hdr.Ttl != 10 {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}

	// Register node with CNAME
	args = &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "google",
		Address:    "www.google.com",
	}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	m = new(dns.Msg)
	m.SetQuestion("google.node.consul.", dns.TypeANY)

	in, _, err = c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	// Should have the CNAME record + a few A records
	if len(in.Answer) < 2 {
		t.Fatalf("Bad: %#v", in)
	}

	cnRec, ok := in.Answer[0].(*dns.CNAME)
	if !ok {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if cnRec.Target != "www.google.com." {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if cnRec.Hdr.Ttl != 10 {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
}

func TestDNS_ServiceLookup_TTL(t *testing.T) {
	config := &DNSConfig{
		ServiceTTL: map[string]time.Duration{
			"db": 10 * time.Second,
			"*":  5 * time.Second,
		},
		AllowStale: true,
		MaxStale:   time.Second,
	}

	dir, srv := makeDNSServerConfig(t, config)
	defer os.RemoveAll(dir)
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	// Register node with 2 services
	args := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "foo",
		Address:    "127.0.0.1",
		Service: &structs.NodeService{
			Service: "db",
			Tags:    []string{"master"},
			Port:    12345,
		},
	}

	var out struct{}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	args = &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "foo",
		Address:    "127.0.0.1",
		Service: &structs.NodeService{
			Service: "api",
			Port:    2222,
		},
	}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	m := new(dns.Msg)
	m.SetQuestion("db.service.consul.", dns.TypeSRV)

	c := new(dns.Client)
	addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
	in, _, err := c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if len(in.Answer) != 1 {
		t.Fatalf("Bad: %#v", in)
	}

	srvRec, ok := in.Answer[0].(*dns.SRV)
	if !ok {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if srvRec.Hdr.Ttl != 10 {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}

	aRec, ok := in.Extra[0].(*dns.A)
	if !ok {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
	if aRec.Hdr.Ttl != 10 {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}

	m = new(dns.Msg)
	m.SetQuestion("api.service.consul.", dns.TypeSRV)
	in, _, err = c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if len(in.Answer) != 1 {
		t.Fatalf("Bad: %#v", in)
	}

	srvRec, ok = in.Answer[0].(*dns.SRV)
	if !ok {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if srvRec.Hdr.Ttl != 5 {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}

	aRec, ok = in.Extra[0].(*dns.A)
	if !ok {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
	if aRec.Hdr.Ttl != 5 {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
}

func TestDNS_ServiceLookup_SRV_RFC(t *testing.T) {
	dir, srv := makeDNSServer(t)
	defer os.RemoveAll(dir)
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	// Register node
	args := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "foo",
		Address:    "127.0.0.1",
		Service: &structs.NodeService{
			Service: "db",
			Tags:    []string{"master"},
			Port:    12345,
		},
	}

	var out struct{}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	m := new(dns.Msg)
	m.SetQuestion("_db._master.service.consul.", dns.TypeSRV)

	c := new(dns.Client)
	addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
	in, _, err := c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if len(in.Answer) != 1 {
		t.Fatalf("Bad: %#v", in)
	}

	srvRec, ok := in.Answer[0].(*dns.SRV)
	if !ok {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if srvRec.Port != 12345 {
		t.Fatalf("Bad: %#v", srvRec)
	}
	if srvRec.Target != "foo.node.dc1.consul." {
		t.Fatalf("Bad: %#v", srvRec)
	}
	if srvRec.Hdr.Ttl != 0 {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}

	aRec, ok := in.Extra[0].(*dns.A)
	if !ok {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
	if aRec.Hdr.Name != "foo.node.dc1.consul." {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
	if aRec.A.String() != "127.0.0.1" {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
	if aRec.Hdr.Ttl != 0 {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
}

func TestDNS_ServiceLookup_SRV_RFC_TCP_Default(t *testing.T) {
	dir, srv := makeDNSServer(t)
	defer os.RemoveAll(dir)
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	// Register node
	args := &structs.RegisterRequest{
		Datacenter: "dc1",
		Node:       "foo",
		Address:    "127.0.0.1",
		Service: &structs.NodeService{
			Service: "db",
			Tags:    []string{"master"},
			Port:    12345,
		},
	}

	var out struct{}
	if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
		t.Fatalf("err: %v", err)
	}

	m := new(dns.Msg)
	m.SetQuestion("_db._tcp.service.consul.", dns.TypeSRV)

	c := new(dns.Client)
	addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
	in, _, err := c.Exchange(m, addr.String())
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if len(in.Answer) != 1 {
		t.Fatalf("Bad: %#v", in)
	}

	srvRec, ok := in.Answer[0].(*dns.SRV)
	if !ok {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}
	if srvRec.Port != 12345 {
		t.Fatalf("Bad: %#v", srvRec)
	}
	if srvRec.Target != "foo.node.dc1.consul." {
		t.Fatalf("Bad: %#v", srvRec)
	}
	if srvRec.Hdr.Ttl != 0 {
		t.Fatalf("Bad: %#v", in.Answer[0])
	}

	aRec, ok := in.Extra[0].(*dns.A)
	if !ok {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
	if aRec.Hdr.Name != "foo.node.dc1.consul." {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
	if aRec.A.String() != "127.0.0.1" {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
	if aRec.Hdr.Ttl != 0 {
		t.Fatalf("Bad: %#v", in.Extra[0])
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/laher/goxc/config/settings.go<|end_filename|>
// config package handles invocation settings for goxc, which can be set using a combination of cli flags plus json-based config files.
package config

/*
   Copyright 2013 <NAME>

   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.
*/

import (
	"log"

	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/laher/goxc/core"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/laher/goxc/typeutils"
)

/* 0.9: removed!
// Resources are files which a user might want to include or exclude from their package or archive
type Resources struct {
	Include string `json:",omitempty"`
	Exclude string `json:",omitempty"`
}
*/

// Invocation settings
type Settings struct {
	AppName       string `json:",omitempty"`
	ArtifactsDest string `json:",omitempty"`
	//0.13.x. If this starts with a FileSeparator then ignore top dir
	OutPath string `json:",omitempty"`

	//0.2.0 ArtifactTypes replaces ZipArchives bool
	//0.5.0 ArtifactTypes is replaced by tasks
	//ArtifactTypes []string //default = 'zip'. Also 'bin'
	//0.5.0 Codesign replaced by codesign task
	//Codesign      string   //mac signing identity

	//0.2.0 Tasks replaces IsBuildToolChain bool
	//0.5.0 Tasks is a much longer list.
	Tasks []string `json:",omitempty"`

	//0.5.0 adding exclusions. Easier for dealing with aliases. (e.g. Tasks=[default], TasksExclude=[rmbin] is easier than specifying individual tasks)
	TasksExclude []string `json:",omitempty"`

	//0.5.0 adding extra tasks.
	TasksAppend []string `json:",omitempty"`
	//0.9.9 adding 'prepend'
	TasksPrepend []string `json:",omitempty"`

	//0.6 complement Os/Arch with BuildConstraints
	Arch string `json:",omitempty"`
	Os   string `json:",omitempty"`
	//NEW 0.5.5 - implemented 0.5.7
	BuildConstraints string `json:",omitempty"`

	//0.7.x experimental option - only 0.7.3. Removed 0.7.4
	//PrependCurrentEnv string `json:",omitempty"`

	//0.9 changed from struct to ResourcesInclude & ResourcesExclude
	ResourcesInclude string `json:",omitempty"`
	ResourcesExclude string `json:",omitempty"`

	//0.10.x source exclusion
	MainDirsExclude string `json:",omitempty"`
	//0.13.x source exclusion (source dirs)
	SourceDirsExclude string `json:",omitempty"`

	//versioning
	PackageVersion string `json:",omitempty"`
	BranchName     string `json:",omitempty"`
	PrereleaseInfo string `json:",omitempty"`
	BuildName      string `json:",omitempty"`

	//0.2.0 Verbosity replaces Verbose bool
	Verbosity string `json:",omitempty"` // none/debug/

	//TaskSettings map[string]map[string]interface{}
	TaskSettings map[string]map[string]interface{} `json:",omitempty"`

	//DEPRECATED (since v0.9. See GoxcConfigVersion)
	FormatVersion string `json:",omitempty"`

	//v0.9, to replace 'FormatVersion'
	GoxcConfigVersion string `json:"ConfigVersion,omitempty"`

	BuildSettings *BuildSettings `json:",omitempty"`

	GoRoot string `json:"-"` //only settable by a flag

	//TODO?
	//PreferredGoVersion string `json:",omitempty"` //try to use a go version...

	//v0.10.x
	Env []string `json:",omitempty"`
}

func (s *Settings) IsVerbose() bool {
	return s.Verbosity == core.VerbosityVerbose
}

func (s *Settings) IsQuiet() bool {
	return s.Verbosity == core.VerbosityQuiet
}

func (s *Settings) IsTask(taskName string) bool {
	for _, t := range s.Tasks {
		if t == taskName {
			return true
		}
	}
	return false
}

func (s *Settings) SetTaskSetting(taskName, settingName string, value interface{}) {
	if s.TaskSettings == nil {
		s.TaskSettings = make(map[string]map[string]interface{})
	}
	if value, keyExists := s.TaskSettings[taskName]; keyExists {
		//ok
	} else {
		value = make(map[string]interface{})
		s.TaskSettings[taskName] = value
	}
	value.(map[string]interface{})[settingName] = value
}

// this helps whenever a 'task' gets refactored to become an 'alias' (e.g. 'pkg-build' task renamed to 'deb', and 'pkg-build' became a task alias)
// note that the task settings take precedence over the alias' settings.
func (s *Settings) MergeAliasedTaskSettings(aliases map[string][]string) {
	//for each per-task setting name/value pair:
	for taskSettingTaskName, taskSettingValue := range s.TaskSettings {
		//loop through aliases, getting alias,tasks:
		for staticSettingAlias, aliasedTasks := range aliases {
			// if the specified TaskSetting == this alias:
			if staticSettingAlias == taskSettingTaskName {
				//merge into results ...
				for _, aliasedTask := range aliasedTasks {
					aliasedTaskValue, exists := s.TaskSettings[aliasedTask]
					//if settings already exists for the actual task - merge
					if exists {
						if s.IsVerbose() {
							log.Printf("Task settings specified for %s. Merging %v with %v", aliasedTask, aliasedTaskValue, taskSettingValue)
						}
						// merge
						s.TaskSettings[aliasedTask] = typeutils.MergeMaps(aliasedTaskValue, taskSettingValue)
					} else {
						if s.IsVerbose() {
							log.Printf("alias didnt exist. Setting %s to %v", aliasedTask, taskSettingValue)
						}
						//add ...
						s.TaskSettings[aliasedTask] = taskSettingValue
					}
				}
			}
		}
	}
}

func (s *Settings) GetTaskSetting(taskName, settingName string) interface{} {
	if value, keyExists := s.TaskSettings[taskName]; keyExists {
		taskMap := value //.(map[string]interface{})
		if settingValue, keyExists := taskMap[settingName]; keyExists {
			return settingValue
		}
	} else {
		if s.IsVerbose() {
			log.Printf("No settings for task '%s'", taskName)
			log.Printf("All task settings: %+v", s.TaskSettings)
		}
	}
	return nil
}
func (s *Settings) GetTaskSettingMap(taskName, settingName string) map[string]interface{} {
	retUntyped := s.GetTaskSetting(taskName, settingName)
	if retUntyped == nil {
		return nil
	}
	mp, err := typeutils.ToMap(retUntyped, taskName+"."+settingName)
	if err != nil {
		//already logged
	}
	return mp

}

func (s *Settings) GetTaskSettingStringSlice(taskName, settingName string) []string {
	retUntyped := s.GetTaskSetting(taskName, settingName)
	if retUntyped == nil {
		return []string{}
	}
	strSlice, err := typeutils.ToStringSlice(retUntyped, taskName+"."+settingName)
	if err != nil {
		//already logged
	}
	return strSlice
}

func (s *Settings) GetTaskSettingString(taskName, settingName string) string {
	retUntyped := s.GetTaskSetting(taskName, settingName)
	if retUntyped == nil {
		return ""
	}
	str, err := typeutils.ToString(retUntyped, taskName+"."+settingName)
	if err != nil {
		//already logged
	}
	return str
}

func (s *Settings) GetTaskSettingBool(taskName, settingName string) bool {
	retUntyped := s.GetTaskSetting(taskName, settingName)
	if retUntyped == nil {
		return false
	}
	ret, err := typeutils.ToBool(retUntyped, taskName+"."+settingName)
	if err != nil {
		//already logged
	}
	return ret
}

func (s *Settings) GetTaskSettingInt(taskName, settingName string, defaultValue int) int {
	retUntyped := s.GetTaskSetting(taskName, settingName)
	if retUntyped == nil {
		return defaultValue
	}
	ret, err := typeutils.ToInt(retUntyped, taskName+"."+settingName)
	if err != nil {
		//already logged
	}
	return ret
}

//Builds version name from PackageVersion, BranchName, PrereleaseInfo, BuildName
//This breakdown is mainly based on 'semantic versioning' See http://semver.org/
//The difference being that you can specify a branch name (which becomes part of the 'prerelease info' as named by semver)
func (settings *Settings) GetFullVersionName() string {
	versionName := settings.PackageVersion
	if settings.BranchName != "" {
		versionName += "-" + settings.BranchName
	}
	if settings.PrereleaseInfo != "" {
		if settings.BranchName == "" {
			versionName += "-"
		} else {
			versionName += "."
		}
		versionName += settings.PrereleaseInfo
	}
	if settings.BuildName != "" {
		versionName += "+b" + settings.BuildName
	}
	return versionName
}

// DEPRECATED!! Merge settings together with priority.
// TODO: deprecate in favour of map merge.
func Merge(high Settings, low Settings) Settings {
	if high.ArtifactsDest == "" {
		high.ArtifactsDest = low.ArtifactsDest
	}
	if high.OutPath == "" {
		high.OutPath = low.OutPath
	}
	//0.6 Adding BuildConstraints
	if high.BuildConstraints == "" {
		high.BuildConstraints = low.BuildConstraints
	}

	if high.ResourcesInclude == "" {
		high.ResourcesInclude = low.ResourcesInclude
	}
	if high.ResourcesExclude == "" {
		high.ResourcesExclude = low.ResourcesExclude
	}
	if high.MainDirsExclude == "" {
		high.MainDirsExclude = low.MainDirsExclude
	}
	if high.AppName == "" {
		high.AppName = low.AppName
	}
	if high.Arch == "" {
		high.Arch = low.Arch
	}

	if high.Os == "" {
		high.Os = low.Os
	}
	if high.BuildConstraints == "" {
		high.BuildConstraints = low.BuildConstraints
	}
	if high.PackageVersion == "" {
		high.PackageVersion = low.PackageVersion
	}
	if high.BranchName == "" {
		high.BranchName = low.BranchName
	}
	if high.PrereleaseInfo == "" {
		high.PrereleaseInfo = low.PrereleaseInfo
	}
	if high.BuildName == "" {
		high.BuildName = low.BuildName
	}
	//TODO: merging of booleans ??
	if high.Verbosity == "" {
		high.Verbosity = low.Verbosity
	}
	//0.5.0 codesign setting is replaced by task setting 'id'
	if len(high.Tasks) == 0 {
		high.Tasks = low.Tasks
	}
	//0.6 fixed missing 'merge'
	if len(high.TasksAppend) == 0 {
		high.TasksAppend = low.TasksAppend
	}
	//0.10 adding 'prepend'
	if len(high.TasksPrepend) == 0 {
		high.TasksPrepend = low.TasksPrepend
	}
	if len(high.TasksExclude) == 0 {
		high.TasksExclude = low.TasksExclude
	}
	//0.5.0 replaced ArtifactTypes
	if len(high.TaskSettings) == 0 {
		high.TaskSettings = low.TaskSettings
	} else {
		high.TaskSettings = typeutils.MergeMapsStringMapStringInterface(high.TaskSettings, low.TaskSettings)
	}
	//0.9 BuildSettings
	if high.BuildSettings == nil || high.BuildSettings.IsEmpty() {
		high.BuildSettings = low.BuildSettings
	} else if low.BuildSettings != nil {
		if high.BuildSettings.Processors == nil {
			high.BuildSettings.Processors = low.BuildSettings.Processors
		}
		if high.BuildSettings.Race == nil {
			high.BuildSettings.Race = low.BuildSettings.Race
		}
		if high.BuildSettings.Verbose == nil {
			high.BuildSettings.Verbose = low.BuildSettings.Verbose
		}
		if high.BuildSettings.PrintCommands == nil {
			high.BuildSettings.PrintCommands = low.BuildSettings.PrintCommands
		}
		if high.BuildSettings.CcFlags == nil {
			high.BuildSettings.CcFlags = low.BuildSettings.CcFlags
		}
		if high.BuildSettings.Compiler == nil {
			high.BuildSettings.Compiler = low.BuildSettings.Compiler
		}
		if high.BuildSettings.GccGoFlags == nil {
			high.BuildSettings.GccGoFlags = low.BuildSettings.GccGoFlags
		}
		if high.BuildSettings.GcFlags == nil {
			high.BuildSettings.GcFlags = low.BuildSettings.GcFlags
		}
		if high.BuildSettings.InstallSuffix == nil {
			high.BuildSettings.InstallSuffix = low.BuildSettings.InstallSuffix
		}
		if high.BuildSettings.LdFlags == nil {
			high.BuildSettings.LdFlags = low.BuildSettings.LdFlags
		}
		if high.BuildSettings.LdFlagsXVars == nil {
			high.BuildSettings.LdFlagsXVars = low.BuildSettings.LdFlagsXVars
		}
		if high.BuildSettings.Tags == nil {
			high.BuildSettings.Tags = low.BuildSettings.Tags
		}
	}
	if len(high.Env) == 0 {
		high.Env = low.Env
	}
	return high
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/command/agent/util_test.go<|end_filename|>
package agent

import (
	"testing"
	"time"
)

func TestAEScale(t *testing.T) {
	intv := time.Minute
	if v := aeScale(intv, 100); v != intv {
		t.Fatalf("Bad: %v", v)
	}
	if v := aeScale(intv, 200); v != 2*intv {
		t.Fatalf("Bad: %v", v)
	}
	if v := aeScale(intv, 1000); v != 4*intv {
		t.Fatalf("Bad: %v", v)
	}
	if v := aeScale(intv, 10000); v != 8*intv {
		t.Fatalf("Bad: %v", v)
	}
}

func TestRandomStagger(t *testing.T) {
	intv := time.Minute
	for i := 0; i < 10; i++ {
		stagger := randomStagger(intv)
		if stagger < 0 || stagger >= intv {
			t.Fatalf("Bad: %v", stagger)
		}
	}
}

func TestStringHash(t *testing.T) {
	in := "hello world"
	expected := "5eb63bbbe01eeed093cb22bb8f5acdc3"

	if out := stringHash(in); out != expected {
		t.Fatalf("bad: %s", out)
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/consul/state_store.go<|end_filename|>
package consul

import (
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"runtime"
	"strings"
	"sync"
	"time"

	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/armon/go-radix"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/armon/gomdb"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/consul/structs"
)

const (
	dbNodes                  = "nodes"
	dbServices               = "services"
	dbChecks                 = "checks"
	dbKVS                    = "kvs"
	dbTombstone              = "tombstones"
	dbSessions               = "sessions"
	dbSessionChecks          = "sessionChecks"
	dbACLs                   = "acls"
	dbMaxMapSize32bit uint64 = 128 * 1024 * 1024       // 128MB maximum size
	dbMaxMapSize64bit uint64 = 32 * 1024 * 1024 * 1024 // 32GB maximum size
	dbMaxReaders      uint   = 4096                    // 4K, default is 126
)

// kvMode is used internally to control which type of set
// operation we are performing
type kvMode int

const (
	kvSet kvMode = iota
	kvCAS
	kvLock
	kvUnlock
)

// The StateStore is responsible for maintaining all the Consul
// state. It is manipulated by the FSM which maintains consistency
// through the use of Raft. The goals of the StateStore are to provide
// high concurrency for read operations without blocking writes, and
// to provide write availability in the face of reads. The current
// implementation uses the Lightning Memory-Mapped Database (MDB).
// This gives us Multi-Version Concurrency Control for "free"
type StateStore struct {
	logger            *log.Logger
	path              string
	env               *mdb.Env
	nodeTable         *MDBTable
	serviceTable      *MDBTable
	checkTable        *MDBTable
	kvsTable          *MDBTable
	tombstoneTable    *MDBTable
	sessionTable      *MDBTable
	sessionCheckTable *MDBTable
	aclTable          *MDBTable
	tables            MDBTables
	watch             map[*MDBTable]*NotifyGroup
	queryTables       map[string]MDBTables

	// kvWatch is a more optimized way of watching for KV changes.
	// Instead of just using a NotifyGroup for the entire table,
	// a watcher is instantiated on a given prefix. When a change happens,
	// only the relevant watchers are woken up. This reduces the cost of
	// watching for KV changes.
	kvWatch     *radix.Tree
	kvWatchLock sync.Mutex

	// lockDelay is used to mark certain locks as unacquirable.
	// When a lock is forcefully released (failing health
	// check, destroyed session, etc), it is subject to the LockDelay
	// impossed by the session. This prevents another session from
	// acquiring the lock for some period of time as a protection against
	// split-brains. This is inspired by the lock-delay in Chubby.
	// Because this relies on wall-time, we cannot assume all peers
	// perceive time as flowing uniformly. This means KVSLock MUST ignore
	// lockDelay, since the lockDelay may have expired on the leader,
	// but not on the follower. Rejecting the lock could result in
	// inconsistencies in the FSMs due to the rate time progresses. Instead,
	// only the opinion of the leader is respected, and the Raft log
	// is never questioned.
	lockDelay     map[string]time.Time
	lockDelayLock sync.RWMutex

	// GC is when we create tombstones to track their time-to-live.
	// The GC is consumed upstream to manage clearing of tombstones.
	gc *TombstoneGC
}

// StateSnapshot is used to provide a point-in-time snapshot
// It works by starting a readonly transaction against all tables.
type StateSnapshot struct {
	store     *StateStore
	tx        *MDBTxn
	lastIndex uint64
}

// sessionCheck is used to create a many-to-one table such
// that each check registered by a session can be mapped back
// to the session row.
type sessionCheck struct {
	Node    string
	CheckID string
	Session string
}

// Close is used to abort the transaction and allow for cleanup
func (s *StateSnapshot) Close() error {
	s.tx.Abort()
	return nil
}

// NewStateStore is used to create a new state store
func NewStateStore(gc *TombstoneGC, logOutput io.Writer) (*StateStore, error) {
	// Create a new temp dir
	path, err := ioutil.TempDir("", "consul")
	if err != nil {
		return nil, err
	}
	return NewStateStorePath(gc, path, logOutput)
}

// NewStateStorePath is used to create a new state store at a given path
// The path is cleared on closing.
func NewStateStorePath(gc *TombstoneGC, path string, logOutput io.Writer) (*StateStore, error) {
	// Open the env
	env, err := mdb.NewEnv()
	if err != nil {
		return nil, err
	}

	s := &StateStore{
		logger:    log.New(logOutput, "", log.LstdFlags),
		path:      path,
		env:       env,
		watch:     make(map[*MDBTable]*NotifyGroup),
		kvWatch:   radix.New(),
		lockDelay: make(map[string]time.Time),
		gc:        gc,
	}

	// Ensure we can initialize
	if err := s.initialize(); err != nil {
		env.Close()
		os.RemoveAll(path)
		return nil, err
	}
	return s, nil
}

// Close is used to safely shutdown the state store
func (s *StateStore) Close() error {
	s.env.Close()
	os.RemoveAll(s.path)
	return nil
}

// initialize is used to setup the store for use
func (s *StateStore) initialize() error {
	// Setup the Env first
	if err := s.env.SetMaxDBs(mdb.DBI(32)); err != nil {
		return err
	}

	// Set the maximum db size based on 32/64bit. Since we are
	// doing an mmap underneath, we need to limit our use of virtual
	// address space on 32bit, but don't have to care on 64bit.
	dbSize := dbMaxMapSize32bit
	if runtime.GOARCH == "amd64" {
		dbSize = dbMaxMapSize64bit
	}

	// Increase the maximum map size
	if err := s.env.SetMapSize(dbSize); err != nil {
		return err
	}

	// Increase the maximum number of concurrent readers
	// TODO: Block transactions if we could exceed dbMaxReaders
	if err := s.env.SetMaxReaders(dbMaxReaders); err != nil {
		return err
	}

	// Optimize our flags for speed over safety, since the Raft log + snapshots
	// are durable. We treat this as an ephemeral in-memory DB, since we nuke
	// the data anyways.
	var flags uint = mdb.NOMETASYNC | mdb.NOSYNC | mdb.NOTLS
	if err := s.env.Open(s.path, flags, 0755); err != nil {
		return err
	}

	// Tables use a generic struct encoder
	encoder := func(obj interface{}) []byte {
		buf, err := structs.Encode(255, obj)
		if err != nil {
			panic(err)
		}
		return buf[1:]
	}

	// Setup our tables
	s.nodeTable = &MDBTable{
		Name: dbNodes,
		Indexes: map[string]*MDBIndex{
			"id": &MDBIndex{
				Unique:          true,
				Fields:          []string{"Node"},
				CaseInsensitive: true,
			},
		},
		Decoder: func(buf []byte) interface{} {
			out := new(structs.Node)
			if err := structs.Decode(buf, out); err != nil {
				panic(err)
			}
			return out
		},
	}

	s.serviceTable = &MDBTable{
		Name: dbServices,
		Indexes: map[string]*MDBIndex{
			"id": &MDBIndex{
				Unique: true,
				Fields: []string{"Node", "ServiceID"},
			},
			"service": &MDBIndex{
				AllowBlank:      true,
				Fields:          []string{"ServiceName"},
				CaseInsensitive: true,
			},
		},
		Decoder: func(buf []byte) interface{} {
			out := new(structs.ServiceNode)
			if err := structs.Decode(buf, out); err != nil {
				panic(err)
			}
			return out
		},
	}

	s.checkTable = &MDBTable{
		Name: dbChecks,
		Indexes: map[string]*MDBIndex{
			"id": &MDBIndex{
				Unique: true,
				Fields: []string{"Node", "CheckID"},
			},
			"status": &MDBIndex{
				Fields: []string{"Status"},
			},
			"service": &MDBIndex{
				AllowBlank: true,
				Fields:     []string{"ServiceName"},
			},
			"node": &MDBIndex{
				AllowBlank: true,
				Fields:     []string{"Node", "ServiceID"},
			},
		},
		Decoder: func(buf []byte) interface{} {
			out := new(structs.HealthCheck)
			if err := structs.Decode(buf, out); err != nil {
				panic(err)
			}
			return out
		},
	}

	s.kvsTable = &MDBTable{
		Name: dbKVS,
		Indexes: map[string]*MDBIndex{
			"id": &MDBIndex{
				Unique: true,
				Fields: []string{"Key"},
			},
			"id_prefix": &MDBIndex{
				Virtual:   true,
				RealIndex: "id",
				Fields:    []string{"Key"},
				IdxFunc:   DefaultIndexPrefixFunc,
			},
			"session": &MDBIndex{
				AllowBlank: true,
				Fields:     []string{"Session"},
			},
		},
		Decoder: func(buf []byte) interface{} {
			out := new(structs.DirEntry)
			if err := structs.Decode(buf, out); err != nil {
				panic(err)
			}
			return out
		},
	}

	s.tombstoneTable = &MDBTable{
		Name: dbTombstone,
		Indexes: map[string]*MDBIndex{
			"id": &MDBIndex{
				Unique: true,
				Fields: []string{"Key"},
			},
			"id_prefix": &MDBIndex{
				Virtual:   true,
				RealIndex: "id",
				Fields:    []string{"Key"},
				IdxFunc:   DefaultIndexPrefixFunc,
			},
		},
		Decoder: func(buf []byte) interface{} {
			out := new(structs.DirEntry)
			if err := structs.Decode(buf, out); err != nil {
				panic(err)
			}
			return out
		},
	}

	s.sessionTable = &MDBTable{
		Name: dbSessions,
		Indexes: map[string]*MDBIndex{
			"id": &MDBIndex{
				Unique: true,
				Fields: []string{"ID"},
			},
			"node": &MDBIndex{
				AllowBlank: true,
				Fields:     []string{"Node"},
			},
		},
		Decoder: func(buf []byte) interface{} {
			out := new(structs.Session)
			if err := structs.Decode(buf, out); err != nil {
				panic(err)
			}
			return out
		},
	}

	s.sessionCheckTable = &MDBTable{
		Name: dbSessionChecks,
		Indexes: map[string]*MDBIndex{
			"id": &MDBIndex{
				Unique: true,
				Fields: []string{"Node", "CheckID", "Session"},
			},
		},
		Decoder: func(buf []byte) interface{} {
			out := new(sessionCheck)
			if err := structs.Decode(buf, out); err != nil {
				panic(err)
			}
			return out
		},
	}

	s.aclTable = &MDBTable{
		Name: dbACLs,
		Indexes: map[string]*MDBIndex{
			"id": &MDBIndex{
				Unique: true,
				Fields: []string{"ID"},
			},
		},
		Decoder: func(buf []byte) interface{} {
			out := new(structs.ACL)
			if err := structs.Decode(buf, out); err != nil {
				panic(err)
			}
			return out
		},
	}

	// Store the set of tables
	s.tables = []*MDBTable{s.nodeTable, s.serviceTable, s.checkTable,
		s.kvsTable, s.tombstoneTable, s.sessionTable, s.sessionCheckTable,
		s.aclTable}
	for _, table := range s.tables {
		table.Env = s.env
		table.Encoder = encoder
		if err := table.Init(); err != nil {
			return err
		}

		// Setup a notification group per table
		s.watch[table] = &NotifyGroup{}
	}

	// Setup the query tables
	s.queryTables = map[string]MDBTables{
		"Nodes":             MDBTables{s.nodeTable},
		"Services":          MDBTables{s.serviceTable},
		"ServiceNodes":      MDBTables{s.nodeTable, s.serviceTable},
		"NodeServices":      MDBTables{s.nodeTable, s.serviceTable},
		"ChecksInState":     MDBTables{s.checkTable},
		"NodeChecks":        MDBTables{s.checkTable},
		"ServiceChecks":     MDBTables{s.checkTable},
		"CheckServiceNodes": MDBTables{s.nodeTable, s.serviceTable, s.checkTable},
		"NodeInfo":          MDBTables{s.nodeTable, s.serviceTable, s.checkTable},
		"NodeDump":          MDBTables{s.nodeTable, s.serviceTable, s.checkTable},
		"SessionGet":        MDBTables{s.sessionTable},
		"SessionList":       MDBTables{s.sessionTable},
		"NodeSessions":      MDBTables{s.sessionTable},
		"ACLGet":            MDBTables{s.aclTable},
		"ACLList":           MDBTables{s.aclTable},
	}
	return nil
}

// Watch is used to subscribe a channel to a set of MDBTables
func (s *StateStore) Watch(tables MDBTables, notify chan struct{}) {
	for _, t := range tables {
		s.watch[t].Wait(notify)
	}
}

// WatchKV is used to subscribe a channel to changes in KV data
func (s *StateStore) WatchKV(prefix string, notify chan struct{}) {
	s.kvWatchLock.Lock()
	defer s.kvWatchLock.Unlock()

	// Check for an existing notify group
	if raw, ok := s.kvWatch.Get(prefix); ok {
		grp := raw.(*NotifyGroup)
		grp.Wait(notify)
		return
	}

	// Create new notify group
	grp := &NotifyGroup{}
	grp.Wait(notify)
	s.kvWatch.Insert(prefix, grp)
}

// notifyKV is used to notify any KV listeners of a change
// on a prefix
func (s *StateStore) notifyKV(path string, prefix bool) {
	s.kvWatchLock.Lock()
	defer s.kvWatchLock.Unlock()

	var toDelete []string
	fn := func(s string, v interface{}) bool {
		group := v.(*NotifyGroup)
		group.Notify()
		if s != "" {
			toDelete = append(toDelete, s)
		}
		return false
	}

	// Invoke any watcher on the path downward to the key.
	s.kvWatch.WalkPath(path, fn)

	// If the entire prefix may be affected (e.g. delete tree),
	// invoke the entire prefix
	if prefix {
		s.kvWatch.WalkPrefix(path, fn)
	}

	// Delete the old watch groups
	for i := len(toDelete) - 1; i >= 0; i-- {
		s.kvWatch.Delete(toDelete[i])
	}
}

// QueryTables returns the Tables that are queried for a given query
func (s *StateStore) QueryTables(q string) MDBTables {
	return s.queryTables[q]
}

// EnsureRegistration is used to make sure a node, service, and check registration
// is performed within a single transaction to avoid race conditions on state updates.
func (s *StateStore) EnsureRegistration(index uint64, req *structs.RegisterRequest) error {
	tx, err := s.tables.StartTxn(false)
	if err != nil {
		panic(fmt.Errorf("Failed to start txn: %v", err))
	}
	defer tx.Abort()

	// Ensure the node
	node := structs.Node{req.Node, req.Address}
	if err := s.ensureNodeTxn(index, node, tx); err != nil {
		return err
	}

	// Ensure the service if provided
	if req.Service != nil {
		if err := s.ensureServiceTxn(index, req.Node, req.Service, tx); err != nil {
			return err
		}
	}

	// Ensure the check if provided
	if req.Check != nil {
		if err := s.ensureCheckTxn(index, req.Check, tx); err != nil {
			return err
		}
	}

	// Commit as one unit
	return tx.Commit()
}

// EnsureNode is used to ensure a given node exists, with the provided address
func (s *StateStore) EnsureNode(index uint64, node structs.Node) error {
	tx, err := s.nodeTable.StartTxn(false, nil)
	if err != nil {
		return err
	}
	defer tx.Abort()
	if err := s.ensureNodeTxn(index, node, tx); err != nil {
		return err
	}
	return tx.Commit()
}

// ensureNodeTxn is used to ensure a given node exists, with the provided address
// within a given txn
func (s *StateStore) ensureNodeTxn(index uint64, node structs.Node, tx *MDBTxn) error {
	if err := s.nodeTable.InsertTxn(tx, node); err != nil {
		return err
	}
	if err := s.nodeTable.SetLastIndexTxn(tx, index); err != nil {
		return err
	}
	tx.Defer(func() { s.watch[s.nodeTable].Notify() })
	return nil
}

// GetNode returns all the address of the known and if it was found
func (s *StateStore) GetNode(name string) (uint64, bool, string) {
	idx, res, err := s.nodeTable.Get("id", name)
	if err != nil {
		s.logger.Printf("[ERR] consul.state: Error during node lookup: %v", err)
		return 0, false, ""
	}
	if len(res) == 0 {
		return idx, false, ""
	}
	return idx, true, res[0].(*structs.Node).Address
}

// GetNodes returns all the known nodes, the slice alternates between
// the node name and address
func (s *StateStore) Nodes() (uint64, structs.Nodes) {
	idx, res, err := s.nodeTable.Get("id")
	if err != nil {
		s.logger.Printf("[ERR] consul.state: Error getting nodes: %v", err)
	}
	results := make([]structs.Node, len(res))
	for i, r := range res {
		results[i] = *r.(*structs.Node)
	}
	return idx, results
}

// EnsureService is used to ensure a given node exposes a service
func (s *StateStore) EnsureService(index uint64, node string, ns *structs.NodeService) error {
	tx, err := s.tables.StartTxn(false)
	if err != nil {
		panic(fmt.Errorf("Failed to start txn: %v", err))
	}
	defer tx.Abort()
	if err := s.ensureServiceTxn(index, node, ns, tx); err != nil {
		return nil
	}
	return tx.Commit()
}

// ensureServiceTxn is used to ensure a given node exposes a service in a transaction
func (s *StateStore) ensureServiceTxn(index uint64, node string, ns *structs.NodeService, tx *MDBTxn) error {
	// Ensure the node exists
	res, err := s.nodeTable.GetTxn(tx, "id", node)
	if err != nil {
		return err
	}
	if len(res) == 0 {
		return fmt.Errorf("Missing node registration")
	}

	// Create the entry
	entry := structs.ServiceNode{
		Node:           node,
		ServiceID:      ns.ID,
		ServiceName:    ns.Service,
		ServiceTags:    ns.Tags,
		ServiceAddress: ns.Address,
		ServicePort:    ns.Port,
	}

	// Ensure the service entry is set
	if err := s.serviceTable.InsertTxn(tx, &entry); err != nil {
		return err
	}
	if err := s.serviceTable.SetLastIndexTxn(tx, index); err != nil {
		return err
	}
	tx.Defer(func() { s.watch[s.serviceTable].Notify() })
	return nil
}

// NodeServices is used to return all the services of a given node
func (s *StateStore) NodeServices(name string) (uint64, *structs.NodeServices) {
	tables := s.queryTables["NodeServices"]
	tx, err := tables.StartTxn(true)
	if err != nil {
		panic(fmt.Errorf("Failed to start txn: %v", err))
	}
	defer tx.Abort()
	return s.parseNodeServices(tables, tx, name)
}

// parseNodeServices is used to get the services belonging to a
// node, using a given txn
func (s *StateStore) parseNodeServices(tables MDBTables, tx *MDBTxn, name string) (uint64, *structs.NodeServices) {
	ns := &structs.NodeServices{
		Services: make(map[string]*structs.NodeService),
	}

	// Get the maximum index
	index, err := tables.LastIndexTxn(tx)
	if err != nil {
		panic(fmt.Errorf("Failed to get last index: %v", err))
	}

	// Get the node first
	res, err := s.nodeTable.GetTxn(tx, "id", name)
	if err != nil {
		s.logger.Printf("[ERR] consul.state: Failed to get node: %v", err)
	}
	if len(res) == 0 {
		return index, nil
	}

	// Set the address
	node := res[0].(*structs.Node)
	ns.Node = *node

	// Get the services
	res, err = s.serviceTable.GetTxn(tx, "id", name)
	if err != nil {
		s.logger.Printf("[ERR] consul.state: Failed to get node '%s' services: %v", name, err)
	}

	// Add each service
	for _, r := range res {
		service := r.(*structs.ServiceNode)
		srv := &structs.NodeService{
			ID:      service.ServiceID,
			Service: service.ServiceName,
			Tags:    service.ServiceTags,
			Address: service.ServiceAddress,
			Port:    service.ServicePort,
		}
		ns.Services[srv.ID] = srv
	}
	return index, ns
}

// DeleteNodeService is used to delete a node service
func (s *StateStore) DeleteNodeService(index uint64, node, id string) error {
	tx, err := s.tables.StartTxn(false)
	if err != nil {
		panic(fmt.Errorf("Failed to start txn: %v", err))
	}
	defer tx.Abort()

	if n, err := s.serviceTable.DeleteTxn(tx, "id", node, id); err != nil {
		return err
	} else if n > 0 {
		if err := s.serviceTable.SetLastIndexTxn(tx, index); err != nil {
			return err
		}
		tx.Defer(func() { s.watch[s.serviceTable].Notify() })
	}

	// Invalidate any sessions using these checks
	checks, err := s.checkTable.GetTxn(tx, "node", node, id)
	if err != nil {
		return err
	}
	for _, c := range checks {
		check := c.(*structs.HealthCheck)
		if err := s.invalidateCheck(index, tx, node, check.CheckID); err != nil {
			return err
		}
	}

	if n, err := s.checkTable.DeleteTxn(tx, "node", node, id); err != nil {
		return err
	} else if n > 0 {
		if err := s.checkTable.SetLastIndexTxn(tx, index); err != nil {
			return err
		}
		tx.Defer(func() { s.watch[s.checkTable].Notify() })
	}
	return tx.Commit()
}

// DeleteNode is used to delete a node and all it's services
func (s *StateStore) DeleteNode(index uint64, node string) error {
	tx, err := s.tables.StartTxn(false)
	if err != nil {
		panic(fmt.Errorf("Failed to start txn: %v", err))
	}
	defer tx.Abort()

	// Invalidate any sessions held by the node
	if err := s.invalidateNode(index, tx, node); err != nil {
		return err
	}

	if n, err := s.serviceTable.DeleteTxn(tx, "id", node); err != nil {
		return err
	} else if n > 0 {
		if err := s.serviceTable.SetLastIndexTxn(tx, index); err != nil {
			return err
		}
		tx.Defer(func() { s.watch[s.serviceTable].Notify() })
	}
	if n, err := s.checkTable.DeleteTxn(tx, "id", node); err != nil {
		return err
	} else if n > 0 {
		if err := s.checkTable.SetLastIndexTxn(tx, index); err != nil {
			return err
		}
		tx.Defer(func() { s.watch[s.checkTable].Notify() })
	}
	if n, err := s.nodeTable.DeleteTxn(tx, "id", node); err != nil {
		return err
	} else if n > 0 {
		if err := s.nodeTable.SetLastIndexTxn(tx, index); err != nil {
			return err
		}
		tx.Defer(func() { s.watch[s.nodeTable].Notify() })
	}
	return tx.Commit()
}

// Services is used to return all the services with a list of associated tags
func (s *StateStore) Services() (uint64, map[string][]string) {
	services := make(map[string][]string)
	idx, res, err := s.serviceTable.Get("id")
	if err != nil {
		s.logger.Printf("[ERR] consul.state: Failed to get services: %v", err)
		return idx, services
	}
	for _, r := range res {
		srv := r.(*structs.ServiceNode)
		tags, ok := services[srv.ServiceName]
		if !ok {
			services[srv.ServiceName] = make([]string, 0)
		}

		for _, tag := range srv.ServiceTags {
			if !strContains(tags, tag) {
				tags = append(tags, tag)
				services[srv.ServiceName] = tags
			}
		}
	}
	return idx, services
}

// ServiceNodes returns the nodes associated with a given service
func (s *StateStore) ServiceNodes(service string) (uint64, structs.ServiceNodes) {
	tables := s.queryTables["ServiceNodes"]
	tx, err := tables.StartTxn(true)
	if err != nil {
		panic(fmt.Errorf("Failed to start txn: %v", err))
	}
	defer tx.Abort()

	idx, err := tables.LastIndexTxn(tx)
	if err != nil {
		panic(fmt.Errorf("Failed to get last index: %v", err))
	}

	res, err := s.serviceTable.GetTxn(tx, "service", service)
	return idx, s.parseServiceNodes(tx, s.nodeTable, res, err)
}

// ServiceTagNodes returns the nodes associated with a given service matching a tag
func (s *StateStore) ServiceTagNodes(service, tag string) (uint64, structs.ServiceNodes) {
	tables := s.queryTables["ServiceNodes"]
	tx, err := tables.StartTxn(true)
	if err != nil {
		panic(fmt.Errorf("Failed to start txn: %v", err))
	}
	defer tx.Abort()

	idx, err := tables.LastIndexTxn(tx)
	if err != nil {
		panic(fmt.Errorf("Failed to get last index: %v", err))
	}

	res, err := s.serviceTable.GetTxn(tx, "service", service)
	res = serviceTagFilter(res, tag)
	return idx, s.parseServiceNodes(tx, s.nodeTable, res, err)
}

// serviceTagFilter is used to filter a list of *structs.ServiceNode which do
// not have the specified tag
func serviceTagFilter(l []interface{}, tag string) []interface{} {
	n := len(l)
	for i := 0; i < n; i++ {
		srv := l[i].(*structs.ServiceNode)
		if !strContains(ToLowerList(srv.ServiceTags), strings.ToLower(tag)) {
			l[i], l[n-1] = l[n-1], nil
			i--
			n--
		}
	}
	return l[:n]
}

// parseServiceNodes parses results ServiceNodes and ServiceTagNodes
func (s *StateStore) parseServiceNodes(tx *MDBTxn, table *MDBTable, res []interface{}, err error) structs.ServiceNodes {
	nodes := make(structs.ServiceNodes, len(res))
	if err != nil {
		s.logger.Printf("[ERR] consul.state: Failed to get service nodes: %v", err)
		return nodes
	}

	for i, r := range res {
		srv := r.(*structs.ServiceNode)

		// Get the address of the node
		nodeRes, err := table.GetTxn(tx, "id", srv.Node)
		if err != nil || len(nodeRes) != 1 {
			s.logger.Printf("[ERR] consul.state: Failed to join service node %#v with node: %v", *srv, err)
			continue
		}
		srv.Address = nodeRes[0].(*structs.Node).Address

		nodes[i] = *srv
	}

	return nodes
}

// EnsureCheck is used to create a check or updates it's state
func (s *StateStore) EnsureCheck(index uint64, check *structs.HealthCheck) error {
	tx, err := s.tables.StartTxn(false)
	if err != nil {
		panic(fmt.Errorf("Failed to start txn: %v", err))
	}
	defer tx.Abort()
	if err := s.ensureCheckTxn(index, check, tx); err != nil {
		return err
	}
	return tx.Commit()
}

// ensureCheckTxn is used to create a check or updates it's state in a transaction
func (s *StateStore) ensureCheckTxn(index uint64, check *structs.HealthCheck, tx *MDBTxn) error {
	// Ensure we have a status
	if check.Status == "" {
		check.Status = structs.HealthCritical
	}

	// Ensure the node exists
	res, err := s.nodeTable.GetTxn(tx, "id", check.Node)
	if err != nil {
		return err
	}
	if len(res) == 0 {
		return fmt.Errorf("Missing node registration")
	}

	// Ensure the service exists if specified
	if check.ServiceID != "" {
		res, err = s.serviceTable.GetTxn(tx, "id", check.Node, check.ServiceID)
		if err != nil {
			return err
		}
		if len(res) == 0 {
			return fmt.Errorf("Missing service registration")
		}
		// Ensure we set the correct service
		srv := res[0].(*structs.ServiceNode)
		check.ServiceName = srv.ServiceName
	}

	// Invalidate any sessions if status is critical
	if check.Status == structs.HealthCritical {
		err := s.invalidateCheck(index, tx, check.Node, check.CheckID)
		if err != nil {
			return err
		}
	}

	// Ensure the check is set
	if err := s.checkTable.InsertTxn(tx, check); err != nil {
		return err
	}
	if err := s.checkTable.SetLastIndexTxn(tx, index); err != nil {
		return err
	}
	tx.Defer(func() { s.watch[s.checkTable].Notify() })
	return nil
}

// DeleteNodeCheck is used to delete a node health check
func (s *StateStore) DeleteNodeCheck(index uint64, node, id string) error {
	tx, err := s.tables.StartTxn(false)
	if err != nil {
		return err
	}
	defer tx.Abort()

	// Invalidate any sessions held by this check
	if err := s.invalidateCheck(index, tx, node, id); err != nil {
		return err
	}

	if n, err := s.checkTable.DeleteTxn(tx, "id", node, id); err != nil {
		return err
	} else if n > 0 {
		if err := s.checkTable.SetLastIndexTxn(tx, index); err != nil {
			return err
		}
		tx.Defer(func() { s.watch[s.checkTable].Notify() })
	}
	return tx.Commit()
}

// NodeChecks is used to get all the checks for a node
func (s *StateStore) NodeChecks(node string) (uint64, structs.HealthChecks) {
	return s.parseHealthChecks(s.checkTable.Get("id", node))
}

// ServiceChecks is used to get all the checks for a service
func (s *StateStore) ServiceChecks(service string) (uint64, structs.HealthChecks) {
	return s.parseHealthChecks(s.checkTable.Get("service", service))
}

// CheckInState is used to get all the checks for a service in a given state
func (s *StateStore) ChecksInState(state string) (uint64, structs.HealthChecks) {
	var idx uint64
	var res []interface{}
	var err error
	if state == structs.HealthAny {
		idx, res, err = s.checkTable.Get("id")
	} else {
		idx, res, err = s.checkTable.Get("status", state)
	}
	return s.parseHealthChecks(idx, res, err)
}

// parseHealthChecks is used to handle the resutls of a Get against
// the checkTable
func (s *StateStore) parseHealthChecks(idx uint64, res []interface{}, err error) (uint64, structs.HealthChecks) {
	results := make([]*structs.HealthCheck, len(res))
	if err != nil {
		s.logger.Printf("[ERR] consul.state: Failed to get health checks: %v", err)
		return idx, results
	}
	for i, r := range res {
		results[i] = r.(*structs.HealthCheck)
	}
	return idx, results
}

// CheckServiceNodes returns the nodes associated with a given service, along
// with any associated check
func (s *StateStore) CheckServiceNodes(service string) (uint64, structs.CheckServiceNodes) {
	tables := s.queryTables["CheckServiceNodes"]
	tx, err := tables.StartTxn(true)
	if err != nil {
		panic(fmt.Errorf("Failed to start txn: %v", err))
	}
	defer tx.Abort()

	idx, err := tables.LastIndexTxn(tx)
	if err != nil {
		panic(fmt.Errorf("Failed to get last index: %v", err))
	}

	res, err := s.serviceTable.GetTxn(tx, "service", service)
	return idx, s.parseCheckServiceNodes(tx, res, err)
}

// CheckServiceNodes returns the nodes associated with a given service, along
// with any associated checks
func (s *StateStore) CheckServiceTagNodes(service, tag string) (uint64, structs.CheckServiceNodes) {
	tables := s.queryTables["CheckServiceNodes"]
	tx, err := tables.StartTxn(true)
	if err != nil {
		panic(fmt.Errorf("Failed to start txn: %v", err))
	}
	defer tx.Abort()

	idx, err := tables.LastIndexTxn(tx)
	if err != nil {
		panic(fmt.Errorf("Failed to get last index: %v", err))
	}

	res, err := s.serviceTable.GetTxn(tx, "service", service)
	res = serviceTagFilter(res, tag)
	return idx, s.parseCheckServiceNodes(tx, res, err)
}

// parseCheckServiceNodes parses results CheckServiceNodes and CheckServiceTagNodes
func (s *StateStore) parseCheckServiceNodes(tx *MDBTxn, res []interface{}, err error) structs.CheckServiceNodes {
	nodes := make(structs.CheckServiceNodes, len(res))
	if err != nil {
		s.logger.Printf("[ERR] consul.state: Failed to get service nodes: %v", err)
		return nodes
	}

	for i, r := range res {
		srv := r.(*structs.ServiceNode)

		// Get the node
		nodeRes, err := s.nodeTable.GetTxn(tx, "id", srv.Node)
		if err != nil || len(nodeRes) != 1 {
			s.logger.Printf("[ERR] consul.state: Failed to join service node %#v with node: %v", *srv, err)
			continue
		}

		// Get any associated checks of the service
		res, err := s.checkTable.GetTxn(tx, "node", srv.Node, srv.ServiceID)
		_, checks := s.parseHealthChecks(0, res, err)

		// Get any checks of the node, not assciated with any service
		res, err = s.checkTable.GetTxn(tx, "node", srv.Node, "")
		_, nodeChecks := s.parseHealthChecks(0, res, err)
		checks = append(checks, nodeChecks...)

		// Setup the node
		nodes[i].Node = *nodeRes[0].(*structs.Node)
		nodes[i].Service = structs.NodeService{
			ID:      srv.ServiceID,
			Service: srv.ServiceName,
			Tags:    srv.ServiceTags,
			Address: srv.ServiceAddress,
			Port:    srv.ServicePort,
		}
		nodes[i].Checks = checks
	}

	return nodes
}

// NodeInfo is used to generate the full info about a node.
func (s *StateStore) NodeInfo(node string) (uint64, structs.NodeDump) {
	tables := s.queryTables["NodeInfo"]
	tx, err := tables.StartTxn(true)
	if err != nil {
		panic(fmt.Errorf("Failed to start txn: %v", err))
	}
	defer tx.Abort()

	idx, err := tables.LastIndexTxn(tx)
	if err != nil {
		panic(fmt.Errorf("Failed to get last index: %v", err))
	}

	res, err := s.nodeTable.GetTxn(tx, "id", node)
	return idx, s.parseNodeInfo(tx, res, err)
}

// NodeDump is used to generate the NodeInfo for all nodes. This is very expensive,
// and should generally be avoided for programatic access.
func (s *StateStore) NodeDump() (uint64, structs.NodeDump) {
	tables := s.queryTables["NodeDump"]
	tx, err := tables.StartTxn(true)
	if err != nil {
		panic(fmt.Errorf("Failed to start txn: %v", err))
	}
	defer tx.Abort()

	idx, err := tables.LastIndexTxn(tx)
	if err != nil {
		panic(fmt.Errorf("Failed to get last index: %v", err))
	}

	res, err := s.nodeTable.GetTxn(tx, "id")
	return idx, s.parseNodeInfo(tx, res, err)
}

// parseNodeInfo is used to scan over the results of a node
// iteration and generate a NodeDump
func (s *StateStore) parseNodeInfo(tx *MDBTxn, res []interface{}, err error) structs.NodeDump {
	dump := make(structs.NodeDump, 0, len(res))
	if err != nil {
		s.logger.Printf("[ERR] consul.state: Failed to get nodes: %v", err)
		return dump
	}

	for _, r := range res {
		// Copy the address and node
		node := r.(*structs.Node)
		info := &structs.NodeInfo{
			Node:    node.Node,
			Address: node.Address,
		}

		// Get any services of the node
		res, err = s.serviceTable.GetTxn(tx, "id", node.Node)
		if err != nil {
			s.logger.Printf("[ERR] consul.state: Failed to get node services: %v", err)
		}
		info.Services = make([]*structs.NodeService, 0, len(res))
		for _, r := range res {
			service := r.(*structs.ServiceNode)
			srv := &structs.NodeService{
				ID:      service.ServiceID,
				Service: service.ServiceName,
				Tags:    service.ServiceTags,
				Address: service.ServiceAddress,
				Port:    service.ServicePort,
			}
			info.Services = append(info.Services, srv)
		}

		// Get any checks of the node
		res, err = s.checkTable.GetTxn(tx, "node", node.Node)
		if err != nil {
			s.logger.Printf("[ERR] consul.state: Failed to get node checks: %v", err)
		}
		info.Checks = make([]*structs.HealthCheck, 0, len(res))
		for _, r := range res {
			chk := r.(*structs.HealthCheck)
			info.Checks = append(info.Checks, chk)
		}

		// Add the node info
		dump = append(dump, info)
	}
	return dump
}

// KVSSet is used to create or update a KV entry
func (s *StateStore) KVSSet(index uint64, d *structs.DirEntry) error {
	_, err := s.kvsSet(index, d, kvSet)
	return err
}

// KVSRestore is used to restore a DirEntry. It should only be used when
// doing a restore, otherwise KVSSet should be used.
func (s *StateStore) KVSRestore(d *structs.DirEntry) error {
	// Start a new txn
	tx, err := s.kvsTable.StartTxn(false, nil)
	if err != nil {
		return err
	}
	defer tx.Abort()

	if err := s.kvsTable.InsertTxn(tx, d); err != nil {
		return err
	}
	if err := s.kvsTable.SetMaxLastIndexTxn(tx, d.ModifyIndex); err != nil {
		return err
	}
	return tx.Commit()
}

// KVSGet is used to get a KV entry
func (s *StateStore) KVSGet(key string) (uint64, *structs.DirEntry, error) {
	idx, res, err := s.kvsTable.Get("id", key)
	var d *structs.DirEntry
	if len(res) > 0 {
		d = res[0].(*structs.DirEntry)
	}
	return idx, d, err
}

// KVSList is used to list all KV entries with a prefix
func (s *StateStore) KVSList(prefix string) (uint64, uint64, structs.DirEntries, error) {
	tables := MDBTables{s.kvsTable, s.tombstoneTable}
	tx, err := tables.StartTxn(true)
	if err != nil {
		return 0, 0, nil, err
	}
	defer tx.Abort()

	idx, err := tables.LastIndexTxn(tx)
	if err != nil {
		return 0, 0, nil, err
	}

	res, err := s.kvsTable.GetTxn(tx, "id_prefix", prefix)
	if err != nil {
		return 0, 0, nil, err
	}
	ents := make(structs.DirEntries, len(res))
	for idx, r := range res {
		ents[idx] = r.(*structs.DirEntry)
	}

	// Check for the higest index in the tombstone table
	var maxIndex uint64
	res, err = s.tombstoneTable.GetTxn(tx, "id_prefix", prefix)
	for _, r := range res {
		ent := r.(*structs.DirEntry)
		if ent.ModifyIndex > maxIndex {
			maxIndex = ent.ModifyIndex
		}
	}

	return maxIndex, idx, ents, err
}

// KVSListKeys is used to list keys with a prefix, and up to a given seperator
func (s *StateStore) KVSListKeys(prefix, seperator string) (uint64, []string, error) {
	tables := MDBTables{s.kvsTable, s.tombstoneTable}
	tx, err := tables.StartTxn(true)
	if err != nil {
		return 0, nil, err
	}
	defer tx.Abort()

	idx, err := s.kvsTable.LastIndexTxn(tx)
	if err != nil {
		return 0, nil, err
	}

	// Ensure a non-zero index
	if idx == 0 {
		// Must provide non-zero index to prevent blocking
		// Index 1 is impossible anyways (due to Raft internals)
		idx = 1
	}

	// Aggregate the stream
	stream := make(chan interface{}, 128)
	streamTomb := make(chan interface{}, 128)
	done := make(chan struct{})
	var keys []string
	var maxIndex uint64
	go func() {
		prefixLen := len(prefix)
		sepLen := len(seperator)
		last := ""
		for raw := range stream {
			ent := raw.(*structs.DirEntry)
			after := ent.Key[prefixLen:]

			// Update the hightest index we've seen
			if ent.ModifyIndex > maxIndex {
				maxIndex = ent.ModifyIndex
			}

			// If there is no seperator, always accumulate
			if sepLen == 0 {
				keys = append(keys, ent.Key)
				continue
			}

			// Check for the seperator
			if idx := strings.Index(after, seperator); idx >= 0 {
				toSep := ent.Key[:prefixLen+idx+sepLen]
				if last != toSep {
					keys = append(keys, toSep)
					last = toSep
				}
			} else {
				keys = append(keys, ent.Key)
			}
		}

		// Handle the tombstones for any index updates
		for raw := range streamTomb {
			ent := raw.(*structs.DirEntry)
			if ent.ModifyIndex > maxIndex {
				maxIndex = ent.ModifyIndex
			}
		}
		close(done)
	}()

	// Start the stream, and wait for completion
	if err = s.kvsTable.StreamTxn(stream, tx, "id_prefix", prefix); err != nil {
		return 0, nil, err
	}
	if err := s.tombstoneTable.StreamTxn(streamTomb, tx, "id_prefix", prefix); err != nil {
		return 0, nil, err
	}
	<-done

	// Use the maxIndex if we have any keys
	if maxIndex != 0 {
		idx = maxIndex
	}
	return idx, keys, nil
}

// KVSDelete is used to delete a KVS entry
func (s *StateStore) KVSDelete(index uint64, key string) error {
	return s.kvsDeleteWithIndex(index, "id", key)
}

// KVSDeleteCheckAndSet is used to perform an atomic delete check-and-set
func (s *StateStore) KVSDeleteCheckAndSet(index uint64, key string, casIndex uint64) (bool, error) {
	tx, err := s.tables.StartTxn(false)
	if err != nil {
		return false, err
	}
	defer tx.Abort()

	// Get the existing node
	res, err := s.kvsTable.GetTxn(tx, "id", key)
	if err != nil {
		return false, err
	}

	// Get the existing node if any
	var exist *structs.DirEntry
	if len(res) > 0 {
		exist = res[0].(*structs.DirEntry)
	}

	// Use the casIndex as the constraint. A modify time of 0 means
	// we are doign a delete-if-not-exists (odd...), while any other
	// value means we expect that modify time.
	if casIndex == 0 {
		return exist == nil, nil
	} else if casIndex > 0 && (exist == nil || exist.ModifyIndex != casIndex) {
		return false, nil
	}

	// Do the actual delete
	if err := s.kvsDeleteWithIndexTxn(index, tx, "id", key); err != nil {
		return false, err
	}
	return true, tx.Commit()
}

// KVSDeleteTree is used to delete all keys with a given prefix
func (s *StateStore) KVSDeleteTree(index uint64, prefix string) error {
	if prefix == "" {
		return s.kvsDeleteWithIndex(index, "id")
	}
	return s.kvsDeleteWithIndex(index, "id_prefix", prefix)
}

// kvsDeleteWithIndex does a delete with either the id or id_prefix
func (s *StateStore) kvsDeleteWithIndex(index uint64, tableIndex string, parts ...string) error {
	tx, err := s.tables.StartTxn(false)
	if err != nil {
		return err
	}
	defer tx.Abort()
	if err := s.kvsDeleteWithIndexTxn(index, tx, tableIndex, parts...); err != nil {
		return err
	}
	return tx.Commit()
}

// kvsDeleteWithIndexTxn does a delete within an existing transaction
func (s *StateStore) kvsDeleteWithIndexTxn(index uint64, tx *MDBTxn, tableIndex string, parts ...string) error {
	num := 0
	for {
		// Get some number of entries to delete
		pairs, err := s.kvsTable.GetTxnLimit(tx, 128, tableIndex, parts...)
		if err != nil {
			return err
		}

		// Create the tombstones and delete
		for _, raw := range pairs {
			ent := raw.(*structs.DirEntry)
			ent.ModifyIndex = index // Update the index
			ent.Value = nil         // Reduce storage required
			ent.Session = ""
			if err := s.tombstoneTable.InsertTxn(tx, ent); err != nil {
				return err
			}
			if num, err := s.kvsTable.DeleteTxn(tx, "id", ent.Key); err != nil {
				return err
			} else if num != 1 {
				return fmt.Errorf("Failed to delete key '%s'", ent.Key)
			}
		}

		// Increment the total number
		num += len(pairs)
		if len(pairs) == 0 {
			break
		}
	}

	if num > 0 {
		if err := s.kvsTable.SetLastIndexTxn(tx, index); err != nil {
			return err
		}
		tx.Defer(func() {
			// Trigger the most fine grained notifications if possible
			switch {
			case len(parts) == 0:
				s.notifyKV("", true)
			case tableIndex == "id":
				s.notifyKV(parts[0], false)
			case tableIndex == "id_prefix":
				s.notifyKV(parts[0], true)
			default:
				s.notifyKV("", true)
			}
			if s.gc != nil {
				// If GC is configured, then we hint that this index
				// required expiration.
				s.gc.Hint(index)
			}
		})
	}
	return nil
}

// KVSCheckAndSet is used to perform an atomic check-and-set
func (s *StateStore) KVSCheckAndSet(index uint64, d *structs.DirEntry) (bool, error) {
	return s.kvsSet(index, d, kvCAS)
}

// KVSLock works like KVSSet but only writes if the lock can be acquired
func (s *StateStore) KVSLock(index uint64, d *structs.DirEntry) (bool, error) {
	return s.kvsSet(index, d, kvLock)
}

// KVSUnlock works like KVSSet but only writes if the lock can be unlocked
func (s *StateStore) KVSUnlock(index uint64, d *structs.DirEntry) (bool, error) {
	return s.kvsSet(index, d, kvUnlock)
}

// KVSLockDelay returns the expiration time of a key lock delay. A key may
// have a lock delay if it was unlocked due to a session invalidation instead
// of a graceful unlock. This must be checked on the leader node, and not in
// KVSLock due to the variability of clocks.
func (s *StateStore) KVSLockDelay(key string) time.Time {
	s.lockDelayLock.RLock()
	expires := s.lockDelay[key]
	s.lockDelayLock.RUnlock()
	return expires
}

// kvsSet is the internal setter
func (s *StateStore) kvsSet(
	index uint64,
	d *structs.DirEntry,
	mode kvMode) (bool, error) {
	// Start a new txn
	tx, err := s.tables.StartTxn(false)
	if err != nil {
		return false, err
	}
	defer tx.Abort()

	// Get the existing node
	res, err := s.kvsTable.GetTxn(tx, "id", d.Key)
	if err != nil {
		return false, err
	}

	// Get the existing node if any
	var exist *structs.DirEntry
	if len(res) > 0 {
		exist = res[0].(*structs.DirEntry)
	}

	// Use the ModifyIndex as the constraint. A modify of time of 0
	// means we are doing a set-if-not-exists, while any other value
	// means we expect that modify time.
	if mode == kvCAS {
		if d.ModifyIndex == 0 && exist != nil {
			return false, nil
		} else if d.ModifyIndex > 0 && (exist == nil || exist.ModifyIndex != d.ModifyIndex) {
			return false, nil
		}
	}

	// If attempting to lock, check this is possible
	if mode == kvLock {
		// Verify we have a session
		if d.Session == "" {
			return false, fmt.Errorf("Missing session")
		}

		// Bail if it is already locked
		if exist != nil && exist.Session != "" {
			return false, nil
		}

		// Verify the session exists
		res, err := s.sessionTable.GetTxn(tx, "id", d.Session)
		if err != nil {
			return false, err
		}
		if len(res) == 0 {
			return false, fmt.Errorf("Invalid session")
		}

		// Update the lock index
		if exist != nil {
			exist.LockIndex++
			exist.Session = d.Session
		} else {
			d.LockIndex = 1
		}
	}

	// If attempting to unlock, verify the key exists and is held
	if mode == kvUnlock {
		if exist == nil || exist.Session != d.Session {
			return false, nil
		}
		// Clear the session to unlock
		exist.Session = ""
	}

	// Set the create and modify times
	if exist == nil {
		d.CreateIndex = index
	} else {
		d.CreateIndex = exist.CreateIndex
		d.LockIndex = exist.LockIndex
		d.Session = exist.Session

	}
	d.ModifyIndex = index

	if err := s.kvsTable.InsertTxn(tx, d); err != nil {
		return false, err
	}
	if err := s.kvsTable.SetLastIndexTxn(tx, index); err != nil {
		return false, err
	}
	tx.Defer(func() { s.notifyKV(d.Key, false) })
	return true, tx.Commit()
}

// ReapTombstones is used to delete all the tombstones with a ModifyTime
// less than or equal to the given index. This is used to prevent unbounded
// storage growth of the tombstones.
func (s *StateStore) ReapTombstones(index uint64) error {
	tx, err := s.tombstoneTable.StartTxn(false, nil)
	if err != nil {
		return fmt.Errorf("failed to start txn: %v", err)
	}
	defer tx.Abort()

	// Scan the tombstone table for all the entries that are
	// eligble for GC. This could be improved by indexing on
	// ModifyTime and doing a less-than-equals scan, however
	// we don't currently support numeric indexes internally.
	// Luckily, this is a low frequency operation.
	var toDelete []string
	streamCh := make(chan interface{}, 128)
	doneCh := make(chan struct{})
	go func() {
		defer close(doneCh)
		for raw := range streamCh {
			ent := raw.(*structs.DirEntry)
			if ent.ModifyIndex <= index {
				toDelete = append(toDelete, ent.Key)
			}
		}
	}()
	if err := s.tombstoneTable.StreamTxn(streamCh, tx, "id"); err != nil {
		s.logger.Printf("[ERR] consul.state: failed to scan tombstones: %v", err)
		return fmt.Errorf("failed to scan tombstones: %v", err)
	}
	<-doneCh

	// Delete each tombstone
	if len(toDelete) > 0 {
		s.logger.Printf("[DEBUG] consul.state: reaping %d tombstones up to %d", len(toDelete), index)
	}
	for _, key := range toDelete {
		num, err := s.tombstoneTable.DeleteTxn(tx, "id", key)
		if err != nil {
			s.logger.Printf("[ERR] consul.state: failed to delete tombstone: %v", err)
			return fmt.Errorf("failed to delete tombstone: %v", err)
		}
		if num != 1 {
			return fmt.Errorf("failed to delete tombstone '%s'", key)
		}
	}
	return tx.Commit()
}

// TombstoneRestore is used to restore a tombstone.
// It should only be used when doing a restore.
func (s *StateStore) TombstoneRestore(d *structs.DirEntry) error {
	// Start a new txn
	tx, err := s.tombstoneTable.StartTxn(false, nil)
	if err != nil {
		return err
	}
	defer tx.Abort()

	if err := s.tombstoneTable.InsertTxn(tx, d); err != nil {
		return err
	}
	return tx.Commit()
}

// SessionCreate is used to create a new session. The
// ID will be populated on a successful return
func (s *StateStore) SessionCreate(index uint64, session *structs.Session) error {
	// Verify a Session ID is generated
	if session.ID == "" {
		return fmt.Errorf("Missing Session ID")
	}

	switch session.Behavior {
	case "":
		// Default behavior is Release for backwards compatibility
		session.Behavior = structs.SessionKeysRelease
	case structs.SessionKeysRelease:
	case structs.SessionKeysDelete:
	default:
		return fmt.Errorf("Invalid Session Behavior setting '%s'", session.Behavior)
	}

	if session.TTL != "" {
		ttl, err := time.ParseDuration(session.TTL)
		if err != nil {
			return fmt.Errorf("Invalid Session TTL '%s': %v", session.TTL, err)
		}

		if ttl != 0 && (ttl < structs.SessionTTLMin || ttl > structs.SessionTTLMax) {
			return fmt.Errorf("Invalid Session TTL '%s', must be between [%v-%v]",
				session.TTL, structs.SessionTTLMin, structs.SessionTTLMax)
		}
	}

	// Assign the create index
	session.CreateIndex = index

	// Start the transaction
	tx, err := s.tables.StartTxn(false)
	if err != nil {
		panic(fmt.Errorf("Failed to start txn: %v", err))
	}
	defer tx.Abort()

	// Verify that the node exists
	res, err := s.nodeTable.GetTxn(tx, "id", session.Node)
	if err != nil {
		return err
	}
	if len(res) == 0 {
		return fmt.Errorf("Missing node registration")
	}

	// Verify that the checks exist and are not critical
	for _, checkId := range session.Checks {
		res, err := s.checkTable.GetTxn(tx, "id", session.Node, checkId)
		if err != nil {
			return err
		}
		if len(res) == 0 {
			return fmt.Errorf("Missing check '%s' registration", checkId)
		}
		chk := res[0].(*structs.HealthCheck)
		if chk.Status == structs.HealthCritical {
			return fmt.Errorf("Check '%s' is in %s state", checkId, chk.Status)
		}
	}

	// Insert the session
	if err := s.sessionTable.InsertTxn(tx, session); err != nil {
		return err
	}

	// Insert the check mappings
	sCheck := sessionCheck{Node: session.Node, Session: session.ID}
	for _, checkID := range session.Checks {
		sCheck.CheckID = checkID
		if err := s.sessionCheckTable.InsertTxn(tx, &sCheck); err != nil {
			return err
		}
	}

	// Trigger the update notifications
	if err := s.sessionTable.SetLastIndexTxn(tx, index); err != nil {
		return err
	}
	tx.Defer(func() { s.watch[s.sessionTable].Notify() })
	return tx.Commit()
}

// SessionRestore is used to restore a session. It should only be used when
// doing a restore, otherwise SessionCreate should be used.
func (s *StateStore) SessionRestore(session *structs.Session) error {
	// Start the transaction
	tx, err := s.tables.StartTxn(false)
	if err != nil {
		panic(fmt.Errorf("Failed to start txn: %v", err))
	}
	defer tx.Abort()

	// Insert the session
	if err := s.sessionTable.InsertTxn(tx, session); err != nil {
		return err
	}

	// Insert the check mappings
	sCheck := sessionCheck{Node: session.Node, Session: session.ID}
	for _, checkID := range session.Checks {
		sCheck.CheckID = checkID
		if err := s.sessionCheckTable.InsertTxn(tx, &sCheck); err != nil {
			return err
		}
	}

	// Trigger the update notifications
	index := session.CreateIndex
	if err := s.sessionTable.SetMaxLastIndexTxn(tx, index); err != nil {
		return err
	}
	tx.Defer(func() { s.watch[s.sessionTable].Notify() })
	return tx.Commit()
}

// SessionGet is used to get a session entry
func (s *StateStore) SessionGet(id string) (uint64, *structs.Session, error) {
	idx, res, err := s.sessionTable.Get("id", id)
	var d *structs.Session
	if len(res) > 0 {
		d = res[0].(*structs.Session)
	}
	return idx, d, err
}

// SessionList is used to list all the open sessions
func (s *StateStore) SessionList() (uint64, []*structs.Session, error) {
	idx, res, err := s.sessionTable.Get("id")
	out := make([]*structs.Session, len(res))
	for i, raw := range res {
		out[i] = raw.(*structs.Session)
	}
	return idx, out, err
}

// NodeSessions is used to list all the open sessions for a node
func (s *StateStore) NodeSessions(node string) (uint64, []*structs.Session, error) {
	idx, res, err := s.sessionTable.Get("node", node)
	out := make([]*structs.Session, len(res))
	for i, raw := range res {
		out[i] = raw.(*structs.Session)
	}
	return idx, out, err
}

// SessionDestroy is used to destroy a session.
func (s *StateStore) SessionDestroy(index uint64, id string) error {
	tx, err := s.tables.StartTxn(false)
	if err != nil {
		panic(fmt.Errorf("Failed to start txn: %v", err))
	}
	defer tx.Abort()

	s.logger.Printf("[DEBUG] consul.state: Invalidating session %s due to session destroy",
		id)
	if err := s.invalidateSession(index, tx, id); err != nil {
		return err
	}
	return tx.Commit()
}

// invalideNode is used to invalide all sessions belonging to a node
// All tables should be locked in the tx.
func (s *StateStore) invalidateNode(index uint64, tx *MDBTxn, node string) error {
	sessions, err := s.sessionTable.GetTxn(tx, "node", node)
	if err != nil {
		return err
	}
	for _, sess := range sessions {
		session := sess.(*structs.Session).ID
		s.logger.Printf("[DEBUG] consul.state: Invalidating session %s due to node '%s' invalidation",
			session, node)
		if err := s.invalidateSession(index, tx, session); err != nil {
			return err
		}
	}
	return nil
}

// invalidateCheck is used to invalide all sessions belonging to a check
// All tables should be locked in the tx.
func (s *StateStore) invalidateCheck(index uint64, tx *MDBTxn, node, check string) error {
	sessionChecks, err := s.sessionCheckTable.GetTxn(tx, "id", node, check)
	if err != nil {
		return err
	}
	for _, sc := range sessionChecks {
		session := sc.(*sessionCheck).Session
		s.logger.Printf("[DEBUG] consul.state: Invalidating session %s due to check '%s' invalidation",
			session, check)
		if err := s.invalidateSession(index, tx, session); err != nil {
			return err
		}
	}
	return nil
}

// invalidateSession is used to invalide a session within a given txn
// All tables should be locked in the tx.
func (s *StateStore) invalidateSession(index uint64, tx *MDBTxn, id string) error {
	// Get the session
	res, err := s.sessionTable.GetTxn(tx, "id", id)
	if err != nil {
		return err
	}

	// Quit if this session does not exist
	if len(res) == 0 {
		return nil
	}
	session := res[0].(*structs.Session)

	// Enforce the MaxLockDelay
	delay := session.LockDelay
	if delay > structs.MaxLockDelay {
		delay = structs.MaxLockDelay
	}

	// Invalidate any held locks
	if session.Behavior == structs.SessionKeysDelete {
		if err := s.deleteLocks(index, tx, delay, id); err != nil {
			return err
		}
	} else if err := s.invalidateLocks(index, tx, delay, id); err != nil {
		return err
	}

	// Nuke the session
	if _, err := s.sessionTable.DeleteTxn(tx, "id", id); err != nil {
		return err
	}

	// Delete the check mappings
	for _, checkID := range session.Checks {
		if _, err := s.sessionCheckTable.DeleteTxn(tx, "id",
			session.Node, checkID, id); err != nil {
			return err
		}
	}

	// Trigger the update notifications
	if err := s.sessionTable.SetLastIndexTxn(tx, index); err != nil {
		return err
	}
	tx.Defer(func() { s.watch[s.sessionTable].Notify() })
	return nil
}

// invalidateLocks is used to invalidate all the locks held by a session
// within a given txn. All tables should be locked in the tx.
func (s *StateStore) invalidateLocks(index uint64, tx *MDBTxn,
	lockDelay time.Duration, id string) error {
	pairs, err := s.kvsTable.GetTxn(tx, "session", id)
	if err != nil {
		return err
	}

	var expires time.Time
	if lockDelay > 0 {
		s.lockDelayLock.Lock()
		defer s.lockDelayLock.Unlock()
		expires = time.Now().Add(lockDelay)
	}

	for _, pair := range pairs {
		kv := pair.(*structs.DirEntry)
		kv.Session = ""        // Clear the lock
		kv.ModifyIndex = index // Update the modified time
		if err := s.kvsTable.InsertTxn(tx, kv); err != nil {
			return err
		}
		// If there is a lock delay, prevent acquisition
		// for at least lockDelay period
		if lockDelay > 0 {
			s.lockDelay[kv.Key] = expires
			time.AfterFunc(lockDelay, func() {
				s.lockDelayLock.Lock()
				delete(s.lockDelay, kv.Key)
				s.lockDelayLock.Unlock()
			})
		}
		tx.Defer(func() { s.notifyKV(kv.Key, false) })
	}
	if len(pairs) > 0 {
		if err := s.kvsTable.SetLastIndexTxn(tx, index); err != nil {
			return err
		}
	}
	return nil
}

// deleteLocks is used to delete all the locks held by a session
// within a given txn. All tables should be locked in the tx.
func (s *StateStore) deleteLocks(index uint64, tx *MDBTxn,
	lockDelay time.Duration, id string) error {
	pairs, err := s.kvsTable.GetTxn(tx, "session", id)
	if err != nil {
		return err
	}

	var expires time.Time
	if lockDelay > 0 {
		s.lockDelayLock.Lock()
		defer s.lockDelayLock.Unlock()
		expires = time.Now().Add(lockDelay)
	}

	for _, pair := range pairs {
		kv := pair.(*structs.DirEntry)
		if err := s.kvsDeleteWithIndexTxn(index, tx, "id", kv.Key); err != nil {
			return err
		}

		// If there is a lock delay, prevent acquisition
		// for at least lockDelay period
		if lockDelay > 0 {
			s.lockDelay[kv.Key] = expires
			time.AfterFunc(lockDelay, func() {
				s.lockDelayLock.Lock()
				delete(s.lockDelay, kv.Key)
				s.lockDelayLock.Unlock()
			})
		}
	}
	return nil
}

// ACLSet is used to create or update an ACL entry
func (s *StateStore) ACLSet(index uint64, acl *structs.ACL) error {
	// Check for an ID
	if acl.ID == "" {
		return fmt.Errorf("Missing ACL ID")
	}

	// Start a new txn
	tx, err := s.tables.StartTxn(false)
	if err != nil {
		return err
	}
	defer tx.Abort()

	// Look for the existing node
	res, err := s.aclTable.GetTxn(tx, "id", acl.ID)
	if err != nil {
		return err
	}

	switch len(res) {
	case 0:
		acl.CreateIndex = index
		acl.ModifyIndex = index
	case 1:
		exist := res[0].(*structs.ACL)
		acl.CreateIndex = exist.CreateIndex
		acl.ModifyIndex = index
	default:
		panic(fmt.Errorf("Duplicate ACL definition. Internal error"))
	}

	// Insert the ACL
	if err := s.aclTable.InsertTxn(tx, acl); err != nil {
		return err
	}

	// Trigger the update notifications
	if err := s.aclTable.SetLastIndexTxn(tx, index); err != nil {
		return err
	}
	tx.Defer(func() { s.watch[s.aclTable].Notify() })
	return tx.Commit()
}

// ACLRestore is used to restore an ACL. It should only be used when
// doing a restore, otherwise ACLSet should be used.
func (s *StateStore) ACLRestore(acl *structs.ACL) error {
	// Start a new txn
	tx, err := s.aclTable.StartTxn(false, nil)
	if err != nil {
		return err
	}
	defer tx.Abort()

	if err := s.aclTable.InsertTxn(tx, acl); err != nil {
		return err
	}
	if err := s.aclTable.SetMaxLastIndexTxn(tx, acl.ModifyIndex); err != nil {
		return err
	}
	return tx.Commit()
}

// ACLGet is used to get an ACL by ID
func (s *StateStore) ACLGet(id string) (uint64, *structs.ACL, error) {
	idx, res, err := s.aclTable.Get("id", id)
	var d *structs.ACL
	if len(res) > 0 {
		d = res[0].(*structs.ACL)
	}
	return idx, d, err
}

// ACLList is used to list all the acls
func (s *StateStore) ACLList() (uint64, []*structs.ACL, error) {
	idx, res, err := s.aclTable.Get("id")
	out := make([]*structs.ACL, len(res))
	for i, raw := range res {
		out[i] = raw.(*structs.ACL)
	}
	return idx, out, err
}

// ACLDelete is used to remove an ACL
func (s *StateStore) ACLDelete(index uint64, id string) error {
	tx, err := s.tables.StartTxn(false)
	if err != nil {
		panic(fmt.Errorf("Failed to start txn: %v", err))
	}
	defer tx.Abort()

	if n, err := s.aclTable.DeleteTxn(tx, "id", id); err != nil {
		return err
	} else if n > 0 {
		if err := s.aclTable.SetLastIndexTxn(tx, index); err != nil {
			return err
		}
		tx.Defer(func() { s.watch[s.aclTable].Notify() })
	}
	return tx.Commit()
}

// Snapshot is used to create a point in time snapshot
func (s *StateStore) Snapshot() (*StateSnapshot, error) {
	// Begin a new txn on all tables
	tx, err := s.tables.StartTxn(true)
	if err != nil {
		return nil, err
	}

	// Determine the max index
	index, err := s.tables.LastIndexTxn(tx)
	if err != nil {
		tx.Abort()
		return nil, err
	}

	// Return the snapshot
	snap := &StateSnapshot{
		store:     s,
		tx:        tx,
		lastIndex: index,
	}
	return snap, nil
}

// LastIndex returns the last index that affects the snapshotted data
func (s *StateSnapshot) LastIndex() uint64 {
	return s.lastIndex
}

// Nodes returns all the known nodes, the slice alternates between
// the node name and address
func (s *StateSnapshot) Nodes() structs.Nodes {
	res, err := s.store.nodeTable.GetTxn(s.tx, "id")
	if err != nil {
		s.store.logger.Printf("[ERR] consul.state: Failed to get nodes: %v", err)
		return nil
	}
	results := make([]structs.Node, len(res))
	for i, r := range res {
		results[i] = *r.(*structs.Node)
	}
	return results
}

// NodeServices is used to return all the services of a given node
func (s *StateSnapshot) NodeServices(name string) *structs.NodeServices {
	_, res := s.store.parseNodeServices(s.store.tables, s.tx, name)
	return res
}

// NodeChecks is used to return all the checks of a given node
func (s *StateSnapshot) NodeChecks(node string) structs.HealthChecks {
	res, err := s.store.checkTable.GetTxn(s.tx, "id", node)
	_, checks := s.store.parseHealthChecks(s.lastIndex, res, err)
	return checks
}

// KVSDump is used to list all KV entries. It takes a channel and streams
// back *struct.DirEntry objects. This will block and should be invoked
// in a goroutine.
func (s *StateSnapshot) KVSDump(stream chan<- interface{}) error {
	return s.store.kvsTable.StreamTxn(stream, s.tx, "id")
}

// TombstoneDump is used to dump all tombstone entries. It takes a channel and streams
// back *struct.DirEntry objects. This will block and should be invoked
// in a goroutine.
func (s *StateSnapshot) TombstoneDump(stream chan<- interface{}) error {
	return s.store.tombstoneTable.StreamTxn(stream, s.tx, "id")
}

// SessionList is used to list all the open sessions
func (s *StateSnapshot) SessionList() ([]*structs.Session, error) {
	res, err := s.store.sessionTable.GetTxn(s.tx, "id")
	out := make([]*structs.Session, len(res))
	for i, raw := range res {
		out[i] = raw.(*structs.Session)
	}
	return out, err
}

// ACLList is used to list all of the ACLs
func (s *StateSnapshot) ACLList() ([]*structs.ACL, error) {
	res, err := s.store.aclTable.GetTxn(s.tx, "id")
	out := make([]*structs.ACL, len(res))
	for i, raw := range res {
		out[i] = raw.(*structs.ACL)
	}
	return out, err
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/hcl/json/json_test.go<|end_filename|>
package json

// This is the directory where our test fixtures are.
const fixtureDir = "./test-fixtures"


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/consul/merge.go<|end_filename|>
package consul

import (
	"log"

	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/serf/serf"
)

// lanMergeDelegate is used to handle a cluster merge on the LAN gossip
// ring. We check that the peers are in the same datacenter and abort the
// merge if there is a mis-match.
type lanMergeDelegate struct {
	logger *log.Logger
	dc     string
}

func (md *lanMergeDelegate) NotifyMerge(members []*serf.Member) (cancel bool) {
	for _, m := range members {
		ok, dc := isConsulNode(*m)
		if ok {
			if dc != md.dc {
				md.logger.Printf("[WARN] consul: Canceling cluster merge, member '%s' part of wrong datacenter '%s'",
					m.Name, dc)
				return true
			}
			continue
		}

		ok, parts := isConsulServer(*m)
		if ok && parts.Datacenter != md.dc {
			md.logger.Printf("[WARN] consul: Canceling cluster merge, member '%s' part of wrong datacenter '%s'",
				m.Name, parts.Datacenter)
			return true
		}
	}
	return false
}

// wanMergeDelegate is used to handle a cluster merge on the WAN gossip
// ring. We check that the peers are server nodes and abort the merge
// otherwise.
type wanMergeDelegate struct {
	logger *log.Logger
}

func (md *wanMergeDelegate) NotifyMerge(members []*serf.Member) (cancel bool) {
	for _, m := range members {
		ok, _ := isConsulServer(*m)
		if !ok {
			md.logger.Printf("[WARN] consul: Canceling cluster merge, member '%s' is not a server",
				m.Name)
			return true
		}
	}
	return false
}


<|start_filename|>Godeps/_workspace/src/github.com/socketplane/go-fastping/cmd/ping/ping.go<|end_filename|>
package main

import (
	"fmt"
	"net"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/socketplane/go-fastping"
)

type response struct {
	addr *net.IPAddr
	rtt  time.Duration
}

func main() {
	once := true
	if len(os.Args) < 2 {
		fmt.Fprintf(os.Stderr, "Usage: %s {hostname}\n", os.Args[0])
		os.Exit(1)
	}
	p := fastping.NewPinger()
	p.Debug = false

	netProto := "ip4:icmp"
	if strings.Index(os.Args[1], ":") != -1 {
		netProto = "ip6:ipv6-icmp"
	}
	ra, err := net.ResolveIPAddr(netProto, os.Args[1])
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	if len(os.Args) > 2 && os.Args[2] != "" {
		iface, err := net.InterfaceByName(os.Args[2])
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
		addrs, err := iface.Addrs()
		if err == nil {
			for i := 0; i < len(addrs); i++ {
				addr := addrs[i].String()
				ip, _, err := net.ParseCIDR(addr)
				if err == nil && ip != nil {
					if ip.To4() != nil {
						p.ListenAddr, _ = net.ResolveIPAddr("ip4", ip.To4().String())
					}
				}
			}
		}
	}

	results := make(map[string]*response)
	results[ra.String()] = nil
	p.AddIPAddr(ra)

	onRecv, onIdle := make(chan *response), make(chan bool)
	p.OnRecv = func(addr *net.IPAddr, t time.Duration) {
		fmt.Printf("%s : %v\n", addr.IP.String(), t)
		if !once {
			onRecv <- &response{addr: addr, rtt: t}
		}
	}
	p.OnIdle = func() {
		fmt.Printf("OnIdle %v", p.Err())
		if !once {
			onIdle <- true
		}
	}

	p.OnErr = func(addr *net.IPAddr, t int) {
		fmt.Printf("Error %s : %d\n", addr.IP.String(), t)
	}

	p.MaxRTT = time.Second
	if once {
		p.Run()
	} else {
		p.RunLoop()

		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt)
		signal.Notify(c, syscall.SIGTERM)

	loop:
		for {
			select {
			case <-c:
				fmt.Println("get interrupted")
				break loop
			case res := <-onRecv:
				results[res.addr.String()] = res
			case <-onIdle:
				for host, r := range results {
					if r == nil {
						fmt.Printf("%s : unreachable %v\n", host, time.Now())
					} else {
						fmt.Printf("%s : %v %v\n", host, r.rtt, time.Now())
					}
					results[host] = nil
				}
			case <-p.Done():
				if err = p.Err(); err != nil {
					fmt.Println("Ping failed:", err)
				}
				break loop
			}
		}
		signal.Stop(c)
		p.Stop()
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/consul/structs/structs_test.go<|end_filename|>
package structs

import (
	"reflect"
	"testing"
)

func TestEncodeDecode(t *testing.T) {
	arg := &RegisterRequest{
		Datacenter: "foo",
		Node:       "bar",
		Address:    "baz",
		Service: &NodeService{
			Service: "test",
			Address: "127.0.0.2",
		},
	}
	buf, err := Encode(RegisterRequestType, arg)
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	var out RegisterRequest
	err = Decode(buf[1:], &out)
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	if !reflect.DeepEqual(arg.Service, out.Service) {
		t.Fatalf("bad: %#v %#v", arg.Service, out.Service)
	}
	if !reflect.DeepEqual(arg, &out) {
		t.Fatalf("bad: %#v %#v", arg, out)
	}
}

func TestStructs_Implements(t *testing.T) {
	var (
		_ RPCInfo          = &RegisterRequest{}
		_ RPCInfo          = &DeregisterRequest{}
		_ RPCInfo          = &DCSpecificRequest{}
		_ RPCInfo          = &ServiceSpecificRequest{}
		_ RPCInfo          = &NodeSpecificRequest{}
		_ RPCInfo          = &ChecksInStateRequest{}
		_ RPCInfo          = &KVSRequest{}
		_ RPCInfo          = &KeyRequest{}
		_ RPCInfo          = &KeyListRequest{}
		_ RPCInfo          = &SessionRequest{}
		_ RPCInfo          = &SessionSpecificRequest{}
		_ RPCInfo          = &EventFireRequest{}
		_ RPCInfo          = &ACLPolicyRequest{}
		_ RPCInfo          = &KeyringRequest{}
		_ CompoundResponse = &KeyringResponses{}
	)
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/command/agent/ui_endpoint.go<|end_filename|>
package agent

import (
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/consul/structs"
	"net/http"
	"sort"
	"strings"
)

// ServiceSummary is used to summarize a service
type ServiceSummary struct {
	Name           string
	Nodes          []string
	ChecksPassing  int
	ChecksWarning  int
	ChecksCritical int
}

// UINodes is used to list the nodes in a given datacenter. We return a
// NodeDump which provides overview information for all the nodes
func (s *HTTPServer) UINodes(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Get the datacenter
	var dc string
	s.parseDC(req, &dc)

	// Try to ge ta node dump
	var dump structs.NodeDump
	if err := s.getNodeDump(resp, dc, "", &dump); err != nil {
		return nil, err
	}

	return dump, nil
}

// UINodeInfo is used to get info on a single node in a given datacenter. We return a
// NodeInfo which provides overview information for the node
func (s *HTTPServer) UINodeInfo(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Get the datacenter
	var dc string
	s.parseDC(req, &dc)

	// Verify we have some DC, or use the default
	node := strings.TrimPrefix(req.URL.Path, "/v1/internal/ui/node/")
	if node == "" {
		resp.WriteHeader(400)
		resp.Write([]byte("Missing node name"))
		return nil, nil
	}

	// Try to get a node dump
	var dump structs.NodeDump
	if err := s.getNodeDump(resp, dc, node, &dump); err != nil {
		return nil, err
	}

	// Return only the first entry
	if len(dump) > 0 {
		return dump[0], nil
	}
	return nil, nil
}

// getNodeDump is used to get a dump of all node data. We make a best effort by
// reading stale data in the case of an availability outage.
func (s *HTTPServer) getNodeDump(resp http.ResponseWriter, dc, node string, dump *structs.NodeDump) error {
	var args interface{}
	var method string
	var allowStale *bool

	if node == "" {
		raw := structs.DCSpecificRequest{Datacenter: dc}
		method = "Internal.NodeDump"
		allowStale = &raw.AllowStale
		args = &raw
	} else {
		raw := &structs.NodeSpecificRequest{Datacenter: dc, Node: node}
		method = "Internal.NodeInfo"
		allowStale = &raw.AllowStale
		args = &raw
	}
	var out structs.IndexedNodeDump
	defer setMeta(resp, &out.QueryMeta)

START:
	if err := s.agent.RPC(method, args, &out); err != nil {
		// Retry the request allowing stale data if no leader. The UI should continue
		// to function even during an outage
		if strings.Contains(err.Error(), structs.ErrNoLeader.Error()) && !*allowStale {
			*allowStale = true
			goto START
		}
		return err
	}

	// Set the result
	*dump = out.Dump
	return nil
}

// UIServices is used to list the services in a given datacenter. We return a
// ServiceSummary which provides overview information for the service
func (s *HTTPServer) UIServices(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Get the datacenter
	var dc string
	s.parseDC(req, &dc)

	// Get the full node dump...
	var dump structs.NodeDump
	if err := s.getNodeDump(resp, dc, "", &dump); err != nil {
		return nil, err
	}

	// Generate the summary
	return summarizeServices(dump), nil
}

func summarizeServices(dump structs.NodeDump) []*ServiceSummary {
	// Collect the summary information
	var services []string
	summary := make(map[string]*ServiceSummary)
	getService := func(service string) *ServiceSummary {
		serv, ok := summary[service]
		if !ok {
			serv = &ServiceSummary{Name: service}
			summary[service] = serv
			services = append(services, service)
		}
		return serv
	}

	// Aggregate all the node information
	for _, node := range dump {
		nodeServices := make([]*ServiceSummary, len(node.Services))
		for idx, service := range node.Services {
			sum := getService(service.Service)
			sum.Nodes = append(sum.Nodes, node.Node)
			nodeServices[idx] = sum
		}
		for _, check := range node.Checks {
			var services []*ServiceSummary
			if check.ServiceName == "" {
				services = nodeServices
			} else {
				services = []*ServiceSummary{getService(check.ServiceName)}
			}
			for _, sum := range services {
				switch check.Status {
				case structs.HealthPassing:
					sum.ChecksPassing++
				case structs.HealthWarning:
					sum.ChecksWarning++
				case structs.HealthCritical:
					sum.ChecksCritical++
				}
			}
		}
	}

	// Return the services in sorted order
	sort.Strings(services)
	output := make([]*ServiceSummary, len(summary))
	for idx, service := range services {
		// Sort the nodes
		sum := summary[service]
		sort.Strings(sum.Nodes)
		output[idx] = sum
	}
	return output
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/command/agent/event_endpoint_test.go<|end_filename|>
package agent

import (
	"bytes"
	"fmt"
	"net/http"
	"net/http/httptest"
	"testing"
	"time"

	"github.com/hashicorp/consul/testutil"
)

func TestEventFire(t *testing.T) {
	httpTest(t, func(srv *HTTPServer) {
		body := bytes.NewBuffer([]byte("test"))
		url := "/v1/event/fire/test?node=Node&service=foo&tag=bar"
		req, err := http.NewRequest("PUT", url, body)
		if err != nil {
			t.Fatalf("err: %v", err)
		}
		resp := httptest.NewRecorder()
		obj, err := srv.EventFire(resp, req)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		event, ok := obj.(*UserEvent)
		if !ok {
			t.Fatalf("bad: %#v", obj)
		}

		if event.ID == "" {
			t.Fatalf("bad: %#v", event)
		}
		if event.Name != "test" {
			t.Fatalf("bad: %#v", event)
		}
		if string(event.Payload) != "test" {
			t.Fatalf("bad: %#v", event)
		}
		if event.NodeFilter != "Node" {
			t.Fatalf("bad: %#v", event)
		}
		if event.ServiceFilter != "foo" {
			t.Fatalf("bad: %#v", event)
		}
		if event.TagFilter != "bar" {
			t.Fatalf("bad: %#v", event)
		}
	})
}

func TestEventList(t *testing.T) {
	httpTest(t, func(srv *HTTPServer) {
		p := &UserEvent{Name: "test"}
		if err := srv.agent.UserEvent("", p); err != nil {
			t.Fatalf("err: %v", err)
		}

		testutil.WaitForResult(func() (bool, error) {
			req, err := http.NewRequest("GET", "/v1/event/list", nil)
			if err != nil {
				return false, err
			}
			resp := httptest.NewRecorder()
			obj, err := srv.EventList(resp, req)
			if err != nil {
				return false, err
			}

			list, ok := obj.([]*UserEvent)
			if !ok {
				return false, fmt.Errorf("bad: %#v", obj)
			}
			if len(list) != 1 || list[0].Name != "test" {
				return false, fmt.Errorf("bad: %#v", list)
			}
			header := resp.Header().Get("X-Consul-Index")
			if header == "" || header == "0" {
				return false, fmt.Errorf("bad: %#v", header)
			}
			return true, nil
		}, func(err error) {
			t.Fatalf("err: %v", err)
		})
	})
}

func TestEventList_Filter(t *testing.T) {
	httpTest(t, func(srv *HTTPServer) {
		p := &UserEvent{Name: "test"}
		if err := srv.agent.UserEvent("", p); err != nil {
			t.Fatalf("err: %v", err)
		}

		p = &UserEvent{Name: "foo"}
		if err := srv.agent.UserEvent("", p); err != nil {
			t.Fatalf("err: %v", err)
		}

		testutil.WaitForResult(func() (bool, error) {
			req, err := http.NewRequest("GET", "/v1/event/list?name=foo", nil)
			if err != nil {
				return false, err
			}
			resp := httptest.NewRecorder()
			obj, err := srv.EventList(resp, req)
			if err != nil {
				return false, err
			}

			list, ok := obj.([]*UserEvent)
			if !ok {
				return false, fmt.Errorf("bad: %#v", obj)
			}
			if len(list) != 1 || list[0].Name != "foo" {
				return false, fmt.Errorf("bad: %#v", list)
			}
			header := resp.Header().Get("X-Consul-Index")
			if header == "" || header == "0" {
				return false, fmt.Errorf("bad: %#v", header)
			}
			return true, nil
		}, func(err error) {
			t.Fatalf("err: %v", err)
		})
	})
}

func TestEventList_Blocking(t *testing.T) {
	httpTest(t, func(srv *HTTPServer) {
		p := &UserEvent{Name: "test"}
		if err := srv.agent.UserEvent("", p); err != nil {
			t.Fatalf("err: %v", err)
		}

		var index string
		testutil.WaitForResult(func() (bool, error) {
			req, err := http.NewRequest("GET", "/v1/event/list", nil)
			if err != nil {
				return false, err
			}
			resp := httptest.NewRecorder()
			_, err = srv.EventList(resp, req)
			if err != nil {
				return false, err
			}
			header := resp.Header().Get("X-Consul-Index")
			if header == "" || header == "0" {
				return false, fmt.Errorf("bad: %#v", header)
			}
			index = header
			return true, nil
		}, func(err error) {
			t.Fatalf("err: %v", err)
		})

		go func() {
			time.Sleep(50 * time.Millisecond)
			p := &UserEvent{Name: "second"}
			if err := srv.agent.UserEvent("", p); err != nil {
				t.Fatalf("err: %v", err)
			}
		}()

		testutil.WaitForResult(func() (bool, error) {
			url := "/v1/event/list?index=" + index
			req, err := http.NewRequest("GET", url, nil)
			if err != nil {
				return false, err
			}
			resp := httptest.NewRecorder()
			obj, err := srv.EventList(resp, req)
			if err != nil {
				return false, err
			}

			list, ok := obj.([]*UserEvent)
			if !ok {
				return false, fmt.Errorf("bad: %#v", obj)
			}
			if len(list) != 2 || list[1].Name != "second" {
				return false, fmt.Errorf("bad: %#v", list)
			}
			return true, nil
		}, func(err error) {
			t.Fatalf("err: %v", err)
		})
	})
}

func TestEventList_EventBufOrder(t *testing.T) {
	httpTest(t, func(srv *HTTPServer) {
		// Fire some events in a non-sequential order
		expected := &UserEvent{Name: "foo"}

		for _, e := range []*UserEvent{
			&UserEvent{Name: "foo"},
			&UserEvent{Name: "bar"},
			&UserEvent{Name: "foo"},
			expected,
			&UserEvent{Name: "bar"},
		} {
			if err := srv.agent.UserEvent("", e); err != nil {
				t.Fatalf("err: %v", err)
			}
		}

		// Test that the event order is preserved when name
		// filtering on a list of > 1 matching event.
		testutil.WaitForResult(func() (bool, error) {
			url := "/v1/event/list?name=foo"
			req, err := http.NewRequest("GET", url, nil)
			if err != nil {
				return false, err
			}
			resp := httptest.NewRecorder()
			obj, err := srv.EventList(resp, req)
			if err != nil {
				return false, err
			}
			list, ok := obj.([]*UserEvent)
			if !ok {
				return false, fmt.Errorf("bad: %#v", obj)
			}
			if len(list) != 3 || list[2].ID != expected.ID {
				return false, fmt.Errorf("bad: %#v", list)
			}
			return true, nil
		}, func(err error) {
			t.Fatalf("err: %v", err)
		})
	})
}

func TestUUIDToUint64(t *testing.T) {
	inp := "cb9a81ad-fff6-52ac-92a7-5f70687805ec"

	// Output value was computed using python
	if uuidToUint64(inp) != 6430540886266763072 {
		t.Fatalf("bad")
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/tlsutil/config_test.go<|end_filename|>
package tlsutil

import (
	"crypto/tls"
	"crypto/x509"
	"io"
	"io/ioutil"
	"net"
	"testing"
)

func TestConfig_AppendCA_None(t *testing.T) {
	conf := &Config{}
	pool := x509.NewCertPool()
	err := conf.AppendCA(pool)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if len(pool.Subjects()) != 0 {
		t.Fatalf("bad: %v", pool.Subjects())
	}
}

func TestConfig_CACertificate_Valid(t *testing.T) {
	conf := &Config{
		CAFile: "../test/ca/root.cer",
	}
	pool := x509.NewCertPool()
	err := conf.AppendCA(pool)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if len(pool.Subjects()) == 0 {
		t.Fatalf("expected cert")
	}
}

func TestConfig_KeyPair_None(t *testing.T) {
	conf := &Config{}
	cert, err := conf.KeyPair()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if cert != nil {
		t.Fatalf("bad: %v", cert)
	}
}

func TestConfig_KeyPair_Valid(t *testing.T) {
	conf := &Config{
		CertFile: "../test/key/ourdomain.cer",
		KeyFile:  "../test/key/ourdomain.key",
	}
	cert, err := conf.KeyPair()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if cert == nil {
		t.Fatalf("expected cert")
	}
}

func TestConfig_OutgoingTLS_MissingCA(t *testing.T) {
	conf := &Config{
		VerifyOutgoing: true,
	}
	tls, err := conf.OutgoingTLSConfig()
	if err == nil {
		t.Fatalf("expected err")
	}
	if tls != nil {
		t.Fatalf("bad: %v", tls)
	}
}

func TestConfig_OutgoingTLS_OnlyCA(t *testing.T) {
	conf := &Config{
		CAFile: "../test/ca/root.cer",
	}
	tls, err := conf.OutgoingTLSConfig()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if tls != nil {
		t.Fatalf("expected no config")
	}
}

func TestConfig_OutgoingTLS_VerifyOutgoing(t *testing.T) {
	conf := &Config{
		VerifyOutgoing: true,
		CAFile:         "../test/ca/root.cer",
	}
	tls, err := conf.OutgoingTLSConfig()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if tls == nil {
		t.Fatalf("expected config")
	}
	if len(tls.RootCAs.Subjects()) != 1 {
		t.Fatalf("expect root cert")
	}
	if tls.ServerName != "" {
		t.Fatalf("expect no server name verification")
	}
	if !tls.InsecureSkipVerify {
		t.Fatalf("should skip built-in verification")
	}
}

func TestConfig_OutgoingTLS_ServerName(t *testing.T) {
	conf := &Config{
		VerifyOutgoing: true,
		CAFile:         "../test/ca/root.cer",
		ServerName:     "consul.example.com",
	}
	tls, err := conf.OutgoingTLSConfig()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if tls == nil {
		t.Fatalf("expected config")
	}
	if len(tls.RootCAs.Subjects()) != 1 {
		t.Fatalf("expect root cert")
	}
	if tls.ServerName != "consul.example.com" {
		t.Fatalf("expect server name")
	}
	if tls.InsecureSkipVerify {
		t.Fatalf("should not skip built-in verification")
	}
}

func TestConfig_OutgoingTLS_WithKeyPair(t *testing.T) {
	conf := &Config{
		VerifyOutgoing: true,
		CAFile:         "../test/ca/root.cer",
		CertFile:       "../test/key/ourdomain.cer",
		KeyFile:        "../test/key/ourdomain.key",
	}
	tls, err := conf.OutgoingTLSConfig()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if tls == nil {
		t.Fatalf("expected config")
	}
	if len(tls.RootCAs.Subjects()) != 1 {
		t.Fatalf("expect root cert")
	}
	if !tls.InsecureSkipVerify {
		t.Fatalf("should skip verification")
	}
	if len(tls.Certificates) != 1 {
		t.Fatalf("expected client cert")
	}
}

func startTLSServer(config *Config) (net.Conn, chan error) {
	errc := make(chan error, 1)

	tlsConfigServer, err := config.IncomingTLSConfig()
	if err != nil {
		errc <- err
		return nil, errc
	}

	client, server := net.Pipe()
	go func() {
		tlsServer := tls.Server(server, tlsConfigServer)
		if err := tlsServer.Handshake(); err != nil {
			errc <- err
		}
		close(errc)
		// Because net.Pipe() is unbuffered, if both sides
		// Close() simultaneously, we will deadlock as they
		// both send an alert and then block. So we make the
		// server read any data from the client until error or
		// EOF, which will allow the client to Close(), and
		// *then* we Close() the server.
		io.Copy(ioutil.Discard, tlsServer)
		tlsServer.Close()
	}()
	return client, errc
}

func TestConfig_wrapTLS_OK(t *testing.T) {
	config := &Config{
		CAFile:         "../test/ca/root.cer",
		CertFile:       "../test/key/ourdomain.cer",
		KeyFile:        "../test/key/ourdomain.key",
		VerifyOutgoing: true,
	}

	client, errc := startTLSServer(config)
	if client == nil {
		t.Fatalf("startTLSServer err: %v", <-errc)
	}

	clientConfig, err := config.OutgoingTLSConfig()
	if err != nil {
		t.Fatalf("OutgoingTLSConfig err: %v", err)
	}

	tlsClient, err := WrapTLSClient(client, clientConfig)
	if err != nil {
		t.Fatalf("wrapTLS err: %v", err)
	} else {
		tlsClient.Close()
	}
	err = <-errc
	if err != nil {
		t.Fatalf("server: %v", err)
	}
}

func TestConfig_wrapTLS_BadCert(t *testing.T) {
	serverConfig := &Config{
		CertFile: "../test/key/ssl-cert-snakeoil.pem",
		KeyFile:  "../test/key/ssl-cert-snakeoil.key",
	}

	client, errc := startTLSServer(serverConfig)
	if client == nil {
		t.Fatalf("startTLSServer err: %v", <-errc)
	}

	clientConfig := &Config{
		CAFile:         "../test/ca/root.cer",
		VerifyOutgoing: true,
	}

	clientTLSConfig, err := clientConfig.OutgoingTLSConfig()
	if err != nil {
		t.Fatalf("OutgoingTLSConfig err: %v", err)
	}

	tlsClient, err := WrapTLSClient(client, clientTLSConfig)
	if err == nil {
		t.Fatalf("wrapTLS no err")
	}
	if tlsClient != nil {
		t.Fatalf("returned a client")
	}

	err = <-errc
	if err != nil {
		t.Fatalf("server: %v", err)
	}
}

func TestConfig_IncomingTLS(t *testing.T) {
	conf := &Config{
		VerifyIncoming: true,
		CAFile:         "../test/ca/root.cer",
		CertFile:       "../test/key/ourdomain.cer",
		KeyFile:        "../test/key/ourdomain.key",
	}
	tlsC, err := conf.IncomingTLSConfig()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if tlsC == nil {
		t.Fatalf("expected config")
	}
	if len(tlsC.ClientCAs.Subjects()) != 1 {
		t.Fatalf("expect client cert")
	}
	if tlsC.ClientAuth != tls.RequireAndVerifyClientCert {
		t.Fatalf("should not skip verification")
	}
	if len(tlsC.Certificates) != 1 {
		t.Fatalf("expected client cert")
	}
}

func TestConfig_IncomingTLS_MissingCA(t *testing.T) {
	conf := &Config{
		VerifyIncoming: true,
		CertFile:       "../test/key/ourdomain.cer",
		KeyFile:        "../test/key/ourdomain.key",
	}
	_, err := conf.IncomingTLSConfig()
	if err == nil {
		t.Fatalf("expected err")
	}
}

func TestConfig_IncomingTLS_MissingKey(t *testing.T) {
	conf := &Config{
		VerifyIncoming: true,
		CAFile:         "../test/ca/root.cer",
	}
	_, err := conf.IncomingTLSConfig()
	if err == nil {
		t.Fatalf("expected err")
	}
}

func TestConfig_IncomingTLS_NoVerify(t *testing.T) {
	conf := &Config{}
	tlsC, err := conf.IncomingTLSConfig()
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if tlsC == nil {
		t.Fatalf("expected config")
	}
	if len(tlsC.ClientCAs.Subjects()) != 0 {
		t.Fatalf("do not expect client cert")
	}
	if tlsC.ClientAuth != tls.NoClientCert {
		t.Fatalf("should skip verification")
	}
	if len(tlsC.Certificates) != 0 {
		t.Fatalf("unexpected client cert")
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/vishvananda/netlink/link.go<|end_filename|>
package netlink

import (
	"net"
)

// Link represents a link device from netlink. Shared link attributes
// like name may be retrieved using the Attrs() method. Unique data
// can be retrieved by casting the object to the proper type.
type Link interface {
	Attrs() *LinkAttrs
	Type() string
}

// LinkAttrs represents data shared by most link types
type LinkAttrs struct {
	Index        int
	MTU          int
	TxQLen       uint32 // Transmit Queue Length
	Name         string
	HardwareAddr net.HardwareAddr
	Flags        net.Flags
	ParentIndex  int // index of the parent link device
	MasterIndex  int // must be the index of a bridge
}

// Device links cannot be created via netlink. These links
// are links created by udev like 'lo' and 'etho0'
type Device struct {
	LinkAttrs
}

func (device *Device) Attrs() *LinkAttrs {
	return &device.LinkAttrs
}

func (device *Device) Type() string {
	return "device"
}

// Dummy links are dummy ethernet devices
type Dummy struct {
	LinkAttrs
}

func (dummy *Dummy) Attrs() *LinkAttrs {
	return &dummy.LinkAttrs
}

func (dummy *Dummy) Type() string {
	return "dummy"
}

// Bridge links are simple linux bridges
type Bridge struct {
	LinkAttrs
}

func (bridge *Bridge) Attrs() *LinkAttrs {
	return &bridge.LinkAttrs
}

func (bridge *Bridge) Type() string {
	return "bridge"
}

// Vlan links have ParentIndex set in their Attrs()
type Vlan struct {
	LinkAttrs
	VlanId int
}

func (vlan *Vlan) Attrs() *LinkAttrs {
	return &vlan.LinkAttrs
}

func (vlan *Vlan) Type() string {
	return "vlan"
}

// Macvlan links have ParentIndex set in their Attrs()
type Macvlan struct {
	LinkAttrs
}

func (macvlan *Macvlan) Attrs() *LinkAttrs {
	return &macvlan.LinkAttrs
}

func (macvlan *Macvlan) Type() string {
	return "macvlan"
}

// Veth devices must specify PeerName on create
type Veth struct {
	LinkAttrs
	PeerName string // veth on create only
}

func (veth *Veth) Attrs() *LinkAttrs {
	return &veth.LinkAttrs
}

func (veth *Veth) Type() string {
	return "veth"
}

// Generic links represent types that are not currently understood
// by this netlink library.
type Generic struct {
	LinkAttrs
	LinkType string
}

func (generic *Generic) Attrs() *LinkAttrs {
	return &generic.LinkAttrs
}

func (generic *Generic) Type() string {
	return generic.LinkType
}

type Vxlan struct {
	LinkAttrs
	VxlanId      int
	VtepDevIndex int
	SrcAddr      net.IP
	Group        net.IP
	TTL          int
	TOS          int
	Learning     bool
	Proxy        bool
	RSC          bool
	L2miss       bool
	L3miss       bool
	NoAge        bool
	Age          int
	Limit        int
	Port         int
	PortLow      int
	PortHigh     int
}

func (vxlan *Vxlan) Attrs() *LinkAttrs {
	return &vxlan.LinkAttrs
}

func (vxlan *Vxlan) Type() string {
	return "vxlan"
}

// iproute2 supported devices;
// vlan | veth | vcan | dummy | ifb | macvlan | macvtap |
// can | bridge | bond | ipoib | ip6tnl | ipip | sit |
// vxlan | gre | gretap | ip6gre | ip6gretap | vti


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/hcl/hcl/valuetype_string.go<|end_filename|>
// generated by stringer -type=ValueType; DO NOT EDIT

package hcl

import "fmt"

const _ValueType_name = "ValueTypeUnknownValueTypeFloatValueTypeIntValueTypeStringValueTypeBoolValueTypeNilValueTypeListValueTypeObject"

var _ValueType_index = [...]uint8{0, 16, 30, 42, 57, 70, 82, 95, 110}

func (i ValueType) String() string {
	if i+1 >= ValueType(len(_ValueType_index)) {
		return fmt.Sprintf("ValueType(%d)", i)
	}
	return _ValueType_name[_ValueType_index[i]:_ValueType_index[i+1]]
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/command/agent/kvs_endpoint_test.go<|end_filename|>
package agent

import (
	"bytes"
	"fmt"
	"net/http"
	"net/http/httptest"
	"os"
	"reflect"
	"testing"

	"github.com/hashicorp/consul/testutil"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/consul/structs"
)

func TestKVSEndpoint_PUT_GET_DELETE(t *testing.T) {
	dir, srv := makeHTTPServer(t)
	defer os.RemoveAll(dir)
	defer srv.Shutdown()
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	keys := []string{
		"baz",
		"bar",
		"foo/sub1",
		"foo/sub2",
		"zip",
	}

	for _, key := range keys {
		buf := bytes.NewBuffer([]byte("test"))
		req, err := http.NewRequest("PUT", "/v1/kv/"+key, buf)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		resp := httptest.NewRecorder()
		obj, err := srv.KVSEndpoint(resp, req)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		if res := obj.(bool); !res {
			t.Fatalf("should work")
		}
	}

	for _, key := range keys {
		req, err := http.NewRequest("GET", "/v1/kv/"+key, nil)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		resp := httptest.NewRecorder()
		obj, err := srv.KVSEndpoint(resp, req)
		if err != nil {
			t.Fatalf("err: %v", err)
		}
		assertIndex(t, resp)

		res, ok := obj.(structs.DirEntries)
		if !ok {
			t.Fatalf("should work")
		}

		if len(res) != 1 {
			t.Fatalf("bad: %v", res)
		}

		if res[0].Key != key {
			t.Fatalf("bad: %v", res)
		}
	}

	for _, key := range keys {
		req, err := http.NewRequest("DELETE", "/v1/kv/"+key, nil)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		resp := httptest.NewRecorder()
		_, err = srv.KVSEndpoint(resp, req)
		if err != nil {
			t.Fatalf("err: %v", err)
		}
	}
}

func TestKVSEndpoint_Recurse(t *testing.T) {
	dir, srv := makeHTTPServer(t)
	defer os.RemoveAll(dir)
	defer srv.Shutdown()
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	keys := []string{
		"bar",
		"baz",
		"foo/sub1",
		"foo/sub2",
		"zip",
	}

	for _, key := range keys {
		buf := bytes.NewBuffer([]byte("test"))
		req, err := http.NewRequest("PUT", "/v1/kv/"+key, buf)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		resp := httptest.NewRecorder()
		obj, err := srv.KVSEndpoint(resp, req)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		if res := obj.(bool); !res {
			t.Fatalf("should work")
		}
	}

	{
		// Get all the keys
		req, err := http.NewRequest("GET", "/v1/kv/?recurse", nil)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		resp := httptest.NewRecorder()
		obj, err := srv.KVSEndpoint(resp, req)
		if err != nil {
			t.Fatalf("err: %v", err)
		}
		assertIndex(t, resp)

		res, ok := obj.(structs.DirEntries)
		if !ok {
			t.Fatalf("should work")
		}

		if len(res) != len(keys) {
			t.Fatalf("bad: %v", res)
		}

		for idx, key := range keys {
			if res[idx].Key != key {
				t.Fatalf("bad: %v %v", res[idx].Key, key)
			}
		}
	}

	{
		req, err := http.NewRequest("DELETE", "/v1/kv/?recurse", nil)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		resp := httptest.NewRecorder()
		_, err = srv.KVSEndpoint(resp, req)
		if err != nil {
			t.Fatalf("err: %v", err)
		}
	}

	{
		// Get all the keys
		req, err := http.NewRequest("GET", "/v1/kv/?recurse", nil)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		resp := httptest.NewRecorder()
		obj, err := srv.KVSEndpoint(resp, req)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		if obj != nil {
			t.Fatalf("bad: %v", obj)
		}
	}
}

func TestKVSEndpoint_DELETE_CAS(t *testing.T) {
	dir, srv := makeHTTPServer(t)
	defer os.RemoveAll(dir)
	defer srv.Shutdown()
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	{
		buf := bytes.NewBuffer([]byte("test"))
		req, err := http.NewRequest("PUT", "/v1/kv/test", buf)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		resp := httptest.NewRecorder()
		obj, err := srv.KVSEndpoint(resp, req)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		if res := obj.(bool); !res {
			t.Fatalf("should work")
		}
	}

	req, err := http.NewRequest("GET", "/v1/kv/test", nil)
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	resp := httptest.NewRecorder()
	obj, err := srv.KVSEndpoint(resp, req)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	d := obj.(structs.DirEntries)[0]

	// Create a CAS request, bad index
	{
		buf := bytes.NewBuffer([]byte("zip"))
		req, err := http.NewRequest("DELETE",
			fmt.Sprintf("/v1/kv/test?cas=%d", d.ModifyIndex-1), buf)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		resp := httptest.NewRecorder()
		obj, err := srv.KVSEndpoint(resp, req)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		if res := obj.(bool); res {
			t.Fatalf("should NOT work")
		}
	}

	// Create a CAS request, good index
	{
		buf := bytes.NewBuffer([]byte("zip"))
		req, err := http.NewRequest("DELETE",
			fmt.Sprintf("/v1/kv/test?cas=%d", d.ModifyIndex), buf)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		resp := httptest.NewRecorder()
		obj, err := srv.KVSEndpoint(resp, req)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		if res := obj.(bool); !res {
			t.Fatalf("should work")
		}
	}

	// Verify the delete
	req, _ = http.NewRequest("GET", "/v1/kv/test", nil)
	resp = httptest.NewRecorder()
	obj, _ = srv.KVSEndpoint(resp, req)
	if obj != nil {
		t.Fatalf("should be destroyed")
	}
}

func TestKVSEndpoint_CAS(t *testing.T) {
	dir, srv := makeHTTPServer(t)
	defer os.RemoveAll(dir)
	defer srv.Shutdown()
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	{
		buf := bytes.NewBuffer([]byte("test"))
		req, err := http.NewRequest("PUT", "/v1/kv/test?flags=50", buf)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		resp := httptest.NewRecorder()
		obj, err := srv.KVSEndpoint(resp, req)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		if res := obj.(bool); !res {
			t.Fatalf("should work")
		}
	}

	req, err := http.NewRequest("GET", "/v1/kv/test", nil)
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	resp := httptest.NewRecorder()
	obj, err := srv.KVSEndpoint(resp, req)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	d := obj.(structs.DirEntries)[0]

	// Check the flags
	if d.Flags != 50 {
		t.Fatalf("bad: %v", d)
	}

	// Create a CAS request, bad index
	{
		buf := bytes.NewBuffer([]byte("zip"))
		req, err := http.NewRequest("PUT",
			fmt.Sprintf("/v1/kv/test?flags=42&cas=%d", d.ModifyIndex-1), buf)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		resp := httptest.NewRecorder()
		obj, err := srv.KVSEndpoint(resp, req)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		if res := obj.(bool); res {
			t.Fatalf("should NOT work")
		}
	}

	// Create a CAS request, good index
	{
		buf := bytes.NewBuffer([]byte("zip"))
		req, err := http.NewRequest("PUT",
			fmt.Sprintf("/v1/kv/test?flags=42&cas=%d", d.ModifyIndex), buf)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		resp := httptest.NewRecorder()
		obj, err := srv.KVSEndpoint(resp, req)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		if res := obj.(bool); !res {
			t.Fatalf("should work")
		}
	}

	// Verify the update
	req, _ = http.NewRequest("GET", "/v1/kv/test", nil)
	resp = httptest.NewRecorder()
	obj, _ = srv.KVSEndpoint(resp, req)
	d = obj.(structs.DirEntries)[0]

	if d.Flags != 42 {
		t.Fatalf("bad: %v", d)
	}
	if string(d.Value) != "zip" {
		t.Fatalf("bad: %v", d)
	}
}

func TestKVSEndpoint_ListKeys(t *testing.T) {
	dir, srv := makeHTTPServer(t)
	defer os.RemoveAll(dir)
	defer srv.Shutdown()
	defer srv.agent.Shutdown()

	testutil.WaitForLeader(t, srv.agent.RPC, "dc1")

	keys := []string{
		"bar",
		"baz",
		"foo/sub1",
		"foo/sub2",
		"zip",
	}

	for _, key := range keys {
		buf := bytes.NewBuffer([]byte("test"))
		req, err := http.NewRequest("PUT", "/v1/kv/"+key, buf)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		resp := httptest.NewRecorder()
		obj, err := srv.KVSEndpoint(resp, req)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		if res := obj.(bool); !res {
			t.Fatalf("should work")
		}
	}

	{
		// Get all the keys
		req, err := http.NewRequest("GET", "/v1/kv/?keys&seperator=/", nil)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		resp := httptest.NewRecorder()
		obj, err := srv.KVSEndpoint(resp, req)
		if err != nil {
			t.Fatalf("err: %v", err)
		}
		assertIndex(t, resp)

		res, ok := obj.([]string)
		if !ok {
			t.Fatalf("should work")
		}

		expect := []string{"bar", "baz", "foo/", "zip"}
		if !reflect.DeepEqual(res, expect) {
			t.Fatalf("bad: %v", res)
		}
	}
}

func TestKVSEndpoint_AcquireRelease(t *testing.T) {
	httpTest(t, func(srv *HTTPServer) {
		// Acquire the lock
		id := makeTestSession(t, srv)
		req, err := http.NewRequest("PUT",
			"/v1/kv/test?acquire="+id, bytes.NewReader(nil))
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		resp := httptest.NewRecorder()
		obj, err := srv.KVSEndpoint(resp, req)
		if err != nil {
			t.Fatalf("err: %v", err)
		}
		if res := obj.(bool); !res {
			t.Fatalf("should work")
		}

		// Verify we have the lock
		req, err = http.NewRequest("GET", "/v1/kv/test", nil)
		if err != nil {
			t.Fatalf("err: %v", err)
		}
		resp = httptest.NewRecorder()
		obj, err = srv.KVSEndpoint(resp, req)
		if err != nil {
			t.Fatalf("err: %v", err)
		}
		d := obj.(structs.DirEntries)[0]

		// Check the flags
		if d.Session != id {
			t.Fatalf("bad: %v", d)
		}

		// Release the lock
		req, err = http.NewRequest("PUT",
			"/v1/kv/test?release="+id, bytes.NewReader(nil))
		if err != nil {
			t.Fatalf("err: %v", err)
		}
		resp = httptest.NewRecorder()
		obj, err = srv.KVSEndpoint(resp, req)
		if err != nil {
			t.Fatalf("err: %v", err)
		}
		if res := obj.(bool); !res {
			t.Fatalf("should work")
		}

		// Verify we do not have the lock
		req, err = http.NewRequest("GET", "/v1/kv/test", nil)
		if err != nil {
			t.Fatalf("err: %v", err)
		}
		resp = httptest.NewRecorder()
		obj, err = srv.KVSEndpoint(resp, req)
		if err != nil {
			t.Fatalf("err: %v", err)
		}
		d = obj.(structs.DirEntries)[0]

		// Check the flags
		if d.Session != "" {
			t.Fatalf("bad: %v", d)
		}
	})
}

func TestKVSEndpoint_GET_Raw(t *testing.T) {
	httpTest(t, func(srv *HTTPServer) {
		buf := bytes.NewBuffer([]byte("test"))
		req, err := http.NewRequest("PUT", "/v1/kv/test", buf)
		if err != nil {
			t.Fatalf("err: %v", err)
		}
		resp := httptest.NewRecorder()
		obj, err := srv.KVSEndpoint(resp, req)
		if err != nil {
			t.Fatalf("err: %v", err)
		}
		if res := obj.(bool); !res {
			t.Fatalf("should work")
		}

		req, err = http.NewRequest("GET", "/v1/kv/test?raw", nil)
		if err != nil {
			t.Fatalf("err: %v", err)
		}
		resp = httptest.NewRecorder()
		obj, err = srv.KVSEndpoint(resp, req)
		if err != nil {
			t.Fatalf("err: %v", err)
		}
		assertIndex(t, resp)

		// Check the body
		if !bytes.Equal(resp.Body.Bytes(), []byte("test")) {
			t.Fatalf("bad: %s", resp.Body.Bytes())
		}
	})
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/consul/tombstone_gc.go<|end_filename|>
package consul

import (
	"fmt"
	"sync"
	"time"
)

// TombstoneGC is used to track creation of tombstones
// so that they can be garbage collected after their TTL
// expires. The tombstones allow queries to provide monotonic
// index values within the TTL window. The GC is used to
// prevent monotonic growth in storage usage. This is a trade off
// between the length of the TTL and the storage overhead.
//
// In practice, this is required to fix the issue of delete
// visibility. When data is deleted from the KV store, the
// "latest" row can go backwards if the newest row is removed.
// The tombstones provide a way to ensure time doesn't move
// backwards within some interval.
//
type TombstoneGC struct {
	ttl         time.Duration
	granularity time.Duration

	// enabled controls if we actually setup any timers.
	enabled bool

	// expires maps the time of expiration to the highest
	// tombstone value that should be expired.
	expires map[time.Time]*expireInterval

	// expireCh is used to stream expiration
	expireCh chan uint64

	// lock is used to ensure safe access to all the fields
	lock sync.Mutex
}

// expireInterval is used to track the maximum index
// to expire in a given interval with a timer
type expireInterval struct {
	maxIndex uint64
	timer    *time.Timer
}

// NewTombstoneGC is used to construct a new TombstoneGC given
// a TTL for tombstones and a tracking granularity. Longer TTLs
// ensure correct behavior for more time, but use more storage.
// A shorter granularity increases the number of Raft transactions
// and reduce how far past the TTL we perform GC.
func NewTombstoneGC(ttl, granularity time.Duration) (*TombstoneGC, error) {
	// Sanity check the inputs
	if ttl <= 0 || granularity <= 0 {
		return nil, fmt.Errorf("Tombstone TTL and granularity must be positive")
	}

	t := &TombstoneGC{
		ttl:         ttl,
		granularity: granularity,
		enabled:     false,
		expires:     make(map[time.Time]*expireInterval),
		expireCh:    make(chan uint64, 1),
	}
	return t, nil
}

// ExpireCh is used to return a channel that streams the next index
// that should be expired
func (t *TombstoneGC) ExpireCh() <-chan uint64 {
	return t.expireCh
}

// SetEnabled is used to control if the tombstone GC is
// enabled. Should only be enabled by the leader node.
func (t *TombstoneGC) SetEnabled(enabled bool) {
	t.lock.Lock()
	defer t.lock.Unlock()
	if enabled == t.enabled {
		return
	}

	// Stop all the timers and clear
	if !enabled {
		for _, exp := range t.expires {
			exp.timer.Stop()
		}
		t.expires = make(map[time.Time]*expireInterval)
	}

	// Update the status
	t.enabled = enabled
}

// Hint is used to indicate that keys at the given index have been
// deleted, and that their GC should be scheduled.
func (t *TombstoneGC) Hint(index uint64) {
	expires := t.nextExpires()

	t.lock.Lock()
	defer t.lock.Unlock()
	if !t.enabled {
		return
	}

	// Check for an existing expiration timer
	exp, ok := t.expires[expires]
	if ok {
		// Increment the highest index to be expired at that time
		if index > exp.maxIndex {
			exp.maxIndex = index
		}
		return
	}

	// Create new expiration time
	t.expires[expires] = &expireInterval{
		maxIndex: index,
		timer: time.AfterFunc(expires.Sub(time.Now()), func() {
			t.expireTime(expires)
		}),
	}
}

// PendingExpiration is used to check if any expirations are pending
func (t *TombstoneGC) PendingExpiration() bool {
	t.lock.Lock()
	defer t.lock.Unlock()
	return len(t.expires) > 0
}

// nextExpires is used to calculate the next experation time
func (t *TombstoneGC) nextExpires() time.Time {
	expires := time.Now().Add(t.ttl)
	remain := expires.UnixNano() % int64(t.granularity)
	adj := expires.Add(t.granularity - time.Duration(remain))
	return adj
}

// expireTime is used to expire the entries at the given time
func (t *TombstoneGC) expireTime(expires time.Time) {
	// Get the maximum index and clear the entry
	t.lock.Lock()
	exp := t.expires[expires]
	delete(t.expires, expires)
	t.lock.Unlock()

	// Notify the expires channel
	t.expireCh <- exp.maxIndex
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/hcl/decoder.go<|end_filename|>
package hcl

import (
	"errors"
	"fmt"
	"reflect"
	"sort"
	"strconv"
	"strings"

	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/hcl/hcl"
)

// This is the tag to use with structures to have settings for HCL
const tagName = "hcl"

// Decode reads the given input and decodes it into the structure
// given by `out`.
func Decode(out interface{}, in string) error {
	obj, err := Parse(in)
	if err != nil {
		return err
	}

	return DecodeObject(out, obj)
}

// DecodeObject is a lower-level version of Decode. It decodes a
// raw Object into the given output.
func DecodeObject(out interface{}, n *hcl.Object) error {
	val := reflect.ValueOf(out)
	if val.Kind() != reflect.Ptr {
		return errors.New("result must be a pointer")
	}

	var d decoder
	return d.decode("root", n, val.Elem())
}

type decoder struct {
	stack []reflect.Kind
}

func (d *decoder) decode(name string, o *hcl.Object, result reflect.Value) error {
	k := result

	// If we have an interface with a valid value, we use that
	// for the check.
	if result.Kind() == reflect.Interface {
		elem := result.Elem()
		if elem.IsValid() {
			k = elem
		}
	}

	// Push current onto stack unless it is an interface.
	if k.Kind() != reflect.Interface {
		d.stack = append(d.stack, k.Kind())

		// Schedule a pop
		defer func() {
			d.stack = d.stack[:len(d.stack)-1]
		}()
	}

	switch k.Kind() {
	case reflect.Bool:
		return d.decodeBool(name, o, result)
	case reflect.Float64:
		return d.decodeFloat(name, o, result)
	case reflect.Int:
		return d.decodeInt(name, o, result)
	case reflect.Interface:
		// When we see an interface, we make our own thing
		return d.decodeInterface(name, o, result)
	case reflect.Map:
		return d.decodeMap(name, o, result)
	case reflect.Ptr:
		return d.decodePtr(name, o, result)
	case reflect.Slice:
		return d.decodeSlice(name, o, result)
	case reflect.String:
		return d.decodeString(name, o, result)
	case reflect.Struct:
		return d.decodeStruct(name, o, result)
	default:
		return fmt.Errorf(
			"%s: unknown kind to decode into: %s", name, k.Kind())
	}

	return nil
}

func (d *decoder) decodeBool(name string, o *hcl.Object, result reflect.Value) error {
	switch o.Type {
	case hcl.ValueTypeBool:
		result.Set(reflect.ValueOf(o.Value.(bool)))
	default:
		return fmt.Errorf("%s: unknown type %v", name, o.Type)
	}

	return nil
}

func (d *decoder) decodeFloat(name string, o *hcl.Object, result reflect.Value) error {
	switch o.Type {
	case hcl.ValueTypeFloat:
		result.Set(reflect.ValueOf(o.Value.(float64)))
	default:
		return fmt.Errorf("%s: unknown type %v", name, o.Type)
	}

	return nil
}

func (d *decoder) decodeInt(name string, o *hcl.Object, result reflect.Value) error {
	switch o.Type {
	case hcl.ValueTypeInt:
		result.Set(reflect.ValueOf(o.Value.(int)))
	case hcl.ValueTypeString:
		v, err := strconv.ParseInt(o.Value.(string), 0, 0)
		if err != nil {
			return err
		}

		result.SetInt(int64(v))
	default:
		return fmt.Errorf("%s: unknown type %v", name, o.Type)
	}

	return nil
}

func (d *decoder) decodeInterface(name string, o *hcl.Object, result reflect.Value) error {
	var set reflect.Value
	redecode := true

	switch o.Type {
	case hcl.ValueTypeObject:
		// If we're at the root or we're directly within a slice, then we
		// decode objects into map[string]interface{}, otherwise we decode
		// them into lists.
		if len(d.stack) == 0 || d.stack[len(d.stack)-1] == reflect.Slice {
			var temp map[string]interface{}
			tempVal := reflect.ValueOf(temp)
			result := reflect.MakeMap(
				reflect.MapOf(
					reflect.TypeOf(""),
					tempVal.Type().Elem()))

			set = result
		} else {
			var temp []map[string]interface{}
			tempVal := reflect.ValueOf(temp)
			result := reflect.MakeSlice(
				reflect.SliceOf(tempVal.Type().Elem()), 0, int(o.Len()))
			set = result
		}
	case hcl.ValueTypeList:
		var temp []interface{}
		tempVal := reflect.ValueOf(temp)
		result := reflect.MakeSlice(
			reflect.SliceOf(tempVal.Type().Elem()), 0, 0)
		set = result
	case hcl.ValueTypeBool:
		var result bool
		set = reflect.Indirect(reflect.New(reflect.TypeOf(result)))
	case hcl.ValueTypeFloat:
		var result float64
		set = reflect.Indirect(reflect.New(reflect.TypeOf(result)))
	case hcl.ValueTypeInt:
		var result int
		set = reflect.Indirect(reflect.New(reflect.TypeOf(result)))
	case hcl.ValueTypeString:
		set = reflect.Indirect(reflect.New(reflect.TypeOf("")))
	default:
		return fmt.Errorf(
			"%s: cannot decode into interface: %T",
			name, o)
	}

	// Set the result to what its supposed to be, then reset
	// result so we don't reflect into this method anymore.
	result.Set(set)

	if redecode {
		// Revisit the node so that we can use the newly instantiated
		// thing and populate it.
		if err := d.decode(name, o, result); err != nil {
			return err
		}
	}

	return nil
}

func (d *decoder) decodeMap(name string, o *hcl.Object, result reflect.Value) error {
	if o.Type != hcl.ValueTypeObject {
		return fmt.Errorf("%s: not an object type for map (%v)", name, o.Type)
	}

	// If we have an interface, then we can address the interface,
	// but not the slice itself, so get the element but set the interface
	set := result
	if result.Kind() == reflect.Interface {
		result = result.Elem()
	}

	resultType := result.Type()
	resultElemType := resultType.Elem()
	resultKeyType := resultType.Key()
	if resultKeyType.Kind() != reflect.String {
		return fmt.Errorf(
			"%s: map must have string keys", name)
	}

	// Make a map if it is nil
	resultMap := result
	if result.IsNil() {
		resultMap = reflect.MakeMap(
			reflect.MapOf(resultKeyType, resultElemType))
	}

	// Go through each element and decode it.
	for _, o := range o.Elem(false) {
		if o.Value == nil {
			continue
		}

		for _, o := range o.Elem(true) {
			// Make the field name
			fieldName := fmt.Sprintf("%s.%s", name, o.Key)

			// Get the key/value as reflection values
			key := reflect.ValueOf(o.Key)
			val := reflect.Indirect(reflect.New(resultElemType))

			// If we have a pre-existing value in the map, use that
			oldVal := resultMap.MapIndex(key)
			if oldVal.IsValid() {
				val.Set(oldVal)
			}

			// Decode!
			if err := d.decode(fieldName, o, val); err != nil {
				return err
			}

			// Set the value on the map
			resultMap.SetMapIndex(key, val)
		}
	}

	// Set the final map if we can
	set.Set(resultMap)
	return nil
}

func (d *decoder) decodePtr(name string, o *hcl.Object, result reflect.Value) error {
	// Create an element of the concrete (non pointer) type and decode
	// into that. Then set the value of the pointer to this type.
	resultType := result.Type()
	resultElemType := resultType.Elem()
	val := reflect.New(resultElemType)
	if err := d.decode(name, o, reflect.Indirect(val)); err != nil {
		return err
	}

	result.Set(val)
	return nil
}

func (d *decoder) decodeSlice(name string, o *hcl.Object, result reflect.Value) error {
	// If we have an interface, then we can address the interface,
	// but not the slice itself, so get the element but set the interface
	set := result
	if result.Kind() == reflect.Interface {
		result = result.Elem()
	}

	// Create the slice if it isn't nil
	resultType := result.Type()
	resultElemType := resultType.Elem()
	if result.IsNil() {
		resultSliceType := reflect.SliceOf(resultElemType)
		result = reflect.MakeSlice(
			resultSliceType, 0, 0)
	}

	// Determine how we're doing this
	expand := true
	switch o.Type {
	case hcl.ValueTypeObject:
		expand = false
	default:
		// Array or anything else: we expand values and take it all
	}

	i := 0
	for _, o := range o.Elem(expand) {
		fieldName := fmt.Sprintf("%s[%d]", name, i)

		// Decode
		val := reflect.Indirect(reflect.New(resultElemType))
		if err := d.decode(fieldName, o, val); err != nil {
			return err
		}

		// Append it onto the slice
		result = reflect.Append(result, val)

		i += 1
	}

	set.Set(result)
	return nil
}

func (d *decoder) decodeString(name string, o *hcl.Object, result reflect.Value) error {
	switch o.Type {
	case hcl.ValueTypeInt:
		result.Set(reflect.ValueOf(
			strconv.FormatInt(int64(o.Value.(int)), 10)).Convert(result.Type()))
	case hcl.ValueTypeString:
		result.Set(reflect.ValueOf(o.Value.(string)).Convert(result.Type()))
	default:
		return fmt.Errorf("%s: unknown type to string: %v", name, o.Type)
	}

	return nil
}

func (d *decoder) decodeStruct(name string, o *hcl.Object, result reflect.Value) error {
	if o.Type != hcl.ValueTypeObject {
		return fmt.Errorf("%s: not an object type for struct (%v)", name, o.Type)
	}

	// This slice will keep track of all the structs we'll be decoding.
	// There can be more than one struct if there are embedded structs
	// that are squashed.
	structs := make([]reflect.Value, 1, 5)
	structs[0] = result

	// Compile the list of all the fields that we're going to be decoding
	// from all the structs.
	fields := make(map[*reflect.StructField]reflect.Value)
	for len(structs) > 0 {
		structVal := structs[0]
		structs = structs[1:]

		structType := structVal.Type()
		for i := 0; i < structType.NumField(); i++ {
			fieldType := structType.Field(i)

			if fieldType.Anonymous {
				fieldKind := fieldType.Type.Kind()
				if fieldKind != reflect.Struct {
					return fmt.Errorf(
						"%s: unsupported type to struct: %s",
						fieldType.Name, fieldKind)
				}

				// We have an embedded field. We "squash" the fields down
				// if specified in the tag.
				squash := false
				tagParts := strings.Split(fieldType.Tag.Get(tagName), ",")
				for _, tag := range tagParts[1:] {
					if tag == "squash" {
						squash = true
						break
					}
				}

				if squash {
					structs = append(
						structs, result.FieldByName(fieldType.Name))
					continue
				}
			}

			// Normal struct field, store it away
			fields[&fieldType] = structVal.Field(i)
		}
	}

	usedKeys := make(map[string]struct{})
	decodedFields := make([]string, 0, len(fields))
	decodedFieldsVal := make([]reflect.Value, 0)
	unusedKeysVal := make([]reflect.Value, 0)
	for fieldType, field := range fields {
		if !field.IsValid() {
			// This should never happen
			panic("field is not valid")
		}

		// If we can't set the field, then it is unexported or something,
		// and we just continue onwards.
		if !field.CanSet() {
			continue
		}

		fieldName := fieldType.Name

		// This is whether or not we expand the object into its children
		// later.
		expand := false

		tagValue := fieldType.Tag.Get(tagName)
		tagParts := strings.SplitN(tagValue, ",", 2)
		if len(tagParts) >= 2 {
			switch tagParts[1] {
			case "expand":
				expand = true
			case "decodedFields":
				decodedFieldsVal = append(decodedFieldsVal, field)
				continue
			case "key":
				field.SetString(o.Key)
				continue
			case "unusedKeys":
				unusedKeysVal = append(unusedKeysVal, field)
				continue
			}
		}

		if tagParts[0] != "" {
			fieldName = tagParts[0]
		}

		// Find the element matching this name
		obj := o.Get(fieldName, true)
		if obj == nil {
			continue
		}

		// Track the used key
		usedKeys[fieldName] = struct{}{}

		// Create the field name and decode. We range over the elements
		// because we actually want the value.
		fieldName = fmt.Sprintf("%s.%s", name, fieldName)
		for _, obj := range obj.Elem(expand) {
			if err := d.decode(fieldName, obj, field); err != nil {
				return err
			}
		}

		decodedFields = append(decodedFields, fieldType.Name)
	}

	if len(decodedFieldsVal) > 0 {
		// Sort it so that it is deterministic
		sort.Strings(decodedFields)

		for _, v := range decodedFieldsVal {
			v.Set(reflect.ValueOf(decodedFields))
		}
	}

	// If we want to know what keys are unused, compile that
	if len(unusedKeysVal) > 0 {
		/*
			unusedKeys := make([]string, 0, int(obj.Len())-len(usedKeys))

			for _, elem := range obj.Elem {
				k := elem.Key()
				if _, ok := usedKeys[k]; !ok {
					unusedKeys = append(unusedKeys, k)
				}
			}

			if len(unusedKeys) == 0 {
				unusedKeys = nil
			}

			for _, v := range unusedKeysVal {
				v.Set(reflect.ValueOf(unusedKeys))
			}
		*/
	}

	return nil
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/consul/command/agent/remote_exec.go<|end_filename|>
package agent

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"strconv"
	"sync"
	"syscall"
	"time"

	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/consul/structs"
)

const (
	// remoteExecFileName is the name of the file we append to
	// the path, e.g. _rexec/session_id/job
	remoteExecFileName = "job"

	// rExecAck is the suffix added to an ack path
	remoteExecAckSuffix = "ack"

	// remoteExecAck is the suffix added to an exit code
	remoteExecExitSuffix = "exit"

	// remoteExecOutputDivider is used to namespace the output
	remoteExecOutputDivider = "out"

	// remoteExecOutputSize is the size we chunk output too
	remoteExecOutputSize = 4 * 1024

	// remoteExecOutputDeadline is how long we wait before uploading
	// less than the chunk size
	remoteExecOutputDeadline = 500 * time.Millisecond
)

// remoteExecEvent is used as the payload of the user event to transmit
// what we need to know about the event
type remoteExecEvent struct {
	Prefix  string
	Session string
}

// remoteExecSpec is used as the specification of the remote exec.
// It is stored in the KV store
type remoteExecSpec struct {
	Command string
	Script  []byte
	Wait    time.Duration
}

type rexecWriter struct {
	BufCh    chan []byte
	BufSize  int
	BufIdle  time.Duration
	CancelCh chan struct{}

	buf     []byte
	bufLen  int
	bufLock sync.Mutex
	flush   *time.Timer
}

func (r *rexecWriter) Write(b []byte) (int, error) {
	r.bufLock.Lock()
	defer r.bufLock.Unlock()
	if r.flush != nil {
		r.flush.Stop()
		r.flush = nil
	}
	inpLen := len(b)
	if r.buf == nil {
		r.buf = make([]byte, r.BufSize)
	}

COPY:
	remain := len(r.buf) - r.bufLen
	if remain > len(b) {
		copy(r.buf[r.bufLen:], b)
		r.bufLen += len(b)
	} else {
		copy(r.buf[r.bufLen:], b[:remain])
		b = b[remain:]
		r.bufLen += remain
		r.bufLock.Unlock()
		r.Flush()
		r.bufLock.Lock()
		goto COPY
	}

	r.flush = time.AfterFunc(r.BufIdle, r.Flush)
	return inpLen, nil
}

func (r *rexecWriter) Flush() {
	r.bufLock.Lock()
	defer r.bufLock.Unlock()
	if r.flush != nil {
		r.flush.Stop()
		r.flush = nil
	}
	if r.bufLen == 0 {
		return
	}
	select {
	case r.BufCh <- r.buf[:r.bufLen]:
		r.buf = make([]byte, r.BufSize)
		r.bufLen = 0
	case <-r.CancelCh:
		r.bufLen = 0
	}
}

// handleRemoteExec is invoked when a new remote exec request is received
func (a *Agent) handleRemoteExec(msg *UserEvent) {
	a.logger.Printf("[DEBUG] agent: received remote exec event (ID: %s)", msg.ID)
	// Decode the event paylaod
	var event remoteExecEvent
	if err := json.Unmarshal(msg.Payload, &event); err != nil {
		a.logger.Printf("[ERR] agent: failed to decode remote exec event: %v", err)
		return
	}

	// Read the job specification
	var spec remoteExecSpec
	if !a.remoteExecGetSpec(&event, &spec) {
		return
	}

	// Write the acknowledgement
	if !a.remoteExecWriteAck(&event) {
		return
	}

	// Ensure we write out an exit code
	exitCode := 0
	defer a.remoteExecWriteExitCode(&event, &exitCode)

	// Check if this is a script, we may need to spill to disk
	var script string
	if len(spec.Script) != 0 {
		tmpFile, err := ioutil.TempFile("", "rexec")
		if err != nil {
			a.logger.Printf("[DEBUG] agent: failed to make tmp file: %v", err)
			exitCode = 255
			return
		}
		defer os.Remove(tmpFile.Name())
		os.Chmod(tmpFile.Name(), 0750)
		tmpFile.Write(spec.Script)
		tmpFile.Close()
		script = tmpFile.Name()
	} else {
		script = spec.Command
	}

	// Create the exec.Cmd
	a.logger.Printf("[INFO] agent: remote exec '%s'", script)
	cmd, err := ExecScript(script)
	if err != nil {
		a.logger.Printf("[DEBUG] agent: failed to start remote exec: %v", err)
		exitCode = 255
		return
	}

	// Setup the output streaming
	writer := &rexecWriter{
		BufCh:    make(chan []byte, 16),
		BufSize:  remoteExecOutputSize,
		BufIdle:  remoteExecOutputDeadline,
		CancelCh: make(chan struct{}),
	}
	cmd.Stdout = writer
	cmd.Stderr = writer

	// Start execution
	err = cmd.Start()
	if err != nil {
		a.logger.Printf("[DEBUG] agent: failed to start remote exec: %v", err)
		exitCode = 255
		return
	}

	// Wait for the process to exit
	exitCh := make(chan int, 1)
	go func() {
		err := cmd.Wait()
		writer.Flush()
		close(writer.BufCh)
		if err == nil {
			exitCh <- 0
			return
		}

		// Try to determine the exit code
		if exitErr, ok := err.(*exec.ExitError); ok {
			if status, ok := exitErr.Sys().(syscall.WaitStatus); ok {
				exitCh <- status.ExitStatus()
				return
			}
		}
		exitCh <- 1
	}()

	// Wait until we are complete, uploading as we go
WAIT:
	for num := 0; ; num++ {
		select {
		case out := <-writer.BufCh:
			if out == nil {
				break WAIT
			}
			if !a.remoteExecWriteOutput(&event, num, out) {
				close(writer.CancelCh)
				exitCode = 255
				return
			}
		case <-time.After(spec.Wait):
			// Acts like a heartbeat, since there is no output
			if !a.remoteExecWriteOutput(&event, num, nil) {
				close(writer.CancelCh)
				exitCode = 255
				return
			}
		}
	}

	// Get the exit code
	exitCode = <-exitCh
}

// remoteExecGetSpec is used to get the exec specification.
// Returns if execution should continue
func (a *Agent) remoteExecGetSpec(event *remoteExecEvent, spec *remoteExecSpec) bool {
	get := structs.KeyRequest{
		Datacenter: a.config.Datacenter,
		Key:        path.Join(event.Prefix, event.Session, remoteExecFileName),
		QueryOptions: structs.QueryOptions{
			AllowStale: true, // Stale read for scale! Retry on failure.
		},
	}
	var out structs.IndexedDirEntries
QUERY:
	if err := a.RPC("KVS.Get", &get, &out); err != nil {
		a.logger.Printf("[ERR] agent: failed to get remote exec job: %v", err)
		return false
	}
	if len(out.Entries) == 0 {
		// If the initial read was stale and had no data, retry as a consistent read
		if get.QueryOptions.AllowStale {
			a.logger.Printf("[DEBUG] agent: trying consistent fetch of remote exec job spec")
			get.QueryOptions.AllowStale = false
			goto QUERY
		} else {
			a.logger.Printf("[DEBUG] agent: remote exec aborted, job spec missing")
			return false
		}
	}
	if err := json.Unmarshal(out.Entries[0].Value, &spec); err != nil {
		a.logger.Printf("[ERR] agent: failed to decode remote exec spec: %v", err)
		return false
	}
	return true
}

// remoteExecWriteAck is used to write an ack. Returns if execution should
// continue.
func (a *Agent) remoteExecWriteAck(event *remoteExecEvent) bool {
	if err := a.remoteExecWriteKey(event, remoteExecAckSuffix, nil); err != nil {
		a.logger.Printf("[ERR] agent: failed to ack remote exec job: %v", err)
		return false
	}
	return true
}

// remoteExecWriteOutput is used to write output
func (a *Agent) remoteExecWriteOutput(event *remoteExecEvent, num int, output []byte) bool {
	suffix := path.Join(remoteExecOutputDivider, fmt.Sprintf("%05x", num))
	if err := a.remoteExecWriteKey(event, suffix, output); err != nil {
		a.logger.Printf("[ERR] agent: failed to write output for remote exec job: %v", err)
		return false
	}
	return true
}

// remoteExecWriteExitCode is used to write an exit code
func (a *Agent) remoteExecWriteExitCode(event *remoteExecEvent, exitCode *int) bool {
	val := []byte(strconv.FormatInt(int64(*exitCode), 10))
	if err := a.remoteExecWriteKey(event, remoteExecExitSuffix, val); err != nil {
		a.logger.Printf("[ERR] agent: failed to write exit code for remote exec job: %v", err)
		return false
	}
	return true
}

// remoteExecWriteKey is used to write an output key for a remote exec job
func (a *Agent) remoteExecWriteKey(event *remoteExecEvent, suffix string, val []byte) error {
	key := path.Join(event.Prefix, event.Session, a.config.NodeName, suffix)
	write := structs.KVSRequest{
		Datacenter: a.config.Datacenter,
		Op:         structs.KVSLock,
		DirEnt: structs.DirEntry{
			Key:     key,
			Value:   val,
			Session: event.Session,
		},
	}
	var success bool
	if err := a.RPC("KVS.Apply", &write, &success); err != nil {
		return err
	}
	if !success {
		return fmt.Errorf("write failed")
	}
	return nil
}


<|start_filename|>daemon/api_test.go<|end_filename|>
package daemon

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"net/http/httptest"
	"reflect"
	"testing"
)

func TestGetConfigurationEmpty(t *testing.T) {
	daemon := NewDaemon()
	request, _ := http.NewRequest("GET", "/v0.1/configuration", nil)
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)

	fmt.Println(response.Body)

	if response.Code != http.StatusOK {
		t.Fatalf("Expected %v:\n\tReceived: %v", "200", response.Code)
	}
}

func TestGetConfiguration(t *testing.T) {
	daemon := NewDaemon()
	daemon.Configuration = &Configuration{
		BridgeIP:   "172.16.42.1",
		BridgeName: "socketplane0",
		BridgeCIDR: "172.16.42.0/24",
		BridgeMTU:  1460,
	}
	request, _ := http.NewRequest("GET", "/v0.1/configuration", nil)
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)

	fmt.Println(response.Body)

	if response.Code != http.StatusOK {
		t.Fatalf("Expected %v:\n\tReceived: %v", "200", response.Code)
	}
}

func TestSetConfigurationNoBody(t *testing.T) {
	daemon := NewDaemon()
	request, _ := http.NewRequest("POST", "/v0.1/configuration", nil)
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusBadRequest {
		t.Fatalf("Expected %v:\n\tReceived: %v", "400", response.Code)
	}
}

func TestSetConfigurationBadBody(t *testing.T) {
	daemon := NewDaemon()
	request, _ := http.NewRequest("POST", "/v0.1/configuration", bytes.NewReader([]byte{1, 2, 3, 4}))
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusInternalServerError {
		t.Fatalf("Expected %v:\n\tReceived: %v", "500", response.Code)
	}
}

func TestSetConfiguration(t *testing.T) {
	daemon := NewDaemon()
	cfg := &Configuration{
		BridgeIP:   "172.16.42.1",
		BridgeName: "socketplane0",
		BridgeCIDR: "172.16.42.0/24",
		BridgeMTU:  1460,
	}
	data, _ := json.Marshal(cfg)
	request, _ := http.NewRequest("POST", "/v0.1/configuration", bytes.NewReader(data))
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusOK {
		t.Fatalf("Expected %v:\n\tReceived: %v", "200", response.Code)
	}
}

func TestGetConnections(t *testing.T) {
	daemon := NewDaemon()
	request, _ := http.NewRequest("GET", "/v0.1/connections", nil)
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusOK {
		t.Fatalf("Expected %v:\n\tReceived: %v", "200", response.Code)
	}
}

func TestGetConnection(t *testing.T) {
	daemon := NewDaemon()
	connection := &Connection{
		ContainerID:   "abc123",
		ContainerName: "test_container",
		ContainerPID:  "1234",
		Network:       "default",
	}
	daemon.Connections["abc123"] = connection
	request, _ := http.NewRequest("GET", "/v0.1/connections/abc123", nil)
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusOK {
		t.Fatalf("Expected %v:\n\tReceived: %v", "404", response.Code)
	}

	expected, _ := json.Marshal(connection)
	if !bytes.Equal(response.Body.Bytes(), expected) {
		t.Fatal("body does not match")
	}

	headers := response.HeaderMap["Content-Type"]
	if headers[0] != "application/json; charset=utf-8" {
		t.Fatal("headers not correctly set")
	}
}

func TestCreateConnection(t *testing.T) {
	daemon := NewDaemon()
	connection := &Connection{
		ContainerID:   "abc123",
		ContainerName: "test_container",
		ContainerPID:  "1234",
		Network:       "foo",
	}
	data, _ := json.Marshal(connection)
	request, _ := http.NewRequest("POST", "/v0.1/connections", bytes.NewReader(data))
	response := httptest.NewRecorder()

	go func() {
		for {
			context := <-daemon.cC
			if context == nil {
				t.Fatalf("Object taken from channel is nil")
			}
			if context.Action != ConnectionAdd {
				t.Fatal("should be adding a new connection")
			}

			if !reflect.DeepEqual(context.Connection, connection) {
				t.Fatal("payload is incorrect")
			}
			context.Result <- connection
		}
	}()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusOK {
		t.Fatalf("Expected %v:\n\tReceived: %v:\n\t%v", "200", response.Code, response.Body)
	}

	if !bytes.Equal(data, response.Body.Bytes()) {
		t.Fatalf("body is not correct")
	}

	contentHeader := response.HeaderMap["Content-Type"]
	if contentHeader[0] != "application/json; charset=utf-8" {
		t.Fatal("headers not correctly set")
	}

	locationHeader := response.HeaderMap["Content-Location"]
	fmt.Println(locationHeader[0])
	expected := "/v0.1/connections/abc123"
	if locationHeader[0] != expected {
		t.Fatal("header not correctly set")
	}
}

func TestCreateConnectionNoNetwork(t *testing.T) {
	daemon := NewDaemon()
	connection := &Connection{
		ContainerID:   "abc123",
		ContainerName: "test_container",
		ContainerPID:  "1234",
		Network:       "",
	}
	expected := &Connection{
		ContainerID:   "abc123",
		ContainerName: "test_container",
		ContainerPID:  "1234",
		Network:       "default",
	}

	data, _ := json.Marshal(connection)
	request, _ := http.NewRequest("POST", "/v0.1/connections", bytes.NewReader(data))
	response := httptest.NewRecorder()

	go func() {
		for {
			context := <-daemon.cC
			if context == nil {
				t.Fatalf("Object taken from channel is nil")
			}
			if context.Action != ConnectionAdd {
				t.Fatal("should be adding a new connection")
			}

			if !reflect.DeepEqual(context.Connection, expected) {
				t.Fatal("payload is incorrect")
			}
			context.Result <- expected
		}
	}()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusOK {
		t.Fatalf("Expected %v:\n\tReceived: %v:\n\t%v", "200", response.Code, response.Body)
	}

	expectedBody, _ := json.Marshal(expected)
	if !bytes.Equal(expectedBody, response.Body.Bytes()) {
		t.Fatalf("body is not correct")
	}

	contentHeader := response.HeaderMap["Content-Type"]
	if contentHeader[0] != "application/json; charset=utf-8" {
		t.Fatal("headers not correctly set")
	}

	locationHeader := response.HeaderMap["Content-Location"]
	fmt.Println(locationHeader[0])
	expectedHeader := "/v0.1/connections/abc123"
	if locationHeader[0] != expectedHeader {
		t.Fatal("header not correctly set")
	}
}

func TestCreateConnectionNoBody(t *testing.T) {
	daemon := NewDaemon()
	request, _ := http.NewRequest("POST", "/v0.1/connections", nil)
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusBadRequest {
		t.Fatalf("Expected %v:\n\tReceived: %v", "400", response.Code)
	}
}

func TestCreateConnectionBadBody(t *testing.T) {
	daemon := NewDaemon()
	request, _ := http.NewRequest("POST", "/v0.1/connections", bytes.NewReader([]byte{1, 2, 3, 4}))
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusInternalServerError {
		t.Fatalf("Expected %v:\n\tReceived: %v", "500", response.Code)
	}
}

func TestGetConnectionNonExistent(t *testing.T) {
	daemon := NewDaemon()
	request, _ := http.NewRequest("GET", "/v0.1/connections/abc123", nil)
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusNotFound {
		t.Fatalf("Expected %v:\n\tReceived: %v", "404", response.Code)
	}
}

func TestDeleteConnectionNonExistent(t *testing.T) {
	daemon := NewDaemon()
	request, _ := http.NewRequest("DELETE", "/v0.1/connections/abc123", nil)
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusNotFound {
		t.Fatalf("Expected %v:\n\tReceived: %v", "404", response.Code)
	}
}

func TestDeleteConnection(t *testing.T) {
	daemon := NewDaemon()
	connection := &Connection{
		ContainerID:   "abc123",
		ContainerName: "test_container",
		ContainerPID:  "1234",
		Network:       "default",
	}
	daemon.Connections["abc123"] = connection
	request, _ := http.NewRequest("DELETE", "/v0.1/connections/abc123", nil)
	response := httptest.NewRecorder()

	go func() {
		for {
			context := <-daemon.cC
			if context == nil {
				t.Fatalf("Object taken from channel is nil")
			}
			if context.Action != ConnectionDelete {
				t.Fatal("should be adding a new connection")
			}

			if !reflect.DeepEqual(context.Connection, connection) {
				t.Fatal("payload is incorrect")
			}
			context.Result <- connection
		}
	}()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusOK {
		t.Fatalf("Expected %v:\n\tReceived: %v", "200", response.Code)
	}

}

func TestGetNetworksApi(t *testing.T) {
	t.Skip("unable to mock network store")
	daemon := NewDaemon()
	request, _ := http.NewRequest("GET", "/v0.1/networks", nil)
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusOK {
		t.Fatalf("Expected %v:\n\tReceived: %v", "200", response.Code)
	}
}

func TestGetNetworkApi(t *testing.T) {
	t.Skip("unable to mock network store")
	daemon := NewDaemon()
	/* ToDo: How do we inject this network?
	network := &Network{
		ID:      "foo",
		Subnet:  "10.10.10.0/24",
		Gateway: "10.10.10.1",
		Vlan:    uint(1),
	}
	*/

	request, _ := http.NewRequest("GET", "/v0.1/networks/foo", nil)
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusOK {
		t.Fatalf("Expected %v:\n\tReceived: %v", "200", response.Code)
	}
}

func TestSetNetworksApi(t *testing.T) {
	t.Skip("unable to mock network store")
	daemon := NewDaemon()
	network := &Network{
		ID:      "foo",
		Subnet:  "10.10.10.0/24",
		Gateway: "10.10.10.1",
		Vlan:    uint(1),
	}
	data, _ := json.Marshal(network)

	request, _ := http.NewRequest("POST", "/v0.1/networks", bytes.NewReader(data))
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusOK {
		t.Fatalf("Expected %v:\n\tReceived: %v", "200", response.Code)
	}
}

func TestDeleteNetworksApi(t *testing.T) {
	t.Skip("unable to mock network store")
	daemon := NewDaemon()
	/* ToDo: How do we inject this network?
	network := &Network{
		ID:      "foo",
		Subnet:  "10.10.10.0/24",
		Gateway: "10.10.10.1",
		Vlan:    uint(1),
	}
	*/

	request, _ := http.NewRequest("DELETE", "/v0.1/networks", nil)
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusOK {
		t.Fatalf("Expected %v:\n\tReceived: %v", "200", response.Code)
	}
}

func TestGetNetworkNonExistentApi(t *testing.T) {
	t.Skip("unable to mock network store")
	daemon := NewDaemon()
	request, _ := http.NewRequest("GET", "/v0.1/networks/abc123", nil)
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusNotFound {
		t.Fatalf("Expected %v:\n\tReceived: %v", "404", response.Code)
	}
}

func TestDeleteNetworkNonExistentApi(t *testing.T) {
	t.Skip("unable to mock network store")
	daemon := NewDaemon()
	request, _ := http.NewRequest("DELETE", "/v0.1/connections/abc123", nil)
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)
	if response.Code != http.StatusNotFound {
		t.Fatalf("Expected %v:\n\tReceived: %v", "404", response.Code)
	}
}

func TestClusterJoin(t *testing.T) {
	daemon := NewDaemon()
	request, _ := http.NewRequest("POST", "/v0.1/cluster/join?address=1.1.1.1", nil)
	response := httptest.NewRecorder()

	go createRouter(daemon).ServeHTTP(response, request)
	foo := <-daemon.bindChan
	if foo == nil {
		t.Fatal("object from bindChan is nil")
	}

	if response.Code != http.StatusOK {
		t.Fatalf("Expected %v:\n\tReceived: %v", "200", response.Code)
	}
}

func TestClusterJoiniBadIp(t *testing.T) {
	daemon := NewDaemon()
	request, _ := http.NewRequest("POST", "/v0.1/cluster/join?address=bar", nil)
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusInternalServerError {
		t.Fatalf("Expected %v:\n\tReceived: %v", "500", response.Code)
	}
}

func TestClusterJoinNoParams(t *testing.T) {
	daemon := NewDaemon()
	request, _ := http.NewRequest("POST", "/v0.1/cluster/join", nil)
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusBadRequest {
		t.Fatal("request should fail")
	}
}

func TestClusterJoinBadParams(t *testing.T) {
	daemon := NewDaemon()
	request, _ := http.NewRequest("POST", "/v0.1/cluster/join?foo!@£%£", nil)
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusBadRequest {
		t.Fatal("request should fail")
	}
}

func TestClusterJoinBadParams2(t *testing.T) {
	daemon := NewDaemon()
	request, _ := http.NewRequest("POST", "/v0.1/cluster/join?foo=bar", nil)
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusBadRequest {
		t.Fatal("request should fail")
	}
}

func TestClusterLeave(t *testing.T) {
	t.Skip("Not implemented")
}

func TestClusterBind(t *testing.T) {
	daemon := NewDaemon()
	request, _ := http.NewRequest("POST", "/v0.1/cluster/bind?iface=eth0", nil)
	response := httptest.NewRecorder()

	go createRouter(daemon).ServeHTTP(response, request)
	foo := <-daemon.bindChan
	if foo == nil {
		t.Fatal("object from bindChan is nil")
	}

	if response.Code != http.StatusOK {
		t.Fatalf("Expected %v:\n\tReceived: %v", "200", response.Code)
	}
}

func TestClusterBindBadIface(t *testing.T) {
	daemon := NewDaemon()
	request, _ := http.NewRequest("POST", "/v0.1/cluster/bind?iface=foo123", nil)
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusInternalServerError {
		t.Fatalf("Expected %v:\n\tReceived: %v", "500", response.Code)
	}
}

func TestClusterBindNoParams(t *testing.T) {
	daemon := NewDaemon()
	request, _ := http.NewRequest("POST", "/v0.1/cluster/bind", nil)
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusBadRequest {
		t.Fatal("request should fail")
	}
}

func TestClusterBindBadParams(t *testing.T) {
	daemon := NewDaemon()
	request, _ := http.NewRequest("POST", "/v0.1/cluster/bind?foo!@£%£", nil)
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusBadRequest {
		t.Fatal("request should fail")
	}
}

func TestClusterBindBadParams2(t *testing.T) {
	daemon := NewDaemon()
	request, _ := http.NewRequest("POST", "/v0.1/cluster/bind?foo=bar", nil)
	response := httptest.NewRecorder()

	createRouter(daemon).ServeHTTP(response, request)

	if response.Code != http.StatusBadRequest {
		t.Fatal("request should fail")
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/hcl/json/parse_test.go<|end_filename|>
package json

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

func TestParse(t *testing.T) {
	cases := []struct {
		Name string
		Err  bool
	}{
		{
			"basic.json",
			false,
		},
		{
			"object.json",
			false,
		},
		{
			"array.json",
			false,
		},
		{
			"types.json",
			false,
		},
	}

	for _, tc := range cases {
		d, err := ioutil.ReadFile(filepath.Join(fixtureDir, tc.Name))
		if err != nil {
			t.Fatalf("err: %s", err)
		}

		_, err = Parse(string(d))
		if (err != nil) != tc.Err {
			t.Fatalf("Input: %s\n\nError: %s", tc.Name, err)
		}
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/socketplane/go-fastping/fastping_test.go<|end_filename|>
package fastping

import (
	"net"
	"sync"
	"testing"
	"time"
)

type addHostTest struct {
	host   string
	addr   *net.IPAddr
	expect bool
}

var addHostTests = []addHostTest{
	{host: "127.0.0.1", addr: &net.IPAddr{IP: net.IPv4(127, 0, 0, 1)}, expect: true},
	{host: "localhost", addr: &net.IPAddr{IP: net.IPv4(127, 0, 0, 1)}, expect: false},
}

func TestAddIP(t *testing.T) {
	p := NewPinger()

	for _, tt := range addHostTests {
		if ok := p.AddIP(tt.host); ok != nil {
			if tt.expect != false {
				t.Errorf("AddIP failed: got %v, expected %v", ok, tt.expect)
			}
		}
	}
	for _, tt := range addHostTests {
		if tt.expect {
			if !p.addrs[tt.host].IP.Equal(tt.addr.IP) {
				t.Errorf("AddIP didn't save IPAddr: %v", tt.host)
			}
		}
	}
}

func TestRun(t *testing.T) {
	p := NewPinger()

	if err := p.AddIP("127.0.0.1"); err != nil {
		t.Fatalf("AddIP failed: %v", err)
	}

	if err := p.AddIP("127.0.0.100"); err != nil {
		t.Fatalf("AddIP failed: %v", err)
	}

	if err := p.AddIP("::1"); err != nil {
		t.Fatalf("AddIP failed: %v", err)
	}

	found1, found100, foundv6 := false, false, false
	called, idle := false, false
	p.OnRecv = func(ip *net.IPAddr, d time.Duration) {
		called = true
		if ip.String() == "127.0.0.1" {
			found1 = true
		} else if ip.String() == "127.0.0.100" {
			found100 = true
		} else if ip.String() == "::1" {
			foundv6 = true
		}
	}

	p.OnIdle = func() {
		idle = true
	}

	err := p.Run()
	if err != nil {
		t.Fatalf("Pinger returns error: %v", err)
	}
	if !called {
		t.Fatalf("Pinger didn't get any responses")
	}
	if !idle {
		t.Fatalf("Pinger didn't call OnIdle function")
	}
	if !found1 {
		t.Fatalf("Pinger `127.0.0.1` didn't respond")
	}
	if found100 {
		t.Fatalf("Pinger `127.0.0.100` responded")
	}
	if !foundv6 {
		t.Fatalf("Pinger `::1` didn't responded")
	}
}

func TestMultiRun(t *testing.T) {
	p1 := NewPinger()
	p2 := NewPinger()

	if err := p1.AddIP("127.0.0.1"); err != nil {
		t.Fatalf("AddIP 1 failed: %v", err)
	}

	if err := p2.AddIP("127.0.0.1"); err != nil {
		t.Fatalf("AddIP 2 failed: %v", err)
	}

	var mu sync.Mutex
	res1 := 0
	p1.OnRecv = func(*net.IPAddr, time.Duration) {
		mu.Lock()
		res1++
		mu.Unlock()
	}

	res2 := 0
	p2.OnRecv = func(*net.IPAddr, time.Duration) {
		mu.Lock()
		res2++
		mu.Unlock()
	}

	p1.MaxRTT, p2.MaxRTT = time.Millisecond*100, time.Millisecond*100

	if err := p1.Run(); err != nil {
		t.Fatalf("Pinger 1 returns error: %v", err)
	}
	if res1 == 0 {
		t.Fatalf("Pinger 1 didn't get any responses")
	}
	if res2 > 0 {
		t.Fatalf("Pinger 2 got response")
	}

	res1, res2 = 0, 0
	if err := p2.Run(); err != nil {
		t.Fatalf("Pinger 2 returns error: %v", err)
	}
	if res1 > 0 {
		t.Fatalf("Pinger 1 got response")
	}
	if res2 == 0 {
		t.Fatalf("Pinger 2 didn't get any responses")
	}

	res1, res2 = 0, 0
	errch1, errch2 := make(chan error), make(chan error)
	go func(ch chan error) {
		err := p1.Run()
		if err != nil {
			ch <- err
		}
	}(errch1)
	go func(ch chan error) {
		err := p2.Run()
		if err != nil {
			ch <- err
		}
	}(errch2)
	ticker := time.NewTicker(time.Millisecond * 200)
	select {
	case err := <-errch1:
		t.Fatalf("Pinger 1 returns error: %v", err)
	case err := <-errch2:
		t.Fatalf("Pinger 2 returns error: %v", err)
	case <-ticker.C:
		break
	}
	mu.Lock()
	defer mu.Unlock()
	if res1 != 1 {
		t.Fatalf("Pinger 1 didn't get correct response")
	}
	if res2 != 1 {
		t.Fatalf("Pinger 2 didn't get correct response")
	}
}

func TestRunLoop(t *testing.T) {
	p := NewPinger()

	if err := p.AddIP("127.0.0.1"); err != nil {
		t.Fatalf("AddIP failed: %v", err)
	}
	p.MaxRTT = time.Millisecond * 100

	recvCount, idleCount := 0, 0
	p.OnRecv = func(*net.IPAddr, time.Duration) {
		recvCount++
	}

	p.OnIdle = func() {
		idleCount++
	}

	var err error
	p.RunLoop()
	ticker := time.NewTicker(time.Millisecond * 250)
	select {
	case <-p.Done():
		if err = p.Err(); err != nil {
			t.Fatalf("Pinger returns error %v", err)
		}
	case <-ticker.C:
		break
	}
	ticker.Stop()
	p.Stop()

	if recvCount < 2 {
		t.Fatalf("Pinger receive count less than 2")
	}
	if idleCount < 2 {
		t.Fatalf("Pinger idle count less than 2")
	}
}

func TestTimeToBytes(t *testing.T) {
	// 2009-11-10 23:00:00 +0000 UTC = 1257894000000000000
	expect := []byte{0x11, 0x74, 0xef, 0xed, 0xab, 0x18, 0x60, 0x00}
	tm, err := time.Parse(time.RFC3339, "2009-11-10T23:00:00Z")
	if err != nil {
		t.Errorf("time.Parse failed: %v", err)
	}
	b := timeToBytes(tm)
	for i := 0; i < 8; i++ {
		if b[i] != expect[i] {
			t.Errorf("timeToBytes failed: got %v, expected: %v", b, expect)
			break
		}
	}
}

func TestBytesToTime(t *testing.T) {
	// 2009-11-10 23:00:00 +0000 UTC = 1257894000000000000
	b := []byte{0x11, 0x74, 0xef, 0xed, 0xab, 0x18, 0x60, 0x00}
	expect, err := time.Parse(time.RFC3339, "2009-11-10T23:00:00Z")
	if err != nil {
		t.Errorf("time.Parse failed: %v", err)
	}
	tm := bytesToTime(b)
	if !tm.Equal(expect) {
		t.Errorf("bytesToTime failed: got %v, expected: %v", tm.UTC(), expect.UTC())
	}
}

func TestTimeToBytesToTime(t *testing.T) {
	tm, err := time.Parse(time.RFC3339, "2009-11-10T23:00:00Z")
	if err != nil {
		t.Errorf("time.Parse failed: %v", err)
	}
	b := timeToBytes(tm)
	tm2 := bytesToTime(b)
	if !tm.Equal(tm2) {
		t.Errorf("bytesToTime failed: got %v, expected: %v", tm2.UTC(), tm.UTC())
	}
}

func TestPayloadSizeDefault(t *testing.T) {
	s := timeToBytes(time.Now())
	d := append(s, byteSliceOfSize(8-TimeSliceLength)...)

	if len(d) != 8 {
		t.Errorf("Payload size incorrect: got %d, expected: %d", len(d), 8)
	}
}

func TestPayloadSizeCustom(t *testing.T) {
	s := timeToBytes(time.Now())
	d := append(s, byteSliceOfSize(64-TimeSliceLength)...)

	if len(d) != 64 {
		t.Errorf("Payload size incorrect: got %d, expected: %d", len(d), 64)
	}
}


<|start_filename|>Godeps/_workspace/src/github.com/hashicorp/hcl/json/lex_test.go<|end_filename|>
package json

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

func TestLexJson(t *testing.T) {
	cases := []struct {
		Input  string
		Output []int
	}{
		{
			"basic.json",
			[]int{
				LEFTBRACE,
				STRING, COLON, STRING,
				RIGHTBRACE,
				lexEOF,
			},
		},
		{
			"array.json",
			[]int{
				LEFTBRACE,
				STRING, COLON, LEFTBRACKET,
				NUMBER, COMMA, NUMBER, COMMA, STRING,
				RIGHTBRACKET, COMMA,
				STRING, COLON, STRING,
				RIGHTBRACE,
				lexEOF,
			},
		},
		{
			"object.json",
			[]int{
				LEFTBRACE,
				STRING, COLON, LEFTBRACE,
				STRING, COLON, LEFTBRACKET,
				NUMBER, COMMA, NUMBER,
				RIGHTBRACKET,
				RIGHTBRACE,
				RIGHTBRACE,
				lexEOF,
			},
		},
	}

	for _, tc := range cases {
		d, err := ioutil.ReadFile(filepath.Join(fixtureDir, tc.Input))
		if err != nil {
			t.Fatalf("err: %s", err)
		}

		l := &jsonLex{Input: string(d)}
		var actual []int
		for {
			token := l.Lex(new(jsonSymType))
			actual = append(actual, token)

			if token == lexEOF {
				break
			}

			if len(actual) > 500 {
				t.Fatalf("Input:%s\n\nExausted.", tc.Input)
			}
		}

		if !reflect.DeepEqual(actual, tc.Output) {
			t.Fatalf(
				"Input: %s\n\nBad: %#v\n\nExpected: %#v",
				tc.Input, actual, tc.Output)
		}
	}
}
