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

package main

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"log"
	"os"
	"time"

	"github.com/maruel/subcommands"

	"go.chromium.org/luci/auth"
	"go.chromium.org/luci/client/archiver"
	"go.chromium.org/luci/client/isolate"
	"go.chromium.org/luci/common/data/text/units"
	"go.chromium.org/luci/common/isolated"
	"go.chromium.org/luci/common/isolatedclient"
	"go.chromium.org/luci/common/system/signals"
)

const (
	// infraFailExit is the exit code used when the exparchive fails due to
	// infrastructure errors (for example, failed server requests).
	infraFailExit = 2
)

func cmdArchive(defaultAuthOpts auth.Options) *subcommands.Command {
	return &subcommands.Command{
		UsageLine: "archive <options>",
		ShortDesc: "parses a .isolate file to create a .isolated file, and uploads it and all referenced files to an isolate server",
		LongDesc:  "All the files listed in the .isolated file are put in the isolate server cache. Small files are combined together in a tar archive before uploading.",
		CommandRun: func() subcommands.CommandRun {
			c := archiveRun{}
			c.commonServerFlags.Init(defaultAuthOpts)
			c.isolateFlags.Init(&c.Flags)
			c.loggingFlags.Init(&c.Flags)
			c.Flags.StringVar(&c.Isolated, "isolated", "", ".isolated file to generate")
			c.Flags.StringVar(&c.Isolated, "s", "", "Alias for --isolated")
			c.Flags.BoolVar(&c.expArchive, "exparchive", true, "IGNORED (deprecated) Whether to use the new exparchive implementation, which tars small files before uploading them.")
			c.Flags.IntVar(&c.maxConcurrentChecks, "max-concurrent-checks", 1, "The maximum number of in-flight check requests.")
			c.Flags.IntVar(&c.maxConcurrentUploads, "max-concurrent-uploads", 8, "The maximum number of in-flight uploads.")
			c.Flags.StringVar(&c.dumpJSON, "dump-json", "",
				"Write isolated digests of archived trees to this file as JSON")
			return &c
		},
	}
}

type archiveRun struct {
	commonServerFlags
	isolateFlags
	loggingFlags         loggingFlags
	expArchive           bool // deprecated
	maxConcurrentChecks  int
	maxConcurrentUploads int
	dumpJSON             string
}

func (c *archiveRun) Parse(a subcommands.Application, args []string) error {
	if err := c.commonServerFlags.Parse(); err != nil {
		return err
	}
	cwd, err := os.Getwd()
	if err != nil {
		return err
	}
	if err := c.isolateFlags.Parse(cwd, RequireIsolateFile&RequireIsolatedFile); err != nil {
		return err
	}
	if len(args) != 0 {
		return errors.New("position arguments not expected")
	}
	return nil
}

func (c *archiveRun) main(a subcommands.Application, args []string) error {
	start := time.Now()
	ctx, cancel := context.WithCancel(c.defaultFlags.MakeLoggingContext(os.Stderr))
	signals.HandleInterrupt(cancel)
	authCl, err := c.createAuthClient(ctx)
	if err != nil {
		return err
	}
	client := isolatedclient.New(nil, authCl, c.isolatedFlags.ServerURL, c.isolatedFlags.Namespace, nil, nil)

	al := archiveLogger{
		start: start,
		quiet: c.defaultFlags.Quiet,
	}

	return archive(ctx, client, &c.ArchiveOptions, c.dumpJSON, c.maxConcurrentChecks, c.maxConcurrentUploads, al)
}

// archiveLogger reports stats to stderr.
type archiveLogger struct {
	start time.Time
	quiet bool
}

// LogSummary logs (to eventlog and stderr) a high-level summary of archive operations(s).
func (al *archiveLogger) LogSummary(ctx context.Context, hits, misses int64, bytesHit, bytesPushed units.Size, digests []string) {
	end := time.Now()

	if !al.quiet {
		duration := end.Sub(al.start)
		fmt.Fprintf(os.Stderr, "Hits    : %5d (%s)\n", hits, bytesHit)
		fmt.Fprintf(os.Stderr, "Misses  : %5d (%s)\n", misses, bytesPushed)
		fmt.Fprintf(os.Stderr, "Duration: %s\n", units.Round(duration, time.Millisecond))
	}
}

// Print acts like fmt.Printf, but may prepend a prefix to format, depending on the value of al.quiet.
func (al *archiveLogger) Printf(format string, a ...interface{}) (n int, err error) {
	return al.Fprintf(os.Stdout, format, a...)
}

// Print acts like fmt.fprintf, but may prepend a prefix to format, depending on the value of al.quiet.
func (al *archiveLogger) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
	prefix := "\n"
	if al.quiet {
		prefix = ""
	}
	args := []interface{}{prefix}
	args = append(args, a...)
	return fmt.Printf("%s"+format, args...)
}

// archive performs the archive operation for an isolate specified by opts.
// dumpJSON is the path to write a JSON summary of the uploaded isolate, in the same format as batch_archive.
func archive(ctx context.Context, client *isolatedclient.Client, opts *isolate.ArchiveOptions, dumpJSON string, concurrentChecks, concurrentUploads int, al archiveLogger) error {
	// Parse the incoming isolate file.
	deps, rootDir, isol, err := isolate.ProcessIsolate(opts)
	if err != nil {
		return fmt.Errorf("isolate %s: failed to process: %v", opts.Isolate, err)
	}
	log.Printf("Isolate %s referenced %d deps", opts.Isolate, len(deps))

	// Set up a checker and uploader.
	checker := archiver.NewChecker(ctx, client, concurrentChecks)
	uploader := archiver.NewUploader(ctx, client, concurrentUploads)
	archiver := archiver.NewTarringArchiver(checker, uploader)

	isolSummary, err := archiver.Archive(deps, rootDir, opts.Blacklist, opts.Isolated, isol)
	if err != nil {
		return fmt.Errorf("isolate %s: %v", opts.Isolate, err)
	}

	// Make sure that all pending items have been checked.
	if err := checker.Close(); err != nil {
		return err
	}

	// Make sure that all the uploads have completed successfully.
	if err := uploader.Close(); err != nil {
		return err
	}

	printSummary(al, isolSummary)
	if err := dumpSummaryJSON(dumpJSON, isolSummary); err != nil {
		return err
	}

	al.LogSummary(ctx, int64(checker.Hit.Count()), int64(checker.Miss.Count()), units.Size(checker.Hit.Bytes()), units.Size(checker.Miss.Bytes()), []string{string(isolSummary.Digest)})
	return nil
}

func (c *archiveRun) Run(a subcommands.Application, args []string, _ subcommands.Env) int {
	if err := c.Parse(a, args); err != nil {
		fmt.Fprintf(a.GetErr(), "%s: %s\n", a.GetName(), err)
		return 1
	}
	cl, err := c.defaultFlags.StartTracing()
	if err != nil {
		fmt.Fprintf(a.GetErr(), "%s: %s\n", a.GetName(), err)
		return 1
	}
	defer cl.Close()
	if err := c.main(a, args); err != nil {
		fmt.Fprintf(a.GetErr(), "%s: %s\n", a.GetName(), err)
		return 1
	}
	return 0
}

func printSummary(al archiveLogger, summary archiver.IsolatedSummary) {
	al.Printf("%s\t%s\n", summary.Digest, summary.Name)
}

func dumpSummaryJSON(filename string, summaries ...archiver.IsolatedSummary) error {
	if len(filename) == 0 {
		return nil
	}
	f, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
	if err != nil {
		return err
	}
	defer f.Close()

	m := map[string]isolated.HexDigest{}
	for _, summary := range summaries {
		m[summary.Name] = summary.Digest
	}
	return json.NewEncoder(f).Encode(m)
}
<commit_msg>isolate: fix conditional<commit_after>// Copyright 2015 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"log"
	"os"
	"time"

	"github.com/maruel/subcommands"

	"go.chromium.org/luci/auth"
	"go.chromium.org/luci/client/archiver"
	"go.chromium.org/luci/client/isolate"
	"go.chromium.org/luci/common/data/text/units"
	"go.chromium.org/luci/common/isolated"
	"go.chromium.org/luci/common/isolatedclient"
	"go.chromium.org/luci/common/system/signals"
)

const (
	// infraFailExit is the exit code used when the exparchive fails due to
	// infrastructure errors (for example, failed server requests).
	infraFailExit = 2
)

func cmdArchive(defaultAuthOpts auth.Options) *subcommands.Command {
	return &subcommands.Command{
		UsageLine: "archive <options>",
		ShortDesc: "parses a .isolate file to create a .isolated file, and uploads it and all referenced files to an isolate server",
		LongDesc:  "All the files listed in the .isolated file are put in the isolate server cache. Small files are combined together in a tar archive before uploading.",
		CommandRun: func() subcommands.CommandRun {
			c := archiveRun{}
			c.commonServerFlags.Init(defaultAuthOpts)
			c.isolateFlags.Init(&c.Flags)
			c.loggingFlags.Init(&c.Flags)
			c.Flags.StringVar(&c.Isolated, "isolated", "", ".isolated file to generate")
			c.Flags.StringVar(&c.Isolated, "s", "", "Alias for --isolated")
			c.Flags.BoolVar(&c.expArchive, "exparchive", true, "IGNORED (deprecated) Whether to use the new exparchive implementation, which tars small files before uploading them.")
			c.Flags.IntVar(&c.maxConcurrentChecks, "max-concurrent-checks", 1, "The maximum number of in-flight check requests.")
			c.Flags.IntVar(&c.maxConcurrentUploads, "max-concurrent-uploads", 8, "The maximum number of in-flight uploads.")
			c.Flags.StringVar(&c.dumpJSON, "dump-json", "",
				"Write isolated digests of archived trees to this file as JSON")
			return &c
		},
	}
}

type archiveRun struct {
	commonServerFlags
	isolateFlags
	loggingFlags         loggingFlags
	expArchive           bool // deprecated
	maxConcurrentChecks  int
	maxConcurrentUploads int
	dumpJSON             string
}

func (c *archiveRun) Parse(a subcommands.Application, args []string) error {
	if err := c.commonServerFlags.Parse(); err != nil {
		return err
	}
	cwd, err := os.Getwd()
	if err != nil {
		return err
	}
	if err := c.isolateFlags.Parse(cwd, RequireIsolateFile); err != nil {
		return err
	}
	if len(args) != 0 {
		return errors.New("position arguments not expected")
	}
	return nil
}

func (c *archiveRun) main(a subcommands.Application, args []string) error {
	start := time.Now()
	ctx, cancel := context.WithCancel(c.defaultFlags.MakeLoggingContext(os.Stderr))
	signals.HandleInterrupt(cancel)
	authCl, err := c.createAuthClient(ctx)
	if err != nil {
		return err
	}
	client := isolatedclient.New(nil, authCl, c.isolatedFlags.ServerURL, c.isolatedFlags.Namespace, nil, nil)

	al := archiveLogger{
		start: start,
		quiet: c.defaultFlags.Quiet,
	}

	return archive(ctx, client, &c.ArchiveOptions, c.dumpJSON, c.maxConcurrentChecks, c.maxConcurrentUploads, al)
}

// archiveLogger reports stats to stderr.
type archiveLogger struct {
	start time.Time
	quiet bool
}

// LogSummary logs (to eventlog and stderr) a high-level summary of archive operations(s).
func (al *archiveLogger) LogSummary(ctx context.Context, hits, misses int64, bytesHit, bytesPushed units.Size, digests []string) {
	end := time.Now()

	if !al.quiet {
		duration := end.Sub(al.start)
		fmt.Fprintf(os.Stderr, "Hits    : %5d (%s)\n", hits, bytesHit)
		fmt.Fprintf(os.Stderr, "Misses  : %5d (%s)\n", misses, bytesPushed)
		fmt.Fprintf(os.Stderr, "Duration: %s\n", units.Round(duration, time.Millisecond))
	}
}

