<commit_before>// Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.

package provider

import (
	"context"

	"github.com/hashicorp/terraform/helper/schema"
	oci_database "github.com/oracle/oci-go-sdk/database"
)

func DatabaseDbSystemShapesDataSource() *schema.Resource {
	return &schema.Resource{
		Read: readDatabaseDbSystemShapes,
		Schema: map[string]*schema.Schema{
			"filter": dataSourceFiltersSchema(),
			"availability_domain": {
				Type:     schema.TypeString,
				Required: true,
			},
			"compartment_id": {
				Type:     schema.TypeString,
				Required: true,
			},
			"db_system_shapes": {
				Type:     schema.TypeList,
				Computed: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						// Required

						// Optional

						// Computed
						"available_core_count": {
							Type:     schema.TypeInt,
							Computed: true,
						},
						"core_count_increment": {
							Type:     schema.TypeInt,
							Computed: true,
						},
						"maximum_node_count": {
							Type:     schema.TypeInt,
							Computed: true,
						},
						"minimum_core_count": {
							Type:     schema.TypeInt,
							Computed: true,
						},
						"minimum_node_count": {
							Type:     schema.TypeInt,
							Computed: true,
						},
						"name": {
							Type:     schema.TypeString,
							Computed: true,
						},
						"shape": {
							Type:     schema.TypeString,
							Computed: true,
						},
					},
				},
			},
			"limit": {
				Type:       schema.TypeInt,
				Optional:   true,
				Deprecated: FieldDeprecated("limit"),
			},
			"page": {
				Type:       schema.TypeString,
				Optional:   true,
				Deprecated: FieldDeprecated("page"),
			},
		},
	}
}

func readDatabaseDbSystemShapes(d *schema.ResourceData, m interface{}) error {
	sync := &DatabaseDbSystemShapesDataSourceCrud{}
	sync.D = d
	sync.Client = m.(*OracleClients).databaseClient

	return ReadResource(sync)
}

type DatabaseDbSystemShapesDataSourceCrud struct {
	D      *schema.ResourceData
	Client *oci_database.DatabaseClient
	Res    *oci_database.ListDbSystemShapesResponse
}

func (s *DatabaseDbSystemShapesDataSourceCrud) VoidState() {
	s.D.SetId("")
}

func (s *DatabaseDbSystemShapesDataSourceCrud) Get() error {
	request := oci_database.ListDbSystemShapesRequest{}

	if availabilityDomain, ok := s.D.GetOkExists("availability_domain"); ok {
		tmp := availabilityDomain.(string)
		request.AvailabilityDomain = &tmp
	}

	if compartmentId, ok := s.D.GetOkExists("compartment_id"); ok {
		tmp := compartmentId.(string)
		request.CompartmentId = &tmp
	}

	if limit, ok := s.D.GetOkExists("limit"); ok {
		tmp := limit.(int)
		request.Limit = &tmp
	}

	if page, ok := s.D.GetOkExists("page"); ok {
		tmp := page.(string)
		request.Page = &tmp
	}

	request.RequestMetadata.RetryPolicy = getRetryPolicy(false, "database")

	response, err := s.Client.ListDbSystemShapes(context.Background(), request)
	if err != nil {
		return err
	}

	s.Res = &response
	request.Page = s.Res.OpcNextPage

	for request.Page != nil {
		listResponse, err := s.Client.ListDbSystemShapes(context.Background(), request)
		if err != nil {
			return err
		}

		s.Res.Items = append(s.Res.Items, listResponse.Items...)
		request.Page = listResponse.OpcNextPage
	}

	return nil
}

func (s *DatabaseDbSystemShapesDataSourceCrud) SetData() error {
	if s.Res == nil {
		return nil
	}

	s.D.SetId(GenerateDataSourceID())
	resources := []map[string]interface{}{}

	for _, r := range s.Res.Items {
		dbSystemShape := map[string]interface{}{}

		if r.AvailableCoreCount != nil {
			dbSystemShape["available_core_count"] = *r.AvailableCoreCount
		}

		if r.CoreCountIncrement != nil {
			dbSystemShape["core_count_increment"] = *r.CoreCountIncrement
		}

		if r.MaximumNodeCount != nil {
			dbSystemShape["maximum_node_count"] = *r.MaximumNodeCount
		}

		if r.MinimumCoreCount != nil {
			dbSystemShape["minimum_core_count"] = *r.MinimumCoreCount
		}

		if r.MinimumNodeCount != nil {
			dbSystemShape["minimum_node_count"] = *r.MinimumNodeCount
		}

		if r.Name != nil {
			dbSystemShape["name"] = *r.Name
		}

		if r.Shape != nil {
			dbSystemShape["shape"] = *r.Shape
		}

		resources = append(resources, dbSystemShape)
	}

	if f, fOk := s.D.GetOkExists("filter"); fOk {
		resources = ApplyFilters(f.(*schema.Set), resources, DatabaseDbSystemShapesDataSource().Schema["db_system_shapes"].Elem.(*schema.Resource).Schema)
	}

	if err := s.D.Set("db_system_shapes", resources); err != nil {
		return err
	}

	return nil
}
<commit_msg>Deprecated shape in Db System Shapes<commit_after>// Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.

package provider

import (
	"context"

	"github.com/hashicorp/terraform/helper/schema"
	oci_database "github.com/oracle/oci-go-sdk/database"
)

func DatabaseDbSystemShapesDataSource() *schema.Resource {
	return &schema.Resource{
		Read: readDatabaseDbSystemShapes,
		Schema: map[string]*schema.Schema{
			"filter": dataSourceFiltersSchema(),
			"availability_domain": {
				Type:     schema.TypeString,
				Required: true,
			},
			"compartment_id": {
				Type:     schema.TypeString,
				Required: true,
			},
			"db_system_shapes": {
				Type:     schema.TypeList,
				Computed: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						// Required

						// Optional

						// Computed
						"available_core_count": {
							Type:     schema.TypeInt,
							Computed: true,
						},
						"core_count_increment": {
							Type:     schema.TypeInt,
							Computed: true,
						},
						"maximum_node_count": {
							Type:     schema.TypeInt,
							Computed: true,
						},
						"minimum_core_count": {
							Type:     schema.TypeInt,
							Computed: true,
						},
						"minimum_node_count": {
							Type:     schema.TypeInt,
							Computed: true,
						},
						"name": {
							Type:     schema.TypeString,
							Computed: true,
						},
						"shape": {
							Type:       schema.TypeString,
							Computed:   true,
							Deprecated: FieldDeprecatedForAnother("shape", "name"),
						},
					},
				},
			},
			"limit": {
				Type:       schema.TypeInt,
				Optional:   true,
				Deprecated: FieldDeprecated("limit"),
			},
			"page": {
				Type:       schema.TypeString,
				Optional:   true,
				Deprecated: FieldDeprecated("page"),
			},
		},
	}
}

func readDatabaseDbSystemShapes(d *schema.ResourceData, m interface{}) error {
	sync := &DatabaseDbSystemShapesDataSourceCrud{}
	sync.D = d
	sync.Client = m.(*OracleClients).databaseClient

	return ReadResource(sync)
}

type DatabaseDbSystemShapesDataSourceCrud struct {
	D      *schema.ResourceData
	Client *oci_database.DatabaseClient
	Res    *oci_database.ListDbSystemShapesResponse
}

func (s *DatabaseDbSystemShapesDataSourceCrud) VoidState() {
	s.D.SetId("")
}

func (s *DatabaseDbSystemShapesDataSourceCrud) Get() error {
	request := oci_database.ListDbSystemShapesRequest{}

	if availabilityDomain, ok := s.D.GetOkExists("availability_domain"); ok {
		tmp := availabilityDomain.(string)
		request.AvailabilityDomain = &tmp
	}

	if compartmentId, ok := s.D.GetOkExists("compartment_id"); ok {
		tmp := compartmentId.(string)
		request.CompartmentId = &tmp
	}

	if limit, ok := s.D.GetOkExists("limit"); ok {
		tmp := limit.(int)
		request.Limit = &tmp
	}

	if page, ok := s.D.GetOkExists("page"); ok {
		tmp := page.(string)
		request.Page = &tmp
	}

	request.RequestMetadata.RetryPolicy = getRetryPolicy(false, "database")

	response, err := s.Client.ListDbSystemShapes(context.Background(), request)
	if err != nil {
		return err
	}

	s.Res = &response
	request.Page = s.Res.OpcNextPage

	for request.Page != nil {
		listResponse, err := s.Client.ListDbSystemShapes(context.Background(), request)
		if err != nil {
			return err
		}

		s.Res.Items = append(s.Res.Items, listResponse.Items...)
		request.Page = listResponse.OpcNextPage
	}

	return nil
}

