<commit_before>package replicaset

import (
	"fmt"
	"testing"
	"time"

	gc "launchpad.net/gocheck"

	"labix.org/v2/mgo"

	coretesting "launchpad.net/juju-core/testing"
	"launchpad.net/juju-core/utils"
)

var (
	name = "juju"
	root *coretesting.MgoInstance
)

func TestPackage(t *testing.T) {
	gc.TestingT(t)
}

func newServer() (*coretesting.MgoInstance, error) {
	inst := &coretesting.MgoInstance{Params: []string{"--replSet", name}}

	err := inst.Start(true)
	if err != nil {
		return nil, fmt.Errorf("Error starting mongo server: %s", err.Error())
	}

	// by dialing right now, we'll wait until it's running
	strategy := utils.AttemptStrategy{Total: time.Second * 5, Delay: time.Millisecond * 100}
	attempt := strategy.Start()
	for attempt.Next() {
		var session *mgo.Session
		session, err = inst.DialDirect()
		if err != nil {
			err = fmt.Errorf("Error dialing mongo server %q: %s", inst.Addr(), err.Error())
		} else {
			session.SetMode(mgo.Monotonic, true)
			err = session.Ping()
			if err != nil {
				err = fmt.Errorf("Error pinging mongo server %q: %s", inst.Addr(), err.Error())
			}
			session.Close()
		}
		if err == nil || !attempt.HasNext() {
			break
		}
	}
	return inst, err
}

type MongoSuite struct{}

var _ = gc.Suite(&MongoSuite{})

func (s *MongoSuite) SetUpSuite(c *gc.C) {
	var err error
	// do all this stuff here, since we don't want to have to redo it for each test
	root, err = newServer()
	if err != nil {
		c.Fatalf("Got error from Start of root server: %s", err.Error())
	}
	// note, this is an actual test around Initiate, but again, I don't want to
	// have to redo it, so I just do it once.
	dialAndTestInitiate(c)
}

func dialAndTestInitiate(c *gc.C) {
	session := root.MustDialDirect()
	defer session.Close()

	err := Initiate(session, root.Addr(), name)
	c.Assert(err, gc.IsNil)

	// Ids start at 1 for us, so we can differentiate between set and unset
	expectedMembers := []Member{Member{Id: 1, Address: root.Addr()}}

	// need to set mode to strong so that we wait for the write to succeed
	// before reading and thus ensure that we're getting consistent reads.
	session.SetMode(mgo.Strong, false)

	mems, err := CurrentMembers(session)
	c.Assert(err, gc.IsNil)
	c.Assert(mems, gc.DeepEquals, expectedMembers)

	// now add some data so we get a more real-life test
	loadData(session, c)
}

func loadData(session *mgo.Session, c *gc.C) {
	type foo struct {
		Name    string
		Address string
		Count   int
	}

	for col := 0; col < 10; col++ {
		foos := make([]foo, 10000)
		for n := range foos {
			foos[n] = foo{
				Name:    fmt.Sprintf("name_%d_%d", col, n),
				Address: fmt.Sprintf("address_%d_%d", col, n),
				Count:   n * (col + 1),
			}
		}

		err := session.DB("testing").C(fmt.Sprintf("data%d", col)).Insert(foos)
		c.Assert(err, gc.IsNil)
	}
}

func (s *MongoSuite) TearDownSuite(c *gc.C) {
	root.Destroy()
}

func (s *MongoSuite) TestAddRemoveSet(c *gc.C) {
	session := root.MustDial()
	defer session.Close()

	members := make([]Member, 0, 5)

	// Add should be idempotent, so re-adding root here shouldn't result in
	// two copies of root in the replica set
	members = append(members, Member{Address: root.Addr()})

	instances := make([]*coretesting.MgoInstance, 0, 5)
	instances = append(instances, root)

	for x := 0; x < 4; x++ {
		inst, err := newServer()
		c.Assert(err, gc.IsNil)
		instances = append(instances, inst)
		defer inst.Destroy()
		defer Remove(session, inst.Addr())

		key := fmt.Sprintf("key%d", x)
		val := fmt.Sprintf("val%d", x)

		tags := map[string]string{key: val}

		members = append(members, Member{Address: inst.Addr(), Tags: tags})
	}

	err := Add(session, members...)
	c.Assert(err, gc.IsNil)

	expectedMembers := make([]Member, len(members))
	for x, m := range members {
		// Ids should start at 1 (for the root) and go up
		m.Id = x + 1
		expectedMembers[x] = m
	}

	cfg, err := CurrentConfig(session)
	c.Assert(err, gc.IsNil)
	c.Assert(cfg.Name, gc.Equals, name)

	// 2 since we already changed it once
	c.Assert(cfg.Version, gc.Equals, 2)

	mems := cfg.Members

	c.Assert(mems, gc.DeepEquals, expectedMembers)

	// Now remove the last two Members
	err = Remove(session, members[3].Address, members[4].Address)
	c.Assert(err, gc.IsNil)

	expectedMembers = expectedMembers[0:3]

	mems, err = CurrentMembers(session)
	c.Assert(err, gc.IsNil)
	c.Assert(mems, gc.DeepEquals, expectedMembers)

	// now let's mix it up and set the new members to a mix of the previous
	// plus the new arbiter
	mems = []Member{members[3], mems[2], mems[0], members[4]}

	err = Set(session, mems)
	c.Assert(err, gc.IsNil)

	deadline := time.Now().Add(time.Second * 60)

	for {
		// can dial whichever replica address here, mongo will figure it out
		session = instances[0].MustDialDirect()
		err := session.Ping()
		if err == nil || time.Now().After(deadline) {
			break
		}
	}
	c.Assert(err, gc.IsNil)

	expectedMembers = []Member{members[3], expectedMembers[2], expectedMembers[0], members[4]}

	// any new members will get an id of max(other_ids...)+1
	expectedMembers[0].Id = 4
	expectedMembers[3].Id = 5

	mems, err = CurrentMembers(session)
	c.Assert(err, gc.IsNil)
	c.Assert(mems, gc.DeepEquals, expectedMembers)
}

func (s *MongoSuite) TestIsMaster(c *gc.C) {
	session := root.MustDial()
	defer session.Close()

	expected := IsMasterResults{
		// The following fields hold information about the specific mongodb node.
		IsMaster:  true,
		Secondary: false,
		Arbiter:   false,
		Address:   root.Addr(),
		LocalTime: time.Time{},

		// The following fields hold information about the replica set.
		ReplicaSetName: name,
		Addresses:      []string{root.Addr()},
		Arbiters:       nil,
		PrimaryAddress: root.Addr(),
	}

	res, err := IsMaster(session)
	c.Assert(err, gc.IsNil)
	c.Check(closeEnough(res.LocalTime, time.Now()), gc.Equals, true)
	res.LocalTime = time.Time{}
	c.Check(*res, gc.DeepEquals, expected)
}

func (s *MongoSuite) TestCurrentStatus(c *gc.C) {
	session := root.MustDial()
	defer session.Close()

	inst1, err := newServer()
	c.Assert(err, gc.IsNil)
	defer inst1.Destroy()
	defer Remove(session, inst1.Addr())

	inst2, err := newServer()
	c.Assert(err, gc.IsNil)
	defer inst2.Destroy()
	defer Remove(session, inst2.Addr())

	err = Add(session, Member{Address: inst1.Addr()}, Member{Address: inst2.Addr()})
	c.Assert(err, gc.IsNil)

	expected := &Status{
		Name: name,
		Members: []MemberStatus{{
			Id:      1,
			Address: root.Addr(),
			Self:    true,
			ErrMsg:  "",
			Healthy: true,
			State:   PrimaryState,
		}, {
			Id:      2,
			Address: inst1.Addr(),
			Self:    false,
			ErrMsg:  "",
			Healthy: true,
			State:   SecondaryState,
		}, {
			Id:      3,
			Address: inst2.Addr(),
			Self:    false,
			ErrMsg:  "",
			Healthy: true,
			State:   SecondaryState,
		}},
	}

	strategy := utils.AttemptStrategy{Total: time.Second * 60, Delay: time.Millisecond * 100}
	attempt := strategy.Start()
	var res *Status
	for attempt.Next() {
		var err error
		res, err = CurrentStatus(session)

		if err != nil && !attempt.HasNext() {
			c.Errorf("Couldn't get status before timeout, got err: %v", err)
			return
		}

		if res.Members[0].State == PrimaryState &&
			res.Members[1].State == SecondaryState &&
			res.Members[2].State == SecondaryState {
			break
		}
		if !attempt.HasNext() {
			c.Errorf("Servers did not get into final state before timeout.  Status: %#v", res)
			return
		}
	}

	for x, _ := range res.Members {
		// non-empty uptime and ping
		c.Check(res.Members[x].Uptime, gc.Not(gc.Equals), 0)

		// ping is always going to be zero since we're on localhost
		// so we can't really test it right now

		// now overwrite Uptime so it won't throw off DeepEquals
		res.Members[x].Uptime = 0
	}
	c.Check(res, gc.DeepEquals, expected)
}

func closeEnough(expected, obtained time.Time) bool {
	t := obtained.Sub(expected)
	return (-500*time.Millisecond) < t && t < (500*time.Millisecond)
}
<commit_msg>add another attempt to try to fix a timing issue on the bot<commit_after>package replicaset

import (
	"fmt"
	"testing"
	"time"

	gc "launchpad.net/gocheck"

	"labix.org/v2/mgo"

	coretesting "launchpad.net/juju-core/testing"
	"launchpad.net/juju-core/utils"
)

var (
	name = "juju"
	root *coretesting.MgoInstance
)

func TestPackage(t *testing.T) {
	gc.TestingT(t)
}

func newServer() (*coretesting.MgoInstance, error) {
	inst := &coretesting.MgoInstance{Params: []string{"--replSet", name}}

	err := inst.Start(true)
	if err != nil {
		return nil, fmt.Errorf("Error starting mongo server: %s", err.Error())
	}

	// by dialing right now, we'll wait until it's running
	strategy := utils.AttemptStrategy{Total: time.Second * 5, Delay: time.Millisecond * 100}
	attempt := strategy.Start()
	for attempt.Next() {
		var session *mgo.Session
		session, err = inst.DialDirect()
		if err != nil {
			err = fmt.Errorf("Error dialing mongo server %q: %s", inst.Addr(), err.Error())
		} else {
			session.SetMode(mgo.Monotonic, true)
			err = session.Ping()
			if err != nil {
				err = fmt.Errorf("Error pinging mongo server %q: %s", inst.Addr(), err.Error())
			}
			session.Close()
		}
		if err == nil || !attempt.HasNext() {
			break
		}
	}
	return inst, err
}

type MongoSuite struct{}

var _ = gc.Suite(&MongoSuite{})

func (s *MongoSuite) SetUpSuite(c *gc.C) {
	var err error
	// do all this stuff here, since we don't want to have to redo it for each test
	root, err = newServer()
	if err != nil {
		c.Fatalf("Got error from Start of root server: %s", err.Error())
	}
	// note, this is an actual test around Initiate, but again, I don't want to
	// have to redo it, so I just do it once.
	dialAndTestInitiate(c)
}

func dialAndTestInitiate(c *gc.C) {
	session := root.MustDialDirect()
	defer session.Close()

	err := Initiate(session, root.Addr(), name)
	c.Assert(err, gc.IsNil)

	// Ids start at 1 for us, so we can differentiate between set and unset
	expectedMembers := []Member{Member{Id: 1, Address: root.Addr()}}

	// need to set mode to strong so that we wait for the write to succeed
	// before reading and thus ensure that we're getting consistent reads.
	session.SetMode(mgo.Strong, false)

	mems, err := CurrentMembers(session)
	c.Assert(err, gc.IsNil)
	c.Assert(mems, gc.DeepEquals, expectedMembers)

	// now add some data so we get a more real-life test
	loadData(session, c)
}

func loadData(session *mgo.Session, c *gc.C) {
	type foo struct {
		Name    string
		Address string
		Count   int
	}

	for col := 0; col < 10; col++ {
		foos := make([]foo, 10000)
		for n := range foos {
			foos[n] = foo{
				Name:    fmt.Sprintf("name_%d_%d", col, n),
				Address: fmt.Sprintf("address_%d_%d", col, n),
				Count:   n * (col + 1),
			}
		}

		err := session.DB("testing").C(fmt.Sprintf("data%d", col)).Insert(foos)
		c.Assert(err, gc.IsNil)
	}
}

func (s *MongoSuite) TearDownSuite(c *gc.C) {
	root.Destroy()
}