// Print acts like fmt.Printf, but may prepend a prefix to format, depending on the value of al.quiet.
func (al *archiveLogger) Printf(format string, a ...interface{}) (n int, err error) {
	return al.Fprintf(os.Stdout, format, a...)
}

// Print acts like fmt.fprintf, but may prepend a prefix to format, depending on the value of al.quiet.
func (al *archiveLogger) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
	prefix := "\n"
	if al.quiet {
		prefix = ""
	}
	args := []interface{}{prefix}
	args = append(args, a...)
	return fmt.Printf("%s"+format, args...)
}

// archive performs the archive operation for an isolate specified by opts.
// dumpJSON is the path to write a JSON summary of the uploaded isolate, in the same format as batch_archive.
func archive(ctx context.Context, client *isolatedclient.Client, opts *isolate.ArchiveOptions, dumpJSON string, concurrentChecks, concurrentUploads int, al archiveLogger) error {
	// Parse the incoming isolate file.
	deps, rootDir, isol, err := isolate.ProcessIsolate(opts)
	if err != nil {
		return fmt.Errorf("isolate %s: failed to process: %v", opts.Isolate, err)
	}
	log.Printf("Isolate %s referenced %d deps", opts.Isolate, len(deps))

	// Set up a checker and uploader.
	checker := archiver.NewChecker(ctx, client, concurrentChecks)
	uploader := archiver.NewUploader(ctx, client, concurrentUploads)
	archiver := archiver.NewTarringArchiver(checker, uploader)

	isolSummary, err := archiver.Archive(deps, rootDir, opts.Blacklist, opts.Isolated, isol)
	if err != nil {
		return fmt.Errorf("isolate %s: %v", opts.Isolate, err)
	}

	// Make sure that all pending items have been checked.
	if err := checker.Close(); err != nil {
		return err
	}

	// Make sure that all the uploads have completed successfully.
	if err := uploader.Close(); err != nil {
		return err
	}

	printSummary(al, isolSummary)
	if err := dumpSummaryJSON(dumpJSON, isolSummary); err != nil {
		return err
	}

	al.LogSummary(ctx, int64(checker.Hit.Count()), int64(checker.Miss.Count()), units.Size(checker.Hit.Bytes()), units.Size(checker.Miss.Bytes()), []string{string(isolSummary.Digest)})
	return nil
}

func (c *archiveRun) Run(a subcommands.Application, args []string, _ subcommands.Env) int {
	if err := c.Parse(a, args); err != nil {
		fmt.Fprintf(a.GetErr(), "%s: %s\n", a.GetName(), err)
		return 1
	}
	cl, err := c.defaultFlags.StartTracing()
	if err != nil {
		fmt.Fprintf(a.GetErr(), "%s: %s\n", a.GetName(), err)
		return 1
	}
	defer cl.Close()
	if err := c.main(a, args); err != nil {
		fmt.Fprintf(a.GetErr(), "%s: %s\n", a.GetName(), err)
		return 1
	}
	return 0
}

func printSummary(al archiveLogger, summary archiver.IsolatedSummary) {
	al.Printf("%s\t%s\n", summary.Digest, summary.Name)
}

func dumpSummaryJSON(filename string, summaries ...archiver.IsolatedSummary) error {
	if len(filename) == 0 {
		return nil
	}
	f, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
	if err != nil {
		return err
	}
	defer f.Close()

	m := map[string]isolated.HexDigest{}
	for _, summary := range summaries {
		m[summary.Name] = summary.Digest
	}
	return json.NewEncoder(f).Encode(m)
}
<|endoftext|>


<commit_before>package main

import "fmt"
import "time"
import "math/rand"
import "math"

/*  A basic hill climbing algorithm that looks at neighbors and then
*	goes to the neighbor at each step that most increases the objective
*	function
*	@param[in] current_solution The starting point
*	@param[in] evaluate The function to evaluate a solution. This function
*	takes in an slice of integers and evaluates it, returning a float64 score
*	@param[in] get_neighbors The function that takes a given solution (which is
*	an slice of integers) and returns a 2d slice containing all of that solution's
*	neighbors
*	@return Returns a slice containing the best solution as well as a float64 with
*	that solution's evaluated score
*/
func hill_climb(initial_solution []int, evaluate func([]int) float64,
				get_neighbors func([]int) [][]int) ([]int, float64){
	current_solution := make([]int,len(initial_solution))
	copy(current_solution,initial_solution)

    var score float64
    highest_score := evaluate(current_solution)
	var highest_score_position int

	for {
		highest_score_position = -1
		neighbors := get_neighbors(current_solution)
	    for i ,value := range neighbors {
	    	score = evaluate(value)
	    	if score > highest_score {
	    		highest_score = score
	    		highest_score_position = i
	    	}
	    }
	    if highest_score_position < 0 {
	    	break
	    } else {
	    	copy(current_solution,neighbors[highest_score_position])
	    }

	}
	return current_solution, highest_score
}

/*  This function calls the hill climb function given a starting solution. This function is made to be
*	called as a goroutine. It returns the best solution slice and that slice's evaluated score through communication
*	channels
*/
func hill_climb_go_routine(current_solution [] int, evaluate func([]int) float64, get_neighbors func([]int) [][]int, ch1 chan<- []int, ch2 chan <- float64) {
	best_solution, highest_score := hill_climb(current_solution, evaluate, get_neighbors)
	ch1 <- best_solution
	ch2 <- highest_score
}

/*  This function calls the hill climbing function through goroutines (using hill_climb_go_routine()). For each
*	call, it starts from a new randomly generated starting point. It will run hill climbing with @a num_restarts
*	starting points
*/
func random_restart_hill_climb(num_restarts int, evaluate func([]int) float64, create_random func() []int, get_neighbors func([]int) [][]int)([]int, float64) {
	var highest_score float64
	highest_score = math.Inf(-1)
	ch1 := make(chan []int)
	ch2 := make(chan float64)

	for i := 0; i < num_restarts; i++ {
		go hill_climb_go_routine(create_random(),evaluate, get_neighbors, ch1, ch2)
	}

	var score float64;
	var best_solution []int

	for i := 0; i < num_restarts; i++ {
        best_solution = <-ch1
        score = <-ch2
        if score > highest_score {
        	highest_score = score
        }
    }

	return best_solution, highest_score
}

/*	This function is for the stochastic hill climbing algorithm. In this algorithm, we check all neighbors of a
*	given solution and evaluate how much they improve the score. Once we do that, we choose a random neighbor, but
*	we weight it such that the neighbors that the chances of a neighbor being picked are proportional to home much
*	that neighbor improves on the solution. The algorithm stops once it gets to a local maximum.
*/
func stochastic_hill_climb(initial_solution []int, evaluate func([]int) float64,
				get_neighbors func([]int) [][]int) ([]int, float64){

	current_solution := make([]int,len(initial_solution))
	copy(current_solution,initial_solution)

    current_score := evaluate(current_solution)
    var total_score_improvement_sum float64
    var score float64
    var randnum float64
    var tempSum float64
    var pickPosition int

    // keep looping until it hits a local maximum
	for {
		total_score_improvement_sum = 0.0
		neighbors := get_neighbors(current_solution)
		scores_slice := make([]float64,len(neighbors))
		// iterate through each neighbor and keep track of how much it improves the solution in "scores_slice".
		// If it doesn't improve the solution, then the corresponding value in scores_slice remains 0.
		for i, value := range neighbors {
			score = evaluate(value)
			if score > current_score {
				scores_slice[i] = score-current_score
				total_score_improvement_sum += score-current_score //keep track of the sum of improvements
			}
		}
		// if there were no solutions that were improvements, then total_score_improvement_sum will be 0, which
		// means that we are at a local minimum, so this is our stopping condition
		if total_score_improvement_sum == 0.0 {
			break
		}
		// divide each element of scores_slice by total_score_improvement_sum. Now, this slice holds the
		// probabilites of each neighbor being picked
		for i, value := range scores_slice {
			scores_slice[i] = value/total_score_improvement_sum
		}

		// pick a random number between 0 and 1
		randnum = rand.Float64()
		tempSum = 0.0
		// iterate through scores_slice until the sum > randnum. At that point, pickPosition will be holding
		// the position of the neighbor that we're going to go to
		for i:=0; tempSum < randnum; i++{
			pickPosition = i
			tempSum += scores_slice[i]
		}

		// assign the appropriate neighbor to the current_solution and then run the same process again until
		// the stopping condition is met
		copy(current_solution,neighbors[pickPosition])
		current_score = evaluate(current_solution)

	}
	return current_solution, evaluate(current_solution)
}

// NOTE: functions below that are not found above can be found in sample_functions.go
func main() {
	rand.Seed(time.Now().Unix())

	// run the problem on our "simple" function, where we try take an array of values and try to set them to
	// values between 1 and 10, in order to maximize an objective function sum(x_i*i)
	fmt.Println("\nRUN ON SIMPLE FUNCTION")
	p := []int{2, 3, 5, 4, 1, 6}
	fmt.Println("p",p)

	best_solution, highest_score := hill_climb(p,simple_evaluation,simple_get_neighbors)
    fmt.Println("hill climb results", best_solution, highest_score)
    best_solution, highest_score = random_restart_hill_climb(1000,simple_evaluation,simple_create_random_start,simple_get_neighbors)
    fmt.Println("random restart hill climb results", best_solution, highest_score)
    best_solution, highest_score = stochastic_hill_climb(p,simple_evaluation,simple_get_neighbors)
    fmt.Println("stochastic hill climb results", best_solution, highest_score, "\n")

    // Run on a travelling salesman problem with cities in the file tsp_data.csv (40 cities)
    fmt.Println("RUN ON TSP")
    tsp_setup_data()
    p2 := make([]int,len(g_data))
    for i := 0; i < len(g_data); i++ {
    	p2[i] = i
    }
    fmt.Println("Initial distance:", -tsp_evaluation(p2))
    best_solution, highest_score = hill_climb(p2,tsp_evaluation,tsp_get_neighbors)
    fmt.Println("Optimized distance (regular hill climb):", -highest_score)
    best_solution, highest_score = random_restart_hill_climb(10,tsp_evaluation,tsp_create_random_start,tsp_get_neighbors)
    fmt.Println("Optimized distance (random restart hill climb):", -highest_score)
    best_solution, highest_score = stochastic_hill_climb(p2,tsp_evaluation,tsp_get_neighbors)
    fmt.Println("Optimized distance (regular hill climb):", -highest_score)
}<commit_msg>small changes<commit_after>package main

import "fmt"
import "time"
import "math/rand"
import "math"

/*  A basic hill climbing algorithm that looks at neighbors and then
*	goes to the neighbor at each step that most increases the objective
*	function
*	@param[in] current_solution The starting point
*	@param[in] evaluate The function to evaluate a solution. This function
*	takes in an slice of integers and evaluates it, returning a float64 score
*	@param[in] get_neighbors The function that takes a given solution (which is
*	an slice of integers) and returns a 2d slice containing all of that solution's
*	neighbors
*	@return Returns a slice containing the best solution as well as a float64 with
*	that solution's evaluated score
*/
func hill_climb(initial_solution []int, evaluate func([]int) float64,
				get_neighbors func([]int) [][]int) ([]int, float64){
	current_solution := make([]int,len(initial_solution))
	copy(current_solution,initial_solution)

    var score float64
    highest_score := evaluate(current_solution)
	var highest_score_position int

	for {
		highest_score_position = -1
		neighbors := get_neighbors(current_solution)
	    for i ,value := range neighbors {
	    	score = evaluate(value)
	    	if score > highest_score {
	    		highest_score = score
	    		highest_score_position = i
	    	}
	    }
	    if highest_score_position < 0 {
	    	break
	    } else {
	    	copy(current_solution,neighbors[highest_score_position])
	    }

	}
	return current_solution, highest_score
}

