<commit_before>// Copyright © 2016 Abcum Ltd
//
// 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 orbit

import (
	"fmt"
	"path"

	"github.com/robertkrimen/otto"
)

func null() module {
	return func(ctx *Orbit) (val otto.Value, err error) {
		return otto.UndefinedValue(), nil
	}
}

func load(name string, fold string) module {
	return func(ctx *Orbit) (val otto.Value, err error) {

		// Check loaded modules
		if module, ok := ctx.modules[name]; ok {
			return module, nil
		}

		// Check global modules
		if module, ok := modules[name]; ok {
			return module(ctx)
		}

		ctx.modules[name], err = find(name, fold)(ctx)

		return ctx.modules[name], err

	}
}

func find(name string, fold string) module {
	return func(ctx *Orbit) (val otto.Value, err error) {

		if len(name) == 0 {
			return otto.UndefinedValue(), fmt.Errorf("No module name specified")
		}

		var files []string

		if path.IsAbs(name) == true {
			if path.Ext(name) != "" {
				files = append(files, name)
			}
			if path.Ext(name) == "" {
				files = append(files, name+".js")
				files = append(files, path.Join(name, "index.js"))
			}
		}

		if path.IsAbs(name) == false {
			if path.Ext(name) != "" {
				files = append(files, path.Join(fold, name))
			}
			if path.Ext(name) == "" {
				files = append(files, path.Join(fold, name)+".js")
				files = append(files, path.Join(fold, name, "index.js"))
			}
		}

		code, file, err := finder(ctx, files)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		return exec(code, file)(ctx)

	}
}

func main(code interface{}, full string) module {
	return func(ctx *Orbit) (val otto.Value, err error) {

		fold, file := path.Split(full)

		script := fmt.Sprintf("%s\n%s\n%s", "(function(module) { var require = module.require; var exports = module.exports;", code, "})")

		module, _ := ctx.Object(`({})`)

		module.Set("id", full)
		module.Set("loaded", true)
		module.Set("filename", full)

		module.Set("exports", map[string]interface{}{})
		ctx.Set("__dirname", fold)
		ctx.Set("__filename", file)

		module.Set("require", func(call otto.FunctionCall) otto.Value {
			arg := call.Argument(0).String()
			val, err := load(arg, fold)(ctx)
			if err != nil {
				ctx.Call("new Error", nil, err.Error())
			}
			return val
		})

		ret, err := ctx.Call(script, nil, module)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		exp, err := module.Get("exports")
		if err != nil {
			return otto.UndefinedValue(), err
		}

		if exp.IsFunction() {
			val, err = module.Call("exports")
			return
		}

		if exp.IsDefined() {
			val = exp
			return
		}

		if ret.IsDefined() {
			val = ret
			return
		}

		return

	}

}

func exec(code interface{}, full string) module {
	return func(ctx *Orbit) (val otto.Value, err error) {

		fold, file := path.Split(full)

		script := fmt.Sprintf("%s\n%s\n%s", "(function(module) { var require = module.require; var exports = module.exports;", code, "})")

		module, _ := ctx.Object(`({})`)

		module.Set("id", full)
		module.Set("loaded", true)
		module.Set("filename", full)

		ctx.Set("__dirname", fold)
		ctx.Set("__filename", file)

		module.Set("require", func(call otto.FunctionCall) otto.Value {
			arg := call.Argument(0).String()
			val, err := load(arg, fold)(ctx)
			if err != nil {
				ctx.Call("new Error", nil, err.Error())
			}
			return val
		})

		ret, err := ctx.Call(data, export, module)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		if ret.IsDefined() {
			val = ret
		}

		if ret.IsUndefined() {
			val, err = module.Get("exports")
		}

		return

	}

}
<commit_msg>Exports must not be set initially<commit_after>// Copyright © 2016 Abcum Ltd
//
// 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 orbit

import (
	"fmt"
	"path"

	"github.com/robertkrimen/otto"
)

func null() module {
	return func(ctx *Orbit) (val otto.Value, err error) {
		return otto.UndefinedValue(), nil
	}
}

func load(name string, fold string) module {
	return func(ctx *Orbit) (val otto.Value, err error) {

		// Check loaded modules
		if module, ok := ctx.modules[name]; ok {
			return module, nil
		}

		// Check global modules
		if module, ok := modules[name]; ok {
			return module(ctx)
		}

		ctx.modules[name], err = find(name, fold)(ctx)

		return ctx.modules[name], err

	}
}

func find(name string, fold string) module {
	return func(ctx *Orbit) (val otto.Value, err error) {

		if len(name) == 0 {
			return otto.UndefinedValue(), fmt.Errorf("No module name specified")
		}

		var files []string

		if path.IsAbs(name) == true {
			if path.Ext(name) != "" {
				files = append(files, name)
			}
			if path.Ext(name) == "" {
				files = append(files, name+".js")
				files = append(files, path.Join(name, "index.js"))
			}
		}

		if path.IsAbs(name) == false {
			if path.Ext(name) != "" {
				files = append(files, path.Join(fold, name))
			}
			if path.Ext(name) == "" {
				files = append(files, path.Join(fold, name)+".js")
				files = append(files, path.Join(fold, name, "index.js"))
			}
		}

		code, file, err := finder(ctx, files)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		return exec(code, file)(ctx)

	}
}

func main(code interface{}, full string) module {
	return func(ctx *Orbit) (val otto.Value, err error) {

		fold, file := path.Split(full)

		script := fmt.Sprintf("%s\n%s\n%s", "(function(module) { var require = module.require; var exports = module.exports;", code, "})")

		module, _ := ctx.Object(`({})`)

		module.Set("id", full)
		module.Set("loaded", true)
		module.Set("filename", full)

		ctx.Set("__dirname", fold)
		ctx.Set("__filename", file)

		module.Set("require", func(call otto.FunctionCall) otto.Value {
			arg := call.Argument(0).String()
			val, err := load(arg, fold)(ctx)
			if err != nil {
				ctx.Call("new Error", nil, err.Error())
			}
			return val
		})

		ret, err := ctx.Call(script, nil, module)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		exp, err := module.Get("exports")
		if err != nil {
			return otto.UndefinedValue(), err
		}

		if exp.IsFunction() {
			val, err = module.Call("exports")
			return
		}

		if exp.IsDefined() {
			val = exp
			return
		}

		if ret.IsDefined() {
			val = ret
			return
		}

		return

	}

}

func exec(code interface{}, full string) module {
	return func(ctx *Orbit) (val otto.Value, err error) {

		fold, file := path.Split(full)

		script := fmt.Sprintf("%s\n%s\n%s", "(function(module) { var require = module.require; var exports = module.exports;", code, "})")

		module, _ := ctx.Object(`({})`)

		module.Set("id", full)
		module.Set("loaded", true)
		module.Set("filename", full)

		ctx.Set("__dirname", fold)
		ctx.Set("__filename", file)

		module.Set("require", func(call otto.FunctionCall) otto.Value {
			arg := call.Argument(0).String()
			val, err := load(arg, fold)(ctx)
			if err != nil {
				ctx.Call("new Error", nil, err.Error())
			}
			return val
		})

		ret, err := ctx.Call(data, export, module)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		if ret.IsDefined() {
			val = ret
		}

		if ret.IsUndefined() {
			val, err = module.Get("exports")
		}

		return

	}

}
<|endoftext|>


<commit_before>package stats

import (
	"time"

	"skia.googlesource.com/buildbot.git/perf/go/config"
	"skia.googlesource.com/buildbot.git/perf/go/gitinfo"
	"skia.googlesource.com/buildbot.git/perf/go/types"

	"github.com/golang/glog"
	"github.com/rcrowley/go-metrics"
)

// Start calculating and reporting statistics on the repo and tiles.
//
// We presume the git.Update(true) is called somewhere else, usually this is done
// in the ingester, so the repo is always as good as the ingested tiles.
func Start(tileStore types.TileStore, git *gitinfo.GitInfo) {
	coverage := metrics.NewRegisteredGaugeFloat64("stats.tests.bench_runs_per_changelist", metrics.DefaultRegistry)
	skpLatency := metrics.NewRegisteredTimer("stats.skp.update_latency", metrics.DefaultRegistry)

	for _ = range time.Tick(2 * time.Minute) {
		tile, err := tileStore.Get(0, -1)
		if err != nil {
			glog.Warning("Failed to get tile: %s", err)
			continue
		}
		numCommits := tile.LastCommitIndex() + 1
		numTraces := len(tile.Traces)
		total := 0
		for _, tr := range tile.Traces {
			for i := 0; i < numCommits; i++ {
				if tr.Values[i] != config.MISSING_DATA_SENTINEL {
					total += 1
				}
			}
		}
		cov := float64(total) / float64(numCommits*numTraces)
		glog.Info("Coverage: ", cov)
		coverage.Update(cov)

		last, err := git.LastSkpCommit()
		if err != nil {
			glog.Warning("Failed to read last SKP commit: %s", err)
			continue
		}
		skpLatency.Update(time.Now().Sub(last))
	}
}
<commit_msg>Fix stats so it doesn't hang the server.<commit_after>package stats

import (
	"time"

	"skia.googlesource.com/buildbot.git/perf/go/config"
	"skia.googlesource.com/buildbot.git/perf/go/gitinfo"
	"skia.googlesource.com/buildbot.git/perf/go/types"

	"github.com/golang/glog"
	"github.com/rcrowley/go-metrics"
)

// Start calculating and reporting statistics on the repo and tiles.
//
// We presume the git.Update(true) is called somewhere else, usually this is done
// in the ingester, so the repo is always as good as the ingested tiles.
func Start(tileStore types.TileStore, git *gitinfo.GitInfo) {
	coverage := metrics.NewRegisteredGaugeFloat64("stats.tests.bench_runs_per_changelist", metrics.DefaultRegistry)
	skpLatency := metrics.NewRegisteredTimer("stats.skp.update_latency", metrics.DefaultRegistry)

	go func() {
		for _ = range time.Tick(2 * time.Minute) {
			tile, err := tileStore.Get(0, -1)
			if err != nil {
				glog.Warning("Failed to get tile: %s", err)
				continue
			}
			numCommits := tile.LastCommitIndex() + 1
			numTraces := len(tile.Traces)
			total := 0
			for _, tr := range tile.Traces {
				for i := 0; i < numCommits; i++ {
					if tr.Values[i] != config.MISSING_DATA_SENTINEL {
						total += 1
					}
				}
			}
			cov := float64(total) / float64(numCommits*numTraces)
			glog.Info("Coverage: ", cov)
			coverage.Update(cov)

			last, err := git.LastSkpCommit()
			if err != nil {
				glog.Warning("Failed to read last SKP commit: %s", err)
				continue
			}
			skpLatency.Update(time.Now().Sub(last))
		}
	}()
}
<|endoftext|>


<commit_before>// Copyright 2015 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package context

import (
	"github.com/juju/errors"

	"github.com/juju/juju/process"
	"github.com/juju/juju/worker/uniter/runner"
	"github.com/juju/juju/worker/uniter/runner/jujuc"
)

func init() {
	runner.RegisterComponentFunc("process", func() jujuc.ContextComponent {
		return NewContext()
	})
}

// Context is the workload process portion of the hook context.
type Context struct {
	processes map[string]*process.Info
	dirty     bool
}

// NewContext returns a new jujuc.ContextComponent for workload processes.
func NewContext(procs ...*process.Info) *Context {
	processes := make(map[string]*process.Info)
	for _, proc := range procs {
		processes[proc.Name] = proc
	}
	return &Context{
		processes: processes,
	}
}

// HookContext is the portion of jujuc.Context used in this package.
type HookContext interface {
	// Component implements jujuc.Context.
	Component(string) (jujuc.ContextComponent, bool)
}

// ContextComponent returns the hook context for the workload
// process component.
func ContextComponent(ctx HookContext) (*Context, error) {
	found, ok := ctx.Component(process.ComponentName)
	if !ok {
		return nil, errors.Errorf("component %q not registered", process.ComponentName)
	}
	if found == nil {
		return nil, errors.Errorf("component %q disabled", process.ComponentName)
	}
	compCtx, ok := found.(*Context)
	if !ok {
		return nil, errors.Errorf("wrong component context type registered: %T", found)
	}
	return compCtx, nil
}

// Processes returns the processes known to the context.
func (c *Context) Processes() []*process.Info {
	var procs []*process.Info
	for _, info := range c.processes {
		procs = append(procs, info)
	}
	return procs
}

// Get implements jujuc.ContextComponent.
func (c *Context) Get(id string, result interface{}) error {
	info, ok := result.(*process.Info)
	if !ok {
		return errors.Errorf("invalid type: expected process.Info, got %T", result)
	}

	actual, ok := c.processes[id]
	if !ok {
		return errors.NotFoundf("%s", id)
	}
	*info = *actual
	return nil
}

// Set implements jujuc.ContextComponent.
func (c *Context) Set(id string, value interface{}) error {
	pInfo, ok := value.(*process.Info)
	if !ok {
		return errors.Errorf("invalid type: expected process.Info, got %T", value)
	}

	if id != pInfo.Name {
		return errors.Errorf("mismatch on name: %s != %s", id, pInfo.Name)
	}

	c.processes[id] = pInfo
	c.dirty = true
	return nil
}