func (s *MongoSuite) TestAddRemoveSet(c *gc.C) {
	session := root.MustDial()
	defer session.Close()

	members := make([]Member, 0, 5)

	// Add should be idempotent, so re-adding root here shouldn't result in
	// two copies of root in the replica set
	members = append(members, Member{Address: root.Addr()})

	instances := make([]*coretesting.MgoInstance, 0, 5)
	instances = append(instances, root)

	for x := 0; x < 4; x++ {
		inst, err := newServer()
		c.Assert(err, gc.IsNil)
		instances = append(instances, inst)
		defer inst.Destroy()
		defer Remove(session, inst.Addr())

		key := fmt.Sprintf("key%d", x)
		val := fmt.Sprintf("val%d", x)

		tags := map[string]string{key: val}

		members = append(members, Member{Address: inst.Addr(), Tags: tags})
	}

	err := Add(session, members...)
	c.Assert(err, gc.IsNil)

	expectedMembers := make([]Member, len(members))
	for x, m := range members {
		// Ids should start at 1 (for the root) and go up
		m.Id = x + 1
		expectedMembers[x] = m
	}

	cfg, err := CurrentConfig(session)
	c.Assert(err, gc.IsNil)
	c.Assert(cfg.Name, gc.Equals, name)

	// 2 since we already changed it once
	c.Assert(cfg.Version, gc.Equals, 2)

	mems := cfg.Members

	c.Assert(mems, gc.DeepEquals, expectedMembers)

	// Now remove the last two Members
	err = Remove(session, members[3].Address, members[4].Address)
	c.Assert(err, gc.IsNil)

	expectedMembers = expectedMembers[0:3]

	mems, err = CurrentMembers(session)
	c.Assert(err, gc.IsNil)
	c.Assert(mems, gc.DeepEquals, expectedMembers)

	// now let's mix it up and set the new members to a mix of the previous
	// plus the new arbiter
	mems = []Member{members[3], mems[2], mems[0], members[4]}

	err = Set(session, mems)
	c.Assert(err, gc.IsNil)

	strategy := utils.AttemptStrategy{Total: time.Second * 30, Delay: time.Millisecond * 100}
	attempt := strategy.Start()
	for attempt.Next() {
		// can dial whichever replica address here, mongo will figure it out
		session = instances[0].MustDialDirect()
		err := session.Ping()
		if err == nil {
			break
		}
	}
	c.Assert(err, gc.IsNil)

	expectedMembers = []Member{members[3], expectedMembers[2], expectedMembers[0], members[4]}

	// any new members will get an id of max(other_ids...)+1
	expectedMembers[0].Id = 4
	expectedMembers[3].Id = 5

	mems, err = CurrentMembers(session)
	c.Assert(err, gc.IsNil)
	c.Assert(mems, gc.DeepEquals, expectedMembers)
}

func (s *MongoSuite) TestIsMaster(c *gc.C) {
	session := root.MustDial()
	defer session.Close()

	expected := IsMasterResults{
		// The following fields hold information about the specific mongodb node.
		IsMaster:  true,
		Secondary: false,
		Arbiter:   false,
		Address:   root.Addr(),
		LocalTime: time.Time{},

		// The following fields hold information about the replica set.
		ReplicaSetName: name,
		Addresses:      []string{root.Addr()},
		Arbiters:       nil,
		PrimaryAddress: root.Addr(),
	}

	res, err := IsMaster(session)
	c.Assert(err, gc.IsNil)
	c.Check(closeEnough(res.LocalTime, time.Now()), gc.Equals, true)
	res.LocalTime = time.Time{}
	c.Check(*res, gc.DeepEquals, expected)
}

func (s *MongoSuite) TestCurrentStatus(c *gc.C) {
	session := root.MustDial()
	defer session.Close()

	inst1, err := newServer()
	c.Assert(err, gc.IsNil)
	defer inst1.Destroy()
	defer Remove(session, inst1.Addr())

	inst2, err := newServer()
	c.Assert(err, gc.IsNil)
	defer inst2.Destroy()
	defer Remove(session, inst2.Addr())

	strategy := utils.AttemptStrategy{Total: time.Second * 30, Delay: time.Millisecond * 100}
	attempt := strategy.Start()
	for attempt.Next() {
		err = Add(session, Member{Address: inst1.Addr()}, Member{Address: inst2.Addr()})
		if err == nil {
			break
		}
	}
	c.Assert(err, gc.IsNil)

	expected := &Status{
		Name: name,
		Members: []MemberStatus{{
			Id:      1,
			Address: root.Addr(),
			Self:    true,
			ErrMsg:  "",
			Healthy: true,
			State:   PrimaryState,
		}, {
			Id:      2,
			Address: inst1.Addr(),
			Self:    false,
			ErrMsg:  "",
			Healthy: true,
			State:   SecondaryState,
		}, {
			Id:      3,
			Address: inst2.Addr(),
			Self:    false,
			ErrMsg:  "",
			Healthy: true,
			State:   SecondaryState,
		}},
	}

	strategy = utils.AttemptStrategy{Total: time.Second * 60, Delay: time.Millisecond * 100}
	attempt = strategy.Start()
	var res *Status
	for attempt.Next() {
		var err error
		res, err = CurrentStatus(session)

		if err != nil && !attempt.HasNext() {
			c.Errorf("Couldn't get status before timeout, got err: %v", err)
			return
		}

		if res.Members[0].State == PrimaryState &&
			res.Members[1].State == SecondaryState &&
			res.Members[2].State == SecondaryState {
			break
		}
		if !attempt.HasNext() {
			c.Errorf("Servers did not get into final state before timeout.  Status: %#v", res)
			return
		}
	}

	for x, _ := range res.Members {
		// non-empty uptime and ping
		c.Check(res.Members[x].Uptime, gc.Not(gc.Equals), 0)

		// ping is always going to be zero since we're on localhost
		// so we can't really test it right now

		// now overwrite Uptime so it won't throw off DeepEquals
		res.Members[x].Uptime = 0
	}
	c.Check(res, gc.DeepEquals, expected)
}

func closeEnough(expected, obtained time.Time) bool {
	t := obtained.Sub(expected)
	return (-500*time.Millisecond) < t && t < (500*time.Millisecond)
}
<|endoftext|>


<commit_before>package besticon

import (
	"encoding/json"
	"errors"
	"fmt"

	"github.com/golang/groupcache"
)

var iconCache *groupcache.Group

type result struct {
	Icons []Icon
	Error string
}

func resultFromCache(siteURL string) ([]Icon, error) {
	if iconCache == nil {
		return FetchIcons(siteURL, false)
	}

	var data []byte
	err := iconCache.Get(nil, siteURL, groupcache.AllocatingByteSliceSink(&data))
	if err != nil {
		logger.Println("ERR:", err)
		return FetchIcons(siteURL, false)
	}

	res := &result{}
	err = json.Unmarshal(data, res)
	if err != nil {
		panic(err)
	}

	if res.Error != "" {
		return res.Icons, errors.New(res.Error)
	}
	return res.Icons, nil
}

func generatorFunc(ctx groupcache.Context, siteURL string, sink groupcache.Sink) error {
	icons, err := FetchIcons(siteURL, false)

	res := result{Icons: icons}
	if err != nil {
		res.Error = err.Error()
	}
	bytes, err := json.Marshal(res)
	if err != nil {
		panic(err)
	}
	sink.SetBytes(bytes)

	return nil
}

func cacheEnabled() bool {
	return iconCache != nil
}

// SetCacheMaxSize enables icon caching if sizeInMB > 0.
func SetCacheMaxSize(sizeInMB int64) {
	if sizeInMB > 0 {
		iconCache = groupcache.NewGroup("icons", sizeInMB<<20, groupcache.GetterFunc(generatorFunc))
	} else {
		iconCache = nil
	}
}

// GetCacheStats returns cache statistics.
func GetCacheStats() groupcache.CacheStats {
	return iconCache.CacheStats(groupcache.MainCache)
}
<commit_msg>Let cached items expire after a day<commit_after>package besticon

import (
	"encoding/json"
	"errors"
	"fmt"
	"time"

	"github.com/golang/groupcache"
)

var iconCache *groupcache.Group

type result struct {
	Icons []Icon
	Error string
}

func resultFromCache(siteURL string) ([]Icon, error) {
	if iconCache == nil {
		return FetchIcons(siteURL, false)
	}

	// Let results expire after a day
	now := time.Now()
	key := fmt.Sprintf("%d-%02d-%02d-%s", now.Year(), now.Month(), now.Day(), siteURL)
	var data []byte
	err := iconCache.Get(siteURL, key, groupcache.AllocatingByteSliceSink(&data))
	if err != nil {
		logger.Println("ERR:", err)
		return FetchIcons(siteURL, false)
	}

	res := &result{}
	err = json.Unmarshal(data, res)
	if err != nil {
		panic(err)
	}

	if res.Error != "" {
		return res.Icons, errors.New(res.Error)
	}
	return res.Icons, nil
}

func generatorFunc(ctx groupcache.Context, key string, sink groupcache.Sink) error {
	siteURL := ctx.(string)
	icons, err := FetchIcons(siteURL, false)

	res := result{Icons: icons}
	if err != nil {
		res.Error = err.Error()
	}
	bytes, err := json.Marshal(res)
	if err != nil {
		panic(err)
	}
	sink.SetBytes(bytes)

	return nil
}

func cacheEnabled() bool {
	return iconCache != nil
}

// SetCacheMaxSize enables icon caching if sizeInMB > 0.
func SetCacheMaxSize(sizeInMB int64) {
	if sizeInMB > 0 {
		iconCache = groupcache.NewGroup("icons", sizeInMB<<20, groupcache.GetterFunc(generatorFunc))
	} else {
		iconCache = nil
	}
}

// GetCacheStats returns cache statistics.
func GetCacheStats() groupcache.CacheStats {
	return iconCache.CacheStats(groupcache.MainCache)
}
<|endoftext|>


<commit_before>package env

import (
	"encoding/json"
	. "github.com/tevid/gohamcrest"
	"github.com/zouyx/agollo/v2/env/config"
	"github.com/zouyx/agollo/v2/env/config/json_config"
	"github.com/zouyx/agollo/v2/utils"
	"os"
	"sync"

	"testing"
	"time"
)

const servicesConfigResponseStr = `[{
"appName": "APOLLO-CONFIGSERVICE",
"instanceId": "10.15.128.102:apollo-configservice:8080",
"homepageUrl": "http://10.15.128.102:8080/"
},
{
"appName": "APOLLO-CONFIGSERVICE",
"instanceId": "10.15.88.125:apollo-configservice:8080",
"homepageUrl": "http://10.15.88.125:8080/"
},
{
"appName": "APOLLO-CONFIGSERVICE",
"instanceId": "10.14.0.11:apollo-configservice:8080",
"homepageUrl": "http://10.14.0.11:8080/"
},
{
"appName": "APOLLO-CONFIGSERVICE",
"instanceId": "10.14.0.193:apollo-configservice:8080",
"homepageUrl": "http://10.14.0.193:8080/"
},
{
"appName": "APOLLO-CONFIGSERVICE",
"instanceId": "10.15.128.101:apollo-configservice:8080",
"homepageUrl": "http://10.15.128.101:8080/"
},
{
"appName": "APOLLO-CONFIGSERVICE",
"instanceId": "10.14.0.192:apollo-configservice:8080",
"homepageUrl": "http://10.14.0.192:8080/"
},
{
"appName": "APOLLO-CONFIGSERVICE",
"instanceId": "10.15.88.124:apollo-configservice:8080",
"homepageUrl": "http://10.15.88.124:8080/"
},
{
"appName": "APOLLO-CONFIGSERVICE",
"instanceId": "10.15.128.103:apollo-configservice:8080",
"homepageUrl": "http://10.15.128.103:8080/"
},
{
"appName": "APOLLO-CONFIGSERVICE",
"instanceId": "localhost:apollo-configservice:8080",
"homepageUrl": "http://10.14.0.12:8080/"
},
{
"appName": "APOLLO-CONFIGSERVICE",
"instanceId": "10.14.0.194:apollo-configservice:8080",
"homepageUrl": "http://10.14.0.194:8080/"
}
]`

var (
	defaultNamespace = "application"
	jsonConfigFile   = &json_config.JSONConfigFile{}
)

func TestInit(t *testing.T) {
	config := GetAppConfig(nil)
	time.Sleep(1 * time.Second)

	Assert(t, config, NotNilVal())
	Assert(t, "test", Equal(config.AppId))
	Assert(t, "dev", Equal(config.Cluster))
	Assert(t, "application,abc1", Equal(config.NamespaceName))
	Assert(t, "localhost:8888", Equal(config.Ip))

	//TODO: 需要确认是否放在这里
	//defaultApolloConfig := GetCurrentApolloConfig()[defaultNamespace]
	//Assert(t, defaultApolloConfig, NotNilVal())
	//Assert(t, "test", Equal(defaultApolloConfig.AppId))
	//Assert(t, "dev", Equal(defaultApolloConfig.Cluster))
	//Assert(t, "application", Equal(defaultApolloConfig.NamespaceName))
}

func TestGetServicesConfigUrl(t *testing.T) {
	appConfig := getTestAppConfig()
	url := GetServicesConfigUrl(appConfig)
	ip := utils.GetInternal()
	Assert(t, "http://localhost:8888/services/config?appId=test&ip="+ip, Equal(url))
}