/*  This function calls the hill climb function given a starting solution. This function is made to be
*	called as a goroutine. It returns the best solution slice and that slice's evaluated score through communication
*	channels
*/
func hill_climb_go_routine(current_solution [] int, evaluate func([]int) float64, get_neighbors func([]int) [][]int, ch1 chan<- []int, ch2 chan <- float64) {
	best_solution, highest_score := hill_climb(current_solution, evaluate, get_neighbors)
	ch1 <- best_solution
	ch2 <- highest_score
}

/*  This function calls the hill climbing function through goroutines (using hill_climb_go_routine()). For each
*	call, it starts from a new randomly generated starting point. It will run hill climbing with @a num_restarts
*	starting points
*/
func random_restart_hill_climb(num_restarts int, evaluate func([]int) float64, create_random func() []int, get_neighbors func([]int) [][]int)([]int, float64) {
	var highest_score float64
	highest_score = math.Inf(-1)
	ch1 := make(chan []int)
	ch2 := make(chan float64)

	for i := 0; i < num_restarts; i++ {
		go hill_climb_go_routine(create_random(),evaluate, get_neighbors, ch1, ch2)
	}

	var score float64;
	var best_solution []int

	for i := 0; i < num_restarts; i++ {
        best_solution = <-ch1
        score = <-ch2
        if score > highest_score {
        	highest_score = score
        }
    }

	return best_solution, highest_score
}

/*	This function is for the stochastic hill climbing algorithm. In this algorithm, we check all neighbors of a
*	given solution and evaluate how much they improve the score. Once we do that, we choose a random neighbor, but
*	we weight it such that the neighbors that the chances of a neighbor being picked are proportional to home much
*	that neighbor improves on the solution. The algorithm stops once it gets to a local maximum.
*/
func stochastic_hill_climb(initial_solution []int, evaluate func([]int) float64,
				get_neighbors func([]int) [][]int) ([]int, float64){

	current_solution := make([]int,len(initial_solution))
	copy(current_solution,initial_solution)

    current_score := evaluate(current_solution)
    var total_score_improvement_sum float64
    var score float64
    var randnum float64
    var tempSum float64
    var pickPosition int

    // keep looping until it hits a local maximum
	for {
		total_score_improvement_sum = 0.0
		neighbors := get_neighbors(current_solution)
		scores_slice := make([]float64,len(neighbors))
		// iterate through each neighbor and keep track of how much it improves the solution in "scores_slice".
		// If it doesn't improve the solution, then the corresponding value in scores_slice remains 0.
		for i, value := range neighbors {
			score = evaluate(value)
			if score > current_score {
				scores_slice[i] = score-current_score
				total_score_improvement_sum += score-current_score //keep track of the sum of improvements
			}
		}
		// if there were no solutions that were improvements, then total_score_improvement_sum will be 0, which
		// means that we are at a local minimum, so this is our stopping condition
		if total_score_improvement_sum == 0.0 {
			break
		}
		// divide each element of scores_slice by total_score_improvement_sum. Now, this slice holds the
		// probabilites of each neighbor being picked
		for i, value := range scores_slice {
			scores_slice[i] = value/total_score_improvement_sum
		}

		// pick a random number between 0 and 1
		randnum = rand.Float64()
		tempSum = 0.0
		// iterate through scores_slice until the sum > randnum. At that point, pickPosition will be holding
		// the position of the neighbor that we're going to go to
		for i:=0; tempSum < randnum; i++{
			pickPosition = i
			tempSum += scores_slice[i]
		}

		// assign the appropriate neighbor to the current_solution and then run the same process again until
		// the stopping condition is met
		copy(current_solution,neighbors[pickPosition])
		current_score = evaluate(current_solution)

	}
	return current_solution, evaluate(current_solution)
}

// NOTE: functions below that are not found above can be found in sample_functions.go
func main() {
	rand.Seed(time.Now().Unix())

	// run the problem on our "simple" function, where we try take an array of values and try to set them to
	// values between 1 and 10, in order to maximize an objective function sum(x_i*i)
	fmt.Println("\nRUN ON SIMPLE FUNCTION")
	p := []int{2, 3, 5, 4, 1, 6}
	fmt.Println("p",p)

	best_solution, highest_score := hill_climb(p,simple_evaluation,simple_get_neighbors)
    fmt.Println("hill climb results", best_solution, highest_score)
    best_solution, highest_score = random_restart_hill_climb(1000,simple_evaluation,simple_create_random_start,simple_get_neighbors)
    fmt.Println("random restart hill climb results", best_solution, highest_score)
    best_solution, highest_score = stochastic_hill_climb(p,simple_evaluation,simple_get_neighbors)
    fmt.Println("stochastic hill climb results", best_solution, highest_score, "\n")

    // Run on a travelling salesman problem with cities in the file tsp_data.csv (40 cities)
    fmt.Println("RUN ON TSP")
    tsp_setup_data()
    p2 := make([]int,len(g_data))
    for i := 0; i < len(g_data); i++ {
    	p2[i] = i
    }
    fmt.Println("Initial distance:", -tsp_evaluation(p2))
    best_solution, highest_score = hill_climb(p2,tsp_evaluation,tsp_get_neighbors)
    fmt.Println("Optimized distance (regular hill climb):", -highest_score)
    best_solution, highest_score = random_restart_hill_climb(10,tsp_evaluation,tsp_create_random_start,tsp_get_neighbors)
    fmt.Println("Optimized distance (random restart hill climb):", -highest_score)
    best_solution, highest_score = stochastic_hill_climb(p2,tsp_evaluation,tsp_get_neighbors)
    fmt.Println("Optimized distance (stochastic hill climb):", -highest_score)
}<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"ashumeow/meow-ml-kmeans/meow-data-structures"
	"ashumeow/meow-ml-kmeans/meow-ml"
	"ashumeow/meow-ml-kmeans"
)

func main() {
	fmt.Println("---Queue---")
	meowQueue := meow-data-structures.meowNewQueue()
	meowQueue.meowPush("Testing... ")
	meowQueue.meowPush(4)
	meowQueue.meowPush(5)
	meowQueue.meowPush(8)
	meowQueue.meowPush(6)
	meowQueue.meowPush("Hold on!")
	fmt.Println("Total stuffs before distribution: ", meowQueue.meowLen())
	fmt.Println("Power before distribution: ", meowQueue.meowErect())
	fmt.Println(meowQueue.meowDistro(),
				meowQueue.meowDistro(),
				meowQueue.meowDistro(),
				meowQueue.meowDistro(),
				meowQueue.meowDistro(),
				meowQueue.meowDistro(),
				meowQueue.meowDistro()
				)
	fmt.Println("Total stuffs after distribution: ", meowQueue.meowLen())
	fmt.Println("Power: ", meowQueue.meowErect())

	fmt.Println("\n")

	fmt.Println("---Stack---")
	meowStack := meow-data-structures.meowNewStack()
	meowStack.meowPush("Hold on... ")
	meowStack.meowPush(4)
	meowStack.meowPush(5)
	meowStack.meowPush(8)
	meowStack.meowPush(6)
	meowStack.meowPush("Testing!")
	fmt.Println("Total stuffs before jump event: ", meowStack.meowLen())
	fmt.Println("Power before jump event: ", meowStack.meowErect())
	fmt.Println(meowStack.meowJump(),
				meowStack.meowJump(),
				meowStack.meowJump(),
				meowStack.meowJump(),
				meowStack.meowJump(),
				meowStack.meowJump(),
				meowStack.meowJump()
				)
	fmt.Println("Total stuffs after jump event: ", meowStack.meowLen())
	fmt.Println("Power: ", meowStack.meowErect())

	fmt.Println("\n")

	fmt.Println("---Array list---")
	meowArray := meow-data-structures.meowNewArrayList()
	fmt.Println("Listing out random stuff in an empty array: ", meowArray.meowSample())
	meowArray.meowAdd("Hello")
	meowArray.meowAdd("Ashu")
	meowArray.meowAdd("Meow")
	fmt.Println("Total stuffs in an array: ", meowArray.meowLen())
	fmt.Println("Array: ", meowArray)
	fmt.Println("Testing arrays now... \n")
	fmt.Println("Array[1]: ", meowArray.meowFetch(1))
	fmt.Println("Getting index of Hello: ", meowArray.IndexOf("Hello"))
	fmt.Println("Fetching registers: ", meowArray.meowRegisters("Hello"), meowArray.meowRegisters("random"))
	fmt.Println("Listing out random stuff in an array: ", meowArray.meowSample())
	fmt.Println("Listing out random stuff in an array: ", meowArray.meowSample())
	for x := 0; x < meowArray.meowLen(); x++; {
		fmt.Println("stuff(" , x, "):", meowArray.meowFetch(x))
	}

	// still more to code...
}<commit_msg>push array list<commit_after>package main

import (
	"fmt"
	"ashumeow/meow-ml-kmeans/meow-data-structures"
	"ashumeow/meow-ml-kmeans/meow-ml"
	"ashumeow/meow-ml-kmeans"
)

func main() {
	fmt.Println("---Queue---")
	meowQueue := meow-data-structures.meowNewQueue()
	meowQueue.meowPush("Testing... ")
	meowQueue.meowPush(4)
	meowQueue.meowPush(5)
	meowQueue.meowPush(8)
	meowQueue.meowPush(6)
	meowQueue.meowPush("Hold on!")
	fmt.Println("Total stuffs before distribution: ", meowQueue.meowLen())
	fmt.Println("Power before distribution: ", meowQueue.meowErect())
	fmt.Println(meowQueue.meowDistro(),
				meowQueue.meowDistro(),
				meowQueue.meowDistro(),
				meowQueue.meowDistro(),
				meowQueue.meowDistro(),
				meowQueue.meowDistro(),
				meowQueue.meowDistro()
				)
	fmt.Println("Total stuffs after distribution: ", meowQueue.meowLen())
	fmt.Println("Power: ", meowQueue.meowErect())

	fmt.Println("\n")

	fmt.Println("---Stack---")
	meowStack := meow-data-structures.meowNewStack()
	meowStack.meowPush("Hold on... ")
	meowStack.meowPush(4)
	meowStack.meowPush(5)
	meowStack.meowPush(8)
	meowStack.meowPush(6)
	meowStack.meowPush("Testing!")
	fmt.Println("Total stuffs before jump event: ", meowStack.meowLen())
	fmt.Println("Power before jump event: ", meowStack.meowErect())
	fmt.Println(meowStack.meowJump(),
				meowStack.meowJump(),
				meowStack.meowJump(),
				meowStack.meowJump(),
				meowStack.meowJump(),
				meowStack.meowJump(),
				meowStack.meowJump()
				)
	fmt.Println("Total stuffs after jump event: ", meowStack.meowLen())
	fmt.Println("Power: ", meowStack.meowErect())

	fmt.Println("\n")

	fmt.Println("---Array list---")
	meowArray := meow-data-structures.meowNewArrayList()
	fmt.Println("Listing out random stuff in an empty array: ", meowArray.meowSample())
	meowArray.meowAdd("Hello")
	meowArray.meowAdd("Ashu")
	meowArray.meowAdd("Meow")
	fmt.Println("Total stuffs in an array: ", meowArray.meowLen())
	fmt.Println("Array: ", meowArray)
	fmt.Println("Testing arrays now... \n")
	fmt.Println("Array[1]: ", meowArray.meowFetch(1))
	fmt.Println("Getting index of Hello: ", meowArray.IndexOf("Hello"))
	fmt.Println("Fetching registers: ", meowArray.meowRegisters("Hello"), meowArray.meowRegisters("random"))
	fmt.Println("Listing out random stuff in an array: ", meowArray.meowSample())
	fmt.Println("Listing out random stuff in an array: ", meowArray.meowSample())
	for x := 0; x < meowArray.meowLen(); x++ {
		fmt.Println("stuff(" , x, "):", meowArray.meowFetch(x))
	}
	fmt.Println("Array removal: ", meowArray.meowRemove("Ashu"), meowArray)
	fmt.Println("Array removal: ", meowArray.meowRemove("Meow"), meowArray)
	fmt.Println("Empty array: ",
				meowArray.IsEmpty(),
				meowArray.meowRemove("Hello"),
				meowArray.IsEmpty(),
				meowArray.meowLen()
				)
	for x := 0; x < 30; x++ {
		meowArray.meowAdd(x)
	}
	fmt.Println("Array indexing: ", meowArray.IndexOf(5), meowArray.meowLen())
	meowArray.meowReset()
	meowArray.meowAdd("un", "deux", "trois")
	meowArray_new2 := meow-data-structures.meowNewArrayList()
	meowArray_new2.meowAdd("quatre", "cinq", "six")
	meowArray.meowAddFromList(meowArray_new2)
	fmt.Println("Array: ", meowArray, meowArray.meowLen())
	fmt.Println("Source-Destination arrays: ", meowArray.meowSource(), meowArray.meowDest())
	fmt.Println("Sliced array: ", meowArray.meowSlice())

	fmt.Println("\n")

	// still more to code...
}<|endoftext|>