// Flush implements jujuc.ContextComponent.
func (c *Context) Flush() error {
	if !c.dirty {
		return nil
	}
	// TODO(ericsnow) finish
	c.dirty = false
	return errors.Errorf("not finished")
}
<commit_msg>Use the constant for the component name.<commit_after>// Copyright 2015 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package context

import (
	"github.com/juju/errors"

	"github.com/juju/juju/process"
	"github.com/juju/juju/worker/uniter/runner"
	"github.com/juju/juju/worker/uniter/runner/jujuc"
)

func init() {
	runner.RegisterComponentFunc(process.ComponentName,
		func() jujuc.ContextComponent {
			return NewContext()
		},
	)
}

// Context is the workload process portion of the hook context.
type Context struct {
	processes map[string]*process.Info
	dirty     bool
}

// NewContext returns a new jujuc.ContextComponent for workload processes.
func NewContext(procs ...*process.Info) *Context {
	processes := make(map[string]*process.Info)
	for _, proc := range procs {
		processes[proc.Name] = proc
	}
	return &Context{
		processes: processes,
	}
}

// HookContext is the portion of jujuc.Context used in this package.
type HookContext interface {
	// Component implements jujuc.Context.
	Component(string) (jujuc.ContextComponent, bool)
}

// ContextComponent returns the hook context for the workload
// process component.
func ContextComponent(ctx HookContext) (*Context, error) {
	found, ok := ctx.Component(process.ComponentName)
	if !ok {
		return nil, errors.Errorf("component %q not registered", process.ComponentName)
	}
	if found == nil {
		return nil, errors.Errorf("component %q disabled", process.ComponentName)
	}
	compCtx, ok := found.(*Context)
	if !ok {
		return nil, errors.Errorf("wrong component context type registered: %T", found)
	}
	return compCtx, nil
}

// Processes returns the processes known to the context.
func (c *Context) Processes() []*process.Info {
	var procs []*process.Info
	for _, info := range c.processes {
		procs = append(procs, info)
	}
	return procs
}

// Get implements jujuc.ContextComponent.
func (c *Context) Get(id string, result interface{}) error {
	info, ok := result.(*process.Info)
	if !ok {
		return errors.Errorf("invalid type: expected process.Info, got %T", result)
	}

	actual, ok := c.processes[id]
	if !ok {
		return errors.NotFoundf("%s", id)
	}
	*info = *actual
	return nil
}

// Set implements jujuc.ContextComponent.
func (c *Context) Set(id string, value interface{}) error {
	pInfo, ok := value.(*process.Info)
	if !ok {
		return errors.Errorf("invalid type: expected process.Info, got %T", value)
	}

	if id != pInfo.Name {
		return errors.Errorf("mismatch on name: %s != %s", id, pInfo.Name)
	}

	c.processes[id] = pInfo
	c.dirty = true
	return nil
}

// Flush implements jujuc.ContextComponent.
func (c *Context) Flush() error {
	if !c.dirty {
		return nil
	}
	// TODO(ericsnow) finish
	c.dirty = false
	return errors.Errorf("not finished")
}
<|endoftext|>


<commit_before>package ecqltest

import (
	"github.com/maraino/ecql"
	"github.com/maraino/go-mock"
)

type Statement struct {
	mock.Mock
}

func NewStatement() ecql.Statement {
	return &Statement{}
}

func (m *Statement) TypeScan() error {
	var result = m.Called()
	return result.Error(0)
}

func (m *Statement) Scan(i ...interface{}) error {
	var result = m.Called(i)
	return result.Error(0)
}

func (m *Statement) Exec() error {
	var result = m.Called()
	return result.Error(0)
}

func (m *Statement) Iter() ecql.Iter {
	var result = m.Called()
	return result.Get(0).(ecql.Iter)
}

func (m *Statement) Do(cmd ecql.Command) ecql.Statement {
	var result = m.Called(cmd)
	return result.Get(0).(ecql.Statement)
}

func (m *Statement) From(table string) ecql.Statement {
	var result = m.Called(table)
	return result.Get(0).(ecql.Statement)
}

func (m *Statement) FromType(i interface{}) ecql.Statement {
	var result = m.Called(i)
	return result.Get(0).(ecql.Statement)
}

func (m *Statement) Columns(columns ...string) ecql.Statement {
	var result = m.Called(columns)
	return result.Get(0).(ecql.Statement)
}

func (m *Statement) Set(column string, value interface{}) ecql.Statement {
	var result = m.Called(column, value)
	return result.Get(0).(ecql.Statement)
}

func (m *Statement) Where(cond ...ecql.Condition) ecql.Statement {
	var result = m.Called(cond)
	return result.Get(0).(ecql.Statement)
}

func (m *Statement) OrderBy(order ...ecql.OrderBy) ecql.Statement {
	var result = m.Called(order)
	return result.Get(0).(ecql.Statement)
}

func (m *Statement) Bind(i interface{}) ecql.Statement {
	var result = m.Called(i)
	return result.Get(0).(ecql.Statement)
}

func (m *Statement) Map(i interface{}) ecql.Statement {
	var result = m.Called(i)
	return result.Get(0).(ecql.Statement)
}

func (m *Statement) Limit(n int) ecql.Statement {
	var result = m.Called(n)
	return result.Get(0).(ecql.Statement)
}

func (m *Statement) TTL(seconds int) ecql.Statement {
	var result = m.Called(seconds)
	return result.Get(0).(ecql.Statement)
}
<commit_msg>Properly unwrap (and rewrap) mock parameters<commit_after>package ecqltest

import (
	"github.com/maraino/ecql"
	"github.com/maraino/go-mock"
)

type Statement struct {
	mock.Mock
}

func NewStatement() ecql.Statement {
	return &Statement{}
}

func (m *Statement) TypeScan() error {
	var result = m.Called()
	return result.Error(0)
}

func (m *Statement) Scan(i ...interface{}) error {
	var result = m.Called(i...)
	return result.Error(0)
}

func (m *Statement) Exec() error {
	var result = m.Called()
	return result.Error(0)
}

func (m *Statement) Iter() ecql.Iter {
	var result = m.Called()
	return result.Get(0).(ecql.Iter)
}

func (m *Statement) Do(cmd ecql.Command) ecql.Statement {
	var result = m.Called(cmd)
	return result.Get(0).(ecql.Statement)
}

func (m *Statement) From(table string) ecql.Statement {
	var result = m.Called(table)
	return result.Get(0).(ecql.Statement)
}

func (m *Statement) FromType(i interface{}) ecql.Statement {
	var result = m.Called(i)
	return result.Get(0).(ecql.Statement)
}

func (m *Statement) Columns(columns ...string) ecql.Statement {
	slice := make([]interface{}, len(columns))
	for i, v := range columns {
		slice[i] = v
	}
	var result = m.Called(slice...)
	return result.Get(0).(ecql.Statement)
}

func (m *Statement) Set(column string, value interface{}) ecql.Statement {
	var result = m.Called(column, value)
	return result.Get(0).(ecql.Statement)
}

func (m *Statement) Where(cond ...ecql.Condition) ecql.Statement {
	slice := make([]interface{}, len(cond))
	for i, v := range cond {
		slice[i] = v
	}

	var result = m.Called(slice...)
	return result.Get(0).(ecql.Statement)
}

func (m *Statement) OrderBy(order ...ecql.OrderBy) ecql.Statement {
	slice := make([]interface{}, len(order))
	for i, v := range order {
		slice[i] = v
	}
	var result = m.Called(slice...)
	return result.Get(0).(ecql.Statement)
}

func (m *Statement) Bind(i interface{}) ecql.Statement {
	var result = m.Called(i)
	return result.Get(0).(ecql.Statement)
}

func (m *Statement) Map(i interface{}) ecql.Statement {
	var result = m.Called(i)
	return result.Get(0).(ecql.Statement)
}

func (m *Statement) Limit(n int) ecql.Statement {
	var result = m.Called(n)
	return result.Get(0).(ecql.Statement)
}

func (m *Statement) TTL(seconds int) ecql.Statement {
	var result = m.Called(seconds)
	return result.Get(0).(ecql.Statement)
}
<|endoftext|>


<commit_before>package ecs

import (
	"fmt"
	"testing"
)

func ExampleClient_DescribeInstanceStatus() {
	fmt.Printf("DescribeInstanceStatus Example\n")

	args := DescribeInstanceStatusArgs{
		RegionId:   "cn-beijing",
		ZoneId:     "cn-beijing-b",
		Pagination: Pagination{1, 1},
	}

	client := NewClient(TestAccessKeyId, TestAccessKeySecret)
	instanceStatus, _, err := client.DescribeInstanceStatus(&args)

	if err != nil {
		fmt.Printf("Failed to describe Instance: %s status:%v \n", TestInstanceId, err)
	} else {
		for i := 0; i < len(instanceStatus); i++ {
			fmt.Printf("Instance %s Status: %s \n", instanceStatus[i].InstanceId, instanceStatus[i].Status)
		}
	}
}

func ExampleClient_DescribeInstanceAttribute() {
	fmt.Printf("DescribeInstanceAttribute Example\n")

	client := NewClient(TestAccessKeyId, TestAccessKeySecret)

	instanceAttributeType, err := client.DescribeInstanceAttribute(TestInstanceId)

	if err != nil {
		fmt.Printf("Failed to describe Instance %s attribute: %v\n", TestInstanceId, err)
	} else {
		fmt.Printf("Instance Information\n")
		fmt.Printf("InstanceId = %s \n", instanceAttributeType.InstanceId)
		fmt.Printf("InstanceName = %s \n", instanceAttributeType.InstanceName)
		fmt.Printf("HostName = %s \n", instanceAttributeType.HostName)
		fmt.Printf("ZoneId = %s \n", instanceAttributeType.ZoneId)
		fmt.Printf("RegionId = %s \n", instanceAttributeType.RegionId)
	}
}

func ExampleClient_DescribeInstanceVncUrl() {
	fmt.Printf("DescribeInstanceVncUrl Example\n")

	args := DescribeInstanceVncUrlArgs{
		RegionId:   "cn-beijing",
		InstanceId: TestInstanceId,
	}

	client := NewClient(TestAccessKeyId, TestAccessKeySecret)

	instanceVncUrl, err := client.DescribeInstanceVncUrl(&args)

	if err != nil {
		fmt.Printf("Failed to describe Instance %s vnc url: %v \n", TestInstanceId, err)
	} else {
		fmt.Printf("VNC URL = %s \n", instanceVncUrl)
	}
}

func ExampleClient_StopInstance() {
	fmt.Printf("Stop Instance Example\n")

	client := NewClient(TestAccessKeyId, TestAccessKeySecret)

	err := client.StopInstance(TestInstanceId, true)

	if err != nil {
		fmt.Printf("Failed to stop Instance %s vnc url: %v \n", TestInstanceId, err)
	}
}

func ExampleClient_DeleteInstance() {
	fmt.Printf("Delete Instance Example")

	client := NewClient(TestAccessKeyId, TestAccessKeySecret)

	err := client.DeleteInstance(TestInstanceId)

	if err != nil {
		fmt.Printf("Failed to delete Instance %s vnc url: %v \n", TestInstanceId, err)
	}
}

func TestECSInstance(t *testing.T) {

	client := NewClient(TestAccessKeyId, TestAccessKeySecret)
	instance, err := client.DescribeInstanceAttribute(TestInstanceId)
	if err != nil {
		t.Fatalf("Failed to describe instance %s: %v", TestInstanceId, err)
	}
	t.Logf("Instance: %++v  %v", instance, err)
	err = client.StopInstance(TestInstanceId, true)
	if err != nil {
		t.Errorf("Failed to stop instance %s: %v", TestInstanceId, err)
	}
	err = client.WaitForInstance(TestInstanceId, Stopped, 0)
	if err != nil {
		t.Errorf("Instance %s is failed to stop: %v", TestInstanceId, err)
	}
	t.Logf("Instance %s is stopped successfully.", TestInstanceId)
	err = client.StartInstance(TestInstanceId)
	if err != nil {
		t.Errorf("Failed to start instance %s: %v", TestInstanceId, err)
	}
	err = client.WaitForInstance(TestInstanceId, Running, 0)
	if err != nil {
		t.Errorf("Instance %s is failed to start: %v", TestInstanceId, err)
	}
	t.Logf("Instance %s is running successfully.", TestInstanceId)
	err = client.RebootInstance(TestInstanceId, true)
	if err != nil {
		t.Errorf("Failed to restart instance %s: %v", TestInstanceId, err)
	}
	err = client.WaitForInstance(TestInstanceId, Running, 0)
	if err != nil {
		t.Errorf("Instance %s is failed to restart: %v", TestInstanceId, err)
	}
	t.Logf("Instance %s is running successfully.", TestInstanceId)
}