func getTestAppConfig() *config.AppConfig {
	jsonStr := `{
    "appId": "test",
    "cluster": "dev",
    "namespaceName": "application",
    "ip": "localhost:8888",
    "releaseKey": "1"
	}`
	c, _ := Unmarshal([]byte(jsonStr))

	return c.(*config.AppConfig)
}

func TestLoadEnvConfig(t *testing.T) {
	envConfigFile := "env_test.properties"
	c, _ := jsonConfigFile.Load(APP_CONFIG_FILE_NAME, Unmarshal)
	config := c.(*config.AppConfig)
	config.Ip = "123"
	config.AppId = "1111"
	config.NamespaceName = "nsabbda"
	file, err := os.Create(envConfigFile)
	if err != nil {
		t.Error(err)
		t.FailNow()
	}
	defer file.Close()
	err = json.NewEncoder(file).Encode(config)
	if err != nil {
		t.Error(err)
		t.FailNow()
	}

	err = os.Setenv(ENV_CONFIG_FILE_PATH, envConfigFile)
	envConfig, envConfigErr := getLoadAppConfig(nil)
	t.Log(config)

	Assert(t, envConfigErr, NilVal())
	Assert(t, envConfig, NotNilVal())
	Assert(t, envConfig.AppId, Equal(config.AppId))
	Assert(t, envConfig.Cluster, Equal(config.Cluster))
	Assert(t, envConfig.NamespaceName, Equal(config.NamespaceName))
	Assert(t, envConfig.Ip, Equal(config.Ip))

	os.Remove(envConfigFile)
}

func TestGetPlainAppConfig(t *testing.T) {
	plainAppConfig := GetPlainAppConfig()
	Assert(t, plainAppConfig, NotNilVal())
}

func TestGetServersLen(t *testing.T) {
	servers.Store("a", "a")
	serversLen := GetServersLen()
	Assert(t, serversLen, Equal(1))
}

func TestSplitNamespaces(t *testing.T) {
	w := &sync.WaitGroup{}
	w.Add(3)
	namespaces := SplitNamespaces("a,b,c", func(namespace string) {
		w.Done()
	})

	Assert(t, len(namespaces), Equal(3))
	w.Wait()
}
func TestSyncServerIpListSuccessCallBack(t *testing.T) {
	SyncServerIpListSuccessCallBack([]byte(servicesConfigResponseStr))
	Assert(t, GetServersLen(), Equal(11))
}

func TestSetDownNode(t *testing.T) {
	SyncServerIpListSuccessCallBack([]byte(servicesConfigResponseStr))

	downNode := "10.15.128.102:8080"
	SetDownNode(downNode)

	value, ok := servers.Load("http://10.15.128.102:8080/")
	info := value.(*config.ServerInfo)
	Assert(t, ok, Equal(true))
	Assert(t, info.IsDown, Equal(true))
}
<commit_msg>add more test case<commit_after>package env

import (
	"encoding/json"
	. "github.com/tevid/gohamcrest"
	"github.com/zouyx/agollo/v2/env/config"
	"github.com/zouyx/agollo/v2/env/config/json_config"
	"github.com/zouyx/agollo/v2/utils"
	"os"
	"sync"

	"testing"
	"time"
)

const servicesConfigResponseStr = `[{
"appName": "APOLLO-CONFIGSERVICE",
"instanceId": "10.15.128.102:apollo-configservice:8080",
"homepageUrl": "http://10.15.128.102:8080/"
},
{
"appName": "APOLLO-CONFIGSERVICE",
"instanceId": "10.15.88.125:apollo-configservice:8080",
"homepageUrl": "http://10.15.88.125:8080/"
},
{
"appName": "APOLLO-CONFIGSERVICE",
"instanceId": "10.14.0.11:apollo-configservice:8080",
"homepageUrl": "http://10.14.0.11:8080/"
},
{
"appName": "APOLLO-CONFIGSERVICE",
"instanceId": "10.14.0.193:apollo-configservice:8080",
"homepageUrl": "http://10.14.0.193:8080/"
},
{
"appName": "APOLLO-CONFIGSERVICE",
"instanceId": "10.15.128.101:apollo-configservice:8080",
"homepageUrl": "http://10.15.128.101:8080/"
},
{
"appName": "APOLLO-CONFIGSERVICE",
"instanceId": "10.14.0.192:apollo-configservice:8080",
"homepageUrl": "http://10.14.0.192:8080/"
},
{
"appName": "APOLLO-CONFIGSERVICE",
"instanceId": "10.15.88.124:apollo-configservice:8080",
"homepageUrl": "http://10.15.88.124:8080/"
},
{
"appName": "APOLLO-CONFIGSERVICE",
"instanceId": "10.15.128.103:apollo-configservice:8080",
"homepageUrl": "http://10.15.128.103:8080/"
},
{
"appName": "APOLLO-CONFIGSERVICE",
"instanceId": "localhost:apollo-configservice:8080",
"homepageUrl": "http://10.14.0.12:8080/"
},
{
"appName": "APOLLO-CONFIGSERVICE",
"instanceId": "10.14.0.194:apollo-configservice:8080",
"homepageUrl": "http://10.14.0.194:8080/"
}
]`

var (
	defaultNamespace = "application"
	jsonConfigFile   = &json_config.JSONConfigFile{}
)

func TestInit(t *testing.T) {
	config := GetAppConfig(nil)
	time.Sleep(1 * time.Second)

	Assert(t, config, NotNilVal())
	Assert(t, "test", Equal(config.AppId))
	Assert(t, "dev", Equal(config.Cluster))
	Assert(t, "application,abc1", Equal(config.NamespaceName))
	Assert(t, "localhost:8888", Equal(config.Ip))

	//TODO: 需要确认是否放在这里
	//defaultApolloConfig := GetCurrentApolloConfig()[defaultNamespace]
	//Assert(t, defaultApolloConfig, NotNilVal())
	//Assert(t, "test", Equal(defaultApolloConfig.AppId))
	//Assert(t, "dev", Equal(defaultApolloConfig.Cluster))
	//Assert(t, "application", Equal(defaultApolloConfig.NamespaceName))
}

func TestGetServicesConfigUrl(t *testing.T) {
	appConfig := getTestAppConfig()
	url := GetServicesConfigUrl(appConfig)
	ip := utils.GetInternal()
	Assert(t, "http://localhost:8888/services/config?appId=test&ip="+ip, Equal(url))
}

func getTestAppConfig() *config.AppConfig {
	jsonStr := `{
    "appId": "test",
    "cluster": "dev",
    "namespaceName": "application",
    "ip": "localhost:8888",
    "releaseKey": "1"
	}`
	c, _ := Unmarshal([]byte(jsonStr))

	return c.(*config.AppConfig)
}

func TestLoadEnvConfig(t *testing.T) {
	envConfigFile := "env_test.properties"
	c, _ := jsonConfigFile.Load(APP_CONFIG_FILE_NAME, Unmarshal)
	config := c.(*config.AppConfig)
	config.Ip = "123"
	config.AppId = "1111"
	config.NamespaceName = "nsabbda"
	file, err := os.Create(envConfigFile)
	if err != nil {
		t.Error(err)
		t.FailNow()
	}
	defer file.Close()
	err = json.NewEncoder(file).Encode(config)
	if err != nil {
		t.Error(err)
		t.FailNow()
	}

	err = os.Setenv(ENV_CONFIG_FILE_PATH, envConfigFile)
	envConfig, envConfigErr := getLoadAppConfig(nil)
	t.Log(config)

	Assert(t, envConfigErr, NilVal())
	Assert(t, envConfig, NotNilVal())
	Assert(t, envConfig.AppId, Equal(config.AppId))
	Assert(t, envConfig.Cluster, Equal(config.Cluster))
	Assert(t, envConfig.NamespaceName, Equal(config.NamespaceName))
	Assert(t, envConfig.Ip, Equal(config.Ip))

	os.Remove(envConfigFile)
}

func TestGetPlainAppConfig(t *testing.T) {
	plainAppConfig := GetPlainAppConfig()
	Assert(t, plainAppConfig, NotNilVal())
}

func TestGetServersLen(t *testing.T) {
	servers.Store("a", "a")
	serversLen := GetServersLen()
	Assert(t, serversLen, Equal(1))
}

func TestSplitNamespaces(t *testing.T) {
	w := &sync.WaitGroup{}
	w.Add(3)
	namespaces := SplitNamespaces("a,b,c", func(namespace string) {
		w.Done()
	})

	Assert(t, len(namespaces), Equal(3))
	w.Wait()
}
func TestSyncServerIpListSuccessCallBack(t *testing.T) {
	SyncServerIpListSuccessCallBack([]byte(servicesConfigResponseStr))
	Assert(t, GetServersLen(), Equal(11))
}

func TestSetDownNode(t *testing.T) {
	t.SkipNow()
	SyncServerIpListSuccessCallBack([]byte(servicesConfigResponseStr))

	downNode := "10.15.128.102:8080"
	SetDownNode(downNode)

	value, ok := servers.Load("http://10.15.128.102:8080/")
	info := value.(*config.ServerInfo)
	Assert(t, ok, Equal(true))
	Assert(t, info.IsDown, Equal(true))
}
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Contributor:
// - Aaron Meihm ameihm@mozilla.com

package main

import (
	"fmt"
	elastigo "github.com/mattbaird/elastigo/lib"
	"time"
)

type queryRequest struct {
	startTime time.Time
	endTime   time.Time
}

func queryUsingPlugin(p plugin, req queryRequest) (err error) {
	defer func() {
		if e := recover(); e != nil {
			err = fmt.Errorf("queryUsingPlugin() -> %v", e)
		}
	}()

	template := `{
		"size": 10000,
		"query": {
			"bool": {
				"must": [
				%v
				]
			}
		},
		"filter": {
			"range": {
				"utctimestamp": {
					"from": "%v",
					"to": "%v"
				}
			}
		}
	}`

	// Add plugins search terms to the query
	mult := false
	temp := ""
	for _, x := range p.searchTerms {
		if mult {
			temp += ","
		}
		termtemplate := `{
			"term": {
				"%v": "%v"
			}
		}`
		termbuf := fmt.Sprintf(termtemplate, x.key, x.value)
		temp += termbuf
		mult = true
	}
	querybuf := fmt.Sprintf(template, temp, req.startTime.Format(time.RFC3339), req.endTime.Format(time.RFC3339))
	conn := elastigo.NewConn()
	conn.Domain = cfg.ES.EventESHost
	res, err := conn.Search(cfg.ES.EventIndex, "", nil, querybuf)
	if err != nil {
		panic(err)
	}
	logf("plugin %v returned %v hits", p.name, res.Hits.Len())

	pluginInput, err := pluginRequestDataFromES(res)
	if err != nil {
		panic(err)
	}
	err = p.runPlugin(pluginInput)
	if err != nil {
		panic(err)
	}

	return nil
}

func handleQueryRequest(q queryRequest) {
	defer func() {
		if e := recover(); e != nil {
			logf("handleQueryRequest() -> %v", e)
		}
	}()
	logf("handling new query request")

	// Execute a query for each registered plugin
	for _, x := range pluginList {
		err := queryUsingPlugin(x, q)
		if err != nil {
			panic(err)
		}
	}
}

func queryHandler(exitCh chan bool, notifyCh chan bool) {
	for {
		select {
		case qr := <-queryRequestCh:
			handleQueryRequest(qr)
		case <-exitCh:
			notifyCh <- true
			return
		}
	}
}
<commit_msg>if no hits are returned, don't dispatch request to plugin<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Contributor:
// - Aaron Meihm ameihm@mozilla.com

package main

import (
	"fmt"
	elastigo "github.com/mattbaird/elastigo/lib"
	"time"
)

type queryRequest struct {
	startTime time.Time
	endTime   time.Time
}

func queryUsingPlugin(p plugin, req queryRequest) (err error) {
	defer func() {
		if e := recover(); e != nil {
			err = fmt.Errorf("queryUsingPlugin() -> %v", e)
		}
	}()

	template := `{
		"size": 10000,
		"query": {
			"bool": {
				"must": [
				%v
				]
			}
		},
		"filter": {
			"range": {
				"utctimestamp": {
					"from": "%v",
					"to": "%v"
				}
			}
		}
	}`

	// Add plugins search terms to the query
	mult := false
	temp := ""
	for _, x := range p.searchTerms {
		if mult {
			temp += ","
		}
		termtemplate := `{
			"term": {
				"%v": "%v"
			}
		}`
		termbuf := fmt.Sprintf(termtemplate, x.key, x.value)
		temp += termbuf
		mult = true
	}
	querybuf := fmt.Sprintf(template, temp, req.startTime.Format(time.RFC3339), req.endTime.Format(time.RFC3339))
	conn := elastigo.NewConn()
	conn.Domain = cfg.ES.EventESHost
	res, err := conn.Search(cfg.ES.EventIndex, "", nil, querybuf)
	if err != nil {
		panic(err)
	}
	logf("plugin %v returned %v hits", p.name, res.Hits.Len())

	if res.Hits.Len() == 0 {
		return nil
	}

	pluginInput, err := pluginRequestDataFromES(res)
	if err != nil {
		panic(err)
	}
	err = p.runPlugin(pluginInput)
	if err != nil {
		panic(err)
	}

	return nil
}