<commit_before>package grim

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"testing"
	"bytes"
	"log"
	"errors"
	"strings"
)

// Copyright 2015 MediaMath <http://www.mediamath.com>.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
var testOwner = "MediaMathTesting"
var testRepo = "grim"

var testHookEvent = hookEvent{
	Owner: testOwner,
	Repo: testRepo,
	EventName: "push",
}
var testEffectiveConfig = &effectiveConfig{
	pendingTemplate: "pending {{.Owner}}",
	errorTemplate:   "error {{.Repo}}",
	failureTemplate: "failure {{.Target}}",
	successTemplate: "success {{.UserName}}",
	hipChatToken: "NOT_EMPTY",
	hipChatRoom: "NON_EMPTY",
}

func TestOnHipChatLoggingGrimError(t *testing.T) {
	var buf bytes.Buffer
	logger := log.New(&buf, "", log.Lshortfile)

	//onHook(string,*effectiveConfig, hookEvent, action hookAction, logger *log.Logg
	onHook("not-used", testEffectiveConfig, testHookEvent, func(r string, resultPath string, c *effectiveConfig, h hookEvent) (*executeResult, string, error) {
			return &executeResult{ExitCode: 0}, "", errors.New("")
		}, logger)
	loggedContent := fmt.Sprintf("%v", &buf)
	if !strings.Contains(loggedContent, "MediaMathTesting") {
		t.Errorf("Failed to log grim pending")
	}
	if !strings.Contains(loggedContent, "error grim") {
		t.Errorf("Failed to log grim error")
	}
}

func TestOnHipChatLoggingGrimSuccess(t *testing.T) {
	var buf bytes.Buffer
	logger := log.New(&buf, "", log.Lshortfile)

	//onHook(string,*effectiveConfig, hookEvent, action hookAction, logger *log.Logg
	onHook("not-used", testEffectiveConfig, testHookEvent, func(r string, resultPath string, c *effectiveConfig, h hookEvent) (*executeResult, string, error) {
			return &executeResult{ExitCode: 0}, "", nil
		}, logger)
	loggedContent := fmt.Sprintf("%v", &buf)
	if !strings.Contains(loggedContent, "MediaMathTesting") {
		t.Errorf("Failed to log grim pending")
	}
	if !strings.Contains(loggedContent, "grim success") {
		t.Errorf("Failed to log grim success%v",loggedContent)
	}
}

func TestOnHipChatLoggingGrimFailure(t *testing.T) {
	var buf bytes.Buffer
	logger := log.New(&buf, "", log.Lshortfile)

	//onHook(string,*effectiveConfig, hookEvent, action hookAction, logger *log.Logg
	onHook("not-used", testEffectiveConfig, testHookEvent, func(r string, resultPath string, c *effectiveConfig, h hookEvent) (*executeResult, string, error) {
			return &executeResult{ExitCode: 1234}, "", nil
		}, logger)
	loggedContent := fmt.Sprintf("%v", &buf)
	if !strings.Contains(loggedContent, "MediaMathTesting") {
		t.Errorf("Failed to log grim pending")
	}
	if !strings.Contains(loggedContent, "grim failure") {
		t.Errorf("Failed to log grim failure%v",loggedContent)
	}
}

func TestOnActionFailure(t *testing.T) {
	tempDir, _ := ioutil.TempDir("", "results-dir-failure")
	defer os.RemoveAll(tempDir)

	doNothingAction(tempDir, testOwner, testRepo, 123, nil)

	if _, err := resultsDirectoryExists(tempDir, testOwner, testRepo); err != nil {
		t.Errorf("|%v|", err)
	}

}

func TestOnActionError(t *testing.T) {
	tempDir, _ := ioutil.TempDir("", "results-dir-error")
	defer os.RemoveAll(tempDir)

	doNothingAction(tempDir, testOwner, testRepo, 0, fmt.Errorf("Bad Bad thing happened"))

	if _, err := resultsDirectoryExists(tempDir, testOwner, testRepo); err != nil {
		t.Errorf("|%v|", err)
	}
}

func TestResultsDirectoryCreatedInOnHook(t *testing.T) {
	tempDir, _ := ioutil.TempDir("", "results-dir-success")
	defer os.RemoveAll(tempDir)

	doNothingAction(tempDir, testOwner, testRepo, 0, nil)

	if _, err := resultsDirectoryExists(tempDir, testOwner, testRepo); err != nil {
		t.Errorf("|%v|", err)
	}
}

func TestHookGetsLogged(t *testing.T) {
	tempDir, _ := ioutil.TempDir("", "results-dir-success")
	defer os.RemoveAll(tempDir)

	hook := hookEvent{Owner: testOwner, Repo: testRepo, StatusRef: "fooooooooooooooooooo"}

	onHook("not-used", &effectiveConfig{resultRoot: tempDir}, hook, func(r string, resultPath string, c *effectiveConfig, h hookEvent) (*executeResult, string, error) {
			return &executeResult{ExitCode: 0}, "", nil
		}, nil)

	results, _ := resultsDirectoryExists(tempDir, testOwner, testRepo)
	hookFile := filepath.Join(results, "hook.json")

	if _, err := os.Stat(hookFile); os.IsNotExist(err) {
		t.Errorf("%s was not created.", hookFile)
	}

	jsonHookFile, readerr := ioutil.ReadFile(hookFile)
	if readerr != nil {
		t.Errorf("Error reading file %v", readerr)
	}

	var parsed hookEvent
	parseErr := json.Unmarshal(jsonHookFile, &parsed)
	if parseErr != nil {
		t.Errorf("Error parsing: %v", parseErr)
	}

	if hook.Owner != parsed.Owner || hook.Repo != parsed.Repo || hook.StatusRef != parsed.StatusRef {
		t.Errorf("Did not match:\n%v\n%v", hook, parsed)
	}

}

func doNothingAction(tempDir, owner, repo string, exitCode int, returnedErr error) error {
	return onHook("not-used", &effectiveConfig{resultRoot: tempDir}, hookEvent{Owner: owner, Repo: repo}, func(r string, resultPath string, c *effectiveConfig, h hookEvent) (*executeResult, string, error) {
			return &executeResult{ExitCode: exitCode}, "", returnedErr
		}, nil)
}

func resultsDirectoryExists(tempDir, owner, repo string) (string, error) {
	files, err := ioutil.ReadDir(tempDir)
	if err != nil {
		return "", err
	}

	var fileNames []string
	for _, stat := range files {
		fileNames = append(fileNames, stat.Name())
	}

	repoResults := filepath.Join(tempDir, owner, repo)

	if _, err := os.Stat(repoResults); os.IsNotExist(err) {
		return "", fmt.Errorf("%s was not created: %s", repoResults, fileNames)
	}

	baseFiles, err := ioutil.ReadDir(repoResults)
	if len(baseFiles) != 1 {
		return "", fmt.Errorf("Did not create base name in repo results")
	}

	return filepath.Join(repoResults, baseFiles[0].Name()), nil
}
<commit_msg>fixed accidental name change<commit_after>package grim

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"testing"
	"bytes"
	"log"
	"errors"
	"strings"
)

// Copyright 2015 MediaMath <http://www.mediamath.com>.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
var testOwner = "MediaMath"
var testRepo = "grim"

var testHookEvent = hookEvent{
	Owner: testOwner,
	Repo: testRepo,
	EventName: "push",
}
var testEffectiveConfig = &effectiveConfig{
	pendingTemplate: "pending {{.Owner}}",
	errorTemplate:   "error {{.Repo}}",
	failureTemplate: "failure {{.Target}}",
	successTemplate: "success {{.UserName}}",
	hipChatToken: "NOT_EMPTY",
	hipChatRoom: "NON_EMPTY",
}

func TestOnHipChatLoggingGrimError(t *testing.T) {
	var buf bytes.Buffer
	logger := log.New(&buf, "", log.Lshortfile)

	//onHook(string,*effectiveConfig, hookEvent, action hookAction, logger *log.Logg
	onHook("not-used", testEffectiveConfig, testHookEvent, func(r string, resultPath string, c *effectiveConfig, h hookEvent) (*executeResult, string, error) {
			return &executeResult{ExitCode: 0}, "", errors.New("")
		}, logger)
	loggedContent := fmt.Sprintf("%v", &buf)
	if !strings.Contains(loggedContent, "MediaMathTesting") {
		t.Errorf("Failed to log grim pending")
	}
	if !strings.Contains(loggedContent, "error grim") {
		t.Errorf("Failed to log grim error")
	}
}

func TestOnHipChatLoggingGrimSuccess(t *testing.T) {
	var buf bytes.Buffer
	logger := log.New(&buf, "", log.Lshortfile)

	//onHook(string,*effectiveConfig, hookEvent, action hookAction, logger *log.Logg
	onHook("not-used", testEffectiveConfig, testHookEvent, func(r string, resultPath string, c *effectiveConfig, h hookEvent) (*executeResult, string, error) {
			return &executeResult{ExitCode: 0}, "", nil
		}, logger)
	loggedContent := fmt.Sprintf("%v", &buf)
	if !strings.Contains(loggedContent, "MediaMathTesting") {
		t.Errorf("Failed to log grim pending")
	}
	if !strings.Contains(loggedContent, "grim success") {
		t.Errorf("Failed to log grim success%v",loggedContent)
	}
}

func TestOnHipChatLoggingGrimFailure(t *testing.T) {
	var buf bytes.Buffer
	logger := log.New(&buf, "", log.Lshortfile)

	//onHook(string,*effectiveConfig, hookEvent, action hookAction, logger *log.Logg
	onHook("not-used", testEffectiveConfig, testHookEvent, func(r string, resultPath string, c *effectiveConfig, h hookEvent) (*executeResult, string, error) {
			return &executeResult{ExitCode: 1234}, "", nil
		}, logger)
	loggedContent := fmt.Sprintf("%v", &buf)
	if !strings.Contains(loggedContent, "MediaMathTesting") {
		t.Errorf("Failed to log grim pending")
	}
	if !strings.Contains(loggedContent, "grim failure") {
		t.Errorf("Failed to log grim failure%v",loggedContent)
	}
}