func TestECSInstanceCreationAndDeletion(t *testing.T) {

	if TestIAmRich == false { // Avoid payment
		return
	}

	client := NewClient(TestAccessKeyId, TestAccessKeySecret)
	instance, err := client.DescribeInstanceAttribute(TestInstanceId)
	t.Logf("Instance: %++v  %v", instance, err)

	args := CreateInstanceArgs{
		RegionId:        instance.RegionId,
		ImageId:         instance.ImageId,
		InstanceType:    "ecs.t1.small",
		SecurityGroupId: instance.SecurityGroupIds.SecurityGroupId[0],
	}

	instanceId, err := client.CreateInstance(&args)
	if err != nil {
		t.Errorf("Failed to create instance from Image %s: %v", args.ImageId, err)
	}
	t.Logf("Instance %s is created successfully.", instanceId)

	instance, err = client.DescribeInstanceAttribute(instanceId)
	t.Logf("Instance: %++v  %v", instance, err)

	err = client.WaitForInstance(instanceId, Stopped, 60)

	err = client.StartInstance(instanceId)
	if err != nil {
		t.Errorf("Failed to start instance %s: %v", instanceId, err)
	}
	err = client.WaitForInstance(instanceId, Running, 0)

	err = client.StopInstance(instanceId, true)
	if err != nil {
		t.Errorf("Failed to stop instance %s: %v", instanceId, err)
	}
	err = client.WaitForInstance(instanceId, Stopped, 0)
	if err != nil {
		t.Errorf("Instance %s is failed to stop: %v", instanceId, err)
	}
	t.Logf("Instance %s is stopped successfully.", instanceId)

	err = client.DeleteInstance(instanceId)

	if err != nil {
		t.Errorf("Failed to delete instance %s: %v", instanceId, err)
	}
	t.Logf("Instance %s is deleted successfully.", instanceId)
}
<commit_msg>Fix the issue for the vet: instances_test.go: instances_test.go:89:2: illegal character U+0001 (and 10 more errors)<commit_after>package ecs

import (
	"fmt"
	"testing"
)

func ExampleClient_DescribeInstanceStatus() {
	fmt.Printf("DescribeInstanceStatus Example\n")

	args := DescribeInstanceStatusArgs{
		RegionId:   "cn-beijing",
		ZoneId:     "cn-beijing-b",
		Pagination: Pagination{1, 1},
	}

	client := NewClient(TestAccessKeyId, TestAccessKeySecret)
	instanceStatus, _, err := client.DescribeInstanceStatus(&args)

	if err != nil {
		fmt.Printf("Failed to describe Instance: %s status:%v \n", TestInstanceId, err)
	} else {
		for i := 0; i < len(instanceStatus); i++ {
			fmt.Printf("Instance %s Status: %s \n", instanceStatus[i].InstanceId, instanceStatus[i].Status)
		}
	}
}

func ExampleClient_DescribeInstanceAttribute() {
	fmt.Printf("DescribeInstanceAttribute Example\n")

	client := NewClient(TestAccessKeyId, TestAccessKeySecret)

	instanceAttributeType, err := client.DescribeInstanceAttribute(TestInstanceId)

	if err != nil {
		fmt.Printf("Failed to describe Instance %s attribute: %v\n", TestInstanceId, err)
	} else {
		fmt.Printf("Instance Information\n")
		fmt.Printf("InstanceId = %s \n", instanceAttributeType.InstanceId)
		fmt.Printf("InstanceName = %s \n", instanceAttributeType.InstanceName)
		fmt.Printf("HostName = %s \n", instanceAttributeType.HostName)
		fmt.Printf("ZoneId = %s \n", instanceAttributeType.ZoneId)
		fmt.Printf("RegionId = %s \n", instanceAttributeType.RegionId)
	}
}

func ExampleClient_DescribeInstanceVncUrl() {
	fmt.Printf("DescribeInstanceVncUrl Example\n")

	args := DescribeInstanceVncUrlArgs{
		RegionId:   "cn-beijing",
		InstanceId: TestInstanceId,
	}

	client := NewClient(TestAccessKeyId, TestAccessKeySecret)

	instanceVncUrl, err := client.DescribeInstanceVncUrl(&args)

	if err != nil {
		fmt.Printf("Failed to describe Instance %s vnc url: %v \n", TestInstanceId, err)
	} else {
		fmt.Printf("VNC URL = %s \n", instanceVncUrl)
	}
}

func ExampleClient_StopInstance() {
	fmt.Printf("Stop Instance Example\n")

	client := NewClient(TestAccessKeyId, TestAccessKeySecret)

	err := client.StopInstance(TestInstanceId, true)

	if err != nil {
		fmt.Printf("Failed to stop Instance %s vnc url: %v \n", TestInstanceId, err)
	}
}

func ExampleClient_DeleteInstance() {
	fmt.Printf("Delete Instance Example")

	client := NewClient(TestAccessKeyId, TestAccessKeySecret)

	err := client.DeleteInstance(TestInstanceId)

	if err != nil {
		fmt.Printf("Failed to delete Instance %s vnc url: %v \n", TestInstanceId, err)
	}
}

func TestECSInstance(t *testing.T) {

	client := NewClient(TestAccessKeyId, TestAccessKeySecret)
	instance, err := client.DescribeInstanceAttribute(TestInstanceId)
	if err != nil {
		t.Fatalf("Failed to describe instance %s: %v", TestInstanceId, err)
	}
	t.Logf("Instance: %++v  %v", instance, err)
	err = client.StopInstance(TestInstanceId, true)
	if err != nil {
		t.Errorf("Failed to stop instance %s: %v", TestInstanceId, err)
	}
	err = client.WaitForInstance(TestInstanceId, Stopped, 0)
	if err != nil {
		t.Errorf("Instance %s is failed to stop: %v", TestInstanceId, err)
	}
	t.Logf("Instance %s is stopped successfully.", TestInstanceId)
	err = client.StartInstance(TestInstanceId)
	if err != nil {
		t.Errorf("Failed to start instance %s: %v", TestInstanceId, err)
	}
	err = client.WaitForInstance(TestInstanceId, Running, 0)
	if err != nil {
		t.Errorf("Instance %s is failed to start: %v", TestInstanceId, err)
	}
	t.Logf("Instance %s is running successfully.", TestInstanceId)
	err = client.RebootInstance(TestInstanceId, true)
	if err != nil {
		t.Errorf("Failed to restart instance %s: %v", TestInstanceId, err)
	}
	err = client.WaitForInstance(TestInstanceId, Running, 0)
	if err != nil {
		t.Errorf("Instance %s is failed to restart: %v", TestInstanceId, err)
	}
	t.Logf("Instance %s is running successfully.", TestInstanceId)
}

func TestECSInstanceCreationAndDeletion(t *testing.T) {

	if TestIAmRich == false { // Avoid payment
		return
	}

	client := NewClient(TestAccessKeyId, TestAccessKeySecret)
	instance, err := client.DescribeInstanceAttribute(TestInstanceId)
	t.Logf("Instance: %++v  %v", instance, err)

	args := CreateInstanceArgs{
		RegionId:        instance.RegionId,
		ImageId:         instance.ImageId,
		InstanceType:    "ecs.t1.small",
		SecurityGroupId: instance.SecurityGroupIds.SecurityGroupId[0],
	}

	instanceId, err := client.CreateInstance(&args)
	if err != nil {
		t.Errorf("Failed to create instance from Image %s: %v", args.ImageId, err)
	}
	t.Logf("Instance %s is created successfully.", instanceId)

	instance, err = client.DescribeInstanceAttribute(instanceId)
	t.Logf("Instance: %++v  %v", instance, err)

	err = client.WaitForInstance(instanceId, Stopped, 60)

	err = client.StartInstance(instanceId)
	if err != nil {
		t.Errorf("Failed to start instance %s: %v", instanceId, err)
	}
	err = client.WaitForInstance(instanceId, Running, 0)

	err = client.StopInstance(instanceId, true)
	if err != nil {
		t.Errorf("Failed to stop instance %s: %v", instanceId, err)
	}
	err = client.WaitForInstance(instanceId, Stopped, 0)
	if err != nil {
		t.Errorf("Instance %s is failed to stop: %v", instanceId, err)
	}
	t.Logf("Instance %s is stopped successfully.", instanceId)

	err = client.DeleteInstance(instanceId)

	if err != nil {
		t.Errorf("Failed to delete instance %s: %v", instanceId, err)
	}
	t.Logf("Instance %s is deleted successfully.", instanceId)
}
<|endoftext|>


<commit_before>package ec2

import (
	"io/ioutil"
	"launchpad.net/goamz/aws"
	. "launchpad.net/gocheck"
	"launchpad.net/goyaml"
	"launchpad.net/juju-core/environs"
	"launchpad.net/juju-core/environs/config"
	"launchpad.net/juju-core/testing"
	"os"
	"path/filepath"
	"strings"
)

// Use local suite since this file lives in the ec2 package
// for testing internals.
type ConfigSuite struct {
	savedHome, savedAccessKey, savedSecretKey string
}

var _ = Suite(&ConfigSuite{})

var configTestRegion = aws.Region{
	Name:        "configtest",
	EC2Endpoint: "testregion.nowhere:1234",
}

var testAuth = aws.Auth{"gopher", "long teeth"}

// configTest specifies a config parsing test, checking that env when
// parsed as the ec2 section of a config file matches baseConfigResult
// when mutated by the mutate function, or that the parse matches the
// given error.
type configTest struct {
	config        attrs
	change        attrs
	region        string
	cbucket       string
	pbucket       string
	pbucketRegion string
	accessKey     string
	secretKey     string
	firewallMode  config.FirewallMode
	err           string
}

type attrs map[string]interface{}

func (t configTest) check(c *C) {
	envs := attrs{
		"environments": attrs{
			"testenv": attrs{
				"type":           "ec2",
				"ca-cert":        testing.CACert,
				"ca-private-key": testing.CAKey,
			},
		},
	}
	testenv := envs["environments"].(attrs)["testenv"].(attrs)
	for k, v := range t.config {
		testenv[k] = v
	}
	if _, ok := testenv["control-bucket"]; !ok {
		testenv["control-bucket"] = "x"
	}
	data, err := goyaml.Marshal(envs)
	c.Assert(err, IsNil)

	es, err := environs.ReadEnvironsBytes(data)
	c.Check(err, IsNil)

	e, err := es.Open("testenv")
	if t.change != nil {
		c.Assert(err, IsNil)

		// Testing a change in configuration.
		var old, changed, valid *config.Config
		ec2env := e.(*environ)
		old = ec2env.ecfg().Config
		changed, err = old.Apply(t.change)
		c.Assert(err, IsNil)

		// Keep err for validation below.
		valid, err = providerInstance.Validate(changed, old)
		if err == nil {
			err = ec2env.SetConfig(valid)
		}
	}
	if t.err != "" {
		c.Check(err, ErrorMatches, t.err)
		return
	}
	c.Assert(err, IsNil)

	ecfg := e.(*environ).ecfg()
	c.Assert(ecfg.Name(), Equals, "testenv")
	c.Assert(ecfg.controlBucket(), Equals, "x")
	if t.region != "" {
		c.Assert(ecfg.region(), Equals, t.region)
	}
	if t.pbucket != "" {
		c.Assert(ecfg.publicBucket(), Equals, t.pbucket)
	}
	if t.accessKey != "" {
		c.Assert(ecfg.accessKey(), Equals, t.accessKey)
		c.Assert(ecfg.secretKey(), Equals, t.secretKey)
		expected := map[string]interface{}{
			"access-key": t.accessKey,
			"secret-key": t.secretKey,
		}
		c.Assert(err, IsNil)
		actual, err := e.Provider().SecretAttrs(ecfg.Config)
		c.Assert(err, IsNil)
		c.Assert(expected, DeepEquals, actual)
	} else {
		c.Assert(ecfg.accessKey(), DeepEquals, testAuth.AccessKey)
		c.Assert(ecfg.secretKey(), DeepEquals, testAuth.SecretKey)
	}
	if t.firewallMode != "" {
		c.Assert(ecfg.FirewallMode(), Equals, t.firewallMode)
	}

	// check storage buckets are configured correctly
	env := e.(*environ)
	c.Assert(env.Storage().(*storage).bucket.Region.Name, Equals, ecfg.region())
	c.Assert(env.PublicStorage().(*storage).bucket.Region.Name, Equals, ecfg.publicBucketRegion())
}

var configTests = []configTest{
	{
		config:  attrs{},
		pbucket: "juju-dist",
	}, {
		// check that region defaults to us-east-1
		config: attrs{},
		region: "us-east-1",
	}, {
		config: attrs{
			"region": "eu-west-1",
		},
		region: "eu-west-1",
	}, {
		config: attrs{
			"region": "unknown",
		},
		err: ".*invalid region name.*",
	}, {
		config: attrs{
			"region": "configtest",
		},
		region: "configtest",
	}, {
		config: attrs{
			"region": "configtest",
		},
		change: attrs{
			"region": "us-east-1",
		},
		err: `cannot change region from "configtest" to "us-east-1"`,
	}, {
		config: attrs{
			"region": 666,
		},
		err: ".*expected string, got 666",
	}, {
		config: attrs{
			"access-key": 666,
		},
		err: ".*expected string, got 666",
	}, {
		config: attrs{
			"secret-key": 666,
		},
		err: ".*expected string, got 666",
	}, {
		config: attrs{
			"control-bucket": 666,
		},
		err: ".*expected string, got 666",
	}, {
		change: attrs{
			"control-bucket": "new-x",
		},
		err: `cannot change control-bucket from "x" to "new-x"`,
	}, {
		config: attrs{
			"public-bucket": 666,
		},
		err: ".*expected string, got 666",
	}, {
		config: attrs{
			"public-bucket": "foo",
		},
		pbucket: "foo",
	}, {
		// check that public-bucket-region defaults to
		// us-east-1, the S3 endpoint that owns juju-dist
		config:        attrs{},
		pbucketRegion: "us-east-1",
	}, {
		config: attrs{
			"public-bucket-region": "foo",
		},
		err: ".*invalid public-bucket-region name.*",
	}, {
		config: attrs{
			"public-bucket-region": "ap-southeast-1",
		},
		pbucketRegion: "ap-southeast-1",
	}, {
		config: attrs{
			"region":               "us-west-1",
			"public-bucket-region": "ap-southeast-1",
		},
		region:        "us-west-1",
		pbucketRegion: "us-east-1",
	}, {
		config: attrs{
			"access-key": "jujuer",
			"secret-key": "open sesame",
		},
		accessKey: "jujuer",
		secretKey: "open sesame",
	}, {
		config: attrs{
			"access-key": "jujuer",
		},
		err: ".*environment has no access-key or secret-key",
	}, {
		config: attrs{
			"secret-key": "badness",
		},
		err: ".*environment has no access-key or secret-key",
	}, {
		config: attrs{
			"admin-secret": "Futumpsh",
		},
	}, {
		config:       attrs{},
		firewallMode: config.FwInstance,
	}, {
		config: attrs{
			"firewall-mode": "",
		},
		firewallMode: config.FwInstance,
	}, {
		config: attrs{
			"firewall-mode": "instance",
		},
		firewallMode: config.FwInstance,
	}, {
		config: attrs{
			"firewall-mode": "global",
		},
		firewallMode: config.FwGlobal,
	},
}