func handleQueryRequest(q queryRequest) {
	defer func() {
		if e := recover(); e != nil {
			logf("handleQueryRequest() -> %v", e)
		}
	}()
	logf("handling new query request")

	// Execute a query for each registered plugin
	for _, x := range pluginList {
		err := queryUsingPlugin(x, q)
		if err != nil {
			panic(err)
		}
	}
}

func queryHandler(exitCh chan bool, notifyCh chan bool) {
	for {
		select {
		case qr := <-queryRequestCh:
			handleQueryRequest(qr)
		case <-exitCh:
			notifyCh <- true
			return
		}
	}
}
<|endoftext|>


<commit_before>// Copyright © 2009 Esko Luontola <www.orfjackal.net>
// This software is released under the Apache License 2.0.
// The license text is at http://www.apache.org/licenses/LICENSE-2.0

package gospec

import (
	"container/list";
)

// Context controls the execution of the current spec. Child specs can be
// created with the Specify method.
type Context struct {
	targetPath path;
	currentSpec *specification;
	executedSpecs *list.List;
	postponedSpecs *list.List;
	done chan bool;
}

func newInitialContext() *Context {
	return newExplicitContext(rootPath())
}

func newExplicitContext(targetPath path) *Context {
	c := new(Context);
	c.targetPath = targetPath;
	c.currentSpec = nil;
	c.executedSpecs = list.New();
	c.postponedSpecs = list.New();
	c.done = make(chan bool);
	return c
}

// Creates a child spec for the currently executing spec. Specs can be nested
// unlimitedly. The name should describe what is the behaviour being specified
// by this spec, and the closure should contain the same specification written
// as code.
func (c *Context) Specify(name string, closure func()) {
	c.enterSpec(name, closure);
	c.processCurrentSpec();
	c.exitSpec();
}

func (c *Context) enterSpec(name string, closure func()) {
	spec := newSpecification(name, closure, c.currentSpec);
	c.currentSpec = spec;
}

func (c *Context) processCurrentSpec() {
	spec := c.currentSpec;
	switch {
	case c.shouldExecute(spec):
		c.execute(spec)
	case c.shouldPostpone(spec):
		c.postpone(spec)
	}
}

func (c *Context) exitSpec() {
	c.currentSpec = c.currentSpec.parent;
}

func (c *Context) shouldExecute(spec *specification) bool {
	return spec.isOnTargetPath(c) || (spec.isUnseen(c) && spec.isFirstChild())
}

func (c *Context) shouldPostpone(spec *specification) bool {
	return spec.isUnseen(c) && !spec.isFirstChild()
}

func (c *Context) execute(spec *specification) {
	c.executedSpecs.PushBack(spec);
	spec.execute();
}

func (c *Context) postpone(spec *specification) {
	c.postponedSpecs.PushBack(spec);
}

<commit_msg>Refactored<commit_after>// Copyright © 2009 Esko Luontola <www.orfjackal.net>
// This software is released under the Apache License 2.0.
// The license text is at http://www.apache.org/licenses/LICENSE-2.0

package gospec

import (
	"container/list";
)

// Context controls the execution of the current spec. Child specs can be
// created with the Specify method.
type Context struct {
	targetPath path;
	currentSpec *specification;
	executedSpecs *list.List;
	postponedSpecs *list.List;
}

func newInitialContext() *Context {
	return newExplicitContext(rootPath())
}

func newExplicitContext(targetPath path) *Context {
	c := new(Context);
	c.targetPath = targetPath;
	c.currentSpec = nil;
	c.executedSpecs = list.New();
	c.postponedSpecs = list.New();
	return c
}

// Creates a child spec for the currently executing spec. Specs can be nested
// unlimitedly. The name should describe what is the behaviour being specified
// by this spec, and the closure should contain the same specification written
// as code.
func (c *Context) Specify(name string, closure func()) {
	c.enterSpec(name, closure);
	c.processCurrentSpec();
	c.exitSpec();
}

func (c *Context) enterSpec(name string, closure func()) {
	spec := newSpecification(name, closure, c.currentSpec);
	c.currentSpec = spec;
}

func (c *Context) processCurrentSpec() {
	spec := c.currentSpec;
	switch {
	case c.shouldExecute(spec):
		c.execute(spec)
	case c.shouldPostpone(spec):
		c.postpone(spec)
	}
}

func (c *Context) exitSpec() {
	c.currentSpec = c.currentSpec.parent;
}

func (c *Context) shouldExecute(spec *specification) bool {
	return spec.isOnTargetPath(c) || (spec.isUnseen(c) && spec.isFirstChild())
}

func (c *Context) shouldPostpone(spec *specification) bool {
	return spec.isUnseen(c) && !spec.isFirstChild()
}

func (c *Context) execute(spec *specification) {
	c.executedSpecs.PushBack(spec);
	spec.execute();
}

func (c *Context) postpone(spec *specification) {
	c.postponedSpecs.PushBack(spec);
}

<|endoftext|>


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

// Package tests contains test cases. To run the tests go to tests directory and run:
// TESTBED_CONFIG=local.yaml go test -v

package tests

import (
	"testing"

	"go.opentelemetry.io/collector/testbed/testbed"
	scenarios "go.opentelemetry.io/collector/testbed/tests"

	"github.com/open-telemetry/opentelemetry-collector-contrib/testbed/datareceivers"
	"github.com/open-telemetry/opentelemetry-collector-contrib/testbed/datasenders"
)

var contribPerfResultsSummary testbed.TestResultsSummary = &testbed.PerformanceResults{}

// TestMain is used to initiate setup, execution and tear down of testbed.
func TestMain(m *testing.M) {
	testbed.DoTestMain(m, contribPerfResultsSummary)
}

func TestTrace10kSPS(t *testing.T) {
	tests := []struct {
		name         string
		sender       testbed.DataSender
		receiver     testbed.DataReceiver
		resourceSpec testbed.ResourceSpec
	}{
		{
			"OTLP",
			testbed.NewOTLPTraceDataSender(testbed.DefaultHost, testbed.GetAvailablePort(t)),
			testbed.NewOTLPDataReceiver(testbed.GetAvailablePort(t)),
			testbed.ResourceSpec{
				ExpectedMaxCPU: 20,
				ExpectedMaxRAM: 70,
			},
		},
		{
			"SAPM",
			datasenders.NewSapmDataSender(testbed.GetAvailablePort(t)),
			datareceivers.NewSapmDataReceiver(testbed.GetAvailablePort(t)),
			testbed.ResourceSpec{
				ExpectedMaxCPU: 40,
				ExpectedMaxRAM: 80,
			},
		},
	}

	processors := map[string]string{
		"batch": `
  batch:
`,
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			scenarios.Scenario10kItemsPerSecond(
				t,
				test.sender,
				test.receiver,
				test.resourceSpec,
				contribPerfResultsSummary,
				processors,
				nil,
			)
		})
	}
}
<commit_msg>tests: increase TestTrace10kSPS memory limits (#1314)<commit_after>// Copyright 2019, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package tests contains test cases. To run the tests go to tests directory and run:
// TESTBED_CONFIG=local.yaml go test -v

package tests

import (
	"testing"

	"go.opentelemetry.io/collector/testbed/testbed"
	scenarios "go.opentelemetry.io/collector/testbed/tests"

	"github.com/open-telemetry/opentelemetry-collector-contrib/testbed/datareceivers"
	"github.com/open-telemetry/opentelemetry-collector-contrib/testbed/datasenders"
)

var contribPerfResultsSummary testbed.TestResultsSummary = &testbed.PerformanceResults{}

// TestMain is used to initiate setup, execution and tear down of testbed.
func TestMain(m *testing.M) {
	testbed.DoTestMain(m, contribPerfResultsSummary)
}

func TestTrace10kSPS(t *testing.T) {
	tests := []struct {
		name         string
		sender       testbed.DataSender
		receiver     testbed.DataReceiver
		resourceSpec testbed.ResourceSpec
	}{
		{
			"OTLP",
			testbed.NewOTLPTraceDataSender(testbed.DefaultHost, testbed.GetAvailablePort(t)),
			testbed.NewOTLPDataReceiver(testbed.GetAvailablePort(t)),
			testbed.ResourceSpec{
				ExpectedMaxCPU: 20,
				ExpectedMaxRAM: 70,
			},
		},
		{
			"SAPM",
			datasenders.NewSapmDataSender(testbed.GetAvailablePort(t)),
			datareceivers.NewSapmDataReceiver(testbed.GetAvailablePort(t)),
			testbed.ResourceSpec{
				ExpectedMaxCPU: 40,
				ExpectedMaxRAM: 85,
			},
		},
	}

	processors := map[string]string{
		"batch": `
  batch:
`,
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			scenarios.Scenario10kItemsPerSecond(
				t,
				test.sender,
				test.receiver,
				test.resourceSpec,
				contribPerfResultsSummary,
				processors,
				nil,
			)
		})
	}
}
<|endoftext|>


<commit_before>// Automatically generated by MockGen. DO NOT EDIT!
// Source: registry.go

package event

import (
	gomock "gomock.googlecode.com/hg/gomock"
)

// Mock of Handler interface
type MockHandler struct {
	ctrl     *gomock.Controller
	recorder *_MockHandlerRecorder
}

// Recorder for MockHandler (not exported)
type _MockHandlerRecorder struct {
	mock *MockHandler
}

func NewMockHandler(ctrl *gomock.Controller) *MockHandler {
	mock := &MockHandler{ctrl: ctrl}
	mock.recorder = &_MockHandlerRecorder{mock}
	return mock
}

func (m *MockHandler) EXPECT() *_MockHandlerRecorder {
	return m.recorder
}

func (m *MockHandler) Run(_param0 ...interface{}) {
	m.ctrl.Call(m, "Run", _param0)
}

func (mr *_MockHandlerRecorder) Run(, arg0 ...interface{}) *gomock.Call {
	return mr.mock.ctrl.RecordCall(mr.mock, "Run", arg0)
}

func (m *MockHandler) Id() HandlerID {
	ret := m.ctrl.Call(m, "Id")
	ret0, _ := ret[0].(HandlerID)
	return ret0
}

func (mr *_MockHandlerRecorder) Id() *gomock.Call {
	return mr.mock.ctrl.RecordCall(mr.mock, "Id")
}
// Mock of EventDispatcher interface
type MockEventDispatcher struct {
	ctrl     *gomock.Controller
	recorder *_MockEventDispatcherRecorder
}

// Recorder for MockEventDispatcher (not exported)
type _MockEventDispatcherRecorder struct {
	mock *MockEventDispatcher
}

func NewMockEventDispatcher(ctrl *gomock.Controller) *MockEventDispatcher {
	mock := &MockEventDispatcher{ctrl: ctrl}
	mock.recorder = &_MockEventDispatcherRecorder{mock}
	return mock
}

func (m *MockEventDispatcher) EXPECT() *_MockEventDispatcherRecorder {
	return m.recorder
}

func (m *MockEventDispatcher) Dispatch(name string, ev ...interface{}) {
	m.ctrl.Call(m, "Dispatch", name, ev)
}

func (mr *_MockEventDispatcherRecorder) Dispatch(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
	return mr.mock.ctrl.RecordCall(mr.mock, "Dispatch", arg0, arg1)
}
// Mock of EventRegistry interface
type MockEventRegistry struct {
	ctrl     *gomock.Controller
	recorder *_MockEventRegistryRecorder
}

// Recorder for MockEventRegistry (not exported)
type _MockEventRegistryRecorder struct {
	mock *MockEventRegistry
}

func NewMockEventRegistry(ctrl *gomock.Controller) *MockEventRegistry {
	mock := &MockEventRegistry{ctrl: ctrl}
	mock.recorder = &_MockEventRegistryRecorder{mock}
	return mock
}

func (m *MockEventRegistry) EXPECT() *_MockEventRegistryRecorder {
	return m.recorder
}

func (m *MockEventRegistry) AddHandler(h Handler, names ...string) {
	m.ctrl.Call(m, "AddHandler", h, names)
}

func (mr *_MockEventRegistryRecorder) AddHandler(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
	return mr.mock.ctrl.RecordCall(mr.mock, "AddHandler", arg0, arg1)
}

func (m *MockEventRegistry) DelHandler(h Handler, names ...string) {
	m.ctrl.Call(m, "DelHandler", h, names)
}

func (mr *_MockEventRegistryRecorder) DelHandler(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
	return mr.mock.ctrl.RecordCall(mr.mock, "DelHandler", arg0, arg1)
}

func (m *MockEventRegistry) Dispatch(name string, ev ...interface{}) {
	m.ctrl.Call(m, "Dispatch", name, ev)
}

func (mr *_MockEventRegistryRecorder) Dispatch(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
	return mr.mock.ctrl.RecordCall(mr.mock, "Dispatch", arg0, arg1)
}