func TestOnActionFailure(t *testing.T) {
	tempDir, _ := ioutil.TempDir("", "results-dir-failure")
	defer os.RemoveAll(tempDir)

	doNothingAction(tempDir, testOwner, testRepo, 123, nil)

	if _, err := resultsDirectoryExists(tempDir, testOwner, testRepo); err != nil {
		t.Errorf("|%v|", err)
	}

}

func TestOnActionError(t *testing.T) {
	tempDir, _ := ioutil.TempDir("", "results-dir-error")
	defer os.RemoveAll(tempDir)

	doNothingAction(tempDir, testOwner, testRepo, 0, fmt.Errorf("Bad Bad thing happened"))

	if _, err := resultsDirectoryExists(tempDir, testOwner, testRepo); err != nil {
		t.Errorf("|%v|", err)
	}
}

func TestResultsDirectoryCreatedInOnHook(t *testing.T) {
	tempDir, _ := ioutil.TempDir("", "results-dir-success")
	defer os.RemoveAll(tempDir)

	doNothingAction(tempDir, testOwner, testRepo, 0, nil)

	if _, err := resultsDirectoryExists(tempDir, testOwner, testRepo); err != nil {
		t.Errorf("|%v|", err)
	}
}

func TestHookGetsLogged(t *testing.T) {
	tempDir, _ := ioutil.TempDir("", "results-dir-success")
	defer os.RemoveAll(tempDir)

	hook := hookEvent{Owner: testOwner, Repo: testRepo, StatusRef: "fooooooooooooooooooo"}

	onHook("not-used", &effectiveConfig{resultRoot: tempDir}, hook, func(r string, resultPath string, c *effectiveConfig, h hookEvent) (*executeResult, string, error) {
			return &executeResult{ExitCode: 0}, "", nil
		}, nil)

	results, _ := resultsDirectoryExists(tempDir, testOwner, testRepo)
	hookFile := filepath.Join(results, "hook.json")

	if _, err := os.Stat(hookFile); os.IsNotExist(err) {
		t.Errorf("%s was not created.", hookFile)
	}

	jsonHookFile, readerr := ioutil.ReadFile(hookFile)
	if readerr != nil {
		t.Errorf("Error reading file %v", readerr)
	}

	var parsed hookEvent
	parseErr := json.Unmarshal(jsonHookFile, &parsed)
	if parseErr != nil {
		t.Errorf("Error parsing: %v", parseErr)
	}

	if hook.Owner != parsed.Owner || hook.Repo != parsed.Repo || hook.StatusRef != parsed.StatusRef {
		t.Errorf("Did not match:\n%v\n%v", hook, parsed)
	}

}

func doNothingAction(tempDir, owner, repo string, exitCode int, returnedErr error) error {
	return onHook("not-used", &effectiveConfig{resultRoot: tempDir}, hookEvent{Owner: owner, Repo: repo}, func(r string, resultPath string, c *effectiveConfig, h hookEvent) (*executeResult, string, error) {
			return &executeResult{ExitCode: exitCode}, "", returnedErr
		}, nil)
}

func resultsDirectoryExists(tempDir, owner, repo string) (string, error) {
	files, err := ioutil.ReadDir(tempDir)
	if err != nil {
		return "", err
	}

	var fileNames []string
	for _, stat := range files {
		fileNames = append(fileNames, stat.Name())
	}

	repoResults := filepath.Join(tempDir, owner, repo)

	if _, err := os.Stat(repoResults); os.IsNotExist(err) {
		return "", fmt.Errorf("%s was not created: %s", repoResults, fileNames)
	}

	baseFiles, err := ioutil.ReadDir(repoResults)
	if len(baseFiles) != 1 {
		return "", fmt.Errorf("Did not create base name in repo results")
	}

	return filepath.Join(repoResults, baseFiles[0].Name()), nil
}
<|endoftext|>


<commit_before>package v7_test

import (
	"errors"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"

	"code.cloudfoundry.org/cli/actor/actionerror"
	"code.cloudfoundry.org/cli/actor/v7action"
	"code.cloudfoundry.org/cli/command/commandfakes"
	"code.cloudfoundry.org/cli/command/translatableerror"
	. "code.cloudfoundry.org/cli/command/v7"
	"code.cloudfoundry.org/cli/command/v7/v7fakes"
	"code.cloudfoundry.org/cli/util/configv3"
	"code.cloudfoundry.org/cli/util/ui"

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

var _ = Describe("download-droplet Command", func() {

	var (
		cmd             DownloadDropletCommand
		testUI          *ui.UI
		fakeConfig      *commandfakes.FakeConfig
		fakeSharedActor *commandfakes.FakeSharedActor
		fakeActor       *v7fakes.FakeActor
		binaryName      string
		executeErr      error
	)

	BeforeEach(func() {
		testUI = ui.NewTestUI(nil, NewBuffer(), NewBuffer())
		fakeConfig = new(commandfakes.FakeConfig)
		fakeSharedActor = new(commandfakes.FakeSharedActor)
		fakeActor = new(v7fakes.FakeActor)

		cmd = DownloadDropletCommand{
			BaseCommand: BaseCommand{
				UI:          testUI,
				Config:      fakeConfig,
				SharedActor: fakeSharedActor,
				Actor:       fakeActor,
			},
		}

		cmd.RequiredArgs.AppName = "some-app"

		binaryName = "faceman"
		fakeConfig.BinaryNameReturns(binaryName)
		fakeConfig.HasTargetedOrganizationReturns(true)
		fakeConfig.TargetedOrganizationReturns(configv3.Organization{Name: "some-org"})
		fakeConfig.HasTargetedSpaceReturns(true)
		fakeConfig.TargetedSpaceReturns(configv3.Space{
			GUID: "some-space-guid",
			Name: "some-space"})
		fakeConfig.CurrentUserReturns(
			configv3.User{Name: "some-user"},
			nil)
	})

	JustBeforeEach(func() {
		executeErr = cmd.Execute(nil)
	})

	When("checking target fails", func() {
		BeforeEach(func() {
			fakeSharedActor.CheckTargetReturns(actionerror.NotLoggedInError{BinaryName: binaryName})
		})

		It("returns an error if the check fails", func() {
			Expect(executeErr).To(MatchError(actionerror.NotLoggedInError{BinaryName: "faceman"}))

			Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1))
			checkTargetedOrg, checkTargetedSpace := fakeSharedActor.CheckTargetArgsForCall(0)
			Expect(checkTargetedOrg).To(BeTrue())
			Expect(checkTargetedSpace).To(BeTrue())
		})
	})

	When("downloading the droplet succeeds", func() {
		var pathToDropletFile string

		BeforeEach(func() {
			fakeActor.DownloadCurrentDropletByAppNameReturns([]byte("some-droplet"), "some-droplet-guid", v7action.Warnings{"some-warning"}, nil)

			pathToDropletFile = filepath.Join("droplet_some-droplet-guid.tgz")
		})

		AfterEach(func() {
			Expect(os.Remove("droplet_some-droplet-guid.tgz")).ToNot(HaveOccurred())
		})

		It("creates a droplet tarball in the current directory", func() {
			Expect(executeErr).ToNot(HaveOccurred())

			Expect(fakeActor.DownloadCurrentDropletByAppNameCallCount()).To(Equal(1))
			appArg, spaceGUIDArg := fakeActor.DownloadCurrentDropletByAppNameArgsForCall(0)
			Expect(appArg).To(Equal("some-app"))
			Expect(spaceGUIDArg).To(Equal("some-space-guid"))

			fileContents, err := ioutil.ReadFile(pathToDropletFile)
			Expect(err).ToNot(HaveOccurred())
			Expect(string(fileContents)).To(Equal("some-droplet"))
		})

		It("displays the file it created and returns no errors", func() {
			Expect(testUI.Out).To(Say("Downloading current droplet for app some-app in org some-org / space some-space as some-user..."))
			Expect(testUI.Err).To(Say("some-warning"))
			Expect(testUI.Out).To(Say(`Droplet downloaded successfully at .*droplet_some-droplet-guid.tgz`))
			Expect(testUI.Out).To(Say("OK"))
			Expect(executeErr).ToNot(HaveOccurred())
		})
	})

	When("the droplet guid is passed in", func() {
		var pathToDropletFile string

		BeforeEach(func() {
			cmd.Droplet = "some-droplet-guid"
			fakeActor.DownloadDropletByGUIDAndAppNameReturns([]byte("some-droplet"), v7action.Warnings{"some-warning"}, nil)

			pathToDropletFile = filepath.Join("droplet_some-droplet-guid.tgz")
		})

		AfterEach(func() {
			Expect(os.Remove("droplet_some-droplet-guid.tgz")).ToNot(HaveOccurred())
		})

		It("creates a droplet tarball in the current directory", func() {
			Expect(executeErr).ToNot(HaveOccurred())

			Expect(fakeActor.DownloadDropletByGUIDAndAppNameCallCount()).To(Equal(1))
			dropletGUIDArg, appArg, spaceGUIDArg := fakeActor.DownloadDropletByGUIDAndAppNameArgsForCall(0)
			Expect(dropletGUIDArg).To(Equal("some-droplet-guid"))
			Expect(appArg).To(Equal("some-app"))
			Expect(spaceGUIDArg).To(Equal("some-space-guid"))

			fileContents, err := ioutil.ReadFile(pathToDropletFile)
			Expect(err).ToNot(HaveOccurred())
			Expect(string(fileContents)).To(Equal("some-droplet"))
		})

		It("displays the file it created and returns no errors", func() {
			Expect(testUI.Out).To(Say("Downloading droplet some-droplet-guid for app some-app in org some-org / space some-space as some-user..."))
			Expect(testUI.Err).To(Say("some-warning"))
			Expect(testUI.Out).To(Say(`Droplet downloaded successfully at .*droplet_some-droplet-guid.tgz`))
			Expect(testUI.Out).To(Say("OK"))
			Expect(executeErr).ToNot(HaveOccurred())
		})
	})

	When("a path to a file is passed in", func() {
		BeforeEach(func() {
			cmd.Path = "some-file.tgz"
			fakeActor.DownloadCurrentDropletByAppNameReturns([]byte("some-droplet"), "some-droplet-guid", v7action.Warnings{"some-warning"}, nil)
		})

		AfterEach(func() {
			Expect(os.Remove(cmd.Path)).ToNot(HaveOccurred())
		})

		It("creates a droplet tarball at the specified path", func() {
			Expect(executeErr).ToNot(HaveOccurred())

			fileContents, err := ioutil.ReadFile(cmd.Path)
			Expect(err).ToNot(HaveOccurred())
			Expect(string(fileContents)).To(Equal("some-droplet"))
		})

		It("displays the file it created and returns no errors", func() {
			Expect(testUI.Out).To(Say("Downloading current droplet for app some-app in org some-org / space some-space as some-user..."))
			Expect(testUI.Err).To(Say("some-warning"))
			Expect(testUI.Out).To(Say(`Droplet downloaded successfully at %s`, cmd.Path))
			Expect(testUI.Out).To(Say("OK"))
			Expect(executeErr).ToNot(HaveOccurred())
		})
	})

	When("a path to an existing directory is passed in", func() {
		BeforeEach(func() {
			tmpDir, err := ioutil.TempDir("", "droplets")
			Expect(err).NotTo(HaveOccurred())
			cmd.Path = tmpDir

			fakeActor.DownloadCurrentDropletByAppNameReturns([]byte("some-droplet"), "some-droplet-guid", v7action.Warnings{"some-warning"}, nil)
		})

		AfterEach(func() {
			Expect(os.RemoveAll(cmd.Path)).ToNot(HaveOccurred())
		})

		It("creates a droplet tarball at the specified path", func() {
			Expect(executeErr).ToNot(HaveOccurred())

			fileContents, err := ioutil.ReadFile(filepath.Join(cmd.Path, "droplet_some-droplet-guid.tgz"))
			Expect(err).ToNot(HaveOccurred())
			Expect(string(fileContents)).To(Equal("some-droplet"))
		})

		It("displays the file it created and returns no errors", func() {
			Expect(executeErr).ToNot(HaveOccurred())
			Expect(testUI.Out).To(Say("Downloading current droplet for app some-app in org some-org / space some-space as some-user..."))
			Expect(testUI.Err).To(Say("some-warning"))
			pathRegExp := regexp.QuoteMeta(filepath.Join(cmd.Path, "droplet_some-droplet-guid.tgz"))
			Expect(testUI.Out).To(Say(`Droplet downloaded successfully at %s`, pathRegExp))
			Expect(testUI.Out).To(Say("OK"))
		})
	})

	When("a path to a file in an invalid directory is passed in", func() {
		BeforeEach(func() {
			cmd.Path = "not/exist/some-file.tgz"
			fakeActor.DownloadCurrentDropletByAppNameReturns([]byte("some-droplet"), "some-droplet-guid", v7action.Warnings{"some-warning"}, nil)
		})

		It("returns an appropriate error", func() {
			_, ok := executeErr.(translatableerror.DropletFileError)
			Expect(ok).To(BeTrue())
		})
	})

	When("there is an error downloading the droplet", func() {
		BeforeEach(func() {
			fakeActor.DownloadCurrentDropletByAppNameReturns([]byte{}, "", v7action.Warnings{"some-warning"}, errors.New("something went wrong"))
		})

		It("displays warnings and returns an error", func() {
			Expect(testUI.Err).To(Say("some-warning"))
			Expect(executeErr).To(MatchError("something went wrong"))
		})
	})

	When("the app does not have a current droplet", func() {
		BeforeEach(func() {
			fakeActor.DownloadCurrentDropletByAppNameReturns([]byte{}, "", v7action.Warnings{"some-warning"}, actionerror.DropletNotFoundError{})
		})

		It("displays warnings and returns an error", func() {
			Expect(testUI.Err).To(Say("some-warning"))
			Expect(executeErr).To(MatchError(translatableerror.NoDropletForAppError{AppName: "some-app"}))
		})
	})
})
<commit_msg>Fix flake in download-droplet unit test<commit_after>package v7_test