func indent(s string, with string) string {
	var r string
	lines := strings.Split(s, "\n")
	for _, l := range lines {
		r += with + l + "\n"
	}
	return r
}

func (s *ConfigSuite) SetUpTest(c *C) {
	s.savedHome = os.Getenv("HOME")
	s.savedAccessKey = os.Getenv("AWS_ACCESS_KEY_ID")
	s.savedSecretKey = os.Getenv("AWS_SECRET_ACCESS_KEY")

	home := c.MkDir()
	sshDir := filepath.Join(home, ".ssh")
	err := os.Mkdir(sshDir, 0777)
	c.Assert(err, IsNil)
	err = ioutil.WriteFile(filepath.Join(sshDir, "id_rsa.pub"), []byte("sshkey\n"), 0666)
	c.Assert(err, IsNil)

	os.Setenv("HOME", home)
	os.Setenv("AWS_ACCESS_KEY_ID", testAuth.AccessKey)
	os.Setenv("AWS_SECRET_ACCESS_KEY", testAuth.SecretKey)
	aws.Regions["configtest"] = configTestRegion
}

func (s *ConfigSuite) TearDownTest(c *C) {
	os.Setenv("HOME", s.savedHome)
	os.Setenv("AWS_ACCESS_KEY_ID", s.savedAccessKey)
	os.Setenv("AWS_SECRET_ACCESS_KEY", s.savedSecretKey)
	delete(aws.Regions, "configtest")
}

func (s *ConfigSuite) TestConfig(c *C) {
	for i, t := range configTests {
		c.Logf("test %d: %v", i, t.config)
		t.check(c)
	}
}

func (s *ConfigSuite) TestMissingAuth(c *C) {
	os.Setenv("AWS_ACCESS_KEY_ID", "")
	os.Setenv("AWS_SECRET_ACCESS_KEY", "")
	test := configTests[0]
	test.err = "environment has no access-key or secret-key"
	test.check(c)
}
<commit_msg>final tweak<commit_after>package ec2

import (
	"io/ioutil"
	"launchpad.net/goamz/aws"
	. "launchpad.net/gocheck"
	"launchpad.net/goyaml"
	"launchpad.net/juju-core/environs"
	"launchpad.net/juju-core/environs/config"
	"launchpad.net/juju-core/testing"
	"os"
	"path/filepath"
	"strings"
)

// Use local suite since this file lives in the ec2 package
// for testing internals.
type ConfigSuite struct {
	savedHome, savedAccessKey, savedSecretKey string
}

var _ = Suite(&ConfigSuite{})

var configTestRegion = aws.Region{
	Name:        "configtest",
	EC2Endpoint: "testregion.nowhere:1234",
}

var testAuth = aws.Auth{"gopher", "long teeth"}

// configTest specifies a config parsing test, checking that env when
// parsed as the ec2 section of a config file matches baseConfigResult
// when mutated by the mutate function, or that the parse matches the
// given error.
type configTest struct {
	config        attrs
	change        attrs
	region        string
	cbucket       string
	pbucket       string
	pbucketRegion string
	accessKey     string
	secretKey     string
	firewallMode  config.FirewallMode
	err           string
}

type attrs map[string]interface{}

func (t configTest) check(c *C) {
	envs := attrs{
		"environments": attrs{
			"testenv": attrs{
				"type":           "ec2",
				"ca-cert":        testing.CACert,
				"ca-private-key": testing.CAKey,
			},
		},
	}
	testenv := envs["environments"].(attrs)["testenv"].(attrs)
	for k, v := range t.config {
		testenv[k] = v
	}
	if _, ok := testenv["control-bucket"]; !ok {
		testenv["control-bucket"] = "x"
	}
	data, err := goyaml.Marshal(envs)
	c.Assert(err, IsNil)

	es, err := environs.ReadEnvironsBytes(data)
	c.Check(err, IsNil)

	e, err := es.Open("testenv")
	if t.change != nil {
		c.Assert(err, IsNil)

		// Testing a change in configuration.
		var old, changed, valid *config.Config
		ec2env := e.(*environ)
		old = ec2env.ecfg().Config
		changed, err = old.Apply(t.change)
		c.Assert(err, IsNil)

		// Keep err for validation below.
		valid, err = providerInstance.Validate(changed, old)
		if err == nil {
			err = ec2env.SetConfig(valid)
		}
	}
	if t.err != "" {
		c.Check(err, ErrorMatches, t.err)
		return
	}
	c.Assert(err, IsNil)

	ecfg := e.(*environ).ecfg()
	c.Assert(ecfg.Name(), Equals, "testenv")
	c.Assert(ecfg.controlBucket(), Equals, "x")
	if t.region != "" {
		c.Assert(ecfg.region(), Equals, t.region)
	}
	if t.pbucket != "" {
		c.Assert(ecfg.publicBucket(), Equals, t.pbucket)
	}
	if t.accessKey != "" {
		c.Assert(ecfg.accessKey(), Equals, t.accessKey)
		c.Assert(ecfg.secretKey(), Equals, t.secretKey)
		expected := map[string]interface{}{
			"access-key": t.accessKey,
			"secret-key": t.secretKey,
		}
		c.Assert(err, IsNil)
		actual, err := e.Provider().SecretAttrs(ecfg.Config)
		c.Assert(err, IsNil)
		c.Assert(expected, DeepEquals, actual)
	} else {
		c.Assert(ecfg.accessKey(), DeepEquals, testAuth.AccessKey)
		c.Assert(ecfg.secretKey(), DeepEquals, testAuth.SecretKey)
	}
	if t.firewallMode != "" {
		c.Assert(ecfg.FirewallMode(), Equals, t.firewallMode)
	}

	// check storage buckets are configured correctly
	env := e.(*environ)
	c.Assert(env.Storage().(*storage).bucket.Region.Name, Equals, ecfg.region())
	c.Assert(env.PublicStorage().(*storage).bucket.Region.Name, Equals, ecfg.publicBucketRegion())
}

var configTests = []configTest{
	{
		config:  attrs{},
		pbucket: "juju-dist",
	}, {
		// check that region defaults to us-east-1
		config: attrs{},
		region: "us-east-1",
	}, {
		config: attrs{
			"region": "eu-west-1",
		},
		region: "eu-west-1",
	}, {
		config: attrs{
			"region": "unknown",
		},
		err: ".*invalid region name.*",
	}, {
		config: attrs{
			"region": "configtest",
		},
		region: "configtest",
	}, {
		config: attrs{
			"region": "configtest",
		},
		change: attrs{
			"region": "us-east-1",
		},
		err: `cannot change region from "configtest" to "us-east-1"`,
	}, {
		config: attrs{
			"region": 666,
		},
		err: ".*expected string, got 666",
	}, {
		config: attrs{
			"access-key": 666,
		},
		err: ".*expected string, got 666",
	}, {
		config: attrs{
			"secret-key": 666,
		},
		err: ".*expected string, got 666",
	}, {
		config: attrs{
			"control-bucket": 666,
		},
		err: ".*expected string, got 666",
	}, {
		change: attrs{
			"control-bucket": "new-x",
		},
		err: `cannot change control-bucket from "x" to "new-x"`,
	}, {
		config: attrs{
			"public-bucket": 666,
		},
		err: ".*expected string, got 666",
	}, {
		// check that the public-bucket defaults to juju-dist
		config:  attrs{},
		pbucket: "juju-dist",
	}, {
		config: attrs{
			"public-bucket": "foo",
		},
		pbucket: "foo",
	}, {
		// check that public-bucket-region defaults to
		// us-east-1, the S3 endpoint that owns juju-dist
		config:        attrs{},
		pbucketRegion: "us-east-1",
	}, {
		config: attrs{
			"public-bucket-region": "foo",
		},
		err: ".*invalid public-bucket-region name.*",
	}, {
		config: attrs{
			"public-bucket-region": "ap-southeast-1",
		},
		pbucketRegion: "ap-southeast-1",
	}, {
		config: attrs{
			"region":               "us-west-1",
			"public-bucket-region": "ap-southeast-1",
		},
		region:        "us-west-1",
		pbucketRegion: "us-east-1",
	}, {
		config: attrs{
			"access-key": "jujuer",
			"secret-key": "open sesame",
		},
		accessKey: "jujuer",
		secretKey: "open sesame",
	}, {
		config: attrs{
			"access-key": "jujuer",
		},
		err: ".*environment has no access-key or secret-key",
	}, {
		config: attrs{
			"secret-key": "badness",
		},
		err: ".*environment has no access-key or secret-key",
	}, {
		config: attrs{
			"admin-secret": "Futumpsh",
		},
	}, {
		config:       attrs{},
		firewallMode: config.FwInstance,
	}, {
		config: attrs{
			"firewall-mode": "",
		},
		firewallMode: config.FwInstance,
	}, {
		config: attrs{
			"firewall-mode": "instance",
		},
		firewallMode: config.FwInstance,
	}, {
		config: attrs{
			"firewall-mode": "global",
		},
		firewallMode: config.FwGlobal,
	},
}

func indent(s string, with string) string {
	var r string
	lines := strings.Split(s, "\n")
	for _, l := range lines {
		r += with + l + "\n"
	}
	return r
}

func (s *ConfigSuite) SetUpTest(c *C) {
	s.savedHome = os.Getenv("HOME")
	s.savedAccessKey = os.Getenv("AWS_ACCESS_KEY_ID")
	s.savedSecretKey = os.Getenv("AWS_SECRET_ACCESS_KEY")

	home := c.MkDir()
	sshDir := filepath.Join(home, ".ssh")
	err := os.Mkdir(sshDir, 0777)
	c.Assert(err, IsNil)
	err = ioutil.WriteFile(filepath.Join(sshDir, "id_rsa.pub"), []byte("sshkey\n"), 0666)
	c.Assert(err, IsNil)

	os.Setenv("HOME", home)
	os.Setenv("AWS_ACCESS_KEY_ID", testAuth.AccessKey)
	os.Setenv("AWS_SECRET_ACCESS_KEY", testAuth.SecretKey)
	aws.Regions["configtest"] = configTestRegion
}

func (s *ConfigSuite) TearDownTest(c *C) {
	os.Setenv("HOME", s.savedHome)
	os.Setenv("AWS_ACCESS_KEY_ID", s.savedAccessKey)
	os.Setenv("AWS_SECRET_ACCESS_KEY", s.savedSecretKey)
	delete(aws.Regions, "configtest")
}

func (s *ConfigSuite) TestConfig(c *C) {
	for i, t := range configTests {
		c.Logf("test %d: %v", i, t.config)
		t.check(c)
	}
}

func (s *ConfigSuite) TestMissingAuth(c *C) {
	os.Setenv("AWS_ACCESS_KEY_ID", "")
	os.Setenv("AWS_SECRET_ACCESS_KEY", "")
	test := configTests[0]
	test.err = "environment has no access-key or secret-key"
	test.check(c)
}
<|endoftext|>


<commit_before>// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package git

import (
	"github.com/emirpasic/gods/trees/binaryheap"
	"gopkg.in/src-d/go-git.v4/plumbing"
	"gopkg.in/src-d/go-git.v4/plumbing/object"
)

// GetCommitsInfo gets information of all commits that are corresponding to these entries
func (tes Entries) GetCommitsInfo(commit *Commit, treePath string, cache LastCommitCache) ([][]interface{}, *Commit, error) {
	entryPaths := make([]string, len(tes)+1)
	// Get the commit for the treePath itself
	entryPaths[0] = ""
	for i, entry := range tes {
		entryPaths[i+1] = entry.Name()
	}

	c, err := commit.repo.gogitRepo.CommitObject(plumbing.Hash(commit.ID))
	if err != nil {
		return nil, nil, err
	}

	revs, err := getLastCommitForPaths(c, treePath, entryPaths)
	if err != nil {
		return nil, nil, err
	}

	commit.repo.gogitStorage.Close()

	commitsInfo := make([][]interface{}, len(tes))
	for i, entry := range tes {
		if rev, ok := revs[entry.Name()]; ok {
			entryCommit := convertCommit(rev)
			if entry.IsSubModule() {
				subModuleURL := ""
				if subModule, err := commit.GetSubModule(entry.Name()); err != nil {
					return nil, nil, err
				} else if subModule != nil {
					subModuleURL = subModule.URL
				}
				subModuleFile := NewSubModuleFile(entryCommit, subModuleURL, entry.ID.String())
				commitsInfo[i] = []interface{}{entry, subModuleFile}
			} else {
				commitsInfo[i] = []interface{}{entry, entryCommit}
			}
		} else {
			commitsInfo[i] = []interface{}{entry, nil}
		}
	}

	// Retrieve the commit for the treePath itself (see above). We basically
	// get it for free during the tree traversal and it's used for listing
	// pages to display information about newest commit for a given path.
	var treeCommit *Commit
	if rev, ok := revs[""]; ok {
		treeCommit = convertCommit(rev)
	}
	return commitsInfo, treeCommit, nil
}