func (m *MockEventRegistry) ClearEvents(name string) {
	m.ctrl.Call(m, "ClearEvents", name)
}

func (mr *_MockEventRegistryRecorder) ClearEvents(arg0 interface{}) *gomock.Call {
	return mr.mock.ctrl.RecordCall(mr.mock, "ClearEvents", arg0)
}
<commit_msg>Hmm, code generation failure<commit_after>// Automatically generated by MockGen. DO NOT EDIT!
// Source: registry.go

package event

import (
	gomock "gomock.googlecode.com/hg/gomock"
)

// Mock of Handler interface
type MockHandler struct {
	ctrl     *gomock.Controller
	recorder *_MockHandlerRecorder
}

// Recorder for MockHandler (not exported)
type _MockHandlerRecorder struct {
	mock *MockHandler
}

func NewMockHandler(ctrl *gomock.Controller) *MockHandler {
	mock := &MockHandler{ctrl: ctrl}
	mock.recorder = &_MockHandlerRecorder{mock}
	return mock
}

func (m *MockHandler) EXPECT() *_MockHandlerRecorder {
	return m.recorder
}

func (m *MockHandler) Run(_param0 ...interface{}) {
	m.ctrl.Call(m, "Run", _param0)
}

func (mr *_MockHandlerRecorder) Run(arg0 ...interface{}) *gomock.Call {
	return mr.mock.ctrl.RecordCall(mr.mock, "Run", arg0)
}

func (m *MockHandler) Id() HandlerID {
	ret := m.ctrl.Call(m, "Id")
	ret0, _ := ret[0].(HandlerID)
	return ret0
}

func (mr *_MockHandlerRecorder) Id() *gomock.Call {
	return mr.mock.ctrl.RecordCall(mr.mock, "Id")
}
// Mock of EventDispatcher interface
type MockEventDispatcher struct {
	ctrl     *gomock.Controller
	recorder *_MockEventDispatcherRecorder
}

// Recorder for MockEventDispatcher (not exported)
type _MockEventDispatcherRecorder struct {
	mock *MockEventDispatcher
}

func NewMockEventDispatcher(ctrl *gomock.Controller) *MockEventDispatcher {
	mock := &MockEventDispatcher{ctrl: ctrl}
	mock.recorder = &_MockEventDispatcherRecorder{mock}
	return mock
}

func (m *MockEventDispatcher) EXPECT() *_MockEventDispatcherRecorder {
	return m.recorder
}

func (m *MockEventDispatcher) Dispatch(name string, ev ...interface{}) {
	m.ctrl.Call(m, "Dispatch", name, ev)
}

func (mr *_MockEventDispatcherRecorder) Dispatch(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
	return mr.mock.ctrl.RecordCall(mr.mock, "Dispatch", arg0, arg1)
}
// Mock of EventRegistry interface
type MockEventRegistry struct {
	ctrl     *gomock.Controller
	recorder *_MockEventRegistryRecorder
}

// Recorder for MockEventRegistry (not exported)
type _MockEventRegistryRecorder struct {
	mock *MockEventRegistry
}

func NewMockEventRegistry(ctrl *gomock.Controller) *MockEventRegistry {
	mock := &MockEventRegistry{ctrl: ctrl}
	mock.recorder = &_MockEventRegistryRecorder{mock}
	return mock
}

func (m *MockEventRegistry) EXPECT() *_MockEventRegistryRecorder {
	return m.recorder
}

func (m *MockEventRegistry) AddHandler(h Handler, names ...string) {
	m.ctrl.Call(m, "AddHandler", h, names)
}

func (mr *_MockEventRegistryRecorder) AddHandler(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
	return mr.mock.ctrl.RecordCall(mr.mock, "AddHandler", arg0, arg1)
}

func (m *MockEventRegistry) DelHandler(h Handler, names ...string) {
	m.ctrl.Call(m, "DelHandler", h, names)
}

func (mr *_MockEventRegistryRecorder) DelHandler(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
	return mr.mock.ctrl.RecordCall(mr.mock, "DelHandler", arg0, arg1)
}

func (m *MockEventRegistry) Dispatch(name string, ev ...interface{}) {
	m.ctrl.Call(m, "Dispatch", name, ev)
}

func (mr *_MockEventRegistryRecorder) Dispatch(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
	return mr.mock.ctrl.RecordCall(mr.mock, "Dispatch", arg0, arg1)
}

func (m *MockEventRegistry) ClearEvents(name string) {
	m.ctrl.Call(m, "ClearEvents", name)
}

func (mr *_MockEventRegistryRecorder) ClearEvents(arg0 interface{}) *gomock.Call {
	return mr.mock.ctrl.RecordCall(mr.mock, "ClearEvents", arg0)
}
<|endoftext|>


<commit_before>package conf

import (
	"errors"
	"io/ioutil"
	"log"
	"time"

	"github.com/BurntSushi/toml"
)

type MysqlConfiguration struct {
	ConnectionString string `toml:"connection-string"`
	Select           string `toml:"select"`
}

type MqttConfiguration struct {
	ListenAddress string `toml:"listen-address"`
	Cert          string `toml:"cert"`
	Key           string `toml:"key"`
}

type InfluxConfiguration struct {
	Host     string `toml:"host"`
	User     string `toml:"user"`
	Pass     string `toml:"pass"`
	Database string `toml:"database"`
}

type LibratoConfiguration struct {
	Email string `toml:"email"`
	Token string `toml:"token"`
}

type Configuration struct {
	BackendServers []string `toml:"backend-servers"`
	User           string   `toml:"user"`
	Pass           string   `toml:"pass"`

	// typically us-west | us-east
	// prepended to metrics
	Region string `toml:"region"`

	// typically develop | beta | prod
	// prepended to metrics
	Environment string `toml:"env"`

	ReadTimeout int `toml:"read-timeout"`

	MqttStoreMysql MysqlConfiguration   `toml:"mqtt-store"`
	Mqtt           MqttConfiguration    `toml:"mqtt"`
	Influx         InfluxConfiguration  `toml:"influx"`
	Librato        LibratoConfiguration `toml:"librato"`
}

func (c *Configuration) GetReadTimeout() time.Duration {
	return time.Second * time.Duration(c.ReadTimeout)
}

func LoadConfiguration(fileName string) *Configuration {
	config, err := parseTomlConfiguration(fileName)
	if err != nil {
		log.Println("Couldn't parse configuration file: " + fileName)
		panic(err)
	}
	return config
}

func parseTomlConfiguration(filename string) (*Configuration, error) {
	body, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	tomlConfiguration := &Configuration{}
	_, err = toml.Decode(string(body), tomlConfiguration)
	if err != nil {
		return nil, err
	}
	if len(tomlConfiguration.BackendServers) == 0 {
		return nil, errors.New("At least one backend servers required.")
	}

	if tomlConfiguration.Region == "" {
		tomlConfiguration.Region = "us-east"
	}

	if tomlConfiguration.Environment == "" {
		tomlConfiguration.Environment = "develop"
	}

	if tomlConfiguration.Mqtt.ListenAddress == "" {
		tomlConfiguration.Mqtt.ListenAddress = ":1883"
	}

	if tomlConfiguration.User == "" {
		tomlConfiguration.User = "guest"
	}

	if tomlConfiguration.Pass == "" {
		tomlConfiguration.Pass = "guest"
	}

	// need a way to merge defaults..
	if tomlConfiguration.MqttStoreMysql.ConnectionString == "" {
		tomlConfiguration.MqttStoreMysql.ConnectionString = "root:@tcp(127.0.0.1:3306)/mqtt"
	}

	if tomlConfiguration.MqttStoreMysql.Select == "" {
		tomlConfiguration.MqttStoreMysql.Select = "select uid, mqtt_id from users where mqtt_id = ?"
	}

	return tomlConfiguration, nil
}
<commit_msg>Tidy up configuration.<commit_after>package conf

import (
	"errors"
	"io/ioutil"
	"log"
	"time"

	"github.com/BurntSushi/toml"
	"github.com/davecgh/go-spew/spew"
)

type MysqlConfiguration struct {
	ConnectionString string `toml:"connection-string"`
	Select           string `toml:"select"`
}

type MqttConfiguration struct {
	ListenAddress string `toml:"listen-address"`
	Cert          string `toml:"cert"`
	Key           string `toml:"key"`
}

type InfluxConfiguration struct {
	Host     string `toml:"host"`
	User     string `toml:"user"`
	Pass     string `toml:"pass"`
	Database string `toml:"database"`
}

type LibratoConfiguration struct {
	Email string `toml:"email"`
	Token string `toml:"token"`
}

type Configuration struct {
	BackendServers []string `toml:"backend-servers"`
	User           string   `toml:"user"`
	Pass           string   `toml:"pass"`

	// typically us-west | us-east
	// prepended to metrics
	Region string `toml:"region"`

	// typically develop | beta | prod
	// prepended to metrics
	Environment string `toml:"env"`

	ReadTimeout int `toml:"read-timeout"`

	MqttStoreMysql MysqlConfiguration   `toml:"mqtt-store"`
	Mqtt           MqttConfiguration    `toml:"mqtt"`
	Influx         InfluxConfiguration  `toml:"influx"`
	Librato        LibratoConfiguration `toml:"librato"`
}

func (c *Configuration) GetReadTimeout() time.Duration {
	return time.Second * time.Duration(c.ReadTimeout)
}

func (c *Configuration) validate() error {

	if len(c.BackendServers) == 0 {
		return errors.New("At least one backend servers required.")
	}

	return nil
}

func (c *Configuration) assignDefaults() {

	if c.Region == "" {
		c.Region = "us-east"
	}

	if c.Environment == "" {
		c.Environment = "develop"
	}

	if c.Mqtt.ListenAddress == "" {
		c.Mqtt.ListenAddress = ":1883"
	}

	if c.User == "" {
		c.User = "guest"
	}

	if c.Pass == "" {
		c.Pass = "guest"
	}

	// need a way to merge defaults..
	if c.MqttStoreMysql.ConnectionString == "" {
		c.MqttStoreMysql.ConnectionString = "root:@tcp(127.0.0.1:3306)/mqtt"
	}

	if c.MqttStoreMysql.Select == "" {
		c.MqttStoreMysql.Select = "select uid, mqtt_id from users where mqtt_id = ?"
	}

}

func LoadConfiguration(fileName string) *Configuration {
	config, err := parseTomlConfiguration(fileName)
	if err != nil {
		log.Println("Couldn't parse configuration file: " + fileName)
		panic(err)
	}
	return config
}

func parseTomlConfiguration(filename string) (*Configuration, error) {
	body, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	tomlConfiguration := &Configuration{}
	_, err = toml.Decode(string(body), tomlConfiguration)
	if err != nil {
		return nil, err
	}
	log.Println(spew.Sprintf("sql = %v", tomlConfiguration))

	tomlConfiguration.assignDefaults()

	err = tomlConfiguration.validate()

	if err != nil {
		return nil, err
	}

	return tomlConfiguration, nil
}
<|endoftext|>


<commit_before>package conf

import (
	"fmt"
	"github.com/yassu/gnuplot.go/utils"
	"regexp"
	"strconv"
)

func isNum(s string) bool {
	r := regexp.MustCompile(`^[+-]?[0-9]*[\.]?[0-9]+$`)
	return r.MatchString(s)
}

func isIntStr(s string) bool {
	r := regexp.MustCompile(`^[+-]?[0-9]+$`)
	return r.MatchString(s)
}

func isSixHex(s string) bool {
	r := regexp.MustCompile(`^[0-9a-f]{6}$`)
	return r.MatchString(s)
}

func isEightHex(s string) bool {
	r := regexp.MustCompile(`^[0-9a-f]{8}$`)
	return r.MatchString(s)
}

// either s is float of 0 ~ 1 or not
func isSmallFloat(s string) bool {
	if !isNum(s) {
		return false
	}
	f, _ := strconv.ParseFloat(s, 32)
	return 0 <= f && f <= 1
}

// Configures
type Configure struct {
	key               string
	aliasKeys         []string
	vals              []string
	requiredCondition func(vals []string) bool
}

func NewConfigure(keys []string, defaultVals []string, requiredCondition func(vals []string) bool) *Configure {
	conf := new(Configure)
	conf.key = keys[0]
	conf.aliasKeys = keys
	conf.vals = defaultVals
	conf.requiredCondition = requiredCondition
	return conf
}

func (conf *Configure) SetVals(vals []string) {
	if conf.requiredCondition(vals) {
		conf.vals = vals
	} else {
		panic(fmt.Sprintf("%v is illegal values of %v.", vals, conf.key))
	}
}

func (conf *Configure) GetKey() string {
	return conf.key
}

func (conf *Configure) GetVals() []string {
	return conf.vals
}

func (conf *Configure) AliasedKeys() []string {
	return conf.aliasKeys
}