import (
	"errors"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"

	"code.cloudfoundry.org/cli/actor/actionerror"
	"code.cloudfoundry.org/cli/actor/v7action"
	"code.cloudfoundry.org/cli/command/commandfakes"
	"code.cloudfoundry.org/cli/command/translatableerror"
	. "code.cloudfoundry.org/cli/command/v7"
	"code.cloudfoundry.org/cli/command/v7/v7fakes"
	"code.cloudfoundry.org/cli/util/configv3"
	"code.cloudfoundry.org/cli/util/ui"

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

var _ = Describe("download-droplet Command", func() {

	var (
		cmd             DownloadDropletCommand
		testUI          *ui.UI
		fakeConfig      *commandfakes.FakeConfig
		fakeSharedActor *commandfakes.FakeSharedActor
		fakeActor       *v7fakes.FakeActor
		binaryName      string
		executeErr      error
	)

	BeforeEach(func() {
		testUI = ui.NewTestUI(nil, NewBuffer(), NewBuffer())
		fakeConfig = new(commandfakes.FakeConfig)
		fakeSharedActor = new(commandfakes.FakeSharedActor)
		fakeActor = new(v7fakes.FakeActor)

		cmd = DownloadDropletCommand{
			BaseCommand: BaseCommand{
				UI:          testUI,
				Config:      fakeConfig,
				SharedActor: fakeSharedActor,
				Actor:       fakeActor,
			},
		}

		cmd.RequiredArgs.AppName = "some-app"

		binaryName = "faceman"
		fakeConfig.BinaryNameReturns(binaryName)
		fakeConfig.HasTargetedOrganizationReturns(true)
		fakeConfig.TargetedOrganizationReturns(configv3.Organization{Name: "some-org"})
		fakeConfig.HasTargetedSpaceReturns(true)
		fakeConfig.TargetedSpaceReturns(configv3.Space{
			GUID: "some-space-guid",
			Name: "some-space"})
		fakeConfig.CurrentUserReturns(
			configv3.User{Name: "some-user"},
			nil)
	})

	JustBeforeEach(func() {
		executeErr = cmd.Execute(nil)
	})

	When("checking target fails", func() {
		BeforeEach(func() {
			fakeSharedActor.CheckTargetReturns(actionerror.NotLoggedInError{BinaryName: binaryName})
		})

		It("returns an error if the check fails", func() {
			Expect(executeErr).To(MatchError(actionerror.NotLoggedInError{BinaryName: "faceman"}))

			Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1))
			checkTargetedOrg, checkTargetedSpace := fakeSharedActor.CheckTargetArgsForCall(0)
			Expect(checkTargetedOrg).To(BeTrue())
			Expect(checkTargetedSpace).To(BeTrue())
		})
	})

	When("downloading the droplet succeeds", func() {
		var pathToDropletFile string

		BeforeEach(func() {
			fakeActor.DownloadCurrentDropletByAppNameReturns([]byte("some-droplet"), "some-droplet-guid", v7action.Warnings{"some-warning"}, nil)

			currentDir, _ := os.Getwd()
			pathToDropletFile = filepath.Join(currentDir, "droplet_some-droplet-guid.tgz")
		})

		AfterEach(func() {
			Expect(os.Remove(pathToDropletFile)).ToNot(HaveOccurred())
		})

		It("creates a droplet tarball in the current directory", func() {
			Expect(executeErr).ToNot(HaveOccurred())

			Expect(fakeActor.DownloadCurrentDropletByAppNameCallCount()).To(Equal(1))
			appArg, spaceGUIDArg := fakeActor.DownloadCurrentDropletByAppNameArgsForCall(0)
			Expect(appArg).To(Equal("some-app"))
			Expect(spaceGUIDArg).To(Equal("some-space-guid"))

			fileContents, err := ioutil.ReadFile(pathToDropletFile)
			Expect(err).ToNot(HaveOccurred())
			Expect(string(fileContents)).To(Equal("some-droplet"))
		})

		It("displays the file it created and returns no errors", func() {
			Expect(testUI.Out).To(Say("Downloading current droplet for app some-app in org some-org / space some-space as some-user..."))
			Expect(testUI.Err).To(Say("some-warning"))
			Expect(testUI.Out).To(Say(`Droplet downloaded successfully at .*droplet_some-droplet-guid.tgz`))
			Expect(testUI.Out).To(Say("OK"))
			Expect(executeErr).ToNot(HaveOccurred())
		})
	})

	When("the droplet guid is passed in", func() {
		var pathToDropletFile string

		BeforeEach(func() {
			cmd.Droplet = "some-droplet-guid"
			fakeActor.DownloadDropletByGUIDAndAppNameReturns([]byte("some-droplet"), v7action.Warnings{"some-warning"}, nil)

			pathToDropletFile = filepath.Join("droplet_some-droplet-guid.tgz")
		})

		AfterEach(func() {
			Expect(os.Remove("droplet_some-droplet-guid.tgz")).ToNot(HaveOccurred())
		})

		It("creates a droplet tarball in the current directory", func() {
			Expect(executeErr).ToNot(HaveOccurred())

			Expect(fakeActor.DownloadDropletByGUIDAndAppNameCallCount()).To(Equal(1))
			dropletGUIDArg, appArg, spaceGUIDArg := fakeActor.DownloadDropletByGUIDAndAppNameArgsForCall(0)
			Expect(dropletGUIDArg).To(Equal("some-droplet-guid"))
			Expect(appArg).To(Equal("some-app"))
			Expect(spaceGUIDArg).To(Equal("some-space-guid"))

			fileContents, err := ioutil.ReadFile(pathToDropletFile)
			Expect(err).ToNot(HaveOccurred())
			Expect(string(fileContents)).To(Equal("some-droplet"))
		})

		It("displays the file it created and returns no errors", func() {
			Expect(testUI.Out).To(Say("Downloading droplet some-droplet-guid for app some-app in org some-org / space some-space as some-user..."))
			Expect(testUI.Err).To(Say("some-warning"))
			Expect(testUI.Out).To(Say(`Droplet downloaded successfully at .*droplet_some-droplet-guid.tgz`))
			Expect(testUI.Out).To(Say("OK"))
			Expect(executeErr).ToNot(HaveOccurred())
		})
	})

	When("a path to a file is passed in", func() {
		BeforeEach(func() {
			cmd.Path = "some-file.tgz"
			fakeActor.DownloadCurrentDropletByAppNameReturns([]byte("some-droplet"), "some-droplet-guid", v7action.Warnings{"some-warning"}, nil)
		})

		AfterEach(func() {
			Expect(os.Remove(cmd.Path)).ToNot(HaveOccurred())
		})

		It("creates a droplet tarball at the specified path", func() {
			Expect(executeErr).ToNot(HaveOccurred())

			fileContents, err := ioutil.ReadFile(cmd.Path)
			Expect(err).ToNot(HaveOccurred())
			Expect(string(fileContents)).To(Equal("some-droplet"))
		})

		It("displays the file it created and returns no errors", func() {
			Expect(testUI.Out).To(Say("Downloading current droplet for app some-app in org some-org / space some-space as some-user..."))
			Expect(testUI.Err).To(Say("some-warning"))
			Expect(testUI.Out).To(Say(`Droplet downloaded successfully at %s`, cmd.Path))
			Expect(testUI.Out).To(Say("OK"))
			Expect(executeErr).ToNot(HaveOccurred())
		})
	})

	When("a path to an existing directory is passed in", func() {
		BeforeEach(func() {
			tmpDir, err := ioutil.TempDir("", "droplets")
			Expect(err).NotTo(HaveOccurred())
			cmd.Path = tmpDir

			fakeActor.DownloadCurrentDropletByAppNameReturns([]byte("some-droplet"), "some-droplet-guid", v7action.Warnings{"some-warning"}, nil)
		})

		AfterEach(func() {
			Expect(os.RemoveAll(cmd.Path)).ToNot(HaveOccurred())
		})

		It("creates a droplet tarball at the specified path", func() {
			Expect(executeErr).ToNot(HaveOccurred())

			fileContents, err := ioutil.ReadFile(filepath.Join(cmd.Path, "droplet_some-droplet-guid.tgz"))
			Expect(err).ToNot(HaveOccurred())
			Expect(string(fileContents)).To(Equal("some-droplet"))
		})

		It("displays the file it created and returns no errors", func() {
			Expect(executeErr).ToNot(HaveOccurred())
			Expect(testUI.Out).To(Say("Downloading current droplet for app some-app in org some-org / space some-space as some-user..."))
			Expect(testUI.Err).To(Say("some-warning"))
			pathRegExp := regexp.QuoteMeta(filepath.Join(cmd.Path, "droplet_some-droplet-guid.tgz"))
			Expect(testUI.Out).To(Say(`Droplet downloaded successfully at %s`, pathRegExp))
			Expect(testUI.Out).To(Say("OK"))
		})
	})

	When("a path to a file in an invalid directory is passed in", func() {
		BeforeEach(func() {
			cmd.Path = "not/exist/some-file.tgz"
			fakeActor.DownloadCurrentDropletByAppNameReturns([]byte("some-droplet"), "some-droplet-guid", v7action.Warnings{"some-warning"}, nil)
		})

		It("returns an appropriate error", func() {
			_, ok := executeErr.(translatableerror.DropletFileError)
			Expect(ok).To(BeTrue())
		})
	})

	When("there is an error downloading the droplet", func() {
		BeforeEach(func() {
			fakeActor.DownloadCurrentDropletByAppNameReturns([]byte{}, "", v7action.Warnings{"some-warning"}, errors.New("something went wrong"))
		})

		It("displays warnings and returns an error", func() {
			Expect(testUI.Err).To(Say("some-warning"))
			Expect(executeErr).To(MatchError("something went wrong"))
		})
	})

	When("the app does not have a current droplet", func() {
		BeforeEach(func() {
			fakeActor.DownloadCurrentDropletByAppNameReturns([]byte{}, "", v7action.Warnings{"some-warning"}, actionerror.DropletNotFoundError{})
		})

		It("displays warnings and returns an error", func() {
			Expect(testUI.Err).To(Say("some-warning"))
			Expect(executeErr).To(MatchError(translatableerror.NoDropletForAppError{AppName: "some-app"}))
		})
	})
})
<|endoftext|>