type commitAndPaths struct {
	commit *object.Commit
	// Paths that are still on the branch represented by commit
	paths []string
	// Set of hashes for the paths
	hashes map[string]plumbing.Hash
}

func getCommitTree(c *object.Commit, treePath string) (*object.Tree, error) {
	tree, err := c.Tree()
	if err != nil {
		return nil, err
	}

	// Optimize deep traversals by focusing only on the specific tree
	if treePath != "" {
		tree, err = tree.Tree(treePath)
		if err != nil {
			return nil, err
		}
	}

	return tree, nil
}

func getFullPath(treePath, path string) string {
	if treePath != "" {
		if path != "" {
			return treePath + "/" + path
		}
		return treePath
	}
	return path
}

func getFileHashes(c *object.Commit, treePath string, paths []string) (map[string]plumbing.Hash, error) {
	tree, err := getCommitTree(c, treePath)
	if err == object.ErrDirectoryNotFound {
		// The whole tree didn't exist, so return empty map
		return make(map[string]plumbing.Hash), nil
	}
	if err != nil {
		return nil, err
	}

	hashes := make(map[string]plumbing.Hash)
	for _, path := range paths {
		if path != "" {
			entry, err := tree.FindEntry(path)
			if err == nil {
				hashes[path] = entry.Hash
			}
		} else {
			hashes[path] = tree.Hash
		}
	}

	return hashes, nil
}