var COLOR_NAMES = []string{
	"white", "black", "dark-grey", "red", "web-green", "web-blue",
	"dark-magenta", "dark-cyan", "dark-orange", "dark-yellow", "royalblue",
	"goldenrod", "dark-spring-green", "purple", "steelblue", "dark-red",
	"dark-chartreuse", "orchild", "aquamarine", "brown", "yellow",
	"turquoise",
	"grey", "grey0", "grey10", "grey20", "grey30", "grey40", "grey50",
	"grey60", "grey70", "grey80", "grey90", "grey100",
	"light-red", "light-green", "light-blue", "light-magenta", "light-cyan",
	"light-goldenrod", "light-pink", "light-turquoise", "gold", "green",
	"dark-green", "sprint-green", "forest-green", "sea-green", "blue",
	"dark-blue", "midnight-blue", "navy", "medium-blue", "skyblue",
	"cyan", "magenta", "dark-turquoise", "dark-pink", "coral", "light-coral",
	"orange-red", "salmon", "dark-salmon", "khaki", "dark-khaki",
	"dark-goldenrod", "beige", "olive", "orange", "violet", "dark-violet",
	"plum", "dark-plum", "dark-olivegreen", "orangered4", "brown4", "sienna4",
	"orchid4", "mediumpurple3", "slateblue1", "yellow4", "sienna1", "tan1",
	"standybrown", "light-salmon", "pink", "khaki1", "lemonchiffon", "bisque",
	"honeydew", "slategrey", "seagreen", "antiquewhite", "chartreuse",
	"greenyellow", "gray", "light-gray", "light-grey",
	"dark-gray", "slategray",
	"gray0", "gray10", "gray20", "gray30", "gray40", "gray50", "gray60",
	"gray70", "gray80", "gray90", "gray100"}

var POSITIONS = []string{"x", "y", "first", "second", "graph", "screen", "character"}

// Function2d or Curve2d options
func WithConf() *Configure {
	return NewConfigure([]string{"with", "w"}, []string{"lines"}, func(vals []string) bool {
		return len(vals) == 1 && utils.InStr(vals[0], []string{
			"lines", "dots", "steps", "errorbars", "xerrorbar",
			"xyerrorlines", "points", "impulses", "fsteps", "errorlines", "xerrorlines",
			"yerrorlines", "surface", "vectors", "parallelaxes"})
	})
}

func LineColorConf() *Configure {
	return NewConfigure([]string{"linecolor", "lc"}, []string{"1"}, func(vals []string) bool {
		if len(vals) == 0 {
			return false
		}
		// in case of linecolor "colorname"
		val := vals[0]
		if utils.InStr(val, COLOR_NAMES) {
			return true
		}

		// in case of linecolor <n>
		if isIntStr(val) {
			return true
		}

		// in case of linecolor <colorspec> and len(vals) == 1
		if utils.InStr(val, []string{"variable", "bgnd", "black"}) {
			return true
		}

		if len(vals) == 2 && vals[0] == "rgbcolor" && utils.InStr(vals[1], COLOR_NAMES) {
			return true
		}
		if len(vals) == 2 && vals[0] == "rgbcolor" && vals[1][0:2] == "0x" && isSixHex(vals[1][2:]) {
			return true
		}
		if len(vals) == 2 && vals[0] == "rgbcolor" && vals[1][0:2] == "0x" && isEightHex(vals[1][2:]) {
			return true
		}
		if len(vals) == 2 && vals[0] == "rgbcolor" && vals[1][0] == '#' && isSixHex(vals[1][1:]) {
			return true
		}
		if len(vals) == 2 && vals[0] == "rgbcolor" && vals[1][0] == '#' && isEightHex(vals[1][1:]) {
			return true
		}
		if len(vals) == 2 && vals[0] == "rgbcolor" && isIntStr(vals[1]) {
			return true
		}
		return false
	})
}

func ArrowConf() *Configure {
	return NewConfigure([]string{"arrow"}, []string{}, func(vals []string) bool {
		if len(vals) == 0 {
			return true
		}

		// set arrow <tag> from <position> to <position>
		if len(vals) == 4 && isNum(vals[0]) &&
			vals[1] == "from" && vals[3] == "to" &&
			utils.InStr(vals[2], POSITIONS) &&
			utils.InStr(vals[4], POSITIONS) {
			return true
		}

		// set arrow from <position> to <position>
		if len(vals) == 3 &&
			vals[0] == "from" && vals[2] == "to" &&
			utils.InStr(vals[1], POSITIONS) &&
			utils.InStr(vals[3], POSITIONS) {
			return true
		}

		// set arrow <tag> from <position> rto <position>
		if len(vals) == 4 && isNum(vals[0]) &&
			vals[1] == "from" && vals[3] == "rto" &&
			utils.InStr(vals[2], POSITIONS) &&
			utils.InStr(vals[4], POSITIONS) {
			return true
		}

		// set arrow from <position> rto <position>
		if len(vals) == 3 &&
			vals[0] == "from" && vals[2] == "rto" &&
			utils.InStr(vals[1], POSITIONS) &&
			utils.InStr(vals[3], POSITIONS) {
			return true
		}

		// set arrow <tag> from <position> length <coord> angle <ang> (until)
		if len(vals) == 7 &&
			vals[1] == "from" && vals[3] == "length" && vals[5] == "angle" &&
			isIntStr(vals[0]) {
			return true
		}
		// TODO: until

		return false
	})
}

func GoXMinConf() *Configure {
	return NewConfigure([]string{"_xMin"}, []string{"-10.0"}, func(vals []string) bool {
		return len(vals) == 1 && isNum(vals[0])
	})
}

func GoXMaxConf() *Configure {
	return NewConfigure([]string{"_xMax"}, []string{"10.0"}, func(vals []string) bool {
		return len(vals) == 1 && isNum(vals[0])
	})
}

func GoTMinConf() *Configure {
	return NewConfigure([]string{"_tMin"}, []string{"-10.0"}, func(vals []string) bool {
		return len(vals) == 1 && isNum(vals[0])
	})
}

func GoTMaxConf() *Configure {
	return NewConfigure([]string{"_tMax"}, []string{"10.0"}, func(vals []string) bool {
		return len(vals) == 1 && isNum(vals[0])
	})
}

func Function2dConfs() []*Configure {
	return []*Configure{WithConf(), GoXMinConf(), GoXMaxConf()}
}

func Curve2dConfs() []*Configure {
	return []*Configure{WithConf(), GoTMinConf(), GoTMaxConf()}
}

// Graph options
func AnglesConf() *Configure {
	return NewConfigure([]string{"angles"}, []string{"radians"}, func(vals []string) bool {
		return len(vals) == 1 && utils.InStr(vals[0], []string{"degrees", "radians", "true", "false"})
	})
}

func Graph2dConfs() []*Configure {
	return []*Configure{AnglesConf()}
}
<commit_msg>define some confs without validation<commit_after>package conf

import (
	"fmt"
	"github.com/yassu/gnuplot.go/utils"
	"regexp"
	"strconv"
)

func isNum(s string) bool {
	r := regexp.MustCompile(`^[+-]?[0-9]*[\.]?[0-9]+$`)
	return r.MatchString(s)
}

func isIntStr(s string) bool {
	r := regexp.MustCompile(`^[+-]?[0-9]+$`)
	return r.MatchString(s)
}

func isSixHex(s string) bool {
	r := regexp.MustCompile(`^[0-9a-f]{6}$`)
	return r.MatchString(s)
}

func isEightHex(s string) bool {
	r := regexp.MustCompile(`^[0-9a-f]{8}$`)
	return r.MatchString(s)
}

// either s is float of 0 ~ 1 or not
func isSmallFloat(s string) bool {
	if !isNum(s) {
		return false
	}
	f, _ := strconv.ParseFloat(s, 32)
	return 0 <= f && f <= 1
}

// Configures
type Configure struct {
	key               string
	aliasKeys         []string
	vals              []string
	requiredCondition func(vals []string) bool
}

func NewConfigure(keys []string, defaultVals []string, requiredCondition func(vals []string) bool) *Configure {
	conf := new(Configure)
	conf.key = keys[0]
	conf.aliasKeys = keys
	conf.vals = defaultVals
	conf.requiredCondition = requiredCondition
	return conf
}

func (conf *Configure) SetVals(vals []string) {
	if conf.requiredCondition(vals) {
		conf.vals = vals
	} else {
		panic(fmt.Sprintf("%v is illegal values of %v.", vals, conf.key))
	}
}

func (conf *Configure) GetKey() string {
	return conf.key
}

func (conf *Configure) GetVals() []string {
	return conf.vals
}

func (conf *Configure) AliasedKeys() []string {
	return conf.aliasKeys
}

var COLOR_NAMES = []string{
	"white", "black", "dark-grey", "red", "web-green", "web-blue",
	"dark-magenta", "dark-cyan", "dark-orange", "dark-yellow", "royalblue",
	"goldenrod", "dark-spring-green", "purple", "steelblue", "dark-red",
	"dark-chartreuse", "orchild", "aquamarine", "brown", "yellow",
	"turquoise",
	"grey", "grey0", "grey10", "grey20", "grey30", "grey40", "grey50",
	"grey60", "grey70", "grey80", "grey90", "grey100",
	"light-red", "light-green", "light-blue", "light-magenta", "light-cyan",
	"light-goldenrod", "light-pink", "light-turquoise", "gold", "green",
	"dark-green", "sprint-green", "forest-green", "sea-green", "blue",
	"dark-blue", "midnight-blue", "navy", "medium-blue", "skyblue",
	"cyan", "magenta", "dark-turquoise", "dark-pink", "coral", "light-coral",
	"orange-red", "salmon", "dark-salmon", "khaki", "dark-khaki",
	"dark-goldenrod", "beige", "olive", "orange", "violet", "dark-violet",
	"plum", "dark-plum", "dark-olivegreen", "orangered4", "brown4", "sienna4",
	"orchid4", "mediumpurple3", "slateblue1", "yellow4", "sienna1", "tan1",
	"standybrown", "light-salmon", "pink", "khaki1", "lemonchiffon", "bisque",
	"honeydew", "slategrey", "seagreen", "antiquewhite", "chartreuse",
	"greenyellow", "gray", "light-gray", "light-grey",
	"dark-gray", "slategray",
	"gray0", "gray10", "gray20", "gray30", "gray40", "gray50", "gray60",
	"gray70", "gray80", "gray90", "gray100"}

var POSITIONS = []string{"x", "y", "first", "second", "graph", "screen", "character"}

// Function2d or Curve2d options
func WithConf() *Configure {
	return NewConfigure([]string{"with", "w"}, []string{"lines"}, func(vals []string) bool {
		return len(vals) == 1 && utils.InStr(vals[0], []string{
			"lines", "dots", "steps", "errorbars", "xerrorbar",
			"xyerrorlines", "points", "impulses", "fsteps", "errorlines", "xerrorlines",
			"yerrorlines", "surface", "vectors", "parallelaxes"})
	})
}

func LineColorConf() *Configure {
	return NewConfigure([]string{"linecolor", "lc"}, []string{"1"}, func(vals []string) bool {
		if len(vals) == 0 {
			return false
		}
		// in case of linecolor "colorname"
		val := vals[0]
		if utils.InStr(val, COLOR_NAMES) {
			return true
		}

		// in case of linecolor <n>
		if isIntStr(val) {
			return true
		}

		// in case of linecolor <colorspec> and len(vals) == 1
		if utils.InStr(val, []string{"variable", "bgnd", "black"}) {
			return true
		}

		if len(vals) == 2 && vals[0] == "rgbcolor" && utils.InStr(vals[1], COLOR_NAMES) {
			return true
		}
		if len(vals) == 2 && vals[0] == "rgbcolor" && vals[1][0:2] == "0x" && isSixHex(vals[1][2:]) {
			return true
		}
		if len(vals) == 2 && vals[0] == "rgbcolor" && vals[1][0:2] == "0x" && isEightHex(vals[1][2:]) {
			return true
		}
		if len(vals) == 2 && vals[0] == "rgbcolor" && vals[1][0] == '#' && isSixHex(vals[1][1:]) {
			return true
		}
		if len(vals) == 2 && vals[0] == "rgbcolor" && vals[1][0] == '#' && isEightHex(vals[1][1:]) {
			return true
		}
		if len(vals) == 2 && vals[0] == "rgbcolor" && isIntStr(vals[1]) {
			return true
		}
		return false
	})
}

func GoXMinConf() *Configure {
	return NewConfigure([]string{"_xMin"}, []string{"-10.0"}, func(vals []string) bool {
		return len(vals) == 1 && isNum(vals[0])
	})
}

func GoXMaxConf() *Configure {
	return NewConfigure([]string{"_xMax"}, []string{"10.0"}, func(vals []string) bool {
		return len(vals) == 1 && isNum(vals[0])
	})
}

func GoTMinConf() *Configure {
	return NewConfigure([]string{"_tMin"}, []string{"-10.0"}, func(vals []string) bool {
		return len(vals) == 1 && isNum(vals[0])
	})
}

func GoTMaxConf() *Configure {
	return NewConfigure([]string{"_tMax"}, []string{"10.0"}, func(vals []string) bool {
		return len(vals) == 1 && isNum(vals[0])
	})
}