func (s *DatabaseDbSystemShapesDataSourceCrud) SetData() error {
	if s.Res == nil {
		return nil
	}

	s.D.SetId(GenerateDataSourceID())
	resources := []map[string]interface{}{}

	for _, r := range s.Res.Items {
		dbSystemShape := map[string]interface{}{}

		if r.AvailableCoreCount != nil {
			dbSystemShape["available_core_count"] = *r.AvailableCoreCount
		}

		if r.CoreCountIncrement != nil {
			dbSystemShape["core_count_increment"] = *r.CoreCountIncrement
		}

		if r.MaximumNodeCount != nil {
			dbSystemShape["maximum_node_count"] = *r.MaximumNodeCount
		}

		if r.MinimumCoreCount != nil {
			dbSystemShape["minimum_core_count"] = *r.MinimumCoreCount
		}

		if r.MinimumNodeCount != nil {
			dbSystemShape["minimum_node_count"] = *r.MinimumNodeCount
		}

		if r.Name != nil {
			dbSystemShape["name"] = *r.Name
		}

		if r.Shape != nil {
			dbSystemShape["shape"] = *r.Shape
		}

		resources = append(resources, dbSystemShape)
	}

	if f, fOk := s.D.GetOkExists("filter"); fOk {
		resources = ApplyFilters(f.(*schema.Set), resources, DatabaseDbSystemShapesDataSource().Schema["db_system_shapes"].Elem.(*schema.Resource).Schema)
	}

	if err := s.D.Set("db_system_shapes", resources); err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package driver

import (
	"flag"
	"fmt"
	"log"
	"reflect"
	"strings"
	"sync"

	"github.com/chrislusf/glow/driver/plan"
	"github.com/chrislusf/glow/flow"
	"github.com/chrislusf/glow/netchan"
)

type TaskOption struct {
	ContextId          int
	TaskGroupId        int
	FistTaskName       string
	Inputs             string
	ExecutableFileHash string
	ChannelBufferSize  int
}

var taskOption TaskOption

func init() {
	flag.IntVar(&taskOption.ContextId, "glow.flow.id", -1, "flow id")
	flag.IntVar(&taskOption.TaskGroupId, "glow.taskGroup.id", -1, "task group id")
	flag.StringVar(&taskOption.FistTaskName, "glow.task.name", "", "name of first task in the task group")
	flag.StringVar(&taskOption.Inputs, "glow.taskGroup.inputs", "", "comma and @ seperated input locations")
	flag.StringVar(&taskOption.ExecutableFileHash, "glow.exe.hash", "", "hash of executable binary file")
	flag.IntVar(&taskOption.ChannelBufferSize, "glow.channel.bufferSize", 0, "channel buffer size for reading inputs")

	flow.RegisterTaskRunner(NewTaskRunner(&taskOption))
}

type TaskRunner struct {
	option      *TaskOption
	Tasks       []*flow.Task
	FlowContext *flow.FlowContext
}

func NewTaskRunner(option *TaskOption) *TaskRunner {
	return &TaskRunner{option: option}
}

func (tr *TaskRunner) IsTaskMode() bool {
	return tr.option.TaskGroupId >= 0 && tr.option.ContextId >= 0
}

// if this should not run, return false
func (tr *TaskRunner) Run(fc *flow.FlowContext) {
	if fc.Id != tr.option.ContextId {
		return
	}
	fc.ChannelBufferSize = tr.option.ChannelBufferSize

	taskGroups := plan.GroupTasks(fc)

	tr.Tasks = taskGroups[tr.option.TaskGroupId].Tasks
	tr.FlowContext = fc

	if len(tr.Tasks) == 0 {
		log.Println("How can the task group has no tasks!")
		return
	}

	// println("taskGroup", tr.Tasks[0].Name(), "starts")
	// 4. setup task input and output channels
	var wg sync.WaitGroup
	tr.connectInputsAndOutputs(&wg)
	// 6. starts to run the task locally
	for _, task := range tr.Tasks {
		// println("run task", task.Name())
		wg.Add(1)
		go func(task *flow.Task) {
			defer wg.Done()
			task.RunTask()
		}(task)
	}
	// 7. need to close connected output channels
	wg.Wait()
	// println("taskGroup", tr.Tasks[0].Name(), "finishes")
}

func (tr *TaskRunner) connectInputsAndOutputs(wg *sync.WaitGroup) {
	name2Location := make(map[string]string)
	if tr.option.Inputs != "" {
		for _, nameLocation := range strings.Split(tr.option.Inputs, ",") {
			// println("input:", nameLocation)
			nl := strings.Split(nameLocation, "@")
			name2Location[nl[0]] = nl[1]
		}
	}
	tr.connectExternalInputChannels(wg)
	tr.connectExternalInputs(wg, name2Location)
	tr.connectInternalInputsAndOutputs(wg)
	tr.connectExternalOutputs(wg)
}

func (tr *TaskRunner) connectInternalInputsAndOutputs(wg *sync.WaitGroup) {
	for i, _ := range tr.Tasks {
		if i == len(tr.Tasks)-1 {
			continue
		}
		currentShard, nextShard := tr.Tasks[i].Outputs[0], tr.Tasks[i+1].Inputs[0]

		currentShard.SetupReadingChans()

		wg.Add(1)
		go func(currentShard, nextShard *flow.DatasetShard, i int) {
			defer wg.Done()
			for {
				if t, ok := currentShard.WriteChan.Recv(); ok {
					nextShard.SendForRead(t)
				} else {
					nextShard.CloseRead()
					break
				}
			}
		}(currentShard, nextShard, i)
	}
}

func (tr *TaskRunner) connectExternalInputs(wg *sync.WaitGroup, name2Location map[string]string) {
	task := tr.Tasks[0]
	for i, shard := range task.Inputs {
		d := shard.Parent
		readChanName := tr.option.ExecutableFileHash + "-" + shard.Name()
		// println("taskGroup", tr.option.TaskGroupId, "task", task.Name(), "trying to read from:", readChanName, len(task.InputChans))
		rawChan, err := netchan.GetDirectReadChannel(readChanName, name2Location[readChanName], tr.FlowContext.ChannelBufferSize)
		if err != nil {
			log.Panic(err)
		}
		netchan.ConnectRawReadChannelToTyped(rawChan, task.InputChans[i], d.Type, wg)
	}
}

func (tr *TaskRunner) connectExternalInputChannels(wg *sync.WaitGroup) {
	// this is only for Channel dataset
	firstTask := tr.Tasks[0]
	if firstTask.Inputs != nil {
		return
	}
	ds := firstTask.Outputs[0].Parent
	for i, _ := range ds.ExternalInputChans {
		inputChanName := fmt.Sprintf("%s-ct-%d-input-%d-p-%d", tr.option.ExecutableFileHash, tr.option.ContextId, ds.Id, i)
		rawChan, err := netchan.GetLocalReadChannel(inputChanName, tr.FlowContext.ChannelBufferSize)
		if err != nil {
			log.Panic(err)
		}
		typedInputChan := make(chan reflect.Value)
		netchan.ConnectRawReadChannelToTyped(rawChan, typedInputChan, ds.Type, wg)
		firstTask.InputChans = append(firstTask.InputChans, typedInputChan)
	}
}

func (tr *TaskRunner) connectExternalOutputs(wg *sync.WaitGroup) {
	task := tr.Tasks[len(tr.Tasks)-1]
	for _, shard := range task.Outputs {
		writeChanName := tr.option.ExecutableFileHash + "-" + shard.Name()
		// println("taskGroup", tr.option.TaskGroupId, "step", task.Step.Id, "task", task.Id, "writing to:", writeChanName)
		rawChan, err := netchan.GetLocalSendChannel(writeChanName, wg)
		if err != nil {
			log.Panic(err)
		}
		netchan.ConnectTypedWriteChannelToRaw(shard.WriteChan, rawChan, wg)
	}
}
<commit_msg>clean up, change variable names<commit_after>package driver

import (
	"flag"
	"fmt"
	"log"
	"reflect"
	"strings"
	"sync"

	"github.com/chrislusf/glow/driver/plan"
	"github.com/chrislusf/glow/flow"
	"github.com/chrislusf/glow/netchan"
)

type TaskOption struct {
	ContextId          int
	TaskGroupId        int
	FistTaskName       string
	Inputs             string
	ExecutableFileHash string
	ChannelBufferSize  int
}

var taskOption TaskOption

func init() {
	flag.IntVar(&taskOption.ContextId, "glow.flow.id", -1, "flow id")
	flag.IntVar(&taskOption.TaskGroupId, "glow.taskGroup.id", -1, "task group id")
	flag.StringVar(&taskOption.FistTaskName, "glow.task.name", "", "name of first task in the task group")
	flag.StringVar(&taskOption.Inputs, "glow.taskGroup.inputs", "", "comma and @ seperated input locations")
	flag.StringVar(&taskOption.ExecutableFileHash, "glow.exe.hash", "", "hash of executable binary file")
	flag.IntVar(&taskOption.ChannelBufferSize, "glow.channel.bufferSize", 0, "channel buffer size for reading inputs")

	flow.RegisterTaskRunner(NewTaskRunner(&taskOption))
}

type TaskRunner struct {
	option      *TaskOption
	Tasks       []*flow.Task
	FlowContext *flow.FlowContext
}

func NewTaskRunner(option *TaskOption) *TaskRunner {
	return &TaskRunner{option: option}
}

func (tr *TaskRunner) IsTaskMode() bool {
	return tr.option.TaskGroupId >= 0 && tr.option.ContextId >= 0
}

// if this should not run, return false
func (tr *TaskRunner) Run(fc *flow.FlowContext) {
	if fc.Id != tr.option.ContextId {
		return
	}
	fc.ChannelBufferSize = tr.option.ChannelBufferSize

	tr.Tasks = plan.GroupTasks(fc)[tr.option.TaskGroupId].Tasks
	tr.FlowContext = fc

	// println("taskGroup", tr.Tasks[0].Name(), "starts")
	// 4. setup task input and output channels
	var wg sync.WaitGroup
	tr.connectInputsAndOutputs(&wg)
	// 6. starts to run the task locally
	for _, task := range tr.Tasks {
		// println("run task", task.Name())
		wg.Add(1)
		go func(task *flow.Task) {
			defer wg.Done()
			task.RunTask()
		}(task)
	}
	// 7. need to close connected output channels
	wg.Wait()
	// println("taskGroup", tr.Tasks[0].Name(), "finishes")
}

func (tr *TaskRunner) connectInputsAndOutputs(wg *sync.WaitGroup) {
	name2Location := make(map[string]string)
	if tr.option.Inputs != "" {
		for _, nameLocation := range strings.Split(tr.option.Inputs, ",") {
			// println("input:", nameLocation)
			nl := strings.Split(nameLocation, "@")
			name2Location[nl[0]] = nl[1]
		}
	}
	tr.connectExternalInputChannels(wg)
	tr.connectExternalInputs(wg, name2Location)
	tr.connectInternalInputsAndOutputs(wg)
	tr.connectExternalOutputs(wg)
}

func (tr *TaskRunner) connectInternalInputsAndOutputs(wg *sync.WaitGroup) {
	for i, _ := range tr.Tasks {
		if i == len(tr.Tasks)-1 {
			continue
		}
		currentShard, nextShard := tr.Tasks[i].Outputs[0], tr.Tasks[i+1].Inputs[0]

		currentShard.SetupReadingChans()

		wg.Add(1)
		go func(currentShard, nextShard *flow.DatasetShard, i int) {
			defer wg.Done()
			for {
				if t, ok := currentShard.WriteChan.Recv(); ok {
					nextShard.SendForRead(t)
				} else {
					nextShard.CloseRead()
					break
				}
			}
		}(currentShard, nextShard, i)
	}
}

func (tr *TaskRunner) connectExternalInputs(wg *sync.WaitGroup, name2Location map[string]string) {
	firstTask := tr.Tasks[0]
	for i, shard := range firstTask.Inputs {
		d := shard.Parent
		readChanName := tr.option.ExecutableFileHash + "-" + shard.Name()
		// println("taskGroup", tr.option.TaskGroupId, "firstTask", firstTask.Name(), "trying to read from:", readChanName, len(firstTask.InputChans))
		rawChan, err := netchan.GetDirectReadChannel(readChanName, name2Location[readChanName], tr.FlowContext.ChannelBufferSize)
		if err != nil {
			log.Panic(err)
		}
		netchan.ConnectRawReadChannelToTyped(rawChan, firstTask.InputChans[i], d.Type, wg)
	}
}

func (tr *TaskRunner) connectExternalInputChannels(wg *sync.WaitGroup) {
	// this is only for Channel dataset
	firstTask := tr.Tasks[0]
	if firstTask.Inputs != nil {
		return
	}
	ds := firstTask.Outputs[0].Parent
	for i, _ := range ds.ExternalInputChans {
		inputChanName := fmt.Sprintf("%s-ct-%d-input-%d-p-%d", tr.option.ExecutableFileHash, tr.option.ContextId, ds.Id, i)
		rawChan, err := netchan.GetLocalReadChannel(inputChanName, tr.FlowContext.ChannelBufferSize)
		if err != nil {
			log.Panic(err)
		}
		typedInputChan := make(chan reflect.Value)
		netchan.ConnectRawReadChannelToTyped(rawChan, typedInputChan, ds.Type, wg)
		firstTask.InputChans = append(firstTask.InputChans, typedInputChan)
	}
}

func (tr *TaskRunner) connectExternalOutputs(wg *sync.WaitGroup) {
	lastTask := tr.Tasks[len(tr.Tasks)-1]
	for _, shard := range lastTask.Outputs {
		writeChanName := tr.option.ExecutableFileHash + "-" + shard.Name()
		// println("taskGroup", tr.option.TaskGroupId, "step", lastTask.Step.Id, "lastTask", lastTask.Id, "writing to:", writeChanName)
		rawChan, err := netchan.GetLocalSendChannel(writeChanName, wg)
		if err != nil {
			log.Panic(err)
		}
		netchan.ConnectTypedWriteChannelToRaw(shard.WriteChan, rawChan, wg)
	}
}
<|endoftext|>


<commit_before>package ramsql

import (
	"database/sql"
	"testing"

	"github.com/proullon/ramsql/engine/log"
)

func TestUpdateSimple(t *testing.T) {
	log.UseTestLogger(t)

	db, err := sql.Open("ramsql", "")
	if err != nil {
		t.Fatalf("sql.Open : Error : %s\n", err)
	}
	defer db.Close()

	_, err = db.Exec("CREATE TABLE account (id INT AUTOINCREMENT, email TEXT)")
	if err != nil {
		t.Fatalf("sql.Exec: Error: %s\n", err)
	}

	_, err = db.Exec("INSERT INTO account ('email') VALUES ('foo@bar.com')")
	if err != nil {
		t.Fatalf("Cannot insert into table account: %s", err)
	}

	_, err = db.Exec("INSERT INTO account ('email') VALUES ('leon@bar.com')")
	if err != nil {
		t.Fatalf("Cannot insert into table account: %s", err)
	}

	_, err = db.Exec("UPDATE account SET email = 'roger@gmail.com' WHERE id = 2")
	if err != nil {
		t.Fatalf("Cannot update table account: %s", err)
	}

	row := db.QueryRow("SELECT * FROM account WHERE id = 2")
	if row == nil {
		t.Fatalf("sql.Query failed")
	}

	var email string
	var id int
	err = row.Scan(&id, &email)
	if err != nil {
		t.Fatalf("row.Scan: %s", err)
	}

	if email != "roger@gmail.com" {
		t.Fatalf("Expected email 'roger@gmail.com', got '%s'", email)
	}
}
<commit_msg>fix: test UpdateSimple<commit_after>package ramsql

import (
	"database/sql"
	"testing"

	"github.com/proullon/ramsql/engine/log"
)

func TestUpdateSimple(t *testing.T) {
	log.UseTestLogger(t)

	db, err := sql.Open("ramsql", "TestUpdateSimple")
	if err != nil {
		t.Fatalf("sql.Open : Error : %s\n", err)
	}
	defer db.Close()

	_, err = db.Exec("CREATE TABLE account (id INT AUTOINCREMENT, email TEXT)")
	if err != nil {
		t.Fatalf("sql.Exec: Error: %s\n", err)
	}

	_, err = db.Exec("INSERT INTO account ('email') VALUES ('foo@bar.com')")
	if err != nil {
		t.Fatalf("Cannot insert into table account: %s", err)
	}

	_, err = db.Exec("INSERT INTO account ('email') VALUES ('leon@bar.com')")
	if err != nil {
		t.Fatalf("Cannot insert into table account: %s", err)
	}

	_, err = db.Exec("UPDATE account SET email = 'roger@gmail.com' WHERE id = 2")
	if err != nil {
		t.Fatalf("Cannot update table account: %s", err)
	}

	row := db.QueryRow("SELECT * FROM account WHERE id = 2")
	if row == nil {
		t.Fatalf("sql.Query failed")
	}

	var email string
	var id int
	err = row.Scan(&id, &email)
	if err != nil {
		t.Fatalf("row.Scan: %s", err)
	}

	if email != "roger@gmail.com" {
		t.Fatalf("Expected email 'roger@gmail.com', got '%s'", email)
	}
}
<|endoftext|>


<commit_before>package autoprofile

import (
	"github.com/instana/go-sensor/autoprofile/internal"
	"github.com/instana/go-sensor/autoprofile/internal/logger"
	instalogger "github.com/instana/go-sensor/logger"
)

var (
	profileRecorder     = internal.NewRecorder()
	cpuSamplerScheduler = internal.NewSamplerScheduler(profileRecorder, internal.NewCPUSampler(), internal.SamplerConfig{
		LogPrefix:          "CPU sampler:",
		MaxProfileDuration: 20,
		MaxSpanDuration:    2,
		MaxSpanCount:       30,
		SamplingInterval:   8,
		ReportInterval:     120,
	})
	allocationSamplerScheduler = internal.NewSamplerScheduler(profileRecorder, internal.NewAllocationSampler(), internal.SamplerConfig{
		LogPrefix:      "Allocation sampler:",
		ReportOnly:     true,
		ReportInterval: 120,
	})
	blockSamplerScheduler = internal.NewSamplerScheduler(profileRecorder, internal.NewBlockSampler(), internal.SamplerConfig{
		LogPrefix:          "Block sampler:",
		MaxProfileDuration: 20,
		MaxSpanDuration:    4,
		MaxSpanCount:       30,
		SamplingInterval:   16,
		ReportInterval:     120,
	})

	enabled bool
)

// SetLogLevel sets the min log level for autoprofiler
func SetLogLevel(level int) {
	switch logger.Level(level) {
	case logger.ErrorLevel:
		logger.SetLogLevel(instalogger.ErrorLevel)
	case logger.WarnLevel:
		logger.SetLogLevel(instalogger.WarnLevel)
	case logger.InfoLevel:
		logger.SetLogLevel(instalogger.InfoLevel)
	default:
		logger.SetLogLevel(instalogger.DebugLevel)
	}
}

// SetLogger sets the leveled logger to use to output the diagnostic messages and errors
func SetLogger(l logger.LeveledLogger) {
	logger.SetLogger(l)
}

// Enable enables the auto profiling (disabled by default)
func Enable() {
	if enabled {
		return
	}

	profileRecorder.Start()
	cpuSamplerScheduler.Start()
	allocationSamplerScheduler.Start()
	blockSamplerScheduler.Start()

	logger.Debug("profiler enabled")
}

// Disable disables the auto profiling (default)
func Disable() {
	if !enabled {
		return
	}

	profileRecorder.Stop()
	cpuSamplerScheduler.Stop()
	allocationSamplerScheduler.Stop()
	blockSamplerScheduler.Stop()

	logger.Debug("profiler disabled")
}

// SetGetExternalPIDFunc configures the profiler to use provided function to retrieve the current PID
func SetGetExternalPIDFunc(fn func() string) {
	if fn == nil {
		fn = internal.GetLocalPID
	}

	internal.GetPID = fn
}

// SetSendProfilesFunc configures the profiler to use provided function to write collected profiles
func SetSendProfilesFunc(fn internal.SendProfilesFunc) {
	if fn == nil {
		fn = internal.NoopSendProfiles
	}

	profileRecorder.SendProfiles = fn
}

// Options contains profiler configuration
type Options struct {
	IncludeProfilerFrames bool
	MaxBufferedProfiles   int
}

// DefaultOptions returns profiler defaults
func DefaultOptions() Options {
	return Options{
		MaxBufferedProfiles: internal.DefaultMaxBufferedProfiles,
	}
}

// SetOptions configures the profiler with provided settings
func SetOptions(opts Options) {
	if opts.MaxBufferedProfiles < 1 {
		opts.MaxBufferedProfiles = internal.DefaultMaxBufferedProfiles
	}

	profileRecorder.MaxBufferedProfiles = opts.MaxBufferedProfiles
	internal.IncludeProfilerFrames = opts.IncludeProfilerFrames
}
<commit_msg>Deprecate autoprofile.SetLogLevel()<commit_after>package autoprofile

import (
	"github.com/instana/go-sensor/autoprofile/internal"
	"github.com/instana/go-sensor/autoprofile/internal/logger"
	instalogger "github.com/instana/go-sensor/logger"
)

var (
	profileRecorder     = internal.NewRecorder()
	cpuSamplerScheduler = internal.NewSamplerScheduler(profileRecorder, internal.NewCPUSampler(), internal.SamplerConfig{
		LogPrefix:          "CPU sampler:",
		MaxProfileDuration: 20,
		MaxSpanDuration:    2,
		MaxSpanCount:       30,
		SamplingInterval:   8,
		ReportInterval:     120,
	})
	allocationSamplerScheduler = internal.NewSamplerScheduler(profileRecorder, internal.NewAllocationSampler(), internal.SamplerConfig{
		LogPrefix:      "Allocation sampler:",
		ReportOnly:     true,
		ReportInterval: 120,
	})
	blockSamplerScheduler = internal.NewSamplerScheduler(profileRecorder, internal.NewBlockSampler(), internal.SamplerConfig{
		LogPrefix:          "Block sampler:",
		MaxProfileDuration: 20,
		MaxSpanDuration:    4,
		MaxSpanCount:       30,
		SamplingInterval:   16,
		ReportInterval:     120,
	})

	enabled bool
)

// SetLogLevel sets the min log level for autoprofiler
//
// Deprecated: use autoprofile.SetLogger() to set the logger and configure the min log level directly
func SetLogLevel(level int) {
	switch logger.Level(level) {
	case logger.ErrorLevel:
		logger.SetLogLevel(instalogger.ErrorLevel)
	case logger.WarnLevel:
		logger.SetLogLevel(instalogger.WarnLevel)
	case logger.InfoLevel:
		logger.SetLogLevel(instalogger.InfoLevel)
	default:
		logger.SetLogLevel(instalogger.DebugLevel)
	}
}

// SetLogger sets the leveled logger to use to output the diagnostic messages and errors
func SetLogger(l logger.LeveledLogger) {
	logger.SetLogger(l)
}

// Enable enables the auto profiling (disabled by default)
func Enable() {
	if enabled {
		return
	}

	profileRecorder.Start()
	cpuSamplerScheduler.Start()
	allocationSamplerScheduler.Start()
	blockSamplerScheduler.Start()

	logger.Debug("profiler enabled")
}

// Disable disables the auto profiling (default)
func Disable() {
	if !enabled {
		return
	}

	profileRecorder.Stop()
	cpuSamplerScheduler.Stop()
	allocationSamplerScheduler.Stop()
	blockSamplerScheduler.Stop()

	logger.Debug("profiler disabled")
}

// SetGetExternalPIDFunc configures the profiler to use provided function to retrieve the current PID
func SetGetExternalPIDFunc(fn func() string) {
	if fn == nil {
		fn = internal.GetLocalPID
	}

	internal.GetPID = fn
}

// SetSendProfilesFunc configures the profiler to use provided function to write collected profiles
func SetSendProfilesFunc(fn internal.SendProfilesFunc) {
	if fn == nil {
		fn = internal.NoopSendProfiles
	}

	profileRecorder.SendProfiles = fn
}

// Options contains profiler configuration
type Options struct {
	IncludeProfilerFrames bool
	MaxBufferedProfiles   int
}

// DefaultOptions returns profiler defaults
func DefaultOptions() Options {
	return Options{
		MaxBufferedProfiles: internal.DefaultMaxBufferedProfiles,
	}
}

// SetOptions configures the profiler with provided settings
func SetOptions(opts Options) {
	if opts.MaxBufferedProfiles < 1 {
		opts.MaxBufferedProfiles = internal.DefaultMaxBufferedProfiles
	}

	profileRecorder.MaxBufferedProfiles = opts.MaxBufferedProfiles
	internal.IncludeProfilerFrames = opts.IncludeProfilerFrames
}
<|endoftext|>


<commit_before>// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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.

// sidecar for the game server that the sdk connects to
package main

import (
	"fmt"
	"net"
	"strings"

	"time"

	"github.com/agonio/agon/gameservers/sidecar/sdk"
	"github.com/agonio/agon/pkg"
	"github.com/agonio/agon/pkg/client/clientset/versioned"
	"github.com/agonio/agon/pkg/util/runtime"
	"github.com/sirupsen/logrus"
	"github.com/spf13/pflag"
	"github.com/spf13/viper"
	"golang.org/x/net/context"
	"google.golang.org/grpc"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"
)

const (
	port = 59357

	// specifically env vars
	gameServerNameEnv = "GAMESERVER_NAME"
	podNamespaceEnv   = "POD_NAMESPACE"

	// Flags (that can also be env vars)
	localFlag                  = "local"
	healthDisabledFlag         = "health-disabled"
	healthTimeoutFlag          = "health-timeout"
	healthInitialDelayFlag     = "health-initial-delay"
	healthFailureThresholdFlag = "health-failure-threshold"
)

func init() {
	logrus.SetFormatter(&logrus.JSONFormatter{})
}

func main() {
	viper.SetDefault(localFlag, false)
	viper.SetDefault(healthDisabledFlag, false)
	viper.SetDefault(healthTimeoutFlag, 5)
	viper.SetDefault(healthInitialDelayFlag, 5)
	viper.SetDefault(healthFailureThresholdFlag, 3)
	pflag.Bool(localFlag, viper.GetBool(localFlag),
		"Set this, or LOCAL env, to 'true' to run this binary in local development mode. Defaults to 'false'")
	pflag.Bool(healthDisabledFlag, viper.GetBool(healthDisabledFlag),
		"Set this, or HEALTH_ENABLED env, to 'true' to enable health checking on the GameServer. Defaults to 'true'")
	pflag.Int64(healthTimeoutFlag, viper.GetInt64(healthTimeoutFlag),
		"Set this or HEALTH_TIMEOUT env to the number of seconds that the health check times out at. Defaults to 5")
	pflag.Int64(healthInitialDelayFlag, viper.GetInt64(healthInitialDelayFlag),
		"Set this or HEALTH_INITIAL_DELAY env to the number of seconds that the health will wait before starting. Defaults to 5")
	pflag.Int64(healthFailureThresholdFlag, viper.GetInt64(healthFailureThresholdFlag),
		"Set this or HEALTH_FAILURE_THRESHOLD env to the number of times the health check needs to fail to be deemed unhealthy. Defaults to 3")
	pflag.Parse()

	viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
	runtime.Must(viper.BindEnv(localFlag))
	runtime.Must(viper.BindEnv(gameServerNameEnv))
	runtime.Must(viper.BindEnv(podNamespaceEnv))
	runtime.Must(viper.BindEnv(healthDisabledFlag))
	runtime.Must(viper.BindEnv(healthTimeoutFlag))
	runtime.Must(viper.BindEnv(healthInitialDelayFlag))
	runtime.Must(viper.BindEnv(healthFailureThresholdFlag))
	runtime.Must(viper.BindPFlags(pflag.CommandLine))

	isLocal := viper.GetBool(localFlag)
	healthDisabled := viper.GetBool(healthDisabledFlag)
	healthTimeout := time.Duration(viper.GetInt64(healthTimeoutFlag)) * time.Second
	healthInitialDelay := time.Duration(viper.GetInt64(healthInitialDelayFlag)) * time.Second
	healthFailureThreshold := viper.GetInt64(healthFailureThresholdFlag)

	logrus.WithField(localFlag, isLocal).WithField("version", pkg.Version).WithField("port", port).
		WithField(healthDisabledFlag, healthDisabled).WithField(healthTimeoutFlag, healthTimeout).
		WithField(healthFailureThresholdFlag, healthFailureThreshold).
		WithField(healthInitialDelayFlag, healthInitialDelay).Info("Starting sdk sidecar")

	lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", port))
	if err != nil {
		logrus.WithField("port", port).Fatalf("Could not listen on port")
	}
	grpcServer := grpc.NewServer()

	if isLocal {
		sdk.RegisterSDKServer(grpcServer, &Local{})
	} else {
		config, err := rest.InClusterConfig()
		if err != nil {
			logrus.WithError(err).Fatal("Could not create in cluster config")
		}

		kubeClient, err := kubernetes.NewForConfig(config)
		if err != nil {
			logrus.WithError(err).Fatal("Could not create the kubernetes clientset")
		}

		agonClient, err := versioned.NewForConfig(config)
		if err != nil {
			logrus.WithError(err).Fatalf("Could not create the agon api clientset")
		}

		var s *Sidecar
		s, err = NewSidecar(viper.GetString(gameServerNameEnv), viper.GetString(podNamespaceEnv),
			healthDisabled, healthTimeout, healthFailureThreshold, healthInitialDelay, kubeClient, agonClient)
		if err != nil {
			logrus.WithError(err).Fatalf("Could not start sidecar")
		}
		ctx, cancel := context.WithCancel(context.Background())
		defer cancel()

		go s.Run(ctx.Done())
		sdk.RegisterSDKServer(grpcServer, s)
	}

	err = grpcServer.Serve(lis)
	if err != nil {
		logrus.WithError(err).Error("Could not serve grpc server")
	}
}
<commit_msg>Address flag for the sidecar<commit_after>// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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.

// sidecar for the game server that the sdk connects to
package main

import (
	"fmt"
	"net"
	"strings"

	"time"

	"github.com/agonio/agon/gameservers/sidecar/sdk"
	"github.com/agonio/agon/pkg"
	"github.com/agonio/agon/pkg/client/clientset/versioned"
	"github.com/agonio/agon/pkg/util/runtime"
	"github.com/sirupsen/logrus"
	"github.com/spf13/pflag"
	"github.com/spf13/viper"
	"golang.org/x/net/context"
	"google.golang.org/grpc"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"
)

const (
	port = 59357

	// specifically env vars
	gameServerNameEnv = "GAMESERVER_NAME"
	podNamespaceEnv   = "POD_NAMESPACE"

	// Flags (that can also be env vars)
	localFlag                  = "local"
	addressFlag                = "address"
	healthDisabledFlag         = "health-disabled"
	healthTimeoutFlag          = "health-timeout"
	healthInitialDelayFlag     = "health-initial-delay"
	healthFailureThresholdFlag = "health-failure-threshold"
)

func init() {
	logrus.SetFormatter(&logrus.JSONFormatter{})
}

func main() {
	viper.SetDefault(localFlag, false)
	viper.SetDefault(addressFlag, "localhost")
	viper.SetDefault(healthDisabledFlag, false)
	viper.SetDefault(healthTimeoutFlag, 5)
	viper.SetDefault(healthInitialDelayFlag, 5)
	viper.SetDefault(healthFailureThresholdFlag, 3)
	pflag.Bool(localFlag, viper.GetBool(localFlag),
		"Set this, or LOCAL env, to 'true' to run this binary in local development mode. Defaults to 'false'")
	pflag.String(addressFlag, viper.GetString(addressFlag), "The address to bind the server port to. Defaults to 'localhost")
	pflag.Bool(healthDisabledFlag, viper.GetBool(healthDisabledFlag),
		"Set this, or HEALTH_ENABLED env, to 'true' to enable health checking on the GameServer. Defaults to 'true'")
	pflag.Int64(healthTimeoutFlag, viper.GetInt64(healthTimeoutFlag),
		"Set this or HEALTH_TIMEOUT env to the number of seconds that the health check times out at. Defaults to 5")
	pflag.Int64(healthInitialDelayFlag, viper.GetInt64(healthInitialDelayFlag),
		"Set this or HEALTH_INITIAL_DELAY env to the number of seconds that the health will wait before starting. Defaults to 5")
	pflag.Int64(healthFailureThresholdFlag, viper.GetInt64(healthFailureThresholdFlag),
		"Set this or HEALTH_FAILURE_THRESHOLD env to the number of times the health check needs to fail to be deemed unhealthy. Defaults to 3")
	pflag.Parse()

	viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
	runtime.Must(viper.BindEnv(localFlag))
	runtime.Must(viper.BindEnv(gameServerNameEnv))
	runtime.Must(viper.BindEnv(podNamespaceEnv))
	runtime.Must(viper.BindEnv(healthDisabledFlag))
	runtime.Must(viper.BindEnv(healthTimeoutFlag))
	runtime.Must(viper.BindEnv(healthInitialDelayFlag))
	runtime.Must(viper.BindEnv(healthFailureThresholdFlag))
	runtime.Must(viper.BindPFlags(pflag.CommandLine))

	isLocal := viper.GetBool(localFlag)
	address := viper.GetString(addressFlag)
	healthDisabled := viper.GetBool(healthDisabledFlag)
	healthTimeout := time.Duration(viper.GetInt64(healthTimeoutFlag)) * time.Second
	healthInitialDelay := time.Duration(viper.GetInt64(healthInitialDelayFlag)) * time.Second
	healthFailureThreshold := viper.GetInt64(healthFailureThresholdFlag)

	logrus.WithField(localFlag, isLocal).WithField("version", pkg.Version).
		WithField("port", port).WithField(addressFlag, address).
		WithField(healthDisabledFlag, healthDisabled).WithField(healthTimeoutFlag, healthTimeout).
		WithField(healthFailureThresholdFlag, healthFailureThreshold).
		WithField(healthInitialDelayFlag, healthInitialDelay).Info("Starting sdk sidecar")

	lis, err := net.Listen("tcp", fmt.Sprintf("%s:%d", address, port))
	if err != nil {
		logrus.WithField("port", port).WithField("address", address).Fatalf("Could not listen on port")
	}
	grpcServer := grpc.NewServer()

	if isLocal {
		sdk.RegisterSDKServer(grpcServer, &Local{})
	} else {
		config, err := rest.InClusterConfig()
		if err != nil {
			logrus.WithError(err).Fatal("Could not create in cluster config")
		}

		kubeClient, err := kubernetes.NewForConfig(config)
		if err != nil {
			logrus.WithError(err).Fatal("Could not create the kubernetes clientset")
		}

		agonClient, err := versioned.NewForConfig(config)
		if err != nil {
			logrus.WithError(err).Fatalf("Could not create the agon api clientset")
		}

		var s *Sidecar
		s, err = NewSidecar(viper.GetString(gameServerNameEnv), viper.GetString(podNamespaceEnv),
			healthDisabled, healthTimeout, healthFailureThreshold, healthInitialDelay, kubeClient, agonClient)
		if err != nil {
			logrus.WithError(err).Fatalf("Could not start sidecar")
		}
		ctx, cancel := context.WithCancel(context.Background())
		defer cancel()

		go s.Run(ctx.Done())
		sdk.RegisterSDKServer(grpcServer, s)
	}

	err = grpcServer.Serve(lis)
	if err != nil {
		logrus.WithError(err).Error("Could not serve grpc server")
	}
}
<|endoftext|>


<commit_before>package isolated

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"path/filepath"
	"strings"

	"code.cloudfoundry.org/cli/integration/helpers"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"
)