<commit_before>package grim

// Copyright 2015 MediaMath <http://www.mediamath.com>.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

import (
	"bufio"
	"fmt"
	"io"
	"os/exec"
	"sync"
	"time"
)

type eitherStringOrError struct {
	str string
	err error
}

func execute(env []string, workingDir string, execPath string, args ...string) (*executeResult, error) {
	outputChan := make(chan string)

	res, err := executeWithOutputChan(outputChan, env, workingDir, execPath, args...)
	if err != nil {
		return nil, err
	}

	out := ""
	for line := range outputChan {
		out += fmt.Sprintf("%v\n", line)
	}

	res.Output = out

	return res, nil
}

func executeWithOutputChan(outputChan chan string, env []string, workingDir string, execPath string, args ...string) (*executeResult, error) {
	var exitCode int

	startTime := time.Now()

	cmd := exec.Command(execPath, args...)
	cmd.Dir = workingDir
	cmd.Env = env

	var startErr error

	var wg sync.WaitGroup

	outReader, orErr := cmd.StdoutPipe()
	if orErr != nil {
		return nil, fmt.Errorf("error capturing stdout: %v", orErr)
	}

	errReader, erErr := cmd.StderrPipe()
	if erErr != nil {
		return nil, fmt.Errorf("error capturing stderr: %v", erErr)
	}

	wg.Add(2)
	go sendLines(outReader, outputChan, &wg)
	go sendLines(errReader, outputChan, &wg)
	go closeAfterDone(outputChan, &wg)

	startErr = cmd.Start()
	if startErr != nil {
		return nil, fmt.Errorf("error starting process: %v", startErr)
	}

	done := make(chan error, 1)
	wg.Add(1)
	go func() {
		done <- cmd.Wait()
	}()
	select {
	case <-time.After(30 * time.Second):
		if err := cmd.Process.Kill(); err != nil {
			return nil, fmt.Errorf("Failed to kill process: ", err)
		}
		<-done
	case err := <-done:
		if err != nil {
			return nil, fmt.Errorf("Process done with error = %v", err)
		}
	}

	return &executeResult{
		StartTime:  startTime,
		EndTime:    time.Now(),
		SysTime:    cmd.ProcessState.SystemTime(),
		UserTime:   cmd.ProcessState.UserTime(),
		InitialEnv: cmd.Env,
		ExitCode:   exitCode,
	}, nil
}

func sendLines(rc io.ReadCloser, linesChan chan string, wg *sync.WaitGroup) {
	scanner := bufio.NewScanner(rc)
	for scanner.Scan() {
		linesChan <- scanner.Text()
	}
	wg.Done()
}

func closeAfterDone(outputChan chan string, wg *sync.WaitGroup) {
	wg.Wait()
	close(outputChan)
}
<commit_msg>removing wg.add<commit_after>package grim

// Copyright 2015 MediaMath <http://www.mediamath.com>.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

import (
	"bufio"
	"fmt"
	"io"
	"os/exec"
	"sync"
	"time"
)

type eitherStringOrError struct {
	str string
	err error
}

func execute(env []string, workingDir string, execPath string, args ...string) (*executeResult, error) {
	outputChan := make(chan string)

	res, err := executeWithOutputChan(outputChan, env, workingDir, execPath, args...)
	if err != nil {
		return nil, err
	}

	out := ""
	for line := range outputChan {
		out += fmt.Sprintf("%v\n", line)
	}

	res.Output = out

	return res, nil
}

func executeWithOutputChan(outputChan chan string, env []string, workingDir string, execPath string, args ...string) (*executeResult, error) {
	var exitCode int

	startTime := time.Now()

	cmd := exec.Command(execPath, args...)
	cmd.Dir = workingDir
	cmd.Env = env

	var startErr error

	var wg sync.WaitGroup

	outReader, orErr := cmd.StdoutPipe()
	if orErr != nil {
		return nil, fmt.Errorf("error capturing stdout: %v", orErr)
	}

	errReader, erErr := cmd.StderrPipe()
	if erErr != nil {
		return nil, fmt.Errorf("error capturing stderr: %v", erErr)
	}

	wg.Add(2)
	go sendLines(outReader, outputChan, &wg)
	go sendLines(errReader, outputChan, &wg)
	go closeAfterDone(outputChan, &wg)

	startErr = cmd.Start()
	if startErr != nil {
		return nil, fmt.Errorf("error starting process: %v", startErr)
	}

	done := make(chan error, 1)
	go func() {
		done <- cmd.Wait()
	}()
	select {
	case <-time.After(30 * time.Second):
		if err := cmd.Process.Kill(); err != nil {
			return nil, fmt.Errorf("Failed to kill process: ", err)
		}
		<-done
	case err := <-done:
		if err != nil {
			return nil, fmt.Errorf("Process done with error = %v", err)
		}
	}

	return &executeResult{
		StartTime:  startTime,
		EndTime:    time.Now(),
		SysTime:    cmd.ProcessState.SystemTime(),
		UserTime:   cmd.ProcessState.UserTime(),
		InitialEnv: cmd.Env,
		ExitCode:   exitCode,
	}, nil
}

func sendLines(rc io.ReadCloser, linesChan chan string, wg *sync.WaitGroup) {
	scanner := bufio.NewScanner(rc)
	for scanner.Scan() {
		linesChan <- scanner.Text()
	}
	wg.Done()
}

func closeAfterDone(outputChan chan string, wg *sync.WaitGroup) {
	wg.Wait()
	close(outputChan)
}
<|endoftext|>


<commit_before>package xco

import (
	"crypto/sha1"
	"encoding/hex"
	"encoding/xml"
	"fmt"
	"io"

	"github.com/pkg/errors"
)

func sendStreamStart(w io.Writer, name string) (err error) {
	_, err = fmt.Fprintf(w,
		`<stream:stream
			xmlns='jabber:component:accept'
			xmlns:stream='http://etherx.jabber.org/streams'
			to='%s'>`, name)
	err = errors.Wrapf(err, "failed to write stream start for %s", name)
	return
}

func sendHandshake(w io.Writer, id string, sharedSecret string) (err error) {
	handshakeInput := id + sharedSecret
	handshake := sha1.Sum([]byte(handshakeInput))
	hexHandshake := hex.EncodeToString(handshake[:])
	_, err = fmt.Fprintf(w, "<handshake>%s</handshake>", hexHandshake)
	err = errors.Wrapf(err, "failed to write handshake for %s", id)
	return
}

func findStreamID(stream *xml.StartElement) (id string, err error) {

	for _, a := range stream.Attr {
		if a.Name.Local == "id" {
			id = a.Value
		}
	}

	if id == "" {
		err = errors.New("Unable to find ID in stream response")
		return
	}

	return
}

func (c *Component) handshakeState() (st stateFn, err error) {

	if err = sendStreamStart(c.conn, c.name); err != nil {
		err = errors.Wrapf(err, "Error sending streamStart")
		return
	}

	for {
		var t xml.Token
		if t, err = c.dec.Token(); err != nil {
			return
		}

		stream, ok := t.(xml.StartElement)
		if !ok {
			continue
		}

		var id string
		id, err = findStreamID(&stream)
		if err != nil {
			err = errors.Wrapf(err, "Failed to find ID attribute in stream response")
			return
		}

		if err = sendHandshake(c.conn, id, c.sharedSecret); err != nil {
			err = errors.Wrapf(err, "Failed to send handshake")
			return
		}

		//TODO: separate each step into a state

		// get handshake response, but ignore it
		_, err = c.dec.Token()
		if err != nil {
			return
		}

		_, err = c.dec.Token()
		if err != nil {
			return
		}

		st = c.readLoopState
		return
	}
}
<commit_msg>sendStream inline<commit_after>package xco

import (
	"crypto/sha1"
	"encoding/hex"
	"encoding/xml"
	"fmt"
	"io"

	"github.com/pkg/errors"
)

func sendStreamStart(w io.Writer, name string) (err error) {
	_, err = fmt.Fprintf(w, `<stream:stream xmlns='jabber:component:accept' xmlns:stream='http://etherx.jabber.org/streams' to='%s'>`, name)
	err = errors.Wrapf(err, "failed to write stream start for %s", name)
	return
}

func sendHandshake(w io.Writer, id string, sharedSecret string) (err error) {
	handshakeInput := id + sharedSecret
	handshake := sha1.Sum([]byte(handshakeInput))
	hexHandshake := hex.EncodeToString(handshake[:])
	_, err = fmt.Fprintf(w, "<handshake>%s</handshake>", hexHandshake)
	err = errors.Wrapf(err, "failed to write handshake for %s", id)
	return
}

func findStreamID(stream *xml.StartElement) (id string, err error) {

	for _, a := range stream.Attr {
		if a.Name.Local == "id" {
			id = a.Value
		}
	}

	if id == "" {
		err = errors.New("Unable to find ID in stream response")
		return
	}

	return
}

func (c *Component) handshakeState() (st stateFn, err error) {

	if err = sendStreamStart(c.conn, c.name); err != nil {
		err = errors.Wrapf(err, "Error sending streamStart")
		return
	}

	for {
		var t xml.Token
		if t, err = c.dec.Token(); err != nil {
			return
		}

		stream, ok := t.(xml.StartElement)
		if !ok {
			continue
		}

		var id string
		id, err = findStreamID(&stream)
		if err != nil {
			err = errors.Wrapf(err, "Failed to find ID attribute in stream response")
			return
		}

		if err = sendHandshake(c.conn, id, c.sharedSecret); err != nil {
			err = errors.Wrapf(err, "Failed to send handshake")
			return
		}

		//TODO: separate each step into a state

		// get handshake response, but ignore it
		_, err = c.dec.Token()
		if err != nil {
			return
		}

		_, err = c.dec.Token()
		if err != nil {
			return
		}

		st = c.readLoopState
		return
	}
}
<|endoftext|>


<commit_before>package philarios

import (
  "github.com/lib/pq"
  "database/sql"
  "strings"
  "fmt"
)

type PhilariosDatabase interface {
  QueryForWord(word string, categories []string) ([]Paragraph, error)
  AddPublication(publication Publication) (error)
  EnsureSchema(db *sql.DB) (error)
}

type PhilariosPostgresDatabase struct {
  DriverName string
  DataSourceName string
}

var philariosSchema = `
CREATE TABLE IF NOT EXISTS publications (
  id bigserial PRIMARY KEY,
  title text,
  author text,
  editor text,
  date date,
  source_url text,
  encoding text,
  type text
);

CREATE TABLE IF NOT EXISTS categories (
  id bigserial PRIMARY KEY,
  publication integer REFERENCES publications (id),
  category text
);

CREATE TABLE IF NOT EXISTS paragraphs (
  id bigserial PRIMARY KEY,
  publication integer REFERENCES publications (id),
  body text
);`