func Function2dConfs() []*Configure {
	return []*Configure{WithConf(), GoXMinConf(), GoXMaxConf()}
}

func Curve2dConfs() []*Configure {
	return []*Configure{WithConf(), GoTMinConf(), GoTMaxConf()}
}

// Graph options
//     angles            arrow             autoscale         bars
//     bmargin           border            boxwidth          cbdata
//     cbdtics           cblabel           cbmtics           cbrange
//     cbtics            clabel            clip              cntrlabel
//     cntrparam         color             colorbox          colorsequence
//     contour           dashtype          data              datafile
//     date_specifiers   decimalsign       dgrid3d           dummy
//     encoding          fit               fontpath          format
//     function          grid              hidden3d          history
//     historysize       isosamples        key               label
//     linetype          link              lmargin           loadpath
//     locale            log               logscale          macros
//     mapping           margin            margins           missing
//     monochrome        mouse             multiplot         mx2tics
//     mxtics            my2tics           mytics            mztics
//     object            offsets           origin            output
//     palette           parametric        paxis             pm3d
//     pointintervalbox  pointsize         polar             print
//     psdir             raxis             rmargin           rrange
//     rtics             samples           size              style
//     surface           table             term              terminal
//     termoption        tics              ticscale          ticslevel
//     time_specifiers   timefmt           timestamp         title
//     tmargin           trange            urange            view
//     vrange            x2data            x2dtics           x2label
//     x2mtics           x2range           x2tics            x2zeroaxis
//     xdata             xdtics            xlabel            xmtics
//     xrange            xtics             xyplane           xzeroaxis
//     y2data            y2dtics           y2label           y2mtics
//     y2range           y2tics            y2zeroaxis        ydata
//     ydtics            ylabel            ymtics            yrange
func Graph2dAnglesConf() *Configure {
	return NewConfigure([]string{"angles"}, []string{"radians"}, func(vals []string) bool {
		return len(vals) == 1 && utils.InStr(vals[0], []string{"degrees", "radians", "true", "false"})
	})
}