var _ = Describe("app command", func() {
	Describe("help", func() {
		Context("when --help flag is set", func() {
			It("Displays command usage to output", func() {
				session := helpers.CF("app", "--help")
				Eventually(session).Should(Exit(0))
				Expect(session).To(Say("NAME:"))
				Expect(session).To(Say("app - Display health and status for app"))
				Expect(session).To(Say("USAGE:"))
				Expect(session).To(Say("cf app APP_NAME"))
				Expect(session).To(Say("OPTIONS:"))
				Expect(session).To(Say("--guid      Retrieve and display the given app's guid.  All other health and status output for the app is suppressed."))
				Expect(session).To(Say("SEE ALSO:"))
				Expect(session).To(Say("apps, events, logs, map-route, push, unmap-route"))
			})
		})
	})

	Context("when the environment is not setup correctly", func() {
		Context("when no API endpoint is set", func() {
			BeforeEach(func() {
				helpers.UnsetAPI()
			})

			It("fails with no API endpoint set message", func() {
				session := helpers.CF("app", "wut")
				Eventually(session).Should(Exit(1))
				Expect(session).To(Say("FAILED"))
				Expect(session).To(Say("No API endpoint set. Use 'cf login' or 'cf api' to target an endpoint."))
			})
		})

		Context("when not logged in", func() {
			BeforeEach(func() {
				helpers.LogoutCF()
			})

			It("fails with not logged in message", func() {
				session := helpers.CF("app", "wut")
				Eventually(session).Should(Exit(1))
				Expect(session).To(Say("FAILED"))
				Expect(session).To(Say("Not logged in. Use 'cf login' to log in."))
			})
		})

		Context("when there is no org and space set", func() {
			BeforeEach(func() {
				helpers.LogoutCF()
				helpers.LoginCF()
			})

			It("fails with no targeted org error message", func() {
				session := helpers.CF("app", "wut")
				Eventually(session).Should(Exit(1))
				Expect(session).To(Say("FAILED"))
				Expect(session).To(Say("No org and space targeted, use 'cf target -o ORG -s SPACE' to target an org and space"))
			})
		})

		Context("when there is no space set", func() {
			BeforeEach(func() {
				helpers.LogoutCF()
				helpers.LoginCF()
				helpers.TargetOrg(ReadOnlyOrg)
			})

			It("fails with no targeted space error message", func() {
				session := helpers.CF("app", "wut")
				Eventually(session).Should(Exit(1))
				Expect(session).To(Say("FAILED"))
				// TODO: change 'cf target -s' to 'cf target -s SPACE'
				Expect(session).To(Say("No space targeted, use 'cf target -s' to target a space."))
			})
		})
	})

	Context("when the environment is set up correctly", func() {
		var (
			orgName   string
			spaceName string
		)

		BeforeEach(func() {
			orgName = helpers.NewOrgName()
			spaceName = helpers.PrefixedRandomName("SPACE")

			setupCF(orgName, spaceName)
		})

		Context("when the app does not exist", func() {
			Context("when no flags are given", func() {
				It("tells the user that the app is not found and exits 1", func() {
					appName := helpers.PrefixedRandomName("app")
					session := helpers.CF("app", appName)

					Eventually(session).Should(Say("FAILED"))
					Eventually(session).Should(Say("App %s not found", appName))
					Eventually(session).Should(Exit(1))
				})
			})

			Context("when the --guid flag is given", func() {
				It("tells the user that the app is not found and exits 1", func() {
					appName := helpers.PrefixedRandomName("app")
					session := helpers.CF("app", "--guid", appName)

					Eventually(session).Should(Say("FAILED"))
					Eventually(session).Should(Say("App %s not found", appName))
					Eventually(session).Should(Exit(1))
				})
			})
		})

		Context("when the app does exist", func() {
			var (
				domainName string
				tcpDomain  helpers.Domain
				appName    string
			)
			BeforeEach(func() {
				appName = helpers.PrefixedRandomName("app")
				domainName = defaultSharedDomain()
				tcpDomain = helpers.NewDomain(orgName, helpers.DomainName("tcp"))
				tcpDomain.CreateWithRouterGroup("default-tcp")
				helpers.WithHelloWorldApp(func(appDir string) {
					manifestContents := []byte(fmt.Sprintf(`
---
applications:
- name: %s
  memory: 128M
  instances: 2
  disk_quota: 128M
  routes:
  - route: %s.%s
  - route: %s:1111
`, appName, appName, domainName, tcpDomain.Name))
					manifestPath := filepath.Join(appDir, "manifest.yml")
					err := ioutil.WriteFile(manifestPath, manifestContents, 0666)
					Expect(err).ToNot(HaveOccurred())

					// Create manifest and add big numbers
					Eventually(helpers.CF("push", appName, "-p", appDir, "-f", manifestPath, "-b", "staticfile_buildpack")).Should(Exit(0))
				})
			})

			AfterEach(func() {
				Eventually(helpers.CF("delete", appName, "-f", "-r")).Should(Exit(0))
			})

			Context("when the app is started and has 2 instances", func() {
				It("displays the app information", func() {
					session := helpers.CF("app", appName)
					// TODO: remove OK
					Eventually(session).Should(Say("OK"))
					Eventually(session).Should(Say("requested state: started"))
					Eventually(session).Should(Say("instances: 2/2"))
					Eventually(session).Should(Say("usage: 128M x 2 instances"))
					Eventually(session).Should(Say("urls: %s.%s, %s:1111", appName, domainName, tcpDomain.Name))
					Eventually(session).Should(Say("last uploaded:"))
					Eventually(session).Should(Say("stack: cflinuxfs2"))
					Eventually(session).Should(Say("buildpack: staticfile_buildpack"))

					Eventually(session).Should(Say("state\\s+since\\s+cpu\\s+memory\\s+disk\\s+details"))
					Eventually(session).Should(Say("#0\\s+running\\s+.*\\d+\\.\\d+%.*of 128M.*of 128M"))
					Eventually(session).Should(Say("#1\\s+running\\s+.*\\d+\\.\\d+%.*of 128M.*of 128M"))
				})
			})

			Context("when the app is stopped", func() {
				BeforeEach(func() {
					Eventually(helpers.CF("stop", appName)).Should(Exit(0))
				})

				It("displays the app information", func() {
					session := helpers.CF("app", appName)
					// TODO: remove OK
					Eventually(session).Should(Say("OK"))
					Eventually(session).Should(Say("requested state: stopped"))
					Eventually(session).Should(Say("instances: 0/2"))
					Eventually(session).Should(Say("usage: 128M x 2 instances"))
					Eventually(session).Should(Say("urls: %s.%s, %s:1111", appName, domainName, tcpDomain.Name))
					Eventually(session).Should(Say("last uploaded:"))
					Eventually(session).Should(Say("stack: cflinuxfs2"))
					Eventually(session).Should(Say("buildpack: staticfile_buildpack"))

					Eventually(session).Should(Say("There are no running instances of this app."))
				})
			})

			Context("when the app has 0 instances", func() {
				BeforeEach(func() {
					Eventually(helpers.CF("scale", appName, "-i", "0")).Should(Exit(0))
				})

				It("displays the app information", func() {
					session := helpers.CF("app", appName)
					// TODO: remove OK
					// TODO: display "there are no running instances" instead of table
					Eventually(session).Should(Say("OK"))
					Eventually(session).Should(Say("requested state: started"))
					Eventually(session).Should(Say("instances: 0/0"))
					Eventually(session).Should(Say("usage: 128M x 0 instances"))
					Eventually(session).Should(Say("urls: %s.%s, %s:1111", appName, domainName, tcpDomain.Name))
					Eventually(session).Should(Say("last uploaded:"))
					Eventually(session).Should(Say("stack: cflinuxfs2"))
					Eventually(session).Should(Say("buildpack: staticfile_buildpack"))

					Eventually(session).Should(Say("state\\s+since\\s+cpu\\s+memory\\s+disk\\s+details"))
				})

			})

			Context("when the --guid flag is given", func() {
				var appGUID string

				BeforeEach(func() {
					session := helpers.CF("curl", fmt.Sprintf("/v2/apps?q=name:%s", appName))
					Eventually(session).Should(Exit(0))
					rawJSON := strings.TrimSpace(string(session.Out.Contents()))
					var AppInfo struct {
						Resources []struct {
							Metadata struct {
								GUID string `json:"guid"`
							} `json:"metadata"`
						} `json:"resources"`
					}

					err := json.Unmarshal([]byte(rawJSON), &AppInfo)
					Expect(err).NotTo(HaveOccurred())

					appGUID = AppInfo.Resources[0].Metadata.GUID
				})

				It("displays the app information", func() {
					session := helpers.CF("app", "--guid", appName)
					Eventually(session).Should(Say(appGUID))
				})
			})
		})
	})
})
<commit_msg>fixed integration tests for the app command - skipping until refactor work is done<commit_after>package isolated

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"path/filepath"
	"strings"

	"code.cloudfoundry.org/cli/integration/helpers"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"
)