/*
Publication is a structure which represents any type of publication (such as
books or articles) which contains text.
*/
type Publication struct {
  Title string
  Author string
  Editor string
  Date string
  SourceURL string
  Encoding string
  Type string
  Text string
  Categories []string
}

type Paragraph struct {
  PublicationId int
  Body string
}

/*
QueryForWord returns SQL rows of paragraphs containing the query word given as
an argument. These are returned from the database.
*/
func (p PhilariosPostgresDatabase) QueryForWord(word string, categories []string) ([]Paragraph, error) {
  db, err := sql.Open(p.DriverName, p.DataSourceName)
  if err != nil {
    return nil, err
  }

  rows, err := performWordQuery(word, db)
  defer rows.Close()
  if err != nil {
    return nil, err
  }

  paragraphs := make([]Paragraph, 0)
  var publicationId int
  var body string
  for rows.Next() {
    err = rows.Scan(&publicationId, &body)
    if err != nil {
      return nil, err
    }
    paragraphs = append(paragraphs, Paragraph{publicationId, body})
  }

  if err = rows.Err(); err != nil {
    return nil, err
  }

  return paragraphs, nil
}

func performWordQuery(word string, db *sql.DB) (*sql.Rows, error) {
  wordQuery := fmt.Sprintf(`SELECT publication, body FROM paragraphs
    WHERE to_tsvector(body) @@ to_tsquery('%s')`, word)
  return db.Query(wordQuery)
}

/*
AddPublication adds a new publication to the database, adding data to the
publications, categories, and paragraphs tables.
*/
func (p PhilariosPostgresDatabase) AddPublication(publication Publication) (error) {
  db, err := sql.Open(p.DriverName, p.DataSourceName)
  if err != nil {
    return err
  }
  p.EnsureSchema(db)

  txn, err := db.Begin()
  if err != nil {
    return err
  }

  var publicationId int
  publicationQuery := fmt.Sprintf(
    `INSERT INTO publications(
        title, author, editor, date, source_url, type, encoding)
      VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s')
      RETURNING id`,
    publication.Title,
    publication.Author,
    publication.Editor,
    publication.Date,
    publication.SourceURL,
    publication.Type,
    publication.Encoding)
  err = db.QueryRow(publicationQuery).Scan(&publicationId)
  if err != nil {
    return err
  }

  categoryStmt, err := txn.Prepare(pq.CopyIn("categories", "publication", "category"))
  for _, category := range publication.Categories {
    _, err = categoryStmt.Exec(publicationId, category)
    if err != nil {
      return err
    }
  }
  err = categoryStmt.Close()
  if err != nil {
    return err
  }

  paragraphStmt, err := txn.Prepare(pq.CopyIn("paragraphs", "publication", "body"))
  paragraphs := strings.Split(publication.Text, "\n")
  for _, paragraph := range paragraphs {
    _, err = paragraphStmt.Exec(publicationId, paragraph)
    if err != nil {
      return err
    }
  }
  err = paragraphStmt.Close()
  if err != nil {
    return err
  }

  err = txn.Commit()
  if err != nil {
    return err
  }

  return nil
}

/*
EnsureSchema is called on a database and ensures that a correct schema has been
applied so that Queries on the database can occur.
*/
func (p PhilariosPostgresDatabase) EnsureSchema(db *sql.DB) (error) {
  _, err := db.Exec(philariosSchema)
  return err
}
<commit_msg>Remove EnsureSchema from PhilariosDatabase interface.<commit_after>package philarios

import (
  "github.com/lib/pq"
  "database/sql"
  "strings"
  "fmt"
)

type PhilariosDatabase interface {
  QueryForWord(word string, categories []string) ([]Paragraph, error)
  AddPublication(publication Publication) (error)
}

type PhilariosPostgresDatabase struct {
  DriverName string
  DataSourceName string
}

var philariosSchema = `
CREATE TABLE IF NOT EXISTS publications (
  id bigserial PRIMARY KEY,
  title text,
  author text,
  editor text,
  date date,
  source_url text,
  encoding text,
  type text
);

CREATE TABLE IF NOT EXISTS categories (
  id bigserial PRIMARY KEY,
  publication integer REFERENCES publications (id),
  category text
);

CREATE TABLE IF NOT EXISTS paragraphs (
  id bigserial PRIMARY KEY,
  publication integer REFERENCES publications (id),
  body text
);`

/*
Publication is a structure which represents any type of publication (such as
books or articles) which contains text.
*/
type Publication struct {
  Title string
  Author string
  Editor string
  Date string
  SourceURL string
  Encoding string
  Type string
  Text string
  Categories []string
}

type Paragraph struct {
  PublicationId int
  Body string
}

/*
QueryForWord returns SQL rows of paragraphs containing the query word given as
an argument. These are returned from the database.
*/
func (p PhilariosPostgresDatabase) QueryForWord(word string, categories []string) ([]Paragraph, error) {
  db, err := sql.Open(p.DriverName, p.DataSourceName)
  if err != nil {
    return nil, err
  }

  rows, err := performWordQuery(word, db)
  defer rows.Close()
  if err != nil {
    return nil, err
  }

  paragraphs := make([]Paragraph, 0)
  var publicationId int
  var body string
  for rows.Next() {
    err = rows.Scan(&publicationId, &body)
    if err != nil {
      return nil, err
    }
    paragraphs = append(paragraphs, Paragraph{publicationId, body})
  }

  if err = rows.Err(); err != nil {
    return nil, err
  }

  return paragraphs, nil
}

func performWordQuery(word string, db *sql.DB) (*sql.Rows, error) {
  wordQuery := fmt.Sprintf(`SELECT publication, body FROM paragraphs
    WHERE to_tsvector(body) @@ to_tsquery('%s')`, word)
  return db.Query(wordQuery)
}

/*
AddPublication adds a new publication to the database, adding data to the
publications, categories, and paragraphs tables.
*/
func (p PhilariosPostgresDatabase) AddPublication(publication Publication) (error) {
  db, err := sql.Open(p.DriverName, p.DataSourceName)
  if err != nil {
    return err
  }
  p.EnsureSchema(db)

  txn, err := db.Begin()
  if err != nil {
    return err
  }

  var publicationId int
  publicationQuery := fmt.Sprintf(
    `INSERT INTO publications(
        title, author, editor, date, source_url, type, encoding)
      VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s')
      RETURNING id`,
    publication.Title,
    publication.Author,
    publication.Editor,
    publication.Date,
    publication.SourceURL,
    publication.Type,
    publication.Encoding)
  err = db.QueryRow(publicationQuery).Scan(&publicationId)
  if err != nil {
    return err
  }

  categoryStmt, err := txn.Prepare(pq.CopyIn("categories", "publication", "category"))
  for _, category := range publication.Categories {
    _, err = categoryStmt.Exec(publicationId, category)
    if err != nil {
      return err
    }
  }
  err = categoryStmt.Close()
  if err != nil {
    return err
  }

  paragraphStmt, err := txn.Prepare(pq.CopyIn("paragraphs", "publication", "body"))
  paragraphs := strings.Split(publication.Text, "\n")
  for _, paragraph := range paragraphs {
    _, err = paragraphStmt.Exec(publicationId, paragraph)
    if err != nil {
      return err
    }
  }
  err = paragraphStmt.Close()
  if err != nil {
    return err
  }

  err = txn.Commit()
  if err != nil {
    return err
  }

  return nil
}

/*
EnsureSchema is called on a database and ensures that a correct schema has been
applied so that Queries on the database can occur.
*/
func (p PhilariosPostgresDatabase) EnsureSchema(db *sql.DB) (error) {
  _, err := db.Exec(philariosSchema)
  return err
}
<|endoftext|>


<commit_before>package ohaus

import (
	"bufio"
	serial "github.com/tarm/serial"
	"log"
	"math/rand"
	"strconv"
	"strings"
	"time"
)

type Scale struct {
	PortName string
}

type Datum struct {
	Time   time.Time `json:"time"`
	Weight float64   `json:"weight"`
	Unit   string    `json:"unit"`
}

func (scale Scale) Open() (port *serial.Port, err error) {
	c := &serial.Config{Name: scale.PortName, Baud: 9600}
	port, err = serial.OpenPort(c)
	return
}

func (scale Scale) Read(port *serial.Port) (value string, err error) {
	port.Write([]byte("IP\r\n"))
	scanner := bufio.NewScanner(port)
	scanner.Scan()
	value = scanner.Text()
	err = scanner.Err()
	return
}

func (scale Scale) TestReader(c chan Datum) {
	var d Datum
	d.Unit = "kg"
	for {
		d.Time = time.Now()
		d.Weight = rand.Float64()
		c <- d
		time.Sleep(2 * time.Second)
	}
}

func (scale Scale) Reader(c chan Datum) {
	var d Datum
	for {
		port, err := scale.Open()

		if err != nil {
			log.Println(err)
			time.Sleep(2 * time.Second)
			continue
		}
		for {
			current_time := time.Now()
			v, err := scale.Read(port)
			if err != nil {
				port.Close()
				log.Println(err)
				break
			}
			value := strings.Split(strings.Trim(v, " "), " ")
			weight, err := strconv.ParseFloat(value[0], 64)
			if err != nil || len(value) < 2 {
				port.Close()
				log.Println(err)
				break
			}

			d.Time = current_time
			d.Weight = weight
			d.Unit = value[1]

			c <- d

			time.Sleep(10 * time.Second)
		}

	}
}
<commit_msg>make a backup off all the data<commit_after>package ohaus

import (
	"bufio"
	"encoding/json"
	serial "github.com/tarm/serial"
	"log"
	"math/rand"
	"os"
	"strconv"
	"strings"
	"time"
)

type Scale struct {
	PortName string
}

type Datum struct {
	Time   time.Time `json:"time"`
	Weight float64   `json:"weight"`
	Unit   string    `json:"unit"`
}

func (scale Scale) Open() (port *serial.Port, err error) {
	c := &serial.Config{Name: scale.PortName, Baud: 9600}
	port, err = serial.OpenPort(c)
	return
}

func (scale Scale) Read(port *serial.Port) (value string, err error) {
	port.Write([]byte("IP\r\n"))
	scanner := bufio.NewScanner(port)
	scanner.Scan()
	value = scanner.Text()
	err = scanner.Err()
	return
}

func (scale Scale) TestReader(c chan Datum) {
	var d Datum
	d.Unit = "kg"
	for {
		d.Time = time.Now()
		d.Weight = rand.Float64()
		c <- d
		time.Sleep(2 * time.Second)
	}
}

func (scale Scale) Reader(c chan Datum) {
	f, err := os.OpenFile("backup-data.json", os.O_APPEND|os.O_WRONLY, 0600)
	if err != nil {
		panic(err)
	}

	defer f.Close()

	var d Datum
	for {
		port, err := scale.Open()

		if err != nil {
			log.Println(err)
			time.Sleep(2 * time.Second)
			continue
		}
		for {
			current_time := time.Now()
			v, err := scale.Read(port)
			if err != nil {
				port.Close()
				log.Println(err)
				break
			}
			value := strings.Split(strings.Trim(v, " "), " ")
			weight, err := strconv.ParseFloat(value[0], 64)
			if err != nil || len(value) < 2 {
				port.Close()
				log.Println(err)
				break
			}

			d.Time = current_time
			d.Weight = weight
			d.Unit = value[1]

			c <- d

			text, err := json.Marshal(d)
			if err != nil {
				log.Println(err)
				continue
			}
			if _, err = f.WriteString(string(text)); err != nil {
				log.Println(err)
				continue
			}

			time.Sleep(10 * time.Second)
		}

	}
}
<|endoftext|>