func Graph2dArrowConf() *Configure {
	return NewConfigure([]string{"arrow"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dAutoScaleConf() *Configure {
	return NewConfigure([]string{"autoscale"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dBarsConf() *Configure {
	return NewConfigure([]string{"bars"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dBmarginConf() *Configure {
	return NewConfigure([]string{"bmargin"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dBorderConf() *Configure {
	return NewConfigure([]string{"border"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dBoxwidthConf() *Configure {
	return NewConfigure([]string{"boxwidth"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dCbdataConf() *Configure {
	return NewConfigure([]string{"cbdata"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dCbdticsConf() *Configure {
	return NewConfigure([]string{"cbdtics"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dCblabelConf() *Configure {
	return NewConfigure([]string{"cblabel"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dCbmticsConf() *Configure {
	return NewConfigure([]string{"cbmtics"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dCbrangeConf() *Configure {
	return NewConfigure([]string{"cbrange"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dCbticsConf() *Configure {
	return NewConfigure([]string{"cbtics"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dClabelConf() *Configure {
	return NewConfigure([]string{"clabel"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dClipConf() *Configure {
	return NewConfigure([]string{"clip"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dCntrlabelConf() *Configure {
	return NewConfigure([]string{"cntrlabel"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dCntrparamConf() *Configure {
	return NewConfigure([]string{"cntrparam"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dColorConf() *Configure {
	return NewConfigure([]string{"color"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dColorboxConf() *Configure {
	return NewConfigure([]string{"colorbox"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dColorsequenceConf() *Configure {
	return NewConfigure([]string{"colorsequence"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dContourConf() *Configure {
	return NewConfigure([]string{"contour"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dDashtypeConf() *Configure {
	return NewConfigure([]string{"dashtype"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dDataConf() *Configure {
	return NewConfigure([]string{"data"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dDatafileConf() *Configure {
	return NewConfigure([]string{"datafile"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dDateSpecifiersConf() *Configure {
	return NewConfigure([]string{"date_specifiers"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dDecimalsignConf() *Configure {
	return NewConfigure([]string{"decimalsign"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dDgrid3dConf() *Configure {
	return NewConfigure([]string{"dgrid3d"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dDummyConf() *Configure {
	return NewConfigure([]string{"dummy"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dEncodingConf() *Configure {
	return NewConfigure([]string{"encoding"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dFitConf() *Configure {
	return NewConfigure([]string{"fit"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dFontPathConf() *Configure {
	return NewConfigure([]string{"fontpath"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dFormatConf() *Configure {
	return NewConfigure([]string{"format"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dFunctionConf() *Configure {
	return NewConfigure([]string{"function"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dGridConf() *Configure {
	return NewConfigure([]string{"grid"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dHidden3dConf() *Configure {
	return NewConfigure([]string{"hidden3d"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dHistoryConf() *Configure {
	return NewConfigure([]string{"history"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dHistorysizeConf() *Configure {
	return NewConfigure([]string{"historysize"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dIsosamplesConf() *Configure {
	return NewConfigure([]string{"isosamples"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dKeyConf() *Configure {
	return NewConfigure([]string{"key"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dLabelConf() *Configure {
	return NewConfigure([]string{"label"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dLinetypeConf() *Configure {
	return NewConfigure([]string{"label"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dLinkConf() *Configure {
	return NewConfigure([]string{"link"}, []string{""}, func(vals []string) bool {
		return true
	})
}

func Graph2dConfs() []*Configure {
	return []*Configure{AnglesConf()}
}
<|endoftext|>


<commit_before>package caixa

import (
	"fmt"

	"github.com/PMoneda/flow"

	"github.com/mundipagg/boleto-api/config"
	"github.com/mundipagg/boleto-api/log"
	"github.com/mundipagg/boleto-api/models"
	"github.com/mundipagg/boleto-api/tmpl"
	"github.com/mundipagg/boleto-api/util"
	"github.com/mundipagg/boleto-api/validations"
)

type bankCaixa struct {
	validate *models.Validator
	log      *log.Log
}

func New() bankCaixa {
	b := bankCaixa{
		validate: models.NewValidator(),
		log:      log.CreateLog(),
	}
	b.validate.Push(validations.ValidateAmount)
	b.validate.Push(validations.ValidateExpireDate)
	b.validate.Push(validations.ValidateBuyerDocumentNumber)
	b.validate.Push(validations.ValidateRecipientDocumentNumber)
	b.validate.Push(caixaValidateAgency)
	b.validate.Push(validateInstructions)
	return b
}

//Log retorna a referencia do log
func (b bankCaixa) Log() *log.Log {
	return b.log
}
func (b bankCaixa) RegisterBoleto(boleto *models.BoletoRequest) (models.BoletoResponse, error) {
	r := flow.NewFlow()
	urlCaixa := config.Get().URLCaixaRegisterBoleto
	from := getResponseCaixa()
	to := getAPIResponseCaixa()
	bod := r.From("message://?source=inline", boleto, getRequestCaixa(), tmpl.GetFuncMaps())
	bod = bod.To("logseq://?type=request&url="+urlCaixa, b.log)
	//bod = bod.To("print://?msg=${body}")
	bod = bod.To(urlCaixa, map[string]string{"method": "POST", "insecureSkipVerify": "true"})
	bod = bod.To("logseq://?type=response&url="+urlCaixa, b.log)
	ch := bod.Choice()
	ch = ch.When(flow.Header("status").IsEqualTo("200"))
	ch = ch.To("transform://?format=xml", from, to, tmpl.GetFuncMaps())
	ch = ch.Otherwise()
	ch = ch.To("logseq://?type=response&url="+urlCaixa, b.log).To("apierro://")

	switch t := bod.GetBody().(type) {
	case string:
		response := util.ParseJSON(t, new(models.BoletoResponse)).(*models.BoletoResponse)
		return *response, nil
	case models.BoletoResponse:
		return t, nil
	}
	return models.BoletoResponse{}, models.NewInternalServerError("MP500", "Erro interno")
}
func (b bankCaixa) ProcessBoleto(boleto *models.BoletoRequest) (models.BoletoResponse, error) {
	errs := b.ValidateBoleto(boleto)
	if len(errs) > 0 {
		return models.BoletoResponse{Errors: errs}, nil
	}
	checkSum := b.getCheckSumCode(*boleto)
	//fmt.Println(checkSum)
	boleto.Authentication.AuthorizationToken = b.getAuthToken(checkSum)
	return b.RegisterBoleto(boleto)
}

func (b bankCaixa) ValidateBoleto(boleto *models.BoletoRequest) models.Errors {
	return models.Errors(b.validate.Assert(boleto))
}

//getCheckSumCode Código do Cedente (7 posições) + Nosso Número (17 posições) + Data de Vencimento (DDMMAAAA) + Valor (15 posições) + CPF/CNPJ (14 Posições)
func (b bankCaixa) getCheckSumCode(boleto models.BoletoRequest) string {
	return fmt.Sprintf("%07d%017d%s%015d%014s",
		boleto.Agreement.AgreementNumber,
		boleto.Title.OurNumber,
		boleto.Title.ExpireDateTime.Format("02012006"),
		boleto.Title.AmountInCents,
		boleto.Recipient.Document.Number)
}

func (b bankCaixa) getAuthToken(info string) string {
	return util.Sha256(info)
}

//GetBankNumber retorna o codigo do banco
func (b bankCaixa) GetBankNumber() models.BankNumber {
	return models.Caixa
}
<commit_msg>Clear ourNumber boleto caixa<commit_after>package caixa

import (
	"fmt"

	"github.com/PMoneda/flow"

	"github.com/mundipagg/boleto-api/config"
	"github.com/mundipagg/boleto-api/log"
	"github.com/mundipagg/boleto-api/models"
	"github.com/mundipagg/boleto-api/tmpl"
	"github.com/mundipagg/boleto-api/util"
	"github.com/mundipagg/boleto-api/validations"
)

type bankCaixa struct {
	validate *models.Validator
	log      *log.Log
}

func New() bankCaixa {
	b := bankCaixa{
		validate: models.NewValidator(),
		log:      log.CreateLog(),
	}
	b.validate.Push(validations.ValidateAmount)
	b.validate.Push(validations.ValidateExpireDate)
	b.validate.Push(validations.ValidateBuyerDocumentNumber)
	b.validate.Push(validations.ValidateRecipientDocumentNumber)
	b.validate.Push(caixaValidateAgency)
	b.validate.Push(validateInstructions)
	return b
}

//Log retorna a referencia do log
func (b bankCaixa) Log() *log.Log {
	return b.log
}
func (b bankCaixa) RegisterBoleto(boleto *models.BoletoRequest) (models.BoletoResponse, error) {
	r := flow.NewFlow()
	urlCaixa := config.Get().URLCaixaRegisterBoleto
	from := getResponseCaixa()
	to := getAPIResponseCaixa()
	bod := r.From("message://?source=inline", boleto, getRequestCaixa(), tmpl.GetFuncMaps())
	bod = bod.To("logseq://?type=request&url="+urlCaixa, b.log)
	//bod = bod.To("print://?msg=${body}")
	bod = bod.To(urlCaixa, map[string]string{"method": "POST", "insecureSkipVerify": "true"})
	bod = bod.To("logseq://?type=response&url="+urlCaixa, b.log)
	ch := bod.Choice()
	ch = ch.When(flow.Header("status").IsEqualTo("200"))
	ch = ch.To("transform://?format=xml", from, to, tmpl.GetFuncMaps())
	ch = ch.Otherwise()
	ch = ch.To("logseq://?type=response&url="+urlCaixa, b.log).To("apierro://")

	switch t := bod.GetBody().(type) {
	case string:
		response := util.ParseJSON(t, new(models.BoletoResponse)).(*models.BoletoResponse)
		return *response, nil
	case models.BoletoResponse:
		return t, nil
	}
	return models.BoletoResponse{}, models.NewInternalServerError("MP500", "Erro interno")
}
func (b bankCaixa) ProcessBoleto(boleto *models.BoletoRequest) (models.BoletoResponse, error) {
	boleto.Title.OurNumber = 0
	errs := b.ValidateBoleto(boleto)
	if len(errs) > 0 {
		return models.BoletoResponse{Errors: errs}, nil
	}
	checkSum := b.getCheckSumCode(*boleto)
	//fmt.Println(checkSum)
	boleto.Authentication.AuthorizationToken = b.getAuthToken(checkSum)
	return b.RegisterBoleto(boleto)
}

func (b bankCaixa) ValidateBoleto(boleto *models.BoletoRequest) models.Errors {
	return models.Errors(b.validate.Assert(boleto))
}

//getCheckSumCode Código do Cedente (7 posições) + Nosso Número (17 posições) + Data de Vencimento (DDMMAAAA) + Valor (15 posições) + CPF/CNPJ (14 Posições)
func (b bankCaixa) getCheckSumCode(boleto models.BoletoRequest) string {
	return fmt.Sprintf("%07d%017d%s%015d%014s",
		boleto.Agreement.AgreementNumber,
		boleto.Title.OurNumber,
		boleto.Title.ExpireDateTime.Format("02012006"),
		boleto.Title.AmountInCents,
		boleto.Recipient.Document.Number)
}

func (b bankCaixa) getAuthToken(info string) string {
	return util.Sha256(info)
}

//GetBankNumber retorna o codigo do banco
func (b bankCaixa) GetBankNumber() models.BankNumber {
	return models.Caixa
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"testing"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
	"github.com/mitchellh/goamz/ec2"
)

func TestAccAWSInstance_normal(t *testing.T) {
	var v ec2.Instance

	testCheck := func(*terraform.State) error {
		if v.AvailZone != "us-west-2a" {
			return fmt.Errorf("bad availability zone: %#v", v.AvailZone)
		}

		if len(v.SecurityGroups) == 0 {
			return fmt.Errorf("no security groups: %#v", v.SecurityGroups)
		}
		if v.SecurityGroups[0].Name != "tf_test_foo" {
			return fmt.Errorf("no security groups: %#v", v.SecurityGroups)
		}

		return nil
	}

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckInstanceDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccInstanceConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckInstanceExists(
						"aws_instance.foo", &v),
					testCheck,
					resource.TestCheckResourceAttr(
						"aws_instance.foo",
						"user_data",
						"0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"),
				),
			},

			// We repeat the exact same test so that we can be sure
			// that the user data hash stuff is working without generating
			// an incorrect diff.
			resource.TestStep{
				Config: testAccInstanceConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckInstanceExists(
						"aws_instance.foo", &v),
					testCheck,
					resource.TestCheckResourceAttr(
						"aws_instance.foo",
						"user_data",
						"0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"),
				),
			},
		},
	})
}

func TestAccAWSInstance_sourceDestCheck(t *testing.T) {
	var v ec2.Instance

	testCheck := func(enabled bool) resource.TestCheckFunc {
		return func(*terraform.State) error {
			if v.SourceDestCheck != enabled {
				return fmt.Errorf("bad source_dest_check: %#v", v.SourceDestCheck)
			}

			return nil
		}
	}

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckInstanceDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccInstanceConfigSourceDest,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckInstanceExists(
						"aws_instance.foo", &v),
					testCheck(true),
				),
			},

			resource.TestStep{
				Config: testAccInstanceConfigSourceDestDisable,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckInstanceExists(
						"aws_instance.foo", &v),
					testCheck(false),
				),
			},
		},
	})
}

func TestAccAWSInstance_vpc(t *testing.T) {
	var v ec2.Instance

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckInstanceDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccInstanceConfigVPC,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckInstanceExists(
						"aws_instance.foo", &v),
				),
			},
		},
	})
}

func TestAccInstance_tags(t *testing.T) {
	var v ec2.Instance

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckInstanceDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccCheckInstanceConfigTags,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckInstanceExists("aws_instance.foo", &v),
					testAccCheckTags(&v.Tags, "foo", "bar"),
				),
			},

			resource.TestStep{
				Config: testAccCheckInstanceConfigTagsUpdate,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckInstanceExists("aws_instance.foo", &v),
					testAccCheckTags(&v.Tags, "foo", ""),
					testAccCheckTags(&v.Tags, "bar", "baz"),
				),
			},
		},
	})
}

func testAccCheckInstanceDestroy(s *terraform.State) error {
	conn := testAccProvider.ec2conn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_instance" {
			continue
		}

		// Try to find the resource
		resp, err := conn.Instances(
			[]string{rs.Primary.ID}, ec2.NewFilter())
		if err == nil {
			if len(resp.Reservations) > 0 {
				return fmt.Errorf("still exist.")
			}

			return nil
		}

		// Verify the error is what we want
		ec2err, ok := err.(*ec2.Error)
		if !ok {
			return err
		}
		if ec2err.Code != "InvalidInstanceID.NotFound" {
			return err
		}
	}

	return nil
}

func testAccCheckInstanceExists(n string, i *ec2.Instance) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No ID is set")
		}

		conn := testAccProvider.ec2conn
		resp, err := conn.Instances(
			[]string{rs.Primary.ID}, ec2.NewFilter())
		if err != nil {
			return err
		}
		if len(resp.Reservations) == 0 {
			return fmt.Errorf("Instance not found")
		}

		*i = resp.Reservations[0].Instances[0]

		return nil
	}
}

const testAccInstanceConfig = `
resource "aws_security_group" "tf_test_foo" {
	name = "tf_test_foo"
	description = "foo"

	ingress {
		protocol = "icmp"
		from_port = -1
		to_port = -1
		cidr_blocks = ["0.0.0.0/0"]
	}
}

resource "aws_instance" "foo" {
	# us-west-2
	ami = "ami-4fccb37f"
	availability_zone = "us-west-2a"

	instance_type = "m1.small"
	security_groups = ["${aws_security_group.tf_test_foo.name}"]
	user_data = "foo"
}
`

const testAccInstanceConfigSourceDest = `
resource "aws_vpc" "foo" {
	cidr_block = "10.1.0.0/16"
}

resource "aws_subnet" "foo" {
	cidr_block = "10.1.1.0/24"
	vpc_id = "${aws_vpc.foo.id}"
}

resource "aws_instance" "foo" {
	# us-west-2
	ami = "ami-4fccb37f"
	instance_type = "m1.small"
	subnet_id = "${aws_subnet.foo.id}"
	source_dest_check = true
}
`

const testAccInstanceConfigSourceDestDisable = `
resource "aws_vpc" "foo" {
	cidr_block = "10.1.0.0/16"
}

resource "aws_subnet" "foo" {
	cidr_block = "10.1.1.0/24"
	vpc_id = "${aws_vpc.foo.id}"
}

resource "aws_instance" "foo" {
	# us-west-2
	ami = "ami-4fccb37f"
	instance_type = "m1.small"
	subnet_id = "${aws_subnet.foo.id}"
	source_dest_check = false
}
`

const testAccInstanceConfigVPC = `
resource "aws_vpc" "foo" {
	cidr_block = "10.1.0.0/16"
}

resource "aws_subnet" "foo" {
	cidr_block = "10.1.1.0/24"
	vpc_id = "${aws_vpc.foo.id}"
}

resource "aws_instance" "foo" {
	# us-west-2
	ami = "ami-4fccb37f"
	instance_type = "m1.small"
	subnet_id = "${aws_subnet.foo.id}"
	associate_public_ip_address = true
}
`

const testAccCheckInstanceConfigTags = `
resource "aws_instance" "foo" {
	tags {
		foo = "bar"
	}
}
`

const testAccCheckInstanceConfigTagsUpdate = `
resource "aws_instance" "foo" {
	tags {
		bar = "baz"
	}
}
<commit_msg>providers/aws: fix compile error<commit_after>package aws

import (
	"fmt"
	"testing"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
	"github.com/mitchellh/goamz/ec2"
)

func TestAccAWSInstance_normal(t *testing.T) {
	var v ec2.Instance

	testCheck := func(*terraform.State) error {
		if v.AvailZone != "us-west-2a" {
			return fmt.Errorf("bad availability zone: %#v", v.AvailZone)
		}

		if len(v.SecurityGroups) == 0 {
			return fmt.Errorf("no security groups: %#v", v.SecurityGroups)
		}
		if v.SecurityGroups[0].Name != "tf_test_foo" {
			return fmt.Errorf("no security groups: %#v", v.SecurityGroups)
		}

		return nil
	}

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckInstanceDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccInstanceConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckInstanceExists(
						"aws_instance.foo", &v),
					testCheck,
					resource.TestCheckResourceAttr(
						"aws_instance.foo",
						"user_data",
						"0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"),
				),
			},

			// We repeat the exact same test so that we can be sure
			// that the user data hash stuff is working without generating
			// an incorrect diff.
			resource.TestStep{
				Config: testAccInstanceConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckInstanceExists(
						"aws_instance.foo", &v),
					testCheck,
					resource.TestCheckResourceAttr(
						"aws_instance.foo",
						"user_data",
						"0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"),
				),
			},
		},
	})
}

func TestAccAWSInstance_sourceDestCheck(t *testing.T) {
	var v ec2.Instance

	testCheck := func(enabled bool) resource.TestCheckFunc {
		return func(*terraform.State) error {
			if v.SourceDestCheck != enabled {
				return fmt.Errorf("bad source_dest_check: %#v", v.SourceDestCheck)
			}

			return nil
		}
	}

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckInstanceDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccInstanceConfigSourceDest,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckInstanceExists(
						"aws_instance.foo", &v),
					testCheck(true),
				),
			},

			resource.TestStep{
				Config: testAccInstanceConfigSourceDestDisable,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckInstanceExists(
						"aws_instance.foo", &v),
					testCheck(false),
				),
			},
		},
	})
}

func TestAccAWSInstance_vpc(t *testing.T) {
	var v ec2.Instance

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckInstanceDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccInstanceConfigVPC,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckInstanceExists(
						"aws_instance.foo", &v),
				),
			},
		},
	})
}

func TestAccInstance_tags(t *testing.T) {
	var v ec2.Instance

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckInstanceDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccCheckInstanceConfigTags,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckInstanceExists("aws_instance.foo", &v),
					testAccCheckTags(&v.Tags, "foo", "bar"),
				),
			},

			resource.TestStep{
				Config: testAccCheckInstanceConfigTagsUpdate,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckInstanceExists("aws_instance.foo", &v),
					testAccCheckTags(&v.Tags, "foo", ""),
					testAccCheckTags(&v.Tags, "bar", "baz"),
				),
			},
		},
	})
}

func testAccCheckInstanceDestroy(s *terraform.State) error {
	conn := testAccProvider.ec2conn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_instance" {
			continue
		}

		// Try to find the resource
		resp, err := conn.Instances(
			[]string{rs.Primary.ID}, ec2.NewFilter())
		if err == nil {
			if len(resp.Reservations) > 0 {
				return fmt.Errorf("still exist.")
			}

			return nil
		}

		// Verify the error is what we want
		ec2err, ok := err.(*ec2.Error)
		if !ok {
			return err
		}
		if ec2err.Code != "InvalidInstanceID.NotFound" {
			return err
		}
	}

	return nil
}

func testAccCheckInstanceExists(n string, i *ec2.Instance) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No ID is set")
		}

		conn := testAccProvider.ec2conn
		resp, err := conn.Instances(
			[]string{rs.Primary.ID}, ec2.NewFilter())
		if err != nil {
			return err
		}
		if len(resp.Reservations) == 0 {
			return fmt.Errorf("Instance not found")
		}

		*i = resp.Reservations[0].Instances[0]

		return nil
	}
}

const testAccInstanceConfig = `
resource "aws_security_group" "tf_test_foo" {
	name = "tf_test_foo"
	description = "foo"

	ingress {
		protocol = "icmp"
		from_port = -1
		to_port = -1
		cidr_blocks = ["0.0.0.0/0"]
	}
}

resource "aws_instance" "foo" {
	# us-west-2
	ami = "ami-4fccb37f"
	availability_zone = "us-west-2a"

	instance_type = "m1.small"
	security_groups = ["${aws_security_group.tf_test_foo.name}"]
	user_data = "foo"
}
`

const testAccInstanceConfigSourceDest = `
resource "aws_vpc" "foo" {
	cidr_block = "10.1.0.0/16"
}

resource "aws_subnet" "foo" {
	cidr_block = "10.1.1.0/24"
	vpc_id = "${aws_vpc.foo.id}"
}

resource "aws_instance" "foo" {
	# us-west-2
	ami = "ami-4fccb37f"
	instance_type = "m1.small"
	subnet_id = "${aws_subnet.foo.id}"
	source_dest_check = true
}
`

const testAccInstanceConfigSourceDestDisable = `
resource "aws_vpc" "foo" {
	cidr_block = "10.1.0.0/16"
}

resource "aws_subnet" "foo" {
	cidr_block = "10.1.1.0/24"
	vpc_id = "${aws_vpc.foo.id}"
}

resource "aws_instance" "foo" {
	# us-west-2
	ami = "ami-4fccb37f"
	instance_type = "m1.small"
	subnet_id = "${aws_subnet.foo.id}"
	source_dest_check = false
}
`

const testAccInstanceConfigVPC = `
resource "aws_vpc" "foo" {
	cidr_block = "10.1.0.0/16"
}

resource "aws_subnet" "foo" {
	cidr_block = "10.1.1.0/24"
	vpc_id = "${aws_vpc.foo.id}"
}

resource "aws_instance" "foo" {
	# us-west-2
	ami = "ami-4fccb37f"
	instance_type = "m1.small"
	subnet_id = "${aws_subnet.foo.id}"
	associate_public_ip_address = true
}
`

const testAccCheckInstanceConfigTags = `
resource "aws_instance" "foo" {
	tags {
		foo = "bar"
	}
}
`

const testAccCheckInstanceConfigTagsUpdate = `
resource "aws_instance" "foo" {
	tags {
		bar = "baz"
	}
}
`
<|endoftext|>