var _ = Describe("app command", func() {
	BeforeEach(func() {
		helpers.SkipIfExperimental("Skipping until story #126256629 is finished")
	})

	Describe("help", func() {
		Context("when --help flag is set", func() {
			It("Displays command usage to output", func() {
				session := helpers.CF("app", "--help")
				Eventually(session).Should(Exit(0))
				Expect(session).To(Say("NAME:"))
				Expect(session).To(Say("app - Display health and status for app"))
				Expect(session).To(Say("USAGE:"))
				Expect(session).To(Say("cf app APP_NAME"))
				Expect(session).To(Say("OPTIONS:"))
				Expect(session).To(Say("--guid      Retrieve and display the given app's guid.  All other health and status output for the app is suppressed."))
				Expect(session).To(Say("SEE ALSO:"))
				Expect(session).To(Say("apps, events, logs, map-route, push, unmap-route"))
			})
		})
	})

	Context("when the environment is not setup correctly", func() {
		Context("when no API endpoint is set", func() {
			BeforeEach(func() {
				helpers.UnsetAPI()
			})

			It("fails with no API endpoint set message", func() {
				session := helpers.CF("app", "wut")
				Eventually(session).Should(Exit(1))
				Expect(session).To(Say("FAILED"))
				Expect(session).To(Say("No API endpoint set. Use 'cf login' or 'cf api' to target an endpoint."))
			})
		})

		Context("when not logged in", func() {
			BeforeEach(func() {
				helpers.LogoutCF()
			})

			It("fails with not logged in message", func() {
				session := helpers.CF("app", "wut")
				Eventually(session).Should(Exit(1))
				Expect(session).To(Say("FAILED"))
				Expect(session).To(Say("Not logged in. Use 'cf login' to log in."))
			})
		})

		Context("when there is no org and space set", func() {
			BeforeEach(func() {
				helpers.LogoutCF()
				helpers.LoginCF()
			})

			It("fails with no targeted org error message", func() {
				session := helpers.CF("app", "wut")
				Eventually(session).Should(Exit(1))
				Expect(session).To(Say("FAILED"))
				Expect(session).To(Say("No org and space targeted, use 'cf target -o ORG -s SPACE' to target an org and space"))
			})
		})

		Context("when there is no space set", func() {
			BeforeEach(func() {
				helpers.LogoutCF()
				helpers.LoginCF()
				helpers.TargetOrg(ReadOnlyOrg)
			})

			It("fails with no targeted space error message", func() {
				session := helpers.CF("app", "wut")
				Eventually(session).Should(Exit(1))
				Expect(session).To(Say("FAILED"))
				Expect(session).To(Say("No space targeted, use 'cf target -s SPACE' to target a space."))
			})
		})
	})

	Context("when the environment is set up correctly", func() {
		var (
			orgName   string
			spaceName string
		)

		BeforeEach(func() {
			orgName = helpers.NewOrgName()
			spaceName = helpers.PrefixedRandomName("SPACE")

			setupCF(orgName, spaceName)
		})

		Context("when the app does not exist", func() {
			Context("when no flags are given", func() {
				It("tells the user that the app is not found and exits 1", func() {
					appName := helpers.PrefixedRandomName("app")
					session := helpers.CF("app", appName)

					Eventually(session).Should(Say("FAILED"))
					Eventually(session).Should(Say("App %s not found", appName))
					Eventually(session).Should(Exit(1))
				})
			})

			Context("when the --guid flag is given", func() {
				It("tells the user that the app is not found and exits 1", func() {
					appName := helpers.PrefixedRandomName("app")
					session := helpers.CF("app", "--guid", appName)

					Eventually(session).Should(Say("FAILED"))
					Eventually(session).Should(Say("App %s not found", appName))
					Eventually(session).Should(Exit(1))
				})
			})
		})

		Context("when the app does exist", func() {
			var (
				domainName string
				tcpDomain  helpers.Domain
				appName    string
			)
			BeforeEach(func() {
				appName = helpers.PrefixedRandomName("app")
				domainName = defaultSharedDomain()
				tcpDomain = helpers.NewDomain(orgName, helpers.DomainName("tcp"))
				tcpDomain.CreateWithRouterGroup("default-tcp")
				helpers.WithHelloWorldApp(func(appDir string) {
					manifestContents := []byte(fmt.Sprintf(`
---
applications:
- name: %s
  memory: 128M
  instances: 2
  disk_quota: 128M
  routes:
  - route: %s.%s
  - route: %s:1111
`, appName, appName, domainName, tcpDomain.Name))
					manifestPath := filepath.Join(appDir, "manifest.yml")
					err := ioutil.WriteFile(manifestPath, manifestContents, 0666)
					Expect(err).ToNot(HaveOccurred())

					// Create manifest and add big numbers
					Eventually(helpers.CF("push", appName, "-p", appDir, "-f", manifestPath, "-b", "staticfile_buildpack")).Should(Exit(0))
				})
			})

			AfterEach(func() {
				Eventually(helpers.CF("delete", appName, "-f", "-r")).Should(Exit(0))
			})

			Context("when the app is started and has 2 instances", func() {
				It("displays the app information", func() {
					session := helpers.CF("app", appName)
					Eventually(session).Should(Say("Name:            %s", appName))
					Eventually(session).Should(Say("Requested state: started"))
					Eventually(session).Should(Say("Instances:       2/2"))
					Eventually(session).Should(Say("Usage:           128M x 2 instances"))
					Eventually(session).Should(Say("Routes:          %s.%s, %s:1111", appName, domainName, tcpDomain.Name))
					Eventually(session).Should(Say("Last uploaded:"))
					Eventually(session).Should(Say("Stack:           cflinuxfs2"))
					Eventually(session).Should(Say("Buildpack:       staticfile_buildpack"))

					Eventually(session).Should(Say("State\\s+Since\\s+Cpu\\s+Memory\\s+Disk\\s+Details"))
					Eventually(session).Should(Say("#0\\s+running\\s+.*\\d+\\.\\d+%.*of 128M.*of 128M"))
					Eventually(session).Should(Say("#1\\s+running\\s+.*\\d+\\.\\d+%.*of 128M.*of 128M"))
				})
			})

			Context("when the app is stopped", func() {
				BeforeEach(func() {
					Eventually(helpers.CF("stop", appName)).Should(Exit(0))
				})

				It("displays the app information", func() {
					session := helpers.CF("app", appName)
					Eventually(session).Should(Say("Name:            %s", appName))
					Eventually(session).Should(Say("Requested state: stopped"))
					Eventually(session).Should(Say("Instances:       0/2"))
					Eventually(session).Should(Say("Usage:           128M x 2 instances"))
					Eventually(session).Should(Say("Routes:          %s.%s, %s:1111", appName, domainName, tcpDomain.Name))
					Eventually(session).Should(Say("Last uploaded:"))
					Eventually(session).Should(Say("Stack:           cflinuxfs2"))
					Eventually(session).Should(Say("Buildpack:       staticfile_buildpack"))

					Eventually(session).Should(Say("There are no running instances of this app."))
				})
			})

			Context("when the app has 0 instances", func() {
				BeforeEach(func() {
					Eventually(helpers.CF("scale", appName, "-i", "0")).Should(Exit(0))
				})

				It("displays the app information", func() {
					session := helpers.CF("app", appName)
					Eventually(session).Should(Say("Name:            %s", appName))
					Eventually(session).Should(Say("Requested state: started"))
					Eventually(session).Should(Say("Instances:       0/0"))
					Eventually(session).Should(Say("Usage:           128M x 0 instances"))
					Eventually(session).Should(Say("Routes:          %s.%s, %s:1111", appName, domainName, tcpDomain.Name))
					Eventually(session).Should(Say("Last uploaded:"))
					Eventually(session).Should(Say("Stack:           cflinuxfs2"))
					Eventually(session).Should(Say("Buildpack:       staticfile_buildpack"))

					Eventually(session).Should(Say("There are no running instances of this app."))
				})

			})

			Context("when the --guid flag is given", func() {
				var appGUID string

				BeforeEach(func() {
					session := helpers.CF("curl", fmt.Sprintf("/v2/apps?q=name:%s", appName))
					Eventually(session).Should(Exit(0))
					rawJSON := strings.TrimSpace(string(session.Out.Contents()))
					var AppInfo struct {
						Resources []struct {
							Metadata struct {
								GUID string `json:"guid"`
							} `json:"metadata"`
						} `json:"resources"`
					}

					err := json.Unmarshal([]byte(rawJSON), &AppInfo)
					Expect(err).NotTo(HaveOccurred())

					appGUID = AppInfo.Resources[0].Metadata.GUID
				})

				It("displays the app information", func() {
					session := helpers.CF("app", "--guid", appName)
					Eventually(session).Should(Say(appGUID))
				})
			})
		})
	})
})
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"
	"regexp"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/iam"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/helper/validation"
)