func getLastCommitForPaths(c *object.Commit, treePath string, paths []string) (map[string]*object.Commit, error) {
	// We do a tree traversal with nodes sorted by commit time
	seen := make(map[plumbing.Hash]bool)
	heap := binaryheap.NewWith(func(a, b interface{}) int {
		if a.(*commitAndPaths).commit.Committer.When.Before(b.(*commitAndPaths).commit.Committer.When) {
			return 1
		}
		return -1
	})

	result := make(map[string]*object.Commit)
	initialHashes, err := getFileHashes(c, treePath, paths)
	if err != nil {
		return nil, err
	}

	// Start search from the root commit and with full set of paths
	heap.Push(&commitAndPaths{c, paths, initialHashes})

	for {
		cIn, ok := heap.Pop()
		if !ok {
			break
		}
		current := cIn.(*commitAndPaths)

		// Load the parent commits for the one we are currently examining
		numParents := current.commit.NumParents()
		var parents []*object.Commit
		for i := 0; i < numParents; i++ {
			parent, err := current.commit.Parent(i)
			if err != nil {
				break
			}
			parents = append(parents, parent)
		}

		// Examine the current commit and set of interesting paths
		pathUnchanged := make([]bool, len(current.paths))
		parentHashes := make([]map[string]plumbing.Hash, len(parents))
		for j, parent := range parents {
			parentHashes[j], err = getFileHashes(parent, treePath, current.paths)
			if err != nil {
				break
			}

			for i, path := range current.paths {
				if parentHashes[j][path] == current.hashes[path] {
					pathUnchanged[i] = true
				}
			}
		}

		var remainingPaths []string
		for i, path := range current.paths {
			// The results could already contain some newer change for the same path,
			// so don't override that and bail out on the file early.
			if result[path] == nil {
				if pathUnchanged[i] {
					// The path existed with the same hash in at least one parent so it could
					// not have been changed in this commit directly.
					remainingPaths = append(remainingPaths, path)
				} else {
					// There are few possible cases how can we get here:
					// - The path didn't exist in any parent, so it must have been created by
					//   this commit.
					// - The path did exist in the parent commit, but the hash of the file has
					//   changed.
					// - We are looking at a merge commit and the hash of the file doesn't
					//   match any of the hashes being merged. This is more common for directories,
					//   but it can also happen if a file is changed through conflict resolution.
					result[path] = current.commit
				}
			}
		}

		if len(remainingPaths) > 0 {
			// Add the parent nodes along with remaining paths to the heap for further
			// processing.
			for j, parent := range parents {
				if seen[parent.ID()] {
					continue
				}
				seen[parent.ID()] = true

				// Combine remainingPath with paths available on the parent branch
				// and make union of them
				var remainingPathsForParent []string
				var newRemainingPaths []string
				for _, path := range remainingPaths {
					if parentHashes[j][path] == current.hashes[path] {
						remainingPathsForParent = append(remainingPathsForParent, path)
					} else {
						newRemainingPaths = append(newRemainingPaths, path)
					}
				}

				if remainingPathsForParent != nil {
					heap.Push(&commitAndPaths{parent, remainingPathsForParent, parentHashes[j]})
				}

				if len(newRemainingPaths) == 0 {
					break
				} else {
					remainingPaths = newRemainingPaths
				}
			}
		}
	}

	return result, nil
}
<commit_msg>Remove `seen` map from `getLastCommitForPaths` (#6807)<commit_after>// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package git

import (
	"github.com/emirpasic/gods/trees/binaryheap"
	"gopkg.in/src-d/go-git.v4/plumbing"
	"gopkg.in/src-d/go-git.v4/plumbing/object"
)

// GetCommitsInfo gets information of all commits that are corresponding to these entries
func (tes Entries) GetCommitsInfo(commit *Commit, treePath string, cache LastCommitCache) ([][]interface{}, *Commit, error) {
	entryPaths := make([]string, len(tes)+1)
	// Get the commit for the treePath itself
	entryPaths[0] = ""
	for i, entry := range tes {
		entryPaths[i+1] = entry.Name()
	}

	c, err := commit.repo.gogitRepo.CommitObject(plumbing.Hash(commit.ID))
	if err != nil {
		return nil, nil, err
	}

	revs, err := getLastCommitForPaths(c, treePath, entryPaths)
	if err != nil {
		return nil, nil, err
	}

	commit.repo.gogitStorage.Close()

	commitsInfo := make([][]interface{}, len(tes))
	for i, entry := range tes {
		if rev, ok := revs[entry.Name()]; ok {
			entryCommit := convertCommit(rev)
			if entry.IsSubModule() {
				subModuleURL := ""
				if subModule, err := commit.GetSubModule(entry.Name()); err != nil {
					return nil, nil, err
				} else if subModule != nil {
					subModuleURL = subModule.URL
				}
				subModuleFile := NewSubModuleFile(entryCommit, subModuleURL, entry.ID.String())
				commitsInfo[i] = []interface{}{entry, subModuleFile}
			} else {
				commitsInfo[i] = []interface{}{entry, entryCommit}
			}
		} else {
			commitsInfo[i] = []interface{}{entry, nil}
		}
	}

	// Retrieve the commit for the treePath itself (see above). We basically
	// get it for free during the tree traversal and it's used for listing
	// pages to display information about newest commit for a given path.
	var treeCommit *Commit
	if rev, ok := revs[""]; ok {
		treeCommit = convertCommit(rev)
	}
	return commitsInfo, treeCommit, nil
}

type commitAndPaths struct {
	commit *object.Commit
	// Paths that are still on the branch represented by commit
	paths []string
	// Set of hashes for the paths
	hashes map[string]plumbing.Hash
}

func getCommitTree(c *object.Commit, treePath string) (*object.Tree, error) {
	tree, err := c.Tree()
	if err != nil {
		return nil, err
	}

	// Optimize deep traversals by focusing only on the specific tree
	if treePath != "" {
		tree, err = tree.Tree(treePath)
		if err != nil {
			return nil, err
		}
	}

	return tree, nil
}

func getFullPath(treePath, path string) string {
	if treePath != "" {
		if path != "" {
			return treePath + "/" + path
		}
		return treePath
	}
	return path
}

func getFileHashes(c *object.Commit, treePath string, paths []string) (map[string]plumbing.Hash, error) {
	tree, err := getCommitTree(c, treePath)
	if err == object.ErrDirectoryNotFound {
		// The whole tree didn't exist, so return empty map
		return make(map[string]plumbing.Hash), nil
	}
	if err != nil {
		return nil, err
	}

	hashes := make(map[string]plumbing.Hash)
	for _, path := range paths {
		if path != "" {
			entry, err := tree.FindEntry(path)
			if err == nil {
				hashes[path] = entry.Hash
			}
		} else {
			hashes[path] = tree.Hash
		}
	}

	return hashes, nil
}

func getLastCommitForPaths(c *object.Commit, treePath string, paths []string) (map[string]*object.Commit, error) {
	// We do a tree traversal with nodes sorted by commit time
	heap := binaryheap.NewWith(func(a, b interface{}) int {
		if a.(*commitAndPaths).commit.Committer.When.Before(b.(*commitAndPaths).commit.Committer.When) {
			return 1
		}
		return -1
	})

	result := make(map[string]*object.Commit)
	initialHashes, err := getFileHashes(c, treePath, paths)
	if err != nil {
		return nil, err
	}

	// Start search from the root commit and with full set of paths
	heap.Push(&commitAndPaths{c, paths, initialHashes})

	for {
		cIn, ok := heap.Pop()
		if !ok {
			break
		}
		current := cIn.(*commitAndPaths)

		// Load the parent commits for the one we are currently examining
		numParents := current.commit.NumParents()
		var parents []*object.Commit
		for i := 0; i < numParents; i++ {
			parent, err := current.commit.Parent(i)
			if err != nil {
				break
			}
			parents = append(parents, parent)
		}

		// Examine the current commit and set of interesting paths
		pathUnchanged := make([]bool, len(current.paths))
		parentHashes := make([]map[string]plumbing.Hash, len(parents))
		for j, parent := range parents {
			parentHashes[j], err = getFileHashes(parent, treePath, current.paths)
			if err != nil {
				break
			}

			for i, path := range current.paths {
				if parentHashes[j][path] == current.hashes[path] {
					pathUnchanged[i] = true
				}
			}
		}

		var remainingPaths []string
		for i, path := range current.paths {
			// The results could already contain some newer change for the same path,
			// so don't override that and bail out on the file early.
			if result[path] == nil {
				if pathUnchanged[i] {
					// The path existed with the same hash in at least one parent so it could
					// not have been changed in this commit directly.
					remainingPaths = append(remainingPaths, path)
				} else {
					// There are few possible cases how can we get here:
					// - The path didn't exist in any parent, so it must have been created by
					//   this commit.
					// - The path did exist in the parent commit, but the hash of the file has
					//   changed.
					// - We are looking at a merge commit and the hash of the file doesn't
					//   match any of the hashes being merged. This is more common for directories,
					//   but it can also happen if a file is changed through conflict resolution.
					result[path] = current.commit
				}
			}
		}

		if len(remainingPaths) > 0 {
			// Add the parent nodes along with remaining paths to the heap for further
			// processing.
			for j, parent := range parents {
				// Combine remainingPath with paths available on the parent branch
				// and make union of them
				remainingPathsForParent := make([]string, 0, len(remainingPaths))
				newRemainingPaths := make([]string, 0, len(remainingPaths))
				for _, path := range remainingPaths {
					if parentHashes[j][path] == current.hashes[path] {
						remainingPathsForParent = append(remainingPathsForParent, path)
					} else {
						newRemainingPaths = append(newRemainingPaths, path)
					}
				}

				if remainingPathsForParent != nil {
					heap.Push(&commitAndPaths{parent, remainingPathsForParent, parentHashes[j]})
				}

				if len(newRemainingPaths) == 0 {
					break
				} else {
					remainingPaths = newRemainingPaths
				}
			}
		}
	}

	return result, nil
}
<|endoftext|>


<commit_before>package models

import (
	"errors"
	"fmt"
	"strings"
	"time"

	envmanModels "github.com/bitrise-io/envman/models"
	"github.com/bitrise-io/go-utils/pointers"
)

const (
	// DefaultIsAlwaysRun ...
	DefaultIsAlwaysRun = false
	// DefaultIsRequiresAdminUser ...
	DefaultIsRequiresAdminUser = false
	// DefaultIsSkippable ...
	DefaultIsSkippable = false
)

// ValidateStepInputOutputModel ...
func ValidateStepInputOutputModel(env envmanModels.EnvironmentItemModel) error {
	key, _, err := env.GetKeyValuePair()
	if err != nil {
		return err
	}
	if key == "" {
		return errors.New("Invalid environment: empty env_key")
	}

	options, err := env.GetOptions()
	if err != nil {
		return err
	}

	if options.Title == nil || *options.Title == "" {
		return errors.New("Invalid environment: missing or empty title")
	}

	return nil
}

// -------------------
// --- Struct methods

// Normalize ...
func (step StepModel) Normalize() error {
	for _, input := range step.Inputs {
		if err := input.Normalize(); err != nil {
			return err
		}
	}
	for _, output := range step.Outputs {
		if err := output.Normalize(); err != nil {
			return err
		}
	}
	return nil
}

// ValidateSource ...
func (source StepSourceModel) ValidateSource() error {
	if source.Git == "" {
		return errors.New("Invalid step: missing or empty required 'source.git' property")
	}

	if !strings.HasPrefix(source.Git, "http://") && !strings.HasPrefix(source.Git, "https://") {
		return errors.New("Invalid step: step source should start with http:// or https://")
	}
	if !strings.HasSuffix(source.Git, ".git") {
		return errors.New("Invalid step: step source should end with .git")
	}

	if source.Commit == "" {
		return errors.New("Invalid step: missing or empty required 'source.commit' property")
	}
	return nil
}

// Validate ...
func (step StepModel) Validate(checkRequiredFields bool) error {
	if checkRequiredFields {
		if step.Title == nil || *step.Title == "" {
			return errors.New("Invalid step: missing or empty required 'title' property")
		}
		if step.Summary == nil || *step.Summary == "" {
			return errors.New("Invalid step: missing or empty required 'summary' property")
		}
		if step.Website == nil || *step.Website == "" {
			return errors.New("Invalid step: missing or empty required 'website' property")
		}
		if step.PublishedAt == nil || (*step.PublishedAt).Equal(time.Time{}) {
			return errors.New("Invalid step: missing or empty required 'PublishedAt' property")
		}
		if err := step.Source.ValidateSource(); err != nil {
			return err
		}
	}

	for _, input := range step.Inputs {
		var err error
		if checkRequiredFields {
			err = ValidateStepInputOutputModel(input)
		} else {
			err = input.Validate()
		}
		if err != nil {
			return err
		}
	}

	for _, output := range step.Outputs {
		var err error
		if checkRequiredFields {
			err = ValidateStepInputOutputModel(output)
		} else {
			err = output.Validate()
		}
		if err != nil {
			return err
		}
	}

	return nil
}

// FillMissingDefaults ...
func (step *StepModel) FillMissingDefaults() error {
	if step.Title == nil {
		step.Title = pointers.NewStringPtr("")
	}
	if step.Description == nil {
		step.Description = pointers.NewStringPtr("")
	}
	if step.Summary == nil {
		step.Summary = pointers.NewStringPtr("")
	}
	if step.Website == nil {
		step.Website = pointers.NewStringPtr("")
	}
	if step.SourceCodeURL == nil {
		step.SourceCodeURL = pointers.NewStringPtr("")
	}
	if step.SupportURL == nil {
		step.SupportURL = pointers.NewStringPtr("")
	}
	if step.IsRequiresAdminUser == nil {
		step.IsRequiresAdminUser = pointers.NewBoolPtr(DefaultIsRequiresAdminUser)
	}
	if step.IsAlwaysRun == nil {
		step.IsAlwaysRun = pointers.NewBoolPtr(DefaultIsAlwaysRun)
	}
	if step.IsSkippable == nil {
		step.IsSkippable = pointers.NewBoolPtr(DefaultIsSkippable)
	}
	if step.RunIf == nil {
		step.RunIf = pointers.NewStringPtr("")
	}

	for _, input := range step.Inputs {
		err := input.FillMissingDefaults()
		if err != nil {
			return err
		}
	}
	for _, output := range step.Outputs {
		err := output.FillMissingDefaults()
		if err != nil {
			return err
		}
	}
	return nil
}

// IsStepExist ...
func (collection StepCollectionModel) IsStepExist(id string) bool {
	stepHash := collection.Steps
	_, found := stepHash[id]
	if !found {
		return false
	}
	return true
}

// GetStep ...
func (collection StepCollectionModel) GetStep(id, version string) (StepModel, bool) {
	stepHash := collection.Steps
	stepVersions, found := stepHash[id]
	if !found {
		return StepModel{}, false
	}
	step, found := stepVersions.Versions[version]
	if !found {
		return StepModel{}, false
	}
	return step, true
}

// GetDownloadLocations ...
func (collection StepCollectionModel) GetDownloadLocations(id, version string) ([]DownloadLocationModel, error) {
	step, found := collection.GetStep(id, version)
	if found == false {
		return []DownloadLocationModel{}, fmt.Errorf("Collection (%s) doesn't contains step %s (%s)", collection.SteplibSource, id, version)
	}

	locations := []DownloadLocationModel{}
	for _, downloadLocation := range collection.DownloadLocations {
		switch downloadLocation.Type {
		case "zip":
			url := downloadLocation.Src + id + "/" + version + "/step.zip"
			location := DownloadLocationModel{
				Type: downloadLocation.Type,
				Src:  url,
			}
			locations = append(locations, location)
		case "git":
			location := DownloadLocationModel{
				Type: downloadLocation.Type,
				Src:  step.Source.Git,
			}
			locations = append(locations, location)
		default:
			return []DownloadLocationModel{}, fmt.Errorf("[STEPMAN] - Invalid download location (%#v) for step (%#v)", downloadLocation, id)
		}
	}
	if len(locations) < 1 {
		return []DownloadLocationModel{}, fmt.Errorf("[STEPMAN] - No download location found for step (%#v)", id)
	}
	return locations, nil
}

// GetLatestStepVersion ...
func (collection StepCollectionModel) GetLatestStepVersion(id string) (string, error) {
	stepHash := collection.Steps
	stepGroup, found := stepHash[id]
	if !found {
		return "", fmt.Errorf("Collection (%s) doesn't contains step (%s)", collection.SteplibSource, id)
	}

	if stepGroup.LatestVersionNumber == "" {
		return "", fmt.Errorf("Failed to find latest version of step %s", id)
	}

	return stepGroup.LatestVersionNumber, nil
}
<commit_msg>PR fix<commit_after>package models

import (
	"errors"
	"fmt"
	"strings"
	"time"

	envmanModels "github.com/bitrise-io/envman/models"
	"github.com/bitrise-io/go-utils/pointers"
)

const (
	// DefaultIsAlwaysRun ...
	DefaultIsAlwaysRun = false
	// DefaultIsRequiresAdminUser ...
	DefaultIsRequiresAdminUser = false
	// DefaultIsSkippable ...
	DefaultIsSkippable = false
)

// ValidateStepInputOutputModel ...
func ValidateStepInputOutputModel(env envmanModels.EnvironmentItemModel, checkRequiredFields bool) error {
	if err := env.Validate(); err != nil {
		return err
	}

	if checkRequiredFields {
		options, err := env.GetOptions()
		if err != nil {
			return err
		}

		if options.Title == nil || *options.Title == "" {
			return errors.New("Invalid environment: missing or empty title")
		}
	}

	return nil
}

// -------------------
// --- Struct methods

// Normalize ...
func (step StepModel) Normalize() error {
	for _, input := range step.Inputs {
		if err := input.Normalize(); err != nil {
			return err
		}
	}
	for _, output := range step.Outputs {
		if err := output.Normalize(); err != nil {
			return err
		}
	}
	return nil
}

// ValidateSource ...
func (source StepSourceModel) ValidateSource() error {
	if source.Git == "" {
		return errors.New("Invalid step: missing or empty required 'source.git' property")
	}

	if !strings.HasPrefix(source.Git, "http://") && !strings.HasPrefix(source.Git, "https://") {
		return errors.New("Invalid step: step source should start with http:// or https://")
	}
	if !strings.HasSuffix(source.Git, ".git") {
		return errors.New("Invalid step: step source should end with .git")
	}

	if source.Commit == "" {
		return errors.New("Invalid step: missing or empty required 'source.commit' property")
	}
	return nil
}

// Validate ...
func (step StepModel) Validate(checkRequiredFields bool) error {
	if checkRequiredFields {
		if step.Title == nil || *step.Title == "" {
			return errors.New("Invalid step: missing or empty required 'title' property")
		}
		if step.Summary == nil || *step.Summary == "" {
			return errors.New("Invalid step: missing or empty required 'summary' property")
		}
		if step.Website == nil || *step.Website == "" {
			return errors.New("Invalid step: missing or empty required 'website' property")
		}
		if step.PublishedAt == nil || (*step.PublishedAt).Equal(time.Time{}) {
			return errors.New("Invalid step: missing or empty required 'PublishedAt' property")
		}
		if err := step.Source.ValidateSource(); err != nil {
			return err
		}
	}

	for _, input := range step.Inputs {
		var err error
		err = ValidateStepInputOutputModel(input, checkRequiredFields)
		if err != nil {
			return err
		}
	}

	for _, output := range step.Outputs {
		var err error
		err = ValidateStepInputOutputModel(output, checkRequiredFields)
		if err != nil {
			return err
		}
	}

	return nil
}

// FillMissingDefaults ...
func (step *StepModel) FillMissingDefaults() error {
	if step.Title == nil {
		step.Title = pointers.NewStringPtr("")
	}
	if step.Description == nil {
		step.Description = pointers.NewStringPtr("")
	}
	if step.Summary == nil {
		step.Summary = pointers.NewStringPtr("")
	}
	if step.Website == nil {
		step.Website = pointers.NewStringPtr("")
	}
	if step.SourceCodeURL == nil {
		step.SourceCodeURL = pointers.NewStringPtr("")
	}
	if step.SupportURL == nil {
		step.SupportURL = pointers.NewStringPtr("")
	}
	if step.IsRequiresAdminUser == nil {
		step.IsRequiresAdminUser = pointers.NewBoolPtr(DefaultIsRequiresAdminUser)
	}
	if step.IsAlwaysRun == nil {
		step.IsAlwaysRun = pointers.NewBoolPtr(DefaultIsAlwaysRun)
	}
	if step.IsSkippable == nil {
		step.IsSkippable = pointers.NewBoolPtr(DefaultIsSkippable)
	}
	if step.RunIf == nil {
		step.RunIf = pointers.NewStringPtr("")
	}

	for _, input := range step.Inputs {
		err := input.FillMissingDefaults()
		if err != nil {
			return err
		}
	}
	for _, output := range step.Outputs {
		err := output.FillMissingDefaults()
		if err != nil {
			return err
		}
	}
	return nil
}

// IsStepExist ...
func (collection StepCollectionModel) IsStepExist(id string) bool {
	stepHash := collection.Steps
	_, found := stepHash[id]
	if !found {
		return false
	}
	return true
}

// GetStep ...
func (collection StepCollectionModel) GetStep(id, version string) (StepModel, bool) {
	stepHash := collection.Steps
	stepVersions, found := stepHash[id]
	if !found {
		return StepModel{}, false
	}
	step, found := stepVersions.Versions[version]
	if !found {
		return StepModel{}, false
	}
	return step, true
}

// GetDownloadLocations ...
func (collection StepCollectionModel) GetDownloadLocations(id, version string) ([]DownloadLocationModel, error) {
	step, found := collection.GetStep(id, version)
	if found == false {
		return []DownloadLocationModel{}, fmt.Errorf("Collection (%s) doesn't contains step %s (%s)", collection.SteplibSource, id, version)
	}

	locations := []DownloadLocationModel{}
	for _, downloadLocation := range collection.DownloadLocations {
		switch downloadLocation.Type {
		case "zip":
			url := downloadLocation.Src + id + "/" + version + "/step.zip"
			location := DownloadLocationModel{
				Type: downloadLocation.Type,
				Src:  url,
			}
			locations = append(locations, location)
		case "git":
			location := DownloadLocationModel{
				Type: downloadLocation.Type,
				Src:  step.Source.Git,
			}
			locations = append(locations, location)
		default:
			return []DownloadLocationModel{}, fmt.Errorf("[STEPMAN] - Invalid download location (%#v) for step (%#v)", downloadLocation, id)
		}
	}
	if len(locations) < 1 {
		return []DownloadLocationModel{}, fmt.Errorf("[STEPMAN] - No download location found for step (%#v)", id)
	}
	return locations, nil
}

// GetLatestStepVersion ...
func (collection StepCollectionModel) GetLatestStepVersion(id string) (string, error) {
	stepHash := collection.Steps
	stepGroup, found := stepHash[id]
	if !found {
		return "", fmt.Errorf("Collection (%s) doesn't contains step (%s)", collection.SteplibSource, id)
	}

	if stepGroup.LatestVersionNumber == "" {
		return "", fmt.Errorf("Failed to find latest version of step %s", id)
	}

	return stepGroup.LatestVersionNumber, nil
}
<|endoftext|>


<commit_before>package main_test

import (
	"fmt"
	"os"
	"syscall"
	"time"

	"github.com/cloudfoundry/gunk/timeprovider"
	"github.com/cloudfoundry/storeadapter"
	"github.com/cloudfoundry/storeadapter/storerunner/etcdstorerunner"
	. "github.com/onsi/ginkgo"
	"github.com/onsi/ginkgo/config"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gexec"
	"github.com/pivotal-golang/lager/lagertest"
	"github.com/tedsuo/ifrit"

	"github.com/cloudfoundry-incubator/converger/converger_runner"
	Bbs "github.com/cloudfoundry-incubator/runtime-schema/bbs"
	"github.com/cloudfoundry-incubator/runtime-schema/bbs/shared"
	"github.com/cloudfoundry-incubator/runtime-schema/models"
)

var _ = Describe("Main", func() {
	var (
		etcdRunner *etcdstorerunner.ETCDClusterRunner
		bbs        *Bbs.BBS
		runner     *converger_runner.ConvergerRunner

		fileServerPresence ifrit.Process

		taskKickInterval = 1 * time.Second

		etcdClient storeadapter.StoreAdapter

		convergeRepeatInterval = time.Second
	)

	BeforeSuite(func() {
		etcdPort := 5001 + config.GinkgoConfig.ParallelNode
		etcdCluster := fmt.Sprintf("http://127.0.0.1:%d", etcdPort)
		etcdRunner = etcdstorerunner.NewETCDClusterRunner(etcdPort, 1)

		etcdClient = etcdRunner.Adapter()
		bbs = Bbs.NewBBS(etcdClient, timeprovider.NewTimeProvider(), lagertest.NewTestLogger("test"))

		convergerBinPath, err := gexec.Build("github.com/cloudfoundry-incubator/converger", "-race")
		Ω(err).ShouldNot(HaveOccurred())

		runner = converger_runner.New(convergerBinPath, etcdCluster, "info")
	})

	AfterSuite(func() {
		etcdRunner.Stop()
		gexec.CleanupBuildArtifacts()
	})

	BeforeEach(func() {
		etcdRunner.Start()

		fileServerPresence = ifrit.Envoke(bbs.NewFileServerHeartbeat("http://some.file.server", "file-server-id", time.Second))

		executorPresence := models.ExecutorPresence{
			ExecutorID: "the-executor-id",
			Stack:      "the-stack",
		}

		etcdClient.Create(storeadapter.StoreNode{
			Key:   shared.ExecutorSchemaPath(executorPresence.ExecutorID),
			Value: executorPresence.ToJSON(),
		})
	})

	AfterEach(func() {
		fileServerPresence.Signal(os.Interrupt)
		Eventually(fileServerPresence.Wait()).Should(Receive(BeNil()))

		runner.KillWithFire()
		etcdRunner.Stop()
	})

	startConverger := func() {
		runner.Start(convergeRepeatInterval, taskKickInterval, 30*time.Minute, 30*time.Second, 300*time.Second)
		time.Sleep(convergeRepeatInterval)
	}

	createClaimedTaskWithDeadExecutor := func() {
		task := models.Task{
			Domain: "tests",

			Guid:  "task-guid",
			Stack: "stack",
			Actions: []models.ExecutorAction{
				{
					Action: models.RunAction{
						Path: "cat",
						Args: []string{"/tmp/file"},
					},
				},
			},
		}

		err := bbs.DesireTask(task)
		Ω(err).ShouldNot(HaveOccurred())

		err = bbs.ClaimTask(task.Guid, "dead-executor")
		Ω(err).ShouldNot(HaveOccurred())
	}

	desireLRP := func() {
		err := bbs.DesireLRP(models.DesiredLRP{
			Domain: "tests",

			ProcessGuid: "the-guid",

			Stack: "some-stack",

			Instances: 3,
			MemoryMB:  128,
			DiskMB:    512,

			Actions: []models.ExecutorAction{
				{
					Action: models.RunAction{
						Path: "the-start-command",
					},
				},
			},
		})
		Ω(err).ShouldNot(HaveOccurred())
	}

	itIsInactive := func() {
		Describe("when an LRP is desired", func() {
			JustBeforeEach(desireLRP)

			It("does not create start auctions for apps that are missing instances", func() {
				Consistently(bbs.GetAllLRPStartAuctions, 0.5).Should(BeEmpty())
			})
		})

		Context("when a claimed task with a dead executor is present", func() {
			JustBeforeEach(createClaimedTaskWithDeadExecutor)

			It("does not change the task", func() {
				Consistently(bbs.GetAllCompletedTasks, taskKickInterval*2).Should(BeEmpty())
			})
		})
	}

	Context("when the converger has the lock", func() {
		BeforeEach(startConverger)

		Describe("when an LRP is desired", func() {
			JustBeforeEach(desireLRP)

			Context("for an app that is not running at all", func() {
				It("desires N start auctions in the BBS", func() {
					Eventually(bbs.GetAllLRPStartAuctions, 0.5).Should(HaveLen(3))
				})
			})

			Context("for an app that is missing instances", func() {
				BeforeEach(func() {
					bbs.ReportActualLRPAsRunning(models.ActualLRP{
						ProcessGuid:  "the-guid",
						InstanceGuid: "a",
						Index:        0,
					}, "the-executor-id")
				})

				It("start auctions for the missing instances", func() {
					Eventually(bbs.GetAllLRPStartAuctions, 0.5).Should(HaveLen(2))
					auctions, err := bbs.GetAllLRPStartAuctions()
					Ω(err).ShouldNot(HaveOccurred())

					indices := []int{auctions[0].Index, auctions[1].Index}
					Ω(indices).Should(ContainElement(1))
					Ω(indices).Should(ContainElement(2))

					Consistently(bbs.GetAllLRPStartAuctions).Should(HaveLen(2))
				})
			})

			Context("for an app that has extra instances", func() {
				BeforeEach(func() {
					bbs.ReportActualLRPAsRunning(models.ActualLRP{
						ProcessGuid:  "the-guid",
						InstanceGuid: "a",
						Index:        0,
					}, "the-executor-id")

					bbs.ReportActualLRPAsRunning(models.ActualLRP{
						ProcessGuid:  "the-guid",
						InstanceGuid: "b",
						Index:        1,
					}, "the-executor-id")

					bbs.ReportActualLRPAsRunning(models.ActualLRP{
						ProcessGuid:  "the-guid",
						InstanceGuid: "c",
						Index:        2,
					}, "the-executor-id")

					bbs.ReportActualLRPAsRunning(models.ActualLRP{
						ProcessGuid:  "the-guid",
						InstanceGuid: "d-extra",
						Index:        3,
					}, "the-executor-id")
				})

				It("stops the extra instances", func() {
					Consistently(bbs.GetAllLRPStartAuctions, 0.5).Should(BeEmpty())
					Eventually(bbs.GetAllStopLRPInstances).Should(HaveLen(1))
					stopInstances, err := bbs.GetAllStopLRPInstances()
					Ω(err).ShouldNot(HaveOccurred())

					Ω(stopInstances[0].ProcessGuid).Should(Equal("the-guid"))
					Ω(stopInstances[0].Index).Should(Equal(3))
					Ω(stopInstances[0].InstanceGuid).Should(Equal("d-extra"))
				})
			})
		})

		Describe("when a claimed task with a dead executor is present", func() {
			JustBeforeEach(createClaimedTaskWithDeadExecutor)

			It("eventually marks the task as failed", func() {
				Eventually(bbs.GetAllCompletedTasks, taskKickInterval*2).Should(HaveLen(1))
				tasks, err := bbs.GetAllTasks()
				Ω(err).ShouldNot(HaveOccurred())
				Ω(tasks).Should(HaveLen(1))
				Ω(tasks[0].State).Should(Equal(models.TaskStateCompleted))
				Ω(tasks[0].Failed).Should(BeTrue())
			})
		})
	})

	Context("when the converger loses the lock", func() {
		BeforeEach(func() {
			startConverger()
			err := etcdClient.Update(storeadapter.StoreNode{
				Key:   shared.LockSchemaPath("converge_lock"),
				Value: []byte("something-else"),
			})
			Ω(err).ShouldNot(HaveOccurred())

			time.Sleep(convergeRepeatInterval + 10*time.Millisecond)
		})

		itIsInactive()

		It("exits with an error", func() {
			Eventually(runner.Session.ExitCode).Should(Equal(1))
		})
	})

	Context("when the converger initially does not have the lock", func() {
		BeforeEach(func() {
			err := etcdClient.Create(storeadapter.StoreNode{
				Key:   shared.LockSchemaPath("converge_lock"),
				Value: []byte("something-else"),
			})
			Ω(err).ShouldNot(HaveOccurred())

			startConverger()
		})

		itIsInactive()

		Describe("when the lock becomes available", func() {
			BeforeEach(func() {
				err := etcdClient.Delete(shared.LockSchemaPath("converge_lock"))
				Ω(err).ShouldNot(HaveOccurred())

				time.Sleep(convergeRepeatInterval + 10*time.Millisecond)
			})

			Describe("when an LRP is desired", func() {
				JustBeforeEach(desireLRP)

				Context("for an app that is not running at all", func() {
					It("desires N start auctions in the BBS", func() {
						Eventually(bbs.GetAllLRPStartAuctions, 0.5).Should(HaveLen(3))
					})
				})
			})

			Describe("when a claimed task with a dead executor is present", func() {
				JustBeforeEach(createClaimedTaskWithDeadExecutor)

				It("eventually marks the task as failed", func() {
					Eventually(bbs.GetAllCompletedTasks, taskKickInterval*2).Should(HaveLen(1))
				})
			})
		})
	})

	Describe("signal handling", func() {
		BeforeEach(func() {
			startConverger()
		})

		Describe("when it receives SIGINT", func() {
			It("exits successfully", func() {
				runner.Session.Command.Process.Signal(syscall.SIGINT)
				Eventually(runner.Session, 4).Should(gexec.Exit(0))
			})
		})

		Describe("when it receives SIGTERM", func() {
			It("exits successfully", func() {
				runner.Session.Command.Process.Signal(syscall.SIGTERM)
				Eventually(runner.Session, 4).Should(gexec.Exit(0))
			})
		})
	})
})
<commit_msg>optimize integration suite: only build assets on node 1<commit_after>package main_test

import (
	"fmt"
	"os"
	"syscall"
	"time"

	"github.com/cloudfoundry/gunk/timeprovider"
	"github.com/cloudfoundry/storeadapter"
	"github.com/cloudfoundry/storeadapter/storerunner/etcdstorerunner"
	. "github.com/onsi/ginkgo"
	"github.com/onsi/ginkgo/config"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gexec"
	"github.com/pivotal-golang/lager/lagertest"
	"github.com/tedsuo/ifrit"

	"github.com/cloudfoundry-incubator/converger/converger_runner"
	Bbs "github.com/cloudfoundry-incubator/runtime-schema/bbs"
	"github.com/cloudfoundry-incubator/runtime-schema/bbs/shared"
	"github.com/cloudfoundry-incubator/runtime-schema/models"
)

var _ = Describe("Main", func() {
	var (
		etcdRunner *etcdstorerunner.ETCDClusterRunner
		bbs        *Bbs.BBS
		runner     *converger_runner.ConvergerRunner

		fileServerPresence ifrit.Process

		taskKickInterval = 1 * time.Second

		etcdClient storeadapter.StoreAdapter

		convergeRepeatInterval = time.Second
	)

	SynchronizedBeforeSuite(func() []byte {
		convergerBinPath, err := gexec.Build("github.com/cloudfoundry-incubator/converger", "-race")
		Ω(err).ShouldNot(HaveOccurred())
		return []byte(convergerBinPath)
	}, func(convergerBinPath []byte) {
		etcdPort := 5001 + config.GinkgoConfig.ParallelNode
		etcdCluster := fmt.Sprintf("http://127.0.0.1:%d", etcdPort)
		etcdRunner = etcdstorerunner.NewETCDClusterRunner(etcdPort, 1)

		etcdClient = etcdRunner.Adapter()
		bbs = Bbs.NewBBS(etcdClient, timeprovider.NewTimeProvider(), lagertest.NewTestLogger("test"))

		runner = converger_runner.New(string(convergerBinPath), etcdCluster, "info")
	})

	SynchronizedAfterSuite(func() {
		etcdRunner.Stop()
	}, func() {
		gexec.CleanupBuildArtifacts()
	})

	BeforeEach(func() {
		etcdRunner.Start()

		fileServerPresence = ifrit.Envoke(bbs.NewFileServerHeartbeat("http://some.file.server", "file-server-id", time.Second))

		executorPresence := models.ExecutorPresence{
			ExecutorID: "the-executor-id",
			Stack:      "the-stack",
		}

		etcdClient.Create(storeadapter.StoreNode{
			Key:   shared.ExecutorSchemaPath(executorPresence.ExecutorID),
			Value: executorPresence.ToJSON(),
		})
	})

	AfterEach(func() {
		fileServerPresence.Signal(os.Interrupt)
		Eventually(fileServerPresence.Wait()).Should(Receive(BeNil()))

		runner.KillWithFire()
		etcdRunner.Stop()
	})

	startConverger := func() {
		runner.Start(convergeRepeatInterval, taskKickInterval, 30*time.Minute, 30*time.Second, 300*time.Second)
		time.Sleep(convergeRepeatInterval)
	}

	createClaimedTaskWithDeadExecutor := func() {
		task := models.Task{
			Domain: "tests",

			Guid:  "task-guid",
			Stack: "stack",
			Actions: []models.ExecutorAction{
				{
					Action: models.RunAction{
						Path: "cat",
						Args: []string{"/tmp/file"},
					},
				},
			},
		}

		err := bbs.DesireTask(task)
		Ω(err).ShouldNot(HaveOccurred())

		err = bbs.ClaimTask(task.Guid, "dead-executor")
		Ω(err).ShouldNot(HaveOccurred())
	}

	desireLRP := func() {
		err := bbs.DesireLRP(models.DesiredLRP{
			Domain: "tests",

			ProcessGuid: "the-guid",

			Stack: "some-stack",

			Instances: 3,
			MemoryMB:  128,
			DiskMB:    512,

			Actions: []models.ExecutorAction{
				{
					Action: models.RunAction{
						Path: "the-start-command",
					},
				},
			},
		})
		Ω(err).ShouldNot(HaveOccurred())
	}

	itIsInactive := func() {
		Describe("when an LRP is desired", func() {
			JustBeforeEach(desireLRP)

			It("does not create start auctions for apps that are missing instances", func() {
				Consistently(bbs.GetAllLRPStartAuctions, 0.5).Should(BeEmpty())
			})
		})

		Context("when a claimed task with a dead executor is present", func() {
			JustBeforeEach(createClaimedTaskWithDeadExecutor)

			It("does not change the task", func() {
				Consistently(bbs.GetAllCompletedTasks, taskKickInterval*2).Should(BeEmpty())
			})
		})
	}

	Context("when the converger has the lock", func() {
		BeforeEach(startConverger)

		Describe("when an LRP is desired", func() {
			JustBeforeEach(desireLRP)

			Context("for an app that is not running at all", func() {
				It("desires N start auctions in the BBS", func() {
					Eventually(bbs.GetAllLRPStartAuctions, 0.5).Should(HaveLen(3))
				})
			})

			Context("for an app that is missing instances", func() {
				BeforeEach(func() {
					bbs.ReportActualLRPAsRunning(models.ActualLRP{
						ProcessGuid:  "the-guid",
						InstanceGuid: "a",
						Index:        0,
					}, "the-executor-id")
				})

				It("start auctions for the missing instances", func() {
					Eventually(bbs.GetAllLRPStartAuctions, 0.5).Should(HaveLen(2))
					auctions, err := bbs.GetAllLRPStartAuctions()
					Ω(err).ShouldNot(HaveOccurred())

					indices := []int{auctions[0].Index, auctions[1].Index}
					Ω(indices).Should(ContainElement(1))
					Ω(indices).Should(ContainElement(2))

					Consistently(bbs.GetAllLRPStartAuctions).Should(HaveLen(2))
				})
			})

			Context("for an app that has extra instances", func() {
				BeforeEach(func() {
					bbs.ReportActualLRPAsRunning(models.ActualLRP{
						ProcessGuid:  "the-guid",
						InstanceGuid: "a",
						Index:        0,
					}, "the-executor-id")

					bbs.ReportActualLRPAsRunning(models.ActualLRP{
						ProcessGuid:  "the-guid",
						InstanceGuid: "b",
						Index:        1,
					}, "the-executor-id")

					bbs.ReportActualLRPAsRunning(models.ActualLRP{
						ProcessGuid:  "the-guid",
						InstanceGuid: "c",
						Index:        2,
					}, "the-executor-id")

					bbs.ReportActualLRPAsRunning(models.ActualLRP{
						ProcessGuid:  "the-guid",
						InstanceGuid: "d-extra",
						Index:        3,
					}, "the-executor-id")
				})

				It("stops the extra instances", func() {
					Consistently(bbs.GetAllLRPStartAuctions, 0.5).Should(BeEmpty())
					Eventually(bbs.GetAllStopLRPInstances).Should(HaveLen(1))
					stopInstances, err := bbs.GetAllStopLRPInstances()
					Ω(err).ShouldNot(HaveOccurred())

					Ω(stopInstances[0].ProcessGuid).Should(Equal("the-guid"))
					Ω(stopInstances[0].Index).Should(Equal(3))
					Ω(stopInstances[0].InstanceGuid).Should(Equal("d-extra"))
				})
			})
		})

		Describe("when a claimed task with a dead executor is present", func() {
			JustBeforeEach(createClaimedTaskWithDeadExecutor)

			It("eventually marks the task as failed", func() {
				Eventually(bbs.GetAllCompletedTasks, taskKickInterval*2).Should(HaveLen(1))
				tasks, err := bbs.GetAllTasks()
				Ω(err).ShouldNot(HaveOccurred())
				Ω(tasks).Should(HaveLen(1))
				Ω(tasks[0].State).Should(Equal(models.TaskStateCompleted))
				Ω(tasks[0].Failed).Should(BeTrue())
			})
		})
	})

	Context("when the converger loses the lock", func() {
		BeforeEach(func() {
			startConverger()
			err := etcdClient.Update(storeadapter.StoreNode{
				Key:   shared.LockSchemaPath("converge_lock"),
				Value: []byte("something-else"),
			})
			Ω(err).ShouldNot(HaveOccurred())

			time.Sleep(convergeRepeatInterval + 10*time.Millisecond)
		})

		itIsInactive()

		It("exits with an error", func() {
			Eventually(runner.Session.ExitCode).Should(Equal(1))
		})
	})

	Context("when the converger initially does not have the lock", func() {
		BeforeEach(func() {
			err := etcdClient.Create(storeadapter.StoreNode{
				Key:   shared.LockSchemaPath("converge_lock"),
				Value: []byte("something-else"),
			})
			Ω(err).ShouldNot(HaveOccurred())

			startConverger()
		})

		itIsInactive()

		Describe("when the lock becomes available", func() {
			BeforeEach(func() {
				err := etcdClient.Delete(shared.LockSchemaPath("converge_lock"))
				Ω(err).ShouldNot(HaveOccurred())

				time.Sleep(convergeRepeatInterval + 10*time.Millisecond)
			})

			Describe("when an LRP is desired", func() {
				JustBeforeEach(desireLRP)

				Context("for an app that is not running at all", func() {
					It("desires N start auctions in the BBS", func() {
						Eventually(bbs.GetAllLRPStartAuctions, 0.5).Should(HaveLen(3))
					})
				})
			})

			Describe("when a claimed task with a dead executor is present", func() {
				JustBeforeEach(createClaimedTaskWithDeadExecutor)

				It("eventually marks the task as failed", func() {
					Eventually(bbs.GetAllCompletedTasks, taskKickInterval*2).Should(HaveLen(1))
				})
			})
		})
	})

	Describe("signal handling", func() {
		BeforeEach(func() {
			startConverger()
		})

		Describe("when it receives SIGINT", func() {
			It("exits successfully", func() {
				runner.Session.Command.Process.Signal(syscall.SIGINT)
				Eventually(runner.Session, 4).Should(gexec.Exit(0))
			})
		})

		Describe("when it receives SIGTERM", func() {
			It("exits successfully", func() {
				runner.Session.Command.Process.Signal(syscall.SIGTERM)
				Eventually(runner.Session, 4).Should(gexec.Exit(0))
			})
		})
	})
})
<|endoftext|>


<commit_before>package main

import (
	"testing"
)

func TestSimpleExample(t *testing.T) {
	if 1 == 2 {
		t.Errorf("1 should not be equel to 2")
	}
}
<commit_msg>add failing test<commit_after>package main

import (
	"testing"
)

func TestSimpleExample(t *testing.T) {
	if 1 == 2 {
		t.Errorf("1 should not be equel to 2")
	}
}

func TestSimpleFailExample(t *testing.T) {
	if 1 == 1 {
		t.Errorf("1 should not be equel to 1")
	}
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"os/exec"
	"testing"
)

var testExec = os.Args[0]

func TestMain(t *testing.T) {
	t.Run("it shows usage", func(tt *testing.T) {
		args := []string{"ergo", "-h"}
		os.Args = args

		main()
		// Output: USAGE
	})
}

// TestMissingCommand will cause the main function to return a non-zero exit code
// so we need to do some wrapping to make the test not fail.
// For more info check ou to uset: https://talks.golang.org/2014/testing.slide#23
func TestMissingCommand(t *testing.T) {
	t.Run("missing a command so it shows usage", func(tt *testing.T) {
		if os.Getenv("TEST_MISSING_COMMAND") == "1" {
			args := []string{"ergo"}
			os.Args = args

			main()
			// Output: USAGE and exit with an error code
		}
		cmd := exec.Command(testExec, "-test.run=TestMissingCommand")
		cmd.Env = append(os.Environ(), "TEST_MISSING_COMMAND=1")
		err := cmd.Run()
		if e, ok := err.(*exec.ExitError); ok && !e.Success() {
			return
		}
		t.Fatalf("process ran with err %v, want exit status 1", err)
	})
}

func TestListCommand(t *testing.T) {
	t.Run("it is list command", func(tt *testing.T) {
		args := []string{"ergo", "list"}
		os.Args = args

		result := command()
		if result == nil {
			t.Errorf("Expected result to not be nil")
		}

		result()
	})
}

func TestListNamesCommand(t *testing.T) {
	t.Run("it is list-names command", func(tt *testing.T) {
		args := []string{"ergo", "list-names"}
		os.Args = args

		result := command()
		if result == nil {
			t.Errorf("Expected result to not be nil")
		}

		result()
	})
}

func TestSetupCommand(t *testing.T) {
	t.Run("it shows usage", func(tt *testing.T) {
		args := []string{"ergo", "setup"}
		os.Args = args

		result := command()
		if result != nil {
			t.Errorf("Expected result to be nil")
		}
	})

	t.Run("it is setup command", func(tt *testing.T) {
		args := []string{"ergo", "setup", "osx"}
		os.Args = args

		result := command()
		if result == nil {
			t.Errorf("Expected result not to be nil")
		}
	})
}

func TestUrlCommand(t *testing.T) {
	t.Run("it shows usage", func(tt *testing.T) {
		args := []string{"ergo", "url"}
		os.Args = args

		result := command()
		if result != nil {
			t.Errorf("Expected result to be nil")
		}
	})

	t.Run("it is url command", func(tt *testing.T) {
		args := []string{"ergo", "url", "foo"}
		os.Args = args

		result := command()
		if result == nil {
			t.Errorf("Expected result not to be nil")
		}

		result()
	})
}

func TestRunCommand(t *testing.T) {
	t.Run("it is url command", func(tt *testing.T) {
		args := []string{"ergo", "run"}
		os.Args = args

		result := command()
		if result == nil {
			t.Errorf("Expected result not to be nil")
		}
	})
}

func TestAddCommand(t *testing.T) {
	t.Run("it shows usage", func(tt *testing.T) {
		args := []string{"ergo", "add"}
		os.Args = args

		result := command()
		if result != nil {
			t.Errorf("Expected result to be nil")
		}
	})

	t.Run("it is url command", func(tt *testing.T) {
		args := []string{"ergo", "add", "foo", "bar"}
		os.Args = args

		result := command()
		if result == nil {
			t.Errorf("Expected result not to be nil")
		}

		result()
	})
}
<commit_msg>Adds error when running ergo without a command<commit_after>package main

import (
	"os"
	"os/exec"
	"testing"
)

var testExec = os.Args[0]

func TestMain(t *testing.T) {
	t.Run("it shows usage", func(tt *testing.T) {
		args := []string{"ergo", "-h"}
		os.Args = args

		main()
		// Output: USAGE
	})
}

// TestMissingCommand will cause the main function to return a non-zero exit code
// so we need to do some wrapping to make the test not fail.
// For more info check ou to uset: https://talks.golang.org/2014/testing.slide#23
func TestMissingCommand(t *testing.T) {
	t.Run("missing a command so it shows usage", func(tt *testing.T) {
		if os.Getenv("TEST_MISSING_COMMAND") == "1" {
			args := []string{"ergo"}
			os.Args = args

			main()
			// Output: USAGE and exit with an error code
		}

		cmd := exec.Command(testExec, "-test.run=TestMissingCommand")
		cmd.Env = append(os.Environ(), "TEST_MISSING_COMMAND=1")
		err := cmd.Run()
		if e, ok := err.(*exec.ExitError); ok && !e.Success() {
			return
		}
		t.Fatalf("process ran with err %v, want exit status 1", err)
	})
}

func TestListCommand(t *testing.T) {
	t.Run("it is list command", func(tt *testing.T) {
		args := []string{"ergo", "list"}
		os.Args = args

		result := command()
		if result == nil {
			t.Errorf("Expected result to not be nil")
		}

		result()
	})
}

func TestListNamesCommand(t *testing.T) {
	t.Run("it is list-names command", func(tt *testing.T) {
		args := []string{"ergo", "list-names"}
		os.Args = args

		result := command()
		if result == nil {
			t.Errorf("Expected result to not be nil")
		}

		result()
	})
}

func TestSetupCommand(t *testing.T) {
	t.Run("it shows usage", func(tt *testing.T) {
		args := []string{"ergo", "setup"}
		os.Args = args

		result := command()
		if result != nil {
			t.Errorf("Expected result to be nil")
		}
	})

	t.Run("it is setup command", func(tt *testing.T) {
		args := []string{"ergo", "setup", "osx"}
		os.Args = args

		result := command()
		if result == nil {
			t.Errorf("Expected result not to be nil")
		}
	})
}

func TestUrlCommand(t *testing.T) {
	t.Run("it shows usage", func(tt *testing.T) {
		args := []string{"ergo", "url"}
		os.Args = args

		result := command()
		if result != nil {
			t.Errorf("Expected result to be nil")
		}
	})

	t.Run("it is url command", func(tt *testing.T) {
		args := []string{"ergo", "url", "foo"}
		os.Args = args

		result := command()
		if result == nil {
			t.Errorf("Expected result not to be nil")
		}

		result()
	})
}

func TestRunCommand(t *testing.T) {
	t.Run("it is url command", func(tt *testing.T) {
		args := []string{"ergo", "run"}
		os.Args = args

		result := command()
		if result == nil {
			t.Errorf("Expected result not to be nil")
		}
	})
}

func TestAddCommand(t *testing.T) {
	t.Run("it shows usage", func(tt *testing.T) {
		args := []string{"ergo", "add"}
		os.Args = args

		result := command()
		if result != nil {
			t.Errorf("Expected result to be nil")
		}
	})

	t.Run("it is url command", func(tt *testing.T) {
		args := []string{"ergo", "add", "foo", "bar"}
		os.Args = args

		result := command()
		if result == nil {
			t.Errorf("Expected result not to be nil")
		}

		result()
	})
}
<|endoftext|>