func resourceAwsIamUser() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsIamUserCreate,
		Read:   resourceAwsIamUserRead,
		Update: resourceAwsIamUserUpdate,
		Delete: resourceAwsIamUserDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"arn": {
				Type:     schema.TypeString,
				Computed: true,
			},
			/*
				The UniqueID could be used as the Id(), but none of the API
				calls allow specifying a user by the UniqueID: they require the
				name. The only way to locate a user by UniqueID is to list them
				all and that would make this provider unnecessarily complex
				and inefficient. Still, there are other reasons one might want
				the UniqueID, so we can make it available.
			*/
			"unique_id": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"name": {
				Type:         schema.TypeString,
				Required:     true,
				ValidateFunc: validateAwsIamUserName,
			},
			"path": {
				Type:     schema.TypeString,
				Optional: true,
				Default:  "/",
			},
			"permissions_boundary": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validation.StringLenBetween(0, 2048),
			},
			"force_destroy": {
				Type:        schema.TypeBool,
				Optional:    true,
				Default:     false,
				Description: "Delete user even if it has non-Terraform-managed IAM access keys, login profile or MFA devices",
			},
		},
	}
}

func resourceAwsIamUserCreate(d *schema.ResourceData, meta interface{}) error {
	iamconn := meta.(*AWSClient).iamconn
	name := d.Get("name").(string)
	path := d.Get("path").(string)

	request := &iam.CreateUserInput{
		Path:     aws.String(path),
		UserName: aws.String(name),
	}

	if v, ok := d.GetOk("permissions_boundary"); ok && v.(string) != "" {
		request.PermissionsBoundary = aws.String(v.(string))
	}

	log.Println("[DEBUG] Create IAM User request:", request)
	createResp, err := iamconn.CreateUser(request)
	if err != nil {
		return fmt.Errorf("Error creating IAM User %s: %s", name, err)
	}

	d.SetId(aws.StringValue(createResp.User.UserName))

	return resourceAwsIamUserRead(d, meta)
}

func resourceAwsIamUserRead(d *schema.ResourceData, meta interface{}) error {
	iamconn := meta.(*AWSClient).iamconn

	request := &iam.GetUserInput{
		UserName: aws.String(d.Id()),
	}

	output, err := iamconn.GetUser(request)
	if err != nil {
		if isAWSErr(err, iam.ErrCodeNoSuchEntityException, "") {
			log.Printf("[WARN] No IAM user by name (%s) found, removing from state", d.Id())
			d.SetId("")
			return nil
		}
		return fmt.Errorf("Error reading IAM User %s: %s", d.Id(), err)
	}

	if output == nil || output.User == nil {
		log.Printf("[WARN] No IAM user by name (%s) found, removing from state", d.Id())
		d.SetId("")
		return nil
	}

	d.Set("arn", output.User.Arn)
	d.Set("name", output.User.UserName)
	d.Set("path", output.User.Path)
	if output.User.PermissionsBoundary != nil {
		d.Set("permissions_boundary", output.User.PermissionsBoundary.PermissionsBoundaryArn)
	}
	d.Set("unique_id", output.User.UserId)

	return nil
}

func resourceAwsIamUserUpdate(d *schema.ResourceData, meta interface{}) error {
	iamconn := meta.(*AWSClient).iamconn

	if d.HasChange("name") || d.HasChange("path") {
		on, nn := d.GetChange("name")
		_, np := d.GetChange("path")

		request := &iam.UpdateUserInput{
			UserName:    aws.String(on.(string)),
			NewUserName: aws.String(nn.(string)),
			NewPath:     aws.String(np.(string)),
		}

		log.Println("[DEBUG] Update IAM User request:", request)
		_, err := iamconn.UpdateUser(request)
		if err != nil {
			if isAWSErr(err, iam.ErrCodeNoSuchEntityException, "") {
				log.Printf("[WARN] No IAM user by name (%s) found", d.Id())
				d.SetId("")
				return nil
			}
			return fmt.Errorf("Error updating IAM User %s: %s", d.Id(), err)
		}

		d.SetId(nn.(string))
	}

	if d.HasChange("permissions_boundary") {
		permissionsBoundary := d.Get("permissions_boundary").(string)
		if permissionsBoundary != "" {
			input := &iam.PutUserPermissionsBoundaryInput{
				PermissionsBoundary: aws.String(permissionsBoundary),
				UserName:            aws.String(d.Id()),
			}
			_, err := iamconn.PutUserPermissionsBoundary(input)
			if err != nil {
				return fmt.Errorf("error updating IAM User permissions boundary: %s", err)
			}
		} else {
			input := &iam.DeleteUserPermissionsBoundaryInput{
				UserName: aws.String(d.Id()),
			}
			_, err := iamconn.DeleteUserPermissionsBoundary(input)
			if err != nil {
				return fmt.Errorf("error deleting IAM User permissions boundary: %s", err)
			}
		}
	}

	return resourceAwsIamUserRead(d, meta)
}

func resourceAwsIamUserDelete(d *schema.ResourceData, meta interface{}) error {
	iamconn := meta.(*AWSClient).iamconn

	// IAM Users must be removed from all groups before they can be deleted
	var groups []string
	listGroups := &iam.ListGroupsForUserInput{
		UserName: aws.String(d.Id()),
	}
	pageOfGroups := func(page *iam.ListGroupsForUserOutput, lastPage bool) (shouldContinue bool) {
		for _, g := range page.Groups {
			groups = append(groups, *g.GroupName)
		}
		return !lastPage
	}
	err := iamconn.ListGroupsForUserPages(listGroups, pageOfGroups)
	if err != nil {
		return fmt.Errorf("Error removing user %q from all groups: %s", d.Id(), err)
	}
	for _, g := range groups {
		// use iam group membership func to remove user from all groups
		log.Printf("[DEBUG] Removing IAM User %s from IAM Group %s", d.Id(), g)
		if err := removeUsersFromGroup(iamconn, []*string{aws.String(d.Id())}, g); err != nil {
			return err
		}
	}

	// All access keys, MFA devices and login profile for the user must be removed
	if d.Get("force_destroy").(bool) {
		var accessKeys []string
		listAccessKeys := &iam.ListAccessKeysInput{
			UserName: aws.String(d.Id()),
		}
		pageOfAccessKeys := func(page *iam.ListAccessKeysOutput, lastPage bool) (shouldContinue bool) {
			for _, k := range page.AccessKeyMetadata {
				accessKeys = append(accessKeys, *k.AccessKeyId)
			}
			return !lastPage
		}
		err = iamconn.ListAccessKeysPages(listAccessKeys, pageOfAccessKeys)
		if err != nil {
			return fmt.Errorf("Error removing access keys of user %s: %s", d.Id(), err)
		}
		for _, k := range accessKeys {
			_, err := iamconn.DeleteAccessKey(&iam.DeleteAccessKeyInput{
				UserName:    aws.String(d.Id()),
				AccessKeyId: aws.String(k),
			})
			if err != nil {
				return fmt.Errorf("Error deleting access key %s: %s", k, err)
			}
		}

		var publicKeys []string
		listSSHPublicKeys := &iam.ListSSHPublicKeysInput{
			UserName: aws.String(d.Id()),
		}
		pageOfListSSHPublicKeys := func(page *iam.ListSSHPublicKeysOutput, lastPage bool) (shouldContinue bool) {
			for _, k := range page.SSHPublicKeys {
				publicKeys = append(publicKeys, *k.SSHPublicKeyId)
			}
			return !lastPage
		}
		err = iamconn.ListSSHPublicKeysPages(listSSHPublicKeys, pageOfListSSHPublicKeys)
		if err != nil {
			return fmt.Errorf("Error removing public ssh keys of user %s: %s", d.Id(), err)
		}
		for _, k := range publicKeys {
			_, err := iamconn.DeleteSSHPublicKey(&iam.DeleteSSHPublicKeyInput{
				UserName:       aws.String(d.Id()),
				SSHPublicKeyId: aws.String(k),
			})
			if err != nil {
				return fmt.Errorf("Error deleting access key %s: %s", k, err)
			}
		}

		var MFADevices []string
		listMFADevices := &iam.ListMFADevicesInput{
			UserName: aws.String(d.Id()),
		}
		pageOfMFADevices := func(page *iam.ListMFADevicesOutput, lastPage bool) (shouldContinue bool) {
			for _, m := range page.MFADevices {
				MFADevices = append(MFADevices, *m.SerialNumber)
			}
			return !lastPage
		}
		err = iamconn.ListMFADevicesPages(listMFADevices, pageOfMFADevices)
		if err != nil {
			return fmt.Errorf("Error removing MFA devices of user %s: %s", d.Id(), err)
		}
		for _, m := range MFADevices {
			_, err := iamconn.DeactivateMFADevice(&iam.DeactivateMFADeviceInput{
				UserName:     aws.String(d.Id()),
				SerialNumber: aws.String(m),
			})
			if err != nil {
				return fmt.Errorf("Error deactivating MFA device %s: %s", m, err)
			}
		}

		err = resource.Retry(1*time.Minute, func() *resource.RetryError {
			_, err = iamconn.DeleteLoginProfile(&iam.DeleteLoginProfileInput{
				UserName: aws.String(d.Id()),
			})
			if err != nil {
				if isAWSErr(err, iam.ErrCodeNoSuchEntityException, "") {
					return nil
				}
				// EntityTemporarilyUnmodifiable: Login Profile for User XXX cannot be modified while login profile is being created.
				if isAWSErr(err, iam.ErrCodeEntityTemporarilyUnmodifiableException, "") {
					return resource.RetryableError(err)
				}
				return resource.NonRetryableError(err)
			}
			return nil
		})

		if err != nil {
			return fmt.Errorf("Error deleting Account Login Profile: %s", err)
		}
	}

	deleteUserInput := &iam.DeleteUserInput{
		UserName: aws.String(d.Id()),
	}

	log.Println("[DEBUG] Delete IAM User request:", deleteUserInput)
	_, err = iamconn.DeleteUser(deleteUserInput)
	if err != nil {
		if isAWSErr(err, iam.ErrCodeNoSuchEntityException, "") {
			return nil
		}
		return fmt.Errorf("Error deleting IAM User %s: %s", d.Id(), err)
	}

	return nil
}

func validateAwsIamUserName(v interface{}, k string) (ws []string, errors []error) {
	value := v.(string)
	if !regexp.MustCompile(`^[0-9A-Za-z=,.@\-_+]+$`).MatchString(value) {
		errors = append(errors, fmt.Errorf(
			"only alphanumeric characters, hyphens, underscores, commas, periods, @ symbols, plus and equals signs allowed in %q: %q",
			k, value))
	}
	return
}
<commit_msg>fixed a copy paste error<commit_after>package aws

import (
	"fmt"
	"log"
	"regexp"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/iam"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/helper/validation"
)

func resourceAwsIamUser() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsIamUserCreate,
		Read:   resourceAwsIamUserRead,
		Update: resourceAwsIamUserUpdate,
		Delete: resourceAwsIamUserDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"arn": {
				Type:     schema.TypeString,
				Computed: true,
			},
			/*
				The UniqueID could be used as the Id(), but none of the API
				calls allow specifying a user by the UniqueID: they require the
				name. The only way to locate a user by UniqueID is to list them
				all and that would make this provider unnecessarily complex
				and inefficient. Still, there are other reasons one might want
				the UniqueID, so we can make it available.
			*/
			"unique_id": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"name": {
				Type:         schema.TypeString,
				Required:     true,
				ValidateFunc: validateAwsIamUserName,
			},
			"path": {
				Type:     schema.TypeString,
				Optional: true,
				Default:  "/",
			},
			"permissions_boundary": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validation.StringLenBetween(0, 2048),
			},
			"force_destroy": {
				Type:        schema.TypeBool,
				Optional:    true,
				Default:     false,
				Description: "Delete user even if it has non-Terraform-managed IAM access keys, login profile or MFA devices",
			},
		},
	}
}

func resourceAwsIamUserCreate(d *schema.ResourceData, meta interface{}) error {
	iamconn := meta.(*AWSClient).iamconn
	name := d.Get("name").(string)
	path := d.Get("path").(string)

	request := &iam.CreateUserInput{
		Path:     aws.String(path),
		UserName: aws.String(name),
	}

	if v, ok := d.GetOk("permissions_boundary"); ok && v.(string) != "" {
		request.PermissionsBoundary = aws.String(v.(string))
	}

	log.Println("[DEBUG] Create IAM User request:", request)
	createResp, err := iamconn.CreateUser(request)
	if err != nil {
		return fmt.Errorf("Error creating IAM User %s: %s", name, err)
	}

	d.SetId(aws.StringValue(createResp.User.UserName))

	return resourceAwsIamUserRead(d, meta)
}

func resourceAwsIamUserRead(d *schema.ResourceData, meta interface{}) error {
	iamconn := meta.(*AWSClient).iamconn

	request := &iam.GetUserInput{
		UserName: aws.String(d.Id()),
	}

	output, err := iamconn.GetUser(request)
	if err != nil {
		if isAWSErr(err, iam.ErrCodeNoSuchEntityException, "") {
			log.Printf("[WARN] No IAM user by name (%s) found, removing from state", d.Id())
			d.SetId("")
			return nil
		}
		return fmt.Errorf("Error reading IAM User %s: %s", d.Id(), err)
	}

	if output == nil || output.User == nil {
		log.Printf("[WARN] No IAM user by name (%s) found, removing from state", d.Id())
		d.SetId("")
		return nil
	}

	d.Set("arn", output.User.Arn)
	d.Set("name", output.User.UserName)
	d.Set("path", output.User.Path)
	if output.User.PermissionsBoundary != nil {
		d.Set("permissions_boundary", output.User.PermissionsBoundary.PermissionsBoundaryArn)
	}
	d.Set("unique_id", output.User.UserId)

	return nil
}

func resourceAwsIamUserUpdate(d *schema.ResourceData, meta interface{}) error {
	iamconn := meta.(*AWSClient).iamconn

	if d.HasChange("name") || d.HasChange("path") {
		on, nn := d.GetChange("name")
		_, np := d.GetChange("path")

		request := &iam.UpdateUserInput{
			UserName:    aws.String(on.(string)),
			NewUserName: aws.String(nn.(string)),
			NewPath:     aws.String(np.(string)),
		}

		log.Println("[DEBUG] Update IAM User request:", request)
		_, err := iamconn.UpdateUser(request)
		if err != nil {
			if isAWSErr(err, iam.ErrCodeNoSuchEntityException, "") {
				log.Printf("[WARN] No IAM user by name (%s) found", d.Id())
				d.SetId("")
				return nil
			}
			return fmt.Errorf("Error updating IAM User %s: %s", d.Id(), err)
		}

		d.SetId(nn.(string))
	}

	if d.HasChange("permissions_boundary") {
		permissionsBoundary := d.Get("permissions_boundary").(string)
		if permissionsBoundary != "" {
			input := &iam.PutUserPermissionsBoundaryInput{
				PermissionsBoundary: aws.String(permissionsBoundary),
				UserName:            aws.String(d.Id()),
			}
			_, err := iamconn.PutUserPermissionsBoundary(input)
			if err != nil {
				return fmt.Errorf("error updating IAM User permissions boundary: %s", err)
			}
		} else {
			input := &iam.DeleteUserPermissionsBoundaryInput{
				UserName: aws.String(d.Id()),
			}
			_, err := iamconn.DeleteUserPermissionsBoundary(input)
			if err != nil {
				return fmt.Errorf("error deleting IAM User permissions boundary: %s", err)
			}
		}
	}

	return resourceAwsIamUserRead(d, meta)
}

func resourceAwsIamUserDelete(d *schema.ResourceData, meta interface{}) error {
	iamconn := meta.(*AWSClient).iamconn

	// IAM Users must be removed from all groups before they can be deleted
	var groups []string
	listGroups := &iam.ListGroupsForUserInput{
		UserName: aws.String(d.Id()),
	}
	pageOfGroups := func(page *iam.ListGroupsForUserOutput, lastPage bool) (shouldContinue bool) {
		for _, g := range page.Groups {
			groups = append(groups, *g.GroupName)
		}
		return !lastPage
	}
	err := iamconn.ListGroupsForUserPages(listGroups, pageOfGroups)
	if err != nil {
		return fmt.Errorf("Error removing user %q from all groups: %s", d.Id(), err)
	}
	for _, g := range groups {
		// use iam group membership func to remove user from all groups
		log.Printf("[DEBUG] Removing IAM User %s from IAM Group %s", d.Id(), g)
		if err := removeUsersFromGroup(iamconn, []*string{aws.String(d.Id())}, g); err != nil {
			return err
		}
	}

	// All access keys, MFA devices and login profile for the user must be removed
	if d.Get("force_destroy").(bool) {
		var accessKeys []string
		listAccessKeys := &iam.ListAccessKeysInput{
			UserName: aws.String(d.Id()),
		}
		pageOfAccessKeys := func(page *iam.ListAccessKeysOutput, lastPage bool) (shouldContinue bool) {
			for _, k := range page.AccessKeyMetadata {
				accessKeys = append(accessKeys, *k.AccessKeyId)
			}
			return !lastPage
		}
		err = iamconn.ListAccessKeysPages(listAccessKeys, pageOfAccessKeys)
		if err != nil {
			return fmt.Errorf("Error removing access keys of user %s: %s", d.Id(), err)
		}
		for _, k := range accessKeys {
			_, err := iamconn.DeleteAccessKey(&iam.DeleteAccessKeyInput{
				UserName:    aws.String(d.Id()),
				AccessKeyId: aws.String(k),
			})
			if err != nil {
				return fmt.Errorf("Error deleting access key %s: %s", k, err)
			}
		}

		var publicKeys []string
		listSSHPublicKeys := &iam.ListSSHPublicKeysInput{
			UserName: aws.String(d.Id()),
		}
		pageOfListSSHPublicKeys := func(page *iam.ListSSHPublicKeysOutput, lastPage bool) (shouldContinue bool) {
			for _, k := range page.SSHPublicKeys {
				publicKeys = append(publicKeys, *k.SSHPublicKeyId)
			}
			return !lastPage
		}
		err = iamconn.ListSSHPublicKeysPages(listSSHPublicKeys, pageOfListSSHPublicKeys)
		if err != nil {
			return fmt.Errorf("Error removing public SSH keys of user %s: %s", d.Id(), err)
		}
		for _, k := range publicKeys {
			_, err := iamconn.DeleteSSHPublicKey(&iam.DeleteSSHPublicKeyInput{
				UserName:       aws.String(d.Id()),
				SSHPublicKeyId: aws.String(k),
			})
			if err != nil {
				return fmt.Errorf("Error deleting public SSH key %s: %s", k, err)
			}
		}

		var MFADevices []string
		listMFADevices := &iam.ListMFADevicesInput{
			UserName: aws.String(d.Id()),
		}
		pageOfMFADevices := func(page *iam.ListMFADevicesOutput, lastPage bool) (shouldContinue bool) {
			for _, m := range page.MFADevices {
				MFADevices = append(MFADevices, *m.SerialNumber)
			}
			return !lastPage
		}
		err = iamconn.ListMFADevicesPages(listMFADevices, pageOfMFADevices)
		if err != nil {
			return fmt.Errorf("Error removing MFA devices of user %s: %s", d.Id(), err)
		}
		for _, m := range MFADevices {
			_, err := iamconn.DeactivateMFADevice(&iam.DeactivateMFADeviceInput{
				UserName:     aws.String(d.Id()),
				SerialNumber: aws.String(m),
			})
			if err != nil {
				return fmt.Errorf("Error deactivating MFA device %s: %s", m, err)
			}
		}

		err = resource.Retry(1*time.Minute, func() *resource.RetryError {
			_, err = iamconn.DeleteLoginProfile(&iam.DeleteLoginProfileInput{
				UserName: aws.String(d.Id()),
			})
			if err != nil {
				if isAWSErr(err, iam.ErrCodeNoSuchEntityException, "") {
					return nil
				}
				// EntityTemporarilyUnmodifiable: Login Profile for User XXX cannot be modified while login profile is being created.
				if isAWSErr(err, iam.ErrCodeEntityTemporarilyUnmodifiableException, "") {
					return resource.RetryableError(err)
				}
				return resource.NonRetryableError(err)
			}
			return nil
		})

		if err != nil {
			return fmt.Errorf("Error deleting Account Login Profile: %s", err)
		}
	}

	deleteUserInput := &iam.DeleteUserInput{
		UserName: aws.String(d.Id()),
	}

	log.Println("[DEBUG] Delete IAM User request:", deleteUserInput)
	_, err = iamconn.DeleteUser(deleteUserInput)
	if err != nil {
		if isAWSErr(err, iam.ErrCodeNoSuchEntityException, "") {
			return nil
		}
		return fmt.Errorf("Error deleting IAM User %s: %s", d.Id(), err)
	}

	return nil
}

func validateAwsIamUserName(v interface{}, k string) (ws []string, errors []error) {
	value := v.(string)
	if !regexp.MustCompile(`^[0-9A-Za-z=,.@\-_+]+$`).MatchString(value) {
		errors = append(errors, fmt.Errorf(
			"only alphanumeric characters, hyphens, underscores, commas, periods, @ symbols, plus and equals signs allowed in %q: %q",
			k, value))
	}
	return
}
<|endoftext|>


<commit_before>package inbloom

import (
	"errors"
	"hash"
	"hash/fnv"
	"math"
	"strings"
)

//ProbabilisticSet represents an abstraction of a Probabilistic
type ProbabilisticSet interface {
	Add(obj *[]byte) error
	Test(obj *[]byte) (bool, error)
}

//BloomFilter is a space-efficient probabilistic data structure, conceived by Burton Howard Bloom in 1970, that is used to test whether an element is a member of a set.
type BloomFilter struct {
	vector         []byte
	baseHashFn     hash.Hash64
	numberOfHashes uint64
}

//Add an object to the set
func (filter BloomFilter) Add(obj *[]byte) error {

	hashValues, err := filter.getHashVector(obj)

	for i := 0; i < len(hashValues); i++ {
		hashVal := hashValues[i]
		filter.vector[hashVal] = 1
	}
	return err
}

func (filter *BloomFilter) getHashVector(obj *[]byte) ([]uint64, error) {

	defer filter.baseHashFn.Reset()

	_, e1 := filter.baseHashFn.Write(*obj)

	if e1 != nil {
		empty := make([]uint64, 0)
		return empty, errors.New("failed to add object to filter")
	}

	// simulate output of two hash functions that will serve as base hashes for simulating the output of n hash functions
	// based on https://www.eecs.harvard.edu/~michaelm/postscripts/rsa2008.pdf

	// instead of generating 2 hash values we optimize and generate only 1 and splitting it's value
	// into 2 distinct values simulating the values of two separate hash functions
	seed1 := filter.baseHashFn.Sum64()

	upperBits := seed1 >> 32 << 32
	lowerBits := seed1 >> 32 << 32
	hashValues := make([]uint64, filter.numberOfHashes)

	for i := uint64(0); i < filter.numberOfHashes; i++ {

		h := (upperBits + lowerBits*i + uint64(i*i)) % filter.numberOfHashes
		hashValues[i] = h
	}

	return hashValues, nil
}

//Test if an element is in the set
func (filter BloomFilter) Test(obj *[]byte) (bool, error) {

	hashVales, e := filter.getHashVector(obj)

	for i := 0; i < len(hashVales); i++ {
		hashVal := hashVales[i]
		if filter.vector[hashVal] == 0 {
			return false, e
		}
	}

	return true, e
}

//NewFilter creates a new BloomFilter. p is the error rate
//and n is the estimated number of elements that will be handled by the filter
func NewFilter(p float64, n int64) (filter ProbabilisticSet, e error) {

	/*
		Given:

		n: how many items you expect to have in your filter (e.g. 216,553)
		p: your acceptable false positive rate {0..1} (e.g. 0.01 → 1%)
		we want to calculate:

		m: the number of bits needed in the bloom filter
		k: the number of hash functions we should apply
		The formulas:

		m = -n*ln(p) / (ln(2)^2) the number of bits
		k = m/n * ln(2) the number of hash functions

	*/

	defer func() {

		if r := recover(); r != nil {

			filter = nil
			err, ok := r.(error)

			if ok {
				msg := err.Error()
				if strings.Contains(msg, "makeslice: len out of range") {
					e = errors.New("failed to create BloomFilter. either reduce error rate or maximum estimated elements in filter ")
				} else {
					e = err
				}

			} else {
				e = errors.New("failed to create BloomFilter")
			}

		}
	}()

	m := -float64(n) * math.Log(p) / math.Pow(math.Ln2, 2)
	k := uint64(m / float64(n) * math.Ln2)
	sliceLength := int64(m)

	bf := BloomFilter{vector: make([]byte, sliceLength),
		baseHashFn:     fnv.New64(),
		numberOfHashes: k}

	return bf, nil

}
<commit_msg>changed internal vector to type []bool<commit_after>package inbloom

import (
	"errors"
	"hash"
	"hash/fnv"
	"math"
	"strings"
)

//ProbabilisticSet represents an abstraction of a Probabilistic
type ProbabilisticSet interface {
	Add(obj *[]byte) error
	Test(obj *[]byte) (bool, error)
}

//BloomFilter is a space-efficient probabilistic data structure, conceived by Burton Howard Bloom in 1970, that is used to test whether an element is a member of a set.
type BloomFilter struct {
	vector         []bool
	baseHashFn     hash.Hash64
	numberOfHashes uint64
}

//Add an object to the set
func (filter BloomFilter) Add(obj *[]byte) error {

	hashValues, err := filter.getHashVector(obj)

	for i := 0; i < len(hashValues); i++ {
		hashVal := hashValues[i]
		filter.vector[hashVal] = true
	}
	return err
}

func (filter *BloomFilter) getHashVector(obj *[]byte) ([]uint64, error) {

	defer filter.baseHashFn.Reset()

	_, e1 := filter.baseHashFn.Write(*obj)

	if e1 != nil {
		empty := make([]uint64, 0)
		return empty, errors.New("failed to add object to filter")
	}

	// simulate output of two hash functions that will serve as base hashes for simulating the output of n hash functions
	// based on https://www.eecs.harvard.edu/~michaelm/postscripts/rsa2008.pdf

	// instead of generating 2 hash values we optimize and generate only 1 and splitting it's value
	// into 2 distinct values simulating the values of two separate hash functions
	seed1 := filter.baseHashFn.Sum64()

	upperBits := seed1 >> 32 << 32
	lowerBits := seed1 >> 32 << 32
	hashValues := make([]uint64, filter.numberOfHashes)

	for i := uint64(0); i < filter.numberOfHashes; i++ {

		h := (upperBits + lowerBits*i + uint64(i*i)) % filter.numberOfHashes
		hashValues[i] = h
	}

	return hashValues, nil
}

//Test if an element is in the set
func (filter BloomFilter) Test(obj *[]byte) (bool, error) {

	hashVales, e := filter.getHashVector(obj)

	for i := 0; i < len(hashVales); i++ {
		hashVal := hashVales[i]
		if filter.vector[hashVal] == false {
			return false, e
		}
	}

	return true, e
}

//NewFilter creates a new BloomFilter. p is the error rate
//and n is the estimated number of elements that will be handled by the filter
func NewFilter(p float64, n int64) (filter ProbabilisticSet, e error) {

	/*
		Given:

		n: how many items you expect to have in your filter (e.g. 216,553)
		p: your acceptable false positive rate {0..1} (e.g. 0.01 → 1%)
		we want to calculate:

		m: the number of bits needed in the bloom filter
		k: the number of hash functions we should apply
		The formulas:

		m = -n*ln(p) / (ln(2)^2) the number of bits
		k = m/n * ln(2) the number of hash functions

	*/

	defer func() {

		if r := recover(); r != nil {

			filter = nil
			err, ok := r.(error)

			if ok {
				msg := err.Error()
				if strings.Contains(msg, "makeslice: len out of range") {
					e = errors.New("failed to create BloomFilter. either reduce error rate or maximum estimated elements in filter ")
				} else {
					e = err
				}

			} else {
				e = errors.New("failed to create BloomFilter")
			}

		}
	}()

	m := -float64(n) * math.Log(p) / math.Pow(math.Ln2, 2)
	k := uint64(m / float64(n) * math.Ln2)
	sliceLength := int64(m)

	bf := BloomFilter{vector: make([]bool, sliceLength),
		baseHashFn:     fnv.New64(),
		numberOfHashes: k}

	return bf, nil

}
<|endoftext|>