<commit_before>/*
Copyright 2016 The Fission 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 router

import (
	"fmt"
	"log"
	"net/http"
	"net/http/httputil"
	"net/url"

	"github.com/platform9/fission"
	poolmgrClient "github.com/platform9/fission/poolmgr/client"
)

type functionHandler struct {
	fmap     *functionServiceMap
	poolmgr  *poolmgrClient.Client
	Function fission.Metadata
}

func (fh *functionHandler) getServiceForFunction() (*url.URL, error) {
	// call poolmgr, get a url for a function
	svcName, err := fh.poolmgr.GetServiceForFunction(&fh.Function)
	if err != nil {
		return nil, err
	}
	svcUrl, err := url.Parse(fmt.Sprintf("http://%v", svcName))
	if err != nil {
		return nil, err
	}
	return svcUrl, nil
}

func (fh *functionHandler) handler(responseWriter http.ResponseWriter, request *http.Request) {
	serviceUrl, err := fh.fmap.lookup(&fh.Function)
	if err != nil {
		// Cache miss: request the Pool Manager to make a new service.
		log.Printf("Not cached, getting new service for %v", fh.Function)
		serviceUrl, poolErr := fh.getServiceForFunction()
		if poolErr != nil {
			log.Printf("Failed to get service for function (%v,%v): %v",
				fh.Function.Name, fh.Function.Uid, poolErr)
			// We might want a specific error code or header for fission
			// failures as opposed to user function bugs.
			http.Error(responseWriter, "Internal server error (fission)", 500)
			return
		}

		// add it to the map
		fh.fmap.assign(&fh.Function, serviceUrl)
	}

	// Proxy off our request to the serviceUrl, and send the response back.
	// TODO: As an optimization we may want to cache proxies too -- this might get us
	// connection reuse and possibly better performance
	director := func(req *http.Request) {
		log.Printf("Proxying request for %v", req.URL)

		// send this request to serviceurl
		req.URL.Scheme = serviceUrl.Scheme
		req.URL.Host = serviceUrl.Host
		req.URL.Path = serviceUrl.Path
		// leave the query string intact (req.URL.RawQuery)

		if _, ok := req.Header["User-Agent"]; !ok {
			// explicitly disable User-Agent so it's not set to default value
			req.Header.Set("User-Agent", "")
		}
	}
	proxy := &httputil.ReverseProxy{Director: director}
	proxy.ServeHTTP(responseWriter, request)

	// TODO: handle failures and possibly retry here.
}
<commit_msg>Another bug due to initialization/assignment confusion<commit_after>/*
Copyright 2016 The Fission 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 router

import (
	"fmt"
	"log"
	"net/http"
	"net/http/httputil"
	"net/url"

	"github.com/platform9/fission"
	poolmgrClient "github.com/platform9/fission/poolmgr/client"
)

type functionHandler struct {
	fmap     *functionServiceMap
	poolmgr  *poolmgrClient.Client
	Function fission.Metadata
}

func (fh *functionHandler) getServiceForFunction() (*url.URL, error) {
	// call poolmgr, get a url for a function
	svcName, err := fh.poolmgr.GetServiceForFunction(&fh.Function)
	if err != nil {
		return nil, err
	}
	svcUrl, err := url.Parse(fmt.Sprintf("http://%v", svcName))
	if err != nil {
		return nil, err
	}
	return svcUrl, nil
}

func (fh *functionHandler) handler(responseWriter http.ResponseWriter, request *http.Request) {
	serviceUrl, err := fh.fmap.lookup(&fh.Function)
	if err != nil {
		// Cache miss: request the Pool Manager to make a new service.
		log.Printf("Not cached, getting new service for %v", fh.Function)

		var poolErr error
		serviceUrl, poolErr = fh.getServiceForFunction()
		if poolErr != nil {
			log.Printf("Failed to get service for function (%v,%v): %v",
				fh.Function.Name, fh.Function.Uid, poolErr)
			// We might want a specific error code or header for fission
			// failures as opposed to user function bugs.
			http.Error(responseWriter, "Internal server error (fission)", 500)
			return
		}

		// add it to the map
		fh.fmap.assign(&fh.Function, serviceUrl)
	}

	// Proxy off our request to the serviceUrl, and send the response back.
	// TODO: As an optimization we may want to cache proxies too -- this might get us
	// connection reuse and possibly better performance
	director := func(req *http.Request) {
		log.Printf("Proxying request for %v", req.URL)

		// send this request to serviceurl
		req.URL.Scheme = serviceUrl.Scheme
		req.URL.Host = serviceUrl.Host
		req.URL.Path = serviceUrl.Path
		// leave the query string intact (req.URL.RawQuery)

		if _, ok := req.Header["User-Agent"]; !ok {
			// explicitly disable User-Agent so it's not set to default value
			req.Header.Set("User-Agent", "")
		}
	}
	proxy := &httputil.ReverseProxy{Director: director}
	proxy.ServeHTTP(responseWriter, request)

	// TODO: handle failures and possibly retry here.
}
<|endoftext|>


<commit_before>/* Copyright ©2015 The corridor Authors. All rights reserved.
Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file. */

package corridor

import (
	"fmt"
	"github.com/gonum/stat"
	"runtime"
	"testing"
	"time"
)

// single small problem benchmark
func BenchmarkSingleSmall(b *testing.B) {

	// set max processing units
	cpuCount := runtime.NumCPU()
	runtime.GOMAXPROCS(cpuCount)

	// initialize integer constants
	const (
		xDim           int = 20
		yDim           int = 20
		bandCount      int = 3
		objectiveCount int = 3
		populationSize int = 1000
	)

	// initialize domain
	sampleDomain := NewSampleDomain(xDim, yDim)
	sampleDomain.BndCnt = bandCount

	// initialize objectives
	sampleObjectives := NewSampleObjectives(sampleDomain.Rows, sampleDomain.Cols, objectiveCount)

	// initialize parameters
	sampleParameters := NewSampleParameters(sampleDomain)
	sampleParameters.PopSize = populationSize

	// evolve populations
	toyEvolution := NewEvolution(sampleParameters, sampleDomain, sampleObjectives)

	// extract output population
	finalPop := <-toyEvolution.Populations

	// view output population
	ViewPopulation(sampleDomain, sampleParameters, finalPop)

	// view sample chromosome
	ViewChromosome(sampleDomain, sampleParameters, <-finalPop.Chromosomes)

	// print top individual fitness
	fmt.Println("Population Mean Fitness =")
	fmt.Println(finalPop.MeanFitness)
}

// medium single problem benchmark
func BenchmarkSingleMedium(b *testing.B) {

	// set max processing units
	cpuCount := runtime.NumCPU()
	runtime.GOMAXPROCS(cpuCount)

	// initialize integer constants
	const (
		xDim           int = 20
		yDim           int = 20
		bandCount      int = 3
		objectiveCount int = 3
		populationSize int = 10000
	)

	// initialize domain
	sampleDomain := NewSampleDomain(xDim, yDim)
	sampleDomain.BndCnt = bandCount

	// initialize objectives
	sampleObjectives := NewSampleObjectives(sampleDomain.Rows, sampleDomain.Cols, objectiveCount)

	// initialize parameters
	sampleParameters := NewSampleParameters(sampleDomain)
	sampleParameters.PopSize = populationSize

	// evolve populations
	toyEvolution := NewEvolution(sampleParameters, sampleDomain, sampleObjectives)

	// extract output population
	finalPop := <-toyEvolution.Populations

	// view sample chromosome
	ViewChromosome(sampleDomain, sampleParameters, <-finalPop.Chromosomes)

	// view output population
	ViewPopulation(sampleDomain, sampleParameters, finalPop)

	// print top individual fitness
	fmt.Println("Population Mean Fitness =")
	fmt.Println(finalPop.MeanFitness)
}

// large single problem benchmark
func BenchmarkSingleLarge(b *testing.B) {

	// set max processing units
	cpuCount := runtime.NumCPU()
	runtime.GOMAXPROCS(cpuCount)

	// initialize integer constants
	const (
		xDim           int = 20
		yDim           int = 20
		bandCount      int = 3
		objectiveCount int = 3
		populationSize int = 10000
	)

	// initialize domain
	sampleDomain := NewSampleDomain(xDim, yDim)
	sampleDomain.BndCnt = bandCount

	// initialize objectives
	sampleObjectives := NewSampleObjectives(sampleDomain.Rows, sampleDomain.Cols, objectiveCount)

	// initialize parameters
	sampleParameters := NewSampleParameters(sampleDomain)
	sampleParameters.PopSize = populationSize

	// evolve populations
	toyEvolution := NewEvolution(sampleParameters, sampleDomain, sampleObjectives)

	// extract output population
	finalPop := <-toyEvolution.Populations

	// view sample chromosome
	ViewChromosome(sampleDomain, sampleParameters, <-finalPop.Chromosomes)

	// view output population
	ViewPopulation(sampleDomain, sampleParameters, finalPop)

	// print top individual fitness
	fmt.Println("Population Mean Fitness =")
	fmt.Println(finalPop.MeanFitness)
}

// small problem monte carlo simulation benchmark
func BenchmarkMonteCarloSmall(b *testing.B) {

	// set max processing units
	cpuCount := runtime.NumCPU()
	runtime.GOMAXPROCS(cpuCount)

	// initialize integer constants
	const (
		xDim           int = 20
		yDim           int = 20
		bandCount      int = 3
		objectiveCount int = 3
		populationSize int = 1000
		sampleCount    int = 100
	)

	// initialize domain
	sampleDomain := NewSampleDomain(xDim, yDim)
	sampleDomain.BndCnt = bandCount

	// initialize objectives
	sampleObjectives := NewSampleObjectives(sampleDomain.Rows, sampleDomain.Cols, objectiveCount)

	// initialize parameters
	sampleParameters := NewSampleParameters(sampleDomain)
	sampleParameters.PopSize = populationSize

	// initialize results slices
	aggMeanFitnesses := make([]float64, sampleCount)
	runtimes := make([]float64, sampleCount)

	// print simulation start message
	fmt.Printf("Simulation 1 of %v \n", sampleCount)

	// start sample runs
	for i := 0; i < sampleCount; i++ {

		fmt.Printf("Simulation %v of %v \n", i+1, sampleCount)

		// start clock
		start := time.Now()

		// generate evolution
		toyEvolution := NewEvolution(sampleParameters, sampleDomain, sampleObjectives)

		// write runtime
		runtimes[i] = time.Since(start).Seconds()

		// extract final output population
		finalPop := <-toyEvolution.Populations

		// write aggregate mean fitness
		aggMeanFitnesses[i] = finalPop.AggregateMeanFitness

	}

	// print sample size
	fmt.Println("Sample Size (N) = 100")

	// print mean aggregate fitness
	fmt.Printf("Mean Population Aggregate Fitnesses = %v \n", stat.Mean(aggMeanFitnesses, nil))

	// pritn standard deviation of aggregate fitness
	fmt.Printf("Standard Deviation of Aggregate Fitnesses = %v \n", stat.StdDev(aggMeanFitnesses, nil))

	// print mean runtimes
	fmt.Printf("Mean Runtime in Seconds = %v \n", stat.Mean(runtimes, nil))

	// print standard deviation of mean runtimes
	fmt.Printf("Standard Deviationof Runtimes in Seconds = %v \n", stat.StdDev(runtimes, nil))
}

// medium problem monte carlo simulation benchmark
func BenchmarkMonteCarloMedium(b *testing.B) {

	// set max processing units
	cpuCount := runtime.NumCPU()
	runtime.GOMAXPROCS(cpuCount)

	// initialize integer constants
	const (
		xDim           int = 20
		yDim           int = 20
		bandCount      int = 3
		objectiveCount int = 3
		populationSize int = 10000
		sampleCount    int = 100
	)

	// initialize domain
	sampleDomain := NewSampleDomain(xDim, yDim)
	sampleDomain.BndCnt = bandCount

	// initialize objectives
	sampleObjectives := NewSampleObjectives(sampleDomain.Rows, sampleDomain.Cols, objectiveCount)

	// initialize parameters
	sampleParameters := NewSampleParameters(sampleDomain)
	sampleParameters.PopSize = populationSize

	// initialize results slices
	aggMeanFitnesses := make([]float64, sampleCount)
	runtimes := make([]float64, sampleCount)

	// print simulation start message
	fmt.Printf("Simulation 1 of %v \n", sampleCount)

	// start sample runs
	for i := 0; i < sampleCount; i++ {

		fmt.Printf("Simulation %v of %v \n", i+1, sampleCount)

		// start clock
		start := time.Now()

		// generate evolution
		toyEvolution := NewEvolution(sampleParameters, sampleDomain, sampleObjectives)

		// write runtime
		runtimes[i] = time.Since(start).Seconds()

		// extract final output population
		finalPop := <-toyEvolution.Populations

		// write aggregate mean fitness
		aggMeanFitnesses[i] = finalPop.AggregateMeanFitness

	}

	// print sample size
	fmt.Println("Sample Size (N) = 100")

	// print mean aggregate fitness
	fmt.Printf("Mean Population Aggregate Fitnesses = %v \n", stat.Mean(aggMeanFitnesses, nil))

	// pritn standard deviation of aggregate fitness
	fmt.Printf("Standard Deviation of Aggregate Fitnesses = %v \n", stat.StdDev(aggMeanFitnesses, nil))

	// print mean runtimes
	fmt.Printf("Mean Runtime in Seconds = %v \n", stat.Mean(runtimes, nil))

	// print standard deviation of mean runtimes
	fmt.Printf("Standard Deviationof Runtimes in Seconds = %v \n", stat.StdDev(runtimes, nil))
}

// large problem monte carlo simulation benchmark
func BenchmarkMonteCarloLarge(b *testing.B) {

	// set max processing units
	cpuCount := runtime.NumCPU()
	runtime.GOMAXPROCS(cpuCount)

	// initialize integer constants
	const (
		xDim           int = 20
		yDim           int = 20
		bandCount      int = 3
		objectiveCount int = 3
		populationSize int = 100000
		sampleCount    int = 100
	)

	// initialize domain
	sampleDomain := NewSampleDomain(xDim, yDim)
	sampleDomain.BndCnt = bandCount

	// initialize objectives
	sampleObjectives := NewSampleObjectives(sampleDomain.Rows, sampleDomain.Cols, objectiveCount)

	// initialize parameters
	sampleParameters := NewSampleParameters(sampleDomain)
	sampleParameters.PopSize = populationSize

	// initialize results slices
	aggMeanFitnesses := make([]float64, sampleCount)
	runtimes := make([]float64, sampleCount)

	// print simulation start message
	fmt.Printf("Simulation 1 of %v \n", sampleCount)

	// start sample runs
	for i := 0; i < sampleCount; i++ {

		fmt.Printf("Simulation %v of %v \n", i+1, sampleCount)

		// start clock
		start := time.Now()

		// generate evolution
		toyEvolution := NewEvolution(sampleParameters, sampleDomain, sampleObjectives)

		// write runtime
		runtimes[i] = time.Since(start).Seconds()

		// extract final output population
		finalPop := <-toyEvolution.Populations

		// write aggregate mean fitness
		aggMeanFitnesses[i] = finalPop.AggregateMeanFitness

	}

	// print sample size
	fmt.Println("Sample Size (N) = 100")

	// print mean aggregate fitness
	fmt.Printf("Mean Population Aggregate Fitnesses = %v \n", stat.Mean(aggMeanFitnesses, nil))

	// pritn standard deviation of aggregate fitness
	fmt.Printf("Standard Deviation of Aggregate Fitnesses = %v \n", stat.StdDev(aggMeanFitnesses, nil))

	// print mean runtimes
	fmt.Printf("Mean Runtime in Seconds = %v \n", stat.Mean(runtimes, nil))

	// print standard deviation of mean runtimes
	fmt.Printf("Standard Deviationof Runtimes in Seconds = %v \n", stat.StdDev(runtimes, nil))

}
<commit_msg>Cleaned up some notification text in the testing suite<commit_after>/* Copyright ©2015 The corridor Authors. All rights reserved.
Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file. */

package corridor

import (
	"fmt"
	"github.com/gonum/stat"
	"runtime"
	"testing"
	"time"
)

// single small problem benchmark
func BenchmarkSingleSmall(b *testing.B) {

	// set max processing units
	cpuCount := runtime.NumCPU()
	runtime.GOMAXPROCS(cpuCount)

	// initialize integer constants
	const (
		xDim           int = 20
		yDim           int = 20
		bandCount      int = 3
		objectiveCount int = 3
		populationSize int = 1000
	)

	// initialize domain
	sampleDomain := NewSampleDomain(xDim, yDim)
	sampleDomain.BndCnt = bandCount

	// initialize objectives
	sampleObjectives := NewSampleObjectives(sampleDomain.Rows, sampleDomain.Cols, objectiveCount)

	// initialize parameters
	sampleParameters := NewSampleParameters(sampleDomain)
	sampleParameters.PopSize = populationSize

	// evolve populations
	toyEvolution := NewEvolution(sampleParameters, sampleDomain, sampleObjectives)

	// extract output population
	finalPop := <-toyEvolution.Populations

	// view output population
	ViewPopulation(sampleDomain, sampleParameters, finalPop)

	// view sample chromosome
	ViewChromosome(sampleDomain, sampleParameters, <-finalPop.Chromosomes)

	// print top individual fitness
	fmt.Println("Population Mean Fitness =")
	fmt.Println(finalPop.MeanFitness)
}

// medium single problem benchmark
func BenchmarkSingleMedium(b *testing.B) {

	// set max processing units
	cpuCount := runtime.NumCPU()
	runtime.GOMAXPROCS(cpuCount)

	// initialize integer constants
	const (
		xDim           int = 20
		yDim           int = 20
		bandCount      int = 3
		objectiveCount int = 3
		populationSize int = 10000
	)

	// initialize domain
	sampleDomain := NewSampleDomain(xDim, yDim)
	sampleDomain.BndCnt = bandCount

	// initialize objectives
	sampleObjectives := NewSampleObjectives(sampleDomain.Rows, sampleDomain.Cols, objectiveCount)

	// initialize parameters
	sampleParameters := NewSampleParameters(sampleDomain)
	sampleParameters.PopSize = populationSize

	// evolve populations
	toyEvolution := NewEvolution(sampleParameters, sampleDomain, sampleObjectives)

	// extract output population
	finalPop := <-toyEvolution.Populations

	// view sample chromosome
	ViewChromosome(sampleDomain, sampleParameters, <-finalPop.Chromosomes)

	// view output population
	ViewPopulation(sampleDomain, sampleParameters, finalPop)

	// print top individual fitness
	fmt.Println("Population Mean Fitness =")
	fmt.Println(finalPop.MeanFitness)
}

// large single problem benchmark
func BenchmarkSingleLarge(b *testing.B) {

	// set max processing units
	cpuCount := runtime.NumCPU()
	runtime.GOMAXPROCS(cpuCount)

	// initialize integer constants
	const (
		xDim           int = 20
		yDim           int = 20
		bandCount      int = 3
		objectiveCount int = 3
		populationSize int = 10000
	)

	// initialize domain
	sampleDomain := NewSampleDomain(xDim, yDim)
	sampleDomain.BndCnt = bandCount

	// initialize objectives
	sampleObjectives := NewSampleObjectives(sampleDomain.Rows, sampleDomain.Cols, objectiveCount)

	// initialize parameters
	sampleParameters := NewSampleParameters(sampleDomain)
	sampleParameters.PopSize = populationSize

	// evolve populations
	toyEvolution := NewEvolution(sampleParameters, sampleDomain, sampleObjectives)

	// extract output population
	finalPop := <-toyEvolution.Populations

	// view sample chromosome
	ViewChromosome(sampleDomain, sampleParameters, <-finalPop.Chromosomes)

	// view output population
	ViewPopulation(sampleDomain, sampleParameters, finalPop)

	// print top individual fitness
	fmt.Println("Population Mean Fitness =")
	fmt.Println(finalPop.MeanFitness)
}

// small problem monte carlo simulation benchmark
func BenchmarkMonteCarloSmall(b *testing.B) {

	// set max processing units
	cpuCount := runtime.NumCPU()
	runtime.GOMAXPROCS(cpuCount)

	// initialize integer constants
	const (
		xDim           int = 20
		yDim           int = 20
		bandCount      int = 3
		objectiveCount int = 3
		populationSize int = 1000
		sampleCount    int = 100
	)

	// initialize domain
	sampleDomain := NewSampleDomain(xDim, yDim)
	sampleDomain.BndCnt = bandCount

	// initialize objectives
	sampleObjectives := NewSampleObjectives(sampleDomain.Rows, sampleDomain.Cols, objectiveCount)

	// initialize parameters
	sampleParameters := NewSampleParameters(sampleDomain)
	sampleParameters.PopSize = populationSize

	// initialize results slices
	aggMeanFitnesses := make([]float64, sampleCount)
	runtimes := make([]float64, sampleCount)

	// print simulation start message
	fmt.Printf("Simulation 1 of %v \n", sampleCount)

	// start sample runs
	for i := 0; i < sampleCount; i++ {

		fmt.Printf("Simulation %v of %v \n", i+1, sampleCount)

		// start clock
		start := time.Now()

		// generate evolution
		toyEvolution := NewEvolution(sampleParameters, sampleDomain, sampleObjectives)

		// write runtime
		runtimes[i] = time.Since(start).Seconds()

		// extract final output population
		finalPop := <-toyEvolution.Populations

		// write aggregate mean fitness
		aggMeanFitnesses[i] = finalPop.AggregateMeanFitness

	}

	// print sample size
	fmt.Printf("Sample Size (N) = %v \n", sampleCount)

	// print mean aggregate fitness
	fmt.Printf("Mean Population Aggregate Fitnesses = %v \n", stat.Mean(aggMeanFitnesses, nil))

	// pritn standard deviation of aggregate fitness
	fmt.Printf("Standard Deviation of Aggregate Fitnesses = %v \n", stat.StdDev(aggMeanFitnesses, nil))

	// print mean runtimes
	fmt.Printf("Mean Runtime in Seconds = %v \n", stat.Mean(runtimes, nil))

	// print standard deviation of mean runtimes
	fmt.Printf("Standard Deviationof Runtimes in Seconds = %v \n", stat.StdDev(runtimes, nil))
}

// medium problem monte carlo simulation benchmark
func BenchmarkMonteCarloMedium(b *testing.B) {

	// set max processing units
	cpuCount := runtime.NumCPU()
	runtime.GOMAXPROCS(cpuCount)

	// initialize integer constants
	const (
		xDim           int = 20
		yDim           int = 20
		bandCount      int = 3
		objectiveCount int = 3
		populationSize int = 10000
		sampleCount    int = 100
	)

	// initialize domain
	sampleDomain := NewSampleDomain(xDim, yDim)
	sampleDomain.BndCnt = bandCount

	// initialize objectives
	sampleObjectives := NewSampleObjectives(sampleDomain.Rows, sampleDomain.Cols, objectiveCount)

	// initialize parameters
	sampleParameters := NewSampleParameters(sampleDomain)
	sampleParameters.PopSize = populationSize

	// initialize results slices
	aggMeanFitnesses := make([]float64, sampleCount)
	runtimes := make([]float64, sampleCount)

	// print simulation start message
	fmt.Printf("Simulation 1 of %v \n", sampleCount)

	// start sample runs
	for i := 0; i < sampleCount; i++ {

		fmt.Printf("Simulation %v of %v \n", i+1, sampleCount)

		// start clock
		start := time.Now()

		// generate evolution
		toyEvolution := NewEvolution(sampleParameters, sampleDomain, sampleObjectives)

		// write runtime
		runtimes[i] = time.Since(start).Seconds()

		// extract final output population
		finalPop := <-toyEvolution.Populations

		// write aggregate mean fitness
		aggMeanFitnesses[i] = finalPop.AggregateMeanFitness

	}

	// print sample size
	fmt.Printf("Sample Size (N) = %v \n", sampleCount)

	// print mean aggregate fitness
	fmt.Printf("Mean Population Aggregate Fitnesses = %v \n", stat.Mean(aggMeanFitnesses, nil))

	// pritn standard deviation of aggregate fitness
	fmt.Printf("Standard Deviation of Aggregate Fitnesses = %v \n", stat.StdDev(aggMeanFitnesses, nil))

	// print mean runtimes
	fmt.Printf("Mean Runtime in Seconds = %v \n", stat.Mean(runtimes, nil))

	// print standard deviation of mean runtimes
	fmt.Printf("Standard Deviationof Runtimes in Seconds = %v \n", stat.StdDev(runtimes, nil))
}

// large problem monte carlo simulation benchmark
func BenchmarkMonteCarloLarge(b *testing.B) {

	// set max processing units
	cpuCount := runtime.NumCPU()
	runtime.GOMAXPROCS(cpuCount)

	// initialize integer constants
	const (
		xDim           int = 20
		yDim           int = 20
		bandCount      int = 3
		objectiveCount int = 3
		populationSize int = 100000
		sampleCount    int = 100
	)

	// initialize domain
	sampleDomain := NewSampleDomain(xDim, yDim)
	sampleDomain.BndCnt = bandCount

	// initialize objectives
	sampleObjectives := NewSampleObjectives(sampleDomain.Rows, sampleDomain.Cols, objectiveCount)

	// initialize parameters
	sampleParameters := NewSampleParameters(sampleDomain)
	sampleParameters.PopSize = populationSize

	// initialize results slices
	aggMeanFitnesses := make([]float64, sampleCount)
	runtimes := make([]float64, sampleCount)

	// print simulation start message
	fmt.Printf("Simulation 1 of %v \n", sampleCount)

	// start sample runs
	for i := 0; i < sampleCount; i++ {

		fmt.Printf("Simulation %v of %v \n", i+1, sampleCount)

		// start clock
		start := time.Now()

		// generate evolution
		toyEvolution := NewEvolution(sampleParameters, sampleDomain, sampleObjectives)

		// write runtime
		runtimes[i] = time.Since(start).Seconds()

		// extract final output population
		finalPop := <-toyEvolution.Populations

		// write aggregate mean fitness
		aggMeanFitnesses[i] = finalPop.AggregateMeanFitness

	}

	// print sample size
	fmt.Printf("Sample Size (N) = %v \n", sampleCount)

	// print mean aggregate fitness
	fmt.Printf("Mean Population Aggregate Fitnesses = %v \n", stat.Mean(aggMeanFitnesses, nil))

	// pritn standard deviation of aggregate fitness
	fmt.Printf("Standard Deviation of Aggregate Fitnesses = %v \n", stat.StdDev(aggMeanFitnesses, nil))

	// print mean runtimes
	fmt.Printf("Mean Runtime in Seconds = %v \n", stat.Mean(runtimes, nil))

	// print standard deviation of mean runtimes
	fmt.Printf("Standard Deviationof Runtimes in Seconds = %v \n", stat.StdDev(runtimes, nil))

}
<|endoftext|>


<commit_before>// Copyright 2019 Google LLC
//
// 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
//
//     https://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 aip0132

import (
	"bitbucket.org/creachadair/stringset"
	"github.com/googleapis/api-linter/lint"
	"github.com/jhump/protoreflect/desc"
)

var allowedFields = stringset.New(
	"parent",       // AIP-132
	"page_size",    // AIP-158
	"page_token",   // AIP-158
	"filter",       // AIP-132
	"order_by",     // AIP-132
	"show_deleted", // AIP-135
	"read_mask",    // AIP-157
	"view",         // AIP-157
)

// List methods should not have unrecognized fields.
var unknownFields = &lint.MessageRule{
	Name:   lint.NewRuleName(132, "request-unknown-fields"),
	OnlyIf: isListRequestMessage,
	LintMessage: func(m *desc.MessageDescriptor) (problems []lint.Problem) {
		for _, field := range m.GetFields() {
			if !allowedFields.Contains(field.GetName()) {
				problems = append(problems, lint.Problem{
					Message:    "List RPCs should only contain fields explicitly described in AIPs.",
					Descriptor: field,
				})
			}
		}

		return
	},
}
<commit_msg>[Refactor] 0132::request-unknown-fields should check fields, not messages. (#385)<commit_after>// Copyright 2019 Google LLC
//
// 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
//
//     https://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 aip0132

import (
	"bitbucket.org/creachadair/stringset"
	"github.com/googleapis/api-linter/lint"
	"github.com/jhump/protoreflect/desc"
)

var allowedFields = stringset.New(
	"parent",       // AIP-132
	"page_size",    // AIP-158
	"page_token",   // AIP-158
	"filter",       // AIP-132
	"order_by",     // AIP-132
	"show_deleted", // AIP-135
	"read_mask",    // AIP-157
	"view",         // AIP-157
)

// List methods should not have unrecognized fields.
var unknownFields = &lint.FieldRule{
	Name: lint.NewRuleName(132, "request-unknown-fields"),
	OnlyIf: func(f *desc.FieldDescriptor) bool {
		return isListRequestMessage(f.GetOwner())
	},
	LintField: func(field *desc.FieldDescriptor) []lint.Problem {
		if !allowedFields.Contains(field.GetName()) {
			return []lint.Problem{{
				Message:    "List RPCs should only contain fields explicitly described in AIPs.",
				Descriptor: field,
			}}
		}

		return nil
	},
}
<|endoftext|>


<commit_before>// Copyright 2014 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.

package main

import (
	configconvert "./../../source/configconvert"
	"fmt"
	specs "github.com/opencontainers/specs"
	"log"
	"os/exec"
)

func testRootReadonlyTrue() {

	cmd := exec.Command("/bin/sh", "-c", " sudo -u zenlin go build root_readonly_true_guest.go")
	_, err := cmd.Output()
	if err != nil {
		log.Fatalf("Specstest root readonly test: build guest programme error, %v", err)
	}

	cmd = exec.Command("/bin/sh", "-c", "mkdir -p /tmp/testtool")
	_, err = cmd.Output()
	if err != nil {
		log.Fatalf("Specstest root readonly test: mkdir testtool dir error, %v", err)
	}

	cmd = exec.Command("/bin/sh", "-c", "mv root_readonly_true_guest /tmp/testtool/")
	_, err = cmd.Output()
	if err != nil {
		log.Fatalf("Specstest root readonly test: mv guest programme error, %v", err)
	}

	cmd = exec.Command("/bin/sh", "-c", "touch  /tmp/testtool/readonly_true_out.txt")
	_, err = cmd.Output()
	if err != nil {
		log.Fatalf("Specstest root readonly test: touch readonly_true_out.txt err, %v", err)
	}

	cmd = exec.Command("/bin/sh", "-c", "chown root:root  /tmp/testtool/readonly_true_out.txt")
	_, err = cmd.Output()
	if err != nil {
		log.Fatalf("Specstest root readonly test: change to root power err, %v", err)
	}

	cmd = exec.Command("/bin/sh", "-c", "docker pull ubuntu:14.04")
	_, err = cmd.Output()
	if err != nil {
		log.Fatalf("Specstest root readonly test: pull image error, %v", err)
	}

	cmd = exec.Command("/bin/sh", "-c", "docker export $(docker create ubuntu) > ubuntu.tar")
	_, err = cmd.Output()
	if err != nil {
		log.Fatalf("Specstest root readonly test: export image error, %v", err)
	}

	cmd = exec.Command("/bin/sh", "-c", "mkdir -p ./../../source/rootfs_rootconfig")
	_, err = cmd.Output()
	if err != nil {
		log.Fatalf("Specstest root readonly test: create rootfs dir error, %v", err)
	}

	cmd = exec.Command("/bin/sh", "-c", "tar -C ./../../source/rootfs_rootconfig -xf ubuntu.tar")
	_, err = cmd.Output()
	if err != nil {
		log.Fatalf("Specstest root readonly test: create rootfs content error, %v", err)
	}

	var filePath string
	filePath = "config.json"

	var linuxspec *specs.LinuxSpec
	linuxspec, err = configconvert.ConfigToLinuxSpec(filePath)
	if err != nil {
		log.Fatalf("Specstestroot readonly test: readconfig error, %v", err)
	}

	linuxspec.Spec.Root.Path = "./../../source/rootfs_rootconfig"
	linuxspec.Spec.Root.Readonly = true
	err = configconvert.LinuxSpecToConfig(filePath, linuxspec)
	//err = wirteConfig(filePath, linuxspec)
	if err != nil {
		log.Fatalf("Specstest root readonly test: writeconfig error, %v", err)
	}
	fmt.Println("Host enviroment for runc is already!")

	/*
		cmd = exec.Command("/bin/bash", "-c", "runc")
		_, err = cmd.Output()
		if err != nil {
			log.Fatalf("Specstest root readonly test: start runc and test error, %v", err)
		}*/
}

func main() {
	testRootReadonlyTrue()
}
<commit_msg>Delete not necessary sudo zenlin power.<commit_after>// Copyright 2014 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.

package main

import (
	configconvert "./../../source/configconvert"
	"fmt"
	specs "github.com/opencontainers/specs"
	"log"
	"os/exec"
)

func testRootReadonlyTrue() {

	cmd := exec.Command("/bin/sh", "-c", "go build root_readonly_true_guest.go")
	_, err := cmd.Output()
	if err != nil {
		log.Fatalf("Specstest root readonly test: build guest programme error, %v", err)
	}

	cmd = exec.Command("/bin/sh", "-c", "mkdir -p /tmp/testtool")
	_, err = cmd.Output()
	if err != nil {
		log.Fatalf("Specstest root readonly test: mkdir testtool dir error, %v", err)
	}

	cmd = exec.Command("/bin/sh", "-c", "mv root_readonly_true_guest /tmp/testtool/")
	_, err = cmd.Output()
	if err != nil {
		log.Fatalf("Specstest root readonly test: mv guest programme error, %v", err)
	}

	cmd = exec.Command("/bin/sh", "-c", "touch  /tmp/testtool/readonly_true_out.txt")
	_, err = cmd.Output()
	if err != nil {
		log.Fatalf("Specstest root readonly test: touch readonly_true_out.txt err, %v", err)
	}

	cmd = exec.Command("/bin/sh", "-c", "chown root:root  /tmp/testtool/readonly_true_out.txt")
	_, err = cmd.Output()
	if err != nil {
		log.Fatalf("Specstest root readonly test: change to root power err, %v", err)
	}

	cmd = exec.Command("/bin/sh", "-c", "docker pull ubuntu:14.04")
	_, err = cmd.Output()
	if err != nil {
		log.Fatalf("Specstest root readonly test: pull image error, %v", err)
	}

	cmd = exec.Command("/bin/sh", "-c", "docker export $(docker create ubuntu) > ubuntu.tar")
	_, err = cmd.Output()
	if err != nil {
		log.Fatalf("Specstest root readonly test: export image error, %v", err)
	}

	cmd = exec.Command("/bin/sh", "-c", "mkdir -p ./../../source/rootfs_rootconfig")
	_, err = cmd.Output()
	if err != nil {
		log.Fatalf("Specstest root readonly test: create rootfs dir error, %v", err)
	}

	cmd = exec.Command("/bin/sh", "-c", "tar -C ./../../source/rootfs_rootconfig -xf ubuntu.tar")
	_, err = cmd.Output()
	if err != nil {
		log.Fatalf("Specstest root readonly test: create rootfs content error, %v", err)
	}

	var filePath string
	filePath = "config.json"

	var linuxspec *specs.LinuxSpec
	linuxspec, err = configconvert.ConfigToLinuxSpec(filePath)
	if err != nil {
		log.Fatalf("Specstestroot readonly test: readconfig error, %v", err)
	}

	linuxspec.Spec.Root.Path = "./../../source/rootfs_rootconfig"
	linuxspec.Spec.Root.Readonly = true
	err = configconvert.LinuxSpecToConfig(filePath, linuxspec)
	//err = wirteConfig(filePath, linuxspec)
	if err != nil {
		log.Fatalf("Specstest root readonly test: writeconfig error, %v", err)
	}
	fmt.Println("Host enviroment for runc is already!")

	/*
		cmd = exec.Command("/bin/bash", "-c", "runc")
		_, err = cmd.Output()
		if err != nil {
			log.Fatalf("Specstest root readonly test: start runc and test error, %v", err)
		}*/
}

func main() {
	testRootReadonlyTrue()
}
<|endoftext|>


<commit_before>package cli

import (
	"errors"
	"fmt"
	"strings"

	log "github.com/Sirupsen/logrus"
	"github.com/bitrise-io/goinp/goinp"
	"github.com/bitrise-tools/releaseman/git"
	"github.com/bitrise-tools/releaseman/releaseman"
	"github.com/codegangsta/cli"
)

//=======================================
// Ask for user input
//=======================================

func askForDevelopmentBranch() (string, error) {
	branches, err := git.LocalBranches()
	if err != nil {
		return "", err
	}

	fmt.Println()
	developmentBranch, err := goinp.SelectFromStrings("Select your development branch!", branches)
	if err != nil {
		return "", err
	}

	// 'git branch --list' marks the current branch with (* )
	if strings.HasPrefix(developmentBranch, "* ") {
		developmentBranch = strings.TrimPrefix(developmentBranch, "* ")
	}
	return developmentBranch, nil
}

func askForReleaseBranch() (string, error) {
	branches, err := git.LocalBranches()
	if err != nil {
		return "", err
	}

	fmt.Println()
	releaseBranch, err := goinp.SelectFromStrings("Select your release branch!", branches)
	if err != nil {
		return "", err
	}

	// 'git branch --list' marks the current branch with (* )
	if strings.HasPrefix(releaseBranch, "* ") {
		releaseBranch = strings.TrimPrefix(releaseBranch, "* ")
	}

	return releaseBranch, nil
}

func askForReleaseVersion() (string, error) {
	fmt.Println()
	return goinp.AskForString("Type in release version!")
}

func askForChangelogPath() (string, error) {
	fmt.Println()
	return goinp.AskForString("Type in changelog path!")
}

func askForChangelogTemplatePath() (string, error) {
	fmt.Println()
	return goinp.AskForString("Type in changelog template path, or press enter to use default one!")
}

//=======================================
// Fill config
//=======================================

func fillDevelopmetnBranch(config releaseman.Config, c *cli.Context) (releaseman.Config, error) {
	var err error

	if c.IsSet(DevelopmentBranchKey) {
		config.Release.DevelopmentBranch = c.String(DevelopmentBranchKey)
	}
	if config.Release.DevelopmentBranch == "" {
		if releaseman.IsCIMode {
			return releaseman.Config{}, errors.New("Missing required input: development branch")
		}
		config.Release.DevelopmentBranch, err = askForDevelopmentBranch()
		if err != nil {
			return releaseman.Config{}, err
		}
	}

	if config.Release.DevelopmentBranch == "" {
		return releaseman.Config{}, errors.New("Missing required input: development branch")
	}

	return config, nil
}

func fillReleaseBranch(config releaseman.Config, c *cli.Context) (releaseman.Config, error) {
	var err error

	if c.IsSet(ReleaseBranchKey) {
		config.Release.ReleaseBranch = c.String(ReleaseBranchKey)
	}
	if config.Release.ReleaseBranch == "" {
		if releaseman.IsCIMode {
			return releaseman.Config{}, errors.New("Missing required input: release branch")
		}

		config.Release.ReleaseBranch, err = askForReleaseBranch()
		if err != nil {
			return releaseman.Config{}, err
		}
	}

	if config.Release.ReleaseBranch == "" {
		return releaseman.Config{}, errors.New("Missing required input: release branch")
	}

	return config, nil
}

func versionSegmentIdx(segmentStr string) (int, error) {
	segmentIdx := 0
	switch segmentStr {
	case PatchKey:
		segmentIdx = 2
	case MinorKey:
		segmentIdx = 1
	case MajorKey:
		segmentIdx = 0
	default:
		return -1, fmt.Errorf("Invalid segment name (%s)", segmentStr)
	}
	return segmentIdx, nil
}

func fillVersion(config releaseman.Config, c *cli.Context) (releaseman.Config, error) {
	var err error

	tags, err := git.TaggedCommits()
	if err != nil {
		return releaseman.Config{}, err
	}

	if c.IsSet(BumpVersionKey) {
		if len(tags) == 0 {
			return releaseman.Config{}, errors.New("There are no tags, nothing to bump")
		}

		segmentIdx, err := versionSegmentIdx(c.String(BumpVersionKey))
		if err != nil {
			return releaseman.Config{}, err
		}
		lastVersion := tags[len(tags)-1].Tag

		config.Release.Version, err = releaseman.BumpedVersion(lastVersion, segmentIdx)
		if err != nil {
			return releaseman.Config{}, err
		}
	} else if c.IsSet(VersionKey) {
		config.Release.Version = c.String(VersionKey)
	}

	if config.Release.Version == "" {
		if releaseman.IsCIMode {
			return releaseman.Config{}, errors.New("Missing required input: release version")
		}

		if len(tags) > 0 {
			fmt.Println()
			log.Infof("Your previous tags:")
			for _, taggedCommit := range tags {
				fmt.Printf("* %s\n", taggedCommit.Tag)
			}
		}

		version, err := askForReleaseVersion()
		if err != nil {
			return releaseman.Config{}, err
		}

		for _, taggedCommit := range tags {
			if taggedCommit.Tag == version {
				return releaseman.Config{}, fmt.Errorf("Tag (%s) already exist", version)
			}
		}

		config.Release.Version = version
	}

	if config.Release.Version == "" {
		return releaseman.Config{}, errors.New("Missing required input: release version")
	}

	return config, nil
}

func fillChangelogPath(config releaseman.Config, c *cli.Context) (releaseman.Config, error) {
	var err error

	if c.IsSet(ChangelogPathKey) {
		config.Changelog.Path = c.String(ChangelogPathKey)
	}
	if config.Changelog.Path == "" {
		if releaseman.IsCIMode {
			return releaseman.Config{}, errors.New("Missing required input: changelog path")
		}

		config.Changelog.Path, err = askForChangelogPath()
		if err != nil {
			return releaseman.Config{}, err
		}
	}

	if config.Changelog.Path == "" {
		return releaseman.Config{}, errors.New("Missing required input: changelog path")
	}

	return config, nil
}

//=======================================
// Ensure
//=======================================

func ensureCleanGit() error {
	if areChanges, err := git.AreUncommitedChanges(); err != nil {
		return err
	} else if areChanges {
		return errors.New("There are uncommited changes in your git, please commit your changes before continue release!")
	}
	return nil
}

func ensureCurrentBranch(config releaseman.Config) error {
	currentBranch, err := git.CurrentBranchName()
	if err != nil {
		return err
	}

	if config.Release.DevelopmentBranch != currentBranch {
		if releaseman.IsCIMode {
			return fmt.Errorf("Your current branch (%s), should be the development branch (%s)!", currentBranch, config.Release.DevelopmentBranch)
		}

		log.Warnf("Your current branch (%s), should be the development branch (%s)!", currentBranch, config.Release.DevelopmentBranch)

		fmt.Println()
		checkout, err := goinp.AskForBool(fmt.Sprintf("Would you like to checkout development branch (%s)?", config.Release.DevelopmentBranch))
		if err != nil {
			return err
		}

		if !checkout {
			return fmt.Errorf("Current branch should be the development branch (%s)!", config.Release.DevelopmentBranch)
		}

		if err := git.CheckoutBranch(config.Release.DevelopmentBranch); err != nil {
			return err
		}
	}

	return nil
}

//=======================================
// Print common messages
//=======================================

func printRollBackMessage() {
	fmt.Println()
	log.Infoln("How to roll-back?")
	log.Infoln("* if you want to undo the last commit you can call:")
	log.Infoln("    $ git reset --hard HEAD~1")
	log.Infoln("* to delete tag:")
	log.Infoln("    $ git tag -d [TAG]")
	log.Infoln("    $ git push origin :refs/tags/[TAG]")
	log.Infoln("* to roll back to the remote state:")
	log.Infoln("    $ git reset --hard origin/[branch-name]")
	fmt.Println()
}

func printCollectingCommits(startCommit git.CommitModel, nextVersion string) {
	fmt.Println()
	if startCommit.Tag != "" {
		log.Infof("Collecting commits between (%s - %s)", startCommit.Tag, nextVersion)
	} else {
		log.Infof("Collecting commits between (initial commit - %s)", nextVersion)
	}
}
<commit_msg>FIX: Only print previous release version<commit_after>package cli

import (
	"errors"
	"fmt"
	"strings"

	log "github.com/Sirupsen/logrus"
	"github.com/bitrise-io/goinp/goinp"
	"github.com/bitrise-tools/releaseman/git"
	"github.com/bitrise-tools/releaseman/releaseman"
	"github.com/codegangsta/cli"
)

//=======================================
// Ask for user input
//=======================================

func askForDevelopmentBranch() (string, error) {
	branches, err := git.LocalBranches()
	if err != nil {
		return "", err
	}

	fmt.Println()
	developmentBranch, err := goinp.SelectFromStrings("Select your development branch!", branches)
	if err != nil {
		return "", err
	}

	// 'git branch --list' marks the current branch with (* )
	if strings.HasPrefix(developmentBranch, "* ") {
		developmentBranch = strings.TrimPrefix(developmentBranch, "* ")
	}
	return developmentBranch, nil
}

func askForReleaseBranch() (string, error) {
	branches, err := git.LocalBranches()
	if err != nil {
		return "", err
	}

	fmt.Println()
	releaseBranch, err := goinp.SelectFromStrings("Select your release branch!", branches)
	if err != nil {
		return "", err
	}

	// 'git branch --list' marks the current branch with (* )
	if strings.HasPrefix(releaseBranch, "* ") {
		releaseBranch = strings.TrimPrefix(releaseBranch, "* ")
	}

	return releaseBranch, nil
}

func askForReleaseVersion() (string, error) {
	fmt.Println()
	return goinp.AskForString("Type in release version!")
}

func askForChangelogPath() (string, error) {
	fmt.Println()
	return goinp.AskForString("Type in changelog path!")
}

func askForChangelogTemplatePath() (string, error) {
	fmt.Println()
	return goinp.AskForString("Type in changelog template path, or press enter to use default one!")
}

//=======================================
// Fill config
//=======================================

func fillDevelopmetnBranch(config releaseman.Config, c *cli.Context) (releaseman.Config, error) {
	var err error

	if c.IsSet(DevelopmentBranchKey) {
		config.Release.DevelopmentBranch = c.String(DevelopmentBranchKey)
	}
	if config.Release.DevelopmentBranch == "" {
		if releaseman.IsCIMode {
			return releaseman.Config{}, errors.New("Missing required input: development branch")
		}
		config.Release.DevelopmentBranch, err = askForDevelopmentBranch()
		if err != nil {
			return releaseman.Config{}, err
		}
	}

	if config.Release.DevelopmentBranch == "" {
		return releaseman.Config{}, errors.New("Missing required input: development branch")
	}

	return config, nil
}

func fillReleaseBranch(config releaseman.Config, c *cli.Context) (releaseman.Config, error) {
	var err error

	if c.IsSet(ReleaseBranchKey) {
		config.Release.ReleaseBranch = c.String(ReleaseBranchKey)
	}
	if config.Release.ReleaseBranch == "" {
		if releaseman.IsCIMode {
			return releaseman.Config{}, errors.New("Missing required input: release branch")
		}

		config.Release.ReleaseBranch, err = askForReleaseBranch()
		if err != nil {
			return releaseman.Config{}, err
		}
	}

	if config.Release.ReleaseBranch == "" {
		return releaseman.Config{}, errors.New("Missing required input: release branch")
	}

	return config, nil
}

func versionSegmentIdx(segmentStr string) (int, error) {
	segmentIdx := 0
	switch segmentStr {
	case PatchKey:
		segmentIdx = 2
	case MinorKey:
		segmentIdx = 1
	case MajorKey:
		segmentIdx = 0
	default:
		return -1, fmt.Errorf("Invalid segment name (%s)", segmentStr)
	}
	return segmentIdx, nil
}

func fillVersion(config releaseman.Config, c *cli.Context) (releaseman.Config, error) {
	var err error

	tags, err := git.TaggedCommits()
	if err != nil {
		return releaseman.Config{}, err
	}

	if c.IsSet(BumpVersionKey) {
		if len(tags) == 0 {
			return releaseman.Config{}, errors.New("There are no tags, nothing to bump")
		}

		segmentIdx, err := versionSegmentIdx(c.String(BumpVersionKey))
		if err != nil {
			return releaseman.Config{}, err
		}
		lastVersion := tags[len(tags)-1].Tag

		config.Release.Version, err = releaseman.BumpedVersion(lastVersion, segmentIdx)
		if err != nil {
			return releaseman.Config{}, err
		}
	} else if c.IsSet(VersionKey) {
		config.Release.Version = c.String(VersionKey)
	}

	if config.Release.Version == "" {
		if releaseman.IsCIMode {
			return releaseman.Config{}, errors.New("Missing required input: release version")
		}

		if len(tags) > 0 {
			fmt.Println()
			log.Infof("Your previous tag: %s", tags[len(tags)-1].Tag)
		}

		version, err := askForReleaseVersion()
		if err != nil {
			return releaseman.Config{}, err
		}

		for _, taggedCommit := range tags {
			if taggedCommit.Tag == version {
				return releaseman.Config{}, fmt.Errorf("Tag (%s) already exist", version)
			}
		}

		config.Release.Version = version
	}

	if config.Release.Version == "" {
		return releaseman.Config{}, errors.New("Missing required input: release version")
	}

	return config, nil
}

func fillChangelogPath(config releaseman.Config, c *cli.Context) (releaseman.Config, error) {
	var err error

	if c.IsSet(ChangelogPathKey) {
		config.Changelog.Path = c.String(ChangelogPathKey)
	}
	if config.Changelog.Path == "" {
		if releaseman.IsCIMode {
			return releaseman.Config{}, errors.New("Missing required input: changelog path")
		}

		config.Changelog.Path, err = askForChangelogPath()
		if err != nil {
			return releaseman.Config{}, err
		}
	}

	if config.Changelog.Path == "" {
		return releaseman.Config{}, errors.New("Missing required input: changelog path")
	}

	return config, nil
}

//=======================================
// Ensure
//=======================================

func ensureCleanGit() error {
	if areChanges, err := git.AreUncommitedChanges(); err != nil {
		return err
	} else if areChanges {
		return errors.New("There are uncommited changes in your git, please commit your changes before continue release!")
	}
	return nil
}

func ensureCurrentBranch(config releaseman.Config) error {
	currentBranch, err := git.CurrentBranchName()
	if err != nil {
		return err
	}

	if config.Release.DevelopmentBranch != currentBranch {
		if releaseman.IsCIMode {
			return fmt.Errorf("Your current branch (%s), should be the development branch (%s)!", currentBranch, config.Release.DevelopmentBranch)
		}

		log.Warnf("Your current branch (%s), should be the development branch (%s)!", currentBranch, config.Release.DevelopmentBranch)

		fmt.Println()
		checkout, err := goinp.AskForBool(fmt.Sprintf("Would you like to checkout development branch (%s)?", config.Release.DevelopmentBranch))
		if err != nil {
			return err
		}

		if !checkout {
			return fmt.Errorf("Current branch should be the development branch (%s)!", config.Release.DevelopmentBranch)
		}

		if err := git.CheckoutBranch(config.Release.DevelopmentBranch); err != nil {
			return err
		}
	}

	return nil
}

//=======================================
// Print common messages
//=======================================

func printRollBackMessage() {
	fmt.Println()
	log.Infoln("How to roll-back?")
	log.Infoln("* if you want to undo the last commit you can call:")
	log.Infoln("    $ git reset --hard HEAD~1")
	log.Infoln("* to delete tag:")
	log.Infoln("    $ git tag -d [TAG]")
	log.Infoln("    $ git push origin :refs/tags/[TAG]")
	log.Infoln("* to roll back to the remote state:")
	log.Infoln("    $ git reset --hard origin/[branch-name]")
	fmt.Println()
}

func printCollectingCommits(startCommit git.CommitModel, nextVersion string) {
	fmt.Println()
	if startCommit.Tag != "" {
		log.Infof("Collecting commits between (%s - %s)", startCommit.Tag, nextVersion)
	} else {
		log.Infof("Collecting commits between (initial commit - %s)", nextVersion)
	}
}
<|endoftext|>


<commit_before><commit_msg>recommented the client test code<commit_after><|endoftext|>


<commit_before><commit_msg>check for EOF in tests<commit_after><|endoftext|>


<commit_before><commit_msg>fix bug<commit_after><|endoftext|>


<commit_before>package thuder

import (
	"path/filepath"
	"io"
	"os"
)

var (
	ErrBadPath = errors.New("the file path is not of required formate")
)

//Node is a node to be modified in the file system, such as files, folders, and
//deletes
type Node struct {
	fc   *FileContext //allow sharing for node with same context
	info os.FileInfo
}

//fileContext contains addition node information
type FileContext struct {
	from string      //source directory
	perm os.FileMode //save as mode perm
}

//NewFileContext Creat a new root node, the fullname must be an absolute path,
//but the file does not need to exist
func NewRootNode(fullname string) (*FileContext, error){
	if !filepath.IsAbs(fullname){
		return nil, ErrBadPath
	}
	dir, file := filepath.Split(fullname)
	fc := &FileContext{
		from dir
	}
}

//NewFileContext Creat a new child file context to be used by files with the same dir and perm
func NewFileContext(fi os.FileInfo, parent *Node) *FileContext{

}

//Collection is a document tree that collects meta data of changes in a directory
//to be made
type Collection struct {
	nodes map[string]Node
}

func (c *Collection) Collect(d DirReader) error {

}

//DirReader can list os.FileInfo, as implemented by os.File
type DirReader interface {
	Readdir(n int) ([]FileInfo, error)
}

type PullJob struct {
	Source string //source path
	Target string //target path
}

func (p *PullJob) Do() error {

	fi, err := os.Stat(dir)
	if err != nil {
		return
	}

	os.Open(name string)

	c := Collection{}
	c.Collect()
}

func NewNode(dir string, fi os.FileInfo, parent *Node) (*Node, error) {
	fi, err := os.Stat(filepath.Join(dir, fi.Name()))
	if err != nil{
		return error
	}
	Node{}
}
<commit_msg>work in progress<commit_after>package thuder

import (
	"path/filepath"
	"io"
	"os"
)

var (
	ErrBadPath = errors.New("the file path is not of required formate")
	ErrNeedDir = errors.New("a directory is required for this operation")
)

//Node is a node to be modified in the file system, such as files, folders, and
//deletes
type Node struct {
	fc   *FileContext //allow sharing for node with same context
	info os.FileInfo  //basic data read from the file system
}

//fileContext contains additional node information
type FileContext struct {
	from string      //source directory
	perm os.FileMode //save as mode perm
	isDelet bool //if true, this file should be removed in a push
}

//NewFileContext Creat a new root node, the fullname must be an absolute path.
func NewRootNode(fullname string) (*Node, error){
	if !filepath.IsAbs(fullname){
		return nil, ErrBadPath
	}
	dir, file := filepath.Split(fullname)
	fc := &FileContext{
		from: dir
		perm: os.FileMode(0755)
	}
	info, err := os.Stat(fullname)
	if err != nil{
		return nil, err
	}
	return &Node{
		fc: fc
		info:info
	}, nil
}

//Open calls os.Open on the file refrenced by this node
func (n *Node) Open() (*os.File, error){
	return os.Open(n.FullName())
}

func (n *Node) FullName() string{
	return filepath.Join(n.fc.from, n.info.Name())
}

//NewFileContext Creat a new child file context to be used by files with the same dir and perm
func NewFileContext(fi os.FileInfo, parent *Node) *FileContext{

}

//Collection is a document tree that collects meta data of changes in a directory
//to be made
type Collection struct {
	nodes map[string]Node
}

//Add adds all nodes by filename to the collection, existing node with the same
//name are overwitten.
func (c *Collection) Add(parent Node) error {
	if !parent.info.IsDir(){
		return ErrNeedDir
	}
	f, err := parent.Open()
	if err != nil{
		return err
	}
	defer f.Close()
	list, err := f.Readdir(-1)
	if err != nil{
		return err
	}
	for _, fi := range list{

	}
	return nil
}

//DirReader can list os.FileInfo, as implemented by os.File
type DirReader interface {
	Readdir(n int) ([]FileInfo, error)
}

type PullJob struct {
	Source string //source path
	Target string //target path
}

func (p *PullJob) Do() error {

	fi, err := os.Stat(dir)
	if err != nil {
		return err
	}

	os.Open(name string)

	c := Collection{}
	c.Collect()

	return nil
}

func ChildNodes(dir string, fi os.FileInfo, parent *Node) ([]Node, error) {
	fi, err := os.Stat(filepath.Join(dir, fi.Name()))
	if err != nil{
		return nil, err
	}
	retu &Node{
	fc   *FileContext //allow sharing for node with same context
	info fi
	}
}
<|endoftext|>


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

// +build !windows,!plan9

package syslog

import (
	"bufio"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net"
	"os"
	"sync"
	"testing"
	"time"
)

func runPktSyslog(c net.PacketConn, done chan<- string) {
	var buf [4096]byte
	var rcvd string
	ct := 0
	for {
		var n int
		var err error

		c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
		n, _, err = c.ReadFrom(buf[:])
		rcvd += string(buf[:n])
		if err != nil {
			if oe, ok := err.(*net.OpError); ok {
				if ct < 3 && oe.Temporary() {
					ct++
					continue
				}
			}
			break
		}
	}
	c.Close()
	done <- rcvd
}

var crashy = false

func runStreamSyslog(l net.Listener, done chan<- string, wg *sync.WaitGroup) {
	for {
		var c net.Conn
		var err error
		if c, err = l.Accept(); err != nil {
			return
		}
		wg.Add(1)
		go func(c net.Conn) {
			defer wg.Done()
			c.SetReadDeadline(time.Now().Add(5 * time.Second))
			b := bufio.NewReader(c)
			for ct := 1; !crashy || ct&7 != 0; ct++ {
				s, err := b.ReadString('\n')
				if err != nil {
					break
				}
				done <- s
			}
			c.Close()
		}(c)
	}
}

func startServer(n, la string, done chan<- string) (addr string, sock io.Closer, wg *sync.WaitGroup) {
	if n == "udp" || n == "tcp" {
		la = "127.0.0.1:0"
	} else {
		// unix and unixgram: choose an address if none given
		if la == "" {
			// use ioutil.TempFile to get a name that is unique
			f, err := ioutil.TempFile("", "syslogtest")
			if err != nil {
				log.Fatal("TempFile: ", err)
			}
			f.Close()
			la = f.Name()
		}
		os.Remove(la)
	}

	wg = new(sync.WaitGroup)
	if n == "udp" || n == "unixgram" {
		l, e := net.ListenPacket(n, la)
		if e != nil {
			log.Fatalf("startServer failed: %v", e)
		}
		addr = l.LocalAddr().String()
		sock = l
		wg.Add(1)
		go func() {
			defer wg.Done()
			runPktSyslog(l, done)
		}()
	} else {
		l, e := net.Listen(n, la)
		if e != nil {
			log.Fatalf("startServer failed: %v", e)
		}
		addr = l.Addr().String()
		sock = l
		wg.Add(1)
		go func() {
			defer wg.Done()
			runStreamSyslog(l, done, wg)
		}()
	}
	return
}

func TestWithSimulated(t *testing.T) {
	msg := "Test 123"
	transport := []string{"unix", "unixgram", "udp", "tcp"}

	for _, tr := range transport {
		done := make(chan string)
		addr, _, _ := startServer(tr, "", done)
		if tr == "unix" || tr == "unixgram" {
			defer os.Remove(addr)
		}
		s, err := Dial(tr, addr, LOG_INFO|LOG_USER, "syslog_test")
		if err != nil {
			t.Fatalf("Dial() failed: %v", err)
		}
		err = s.Info(msg)
		if err != nil {
			t.Fatalf("log failed: %v", err)
		}
		check(t, msg, <-done)
		s.Close()
	}
}

func TestFlap(t *testing.T) {
	net := "unix"
	done := make(chan string)
	addr, sock, _ := startServer(net, "", done)
	defer os.Remove(addr)
	defer sock.Close()

	s, err := Dial(net, addr, LOG_INFO|LOG_USER, "syslog_test")
	if err != nil {
		t.Fatalf("Dial() failed: %v", err)
	}
	msg := "Moo 2"
	err = s.Info(msg)
	if err != nil {
		t.Fatalf("log failed: %v", err)
	}
	check(t, msg, <-done)

	// restart the server
	_, sock2, _ := startServer(net, addr, done)
	defer sock2.Close()

	// and try retransmitting
	msg = "Moo 3"
	err = s.Info(msg)
	if err != nil {
		t.Fatalf("log failed: %v", err)
	}
	check(t, msg, <-done)

	s.Close()
}

func TestNew(t *testing.T) {
	if LOG_LOCAL7 != 23<<3 {
		t.Fatalf("LOG_LOCAL7 has wrong value")
	}
	if testing.Short() {
		// Depends on syslog daemon running, and sometimes it's not.
		t.Skip("skipping syslog test during -short")
	}

	s, err := New(LOG_INFO|LOG_USER, "the_tag")
	if err != nil {
		t.Fatalf("New() failed: %s", err)
	}
	// Don't send any messages.
	s.Close()
}

func TestNewLogger(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping syslog test during -short")
	}
	f, err := NewLogger(LOG_USER|LOG_INFO, 0)
	if f == nil {
		t.Error(err)
	}
}

func TestDial(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping syslog test during -short")
	}
	f, err := Dial("", "", (LOG_LOCAL7|LOG_DEBUG)+1, "syslog_test")
	if f != nil {
		t.Fatalf("Should have trapped bad priority")
	}
	f, err = Dial("", "", -1, "syslog_test")
	if f != nil {
		t.Fatalf("Should have trapped bad priority")
	}
	l, err := Dial("", "", LOG_USER|LOG_ERR, "syslog_test")
	if err != nil {
		t.Fatalf("Dial() failed: %s", err)
	}
	l.Close()
}

func check(t *testing.T, in, out string) {
	tmpl := fmt.Sprintf("<%d>%%s %%s syslog_test[%%d]: %s\n", LOG_USER+LOG_INFO, in)
	if hostname, err := os.Hostname(); err != nil {
		t.Error("Error retrieving hostname")
	} else {
		var parsedHostname, timestamp string
		var pid int
		if n, err := fmt.Sscanf(out, tmpl, &timestamp, &parsedHostname, &pid); n != 3 || err != nil || hostname != parsedHostname {
			t.Errorf("Got %q, does not match template %q (%d %s)", out, tmpl, n, err)
		}
	}
}

func TestWrite(t *testing.T) {
	tests := []struct {
		pri Priority
		pre string
		msg string
		exp string
	}{
		{LOG_USER | LOG_ERR, "syslog_test", "", "%s %s syslog_test[%d]: \n"},
		{LOG_USER | LOG_ERR, "syslog_test", "write test", "%s %s syslog_test[%d]: write test\n"},
		// Write should not add \n if there already is one
		{LOG_USER | LOG_ERR, "syslog_test", "write test 2\n", "%s %s syslog_test[%d]: write test 2\n"},
	}

	if hostname, err := os.Hostname(); err != nil {
		t.Fatalf("Error retrieving hostname")
	} else {
		for _, test := range tests {
			done := make(chan string)
			addr, sock, _ := startServer("udp", "", done)
			defer sock.Close()
			l, err := Dial("udp", addr, test.pri, test.pre)
			if err != nil {
				t.Fatalf("syslog.Dial() failed: %v", err)
			}
			_, err = io.WriteString(l, test.msg)
			if err != nil {
				t.Fatalf("WriteString() failed: %v", err)
			}
			rcvd := <-done
			test.exp = fmt.Sprintf("<%d>", test.pri) + test.exp
			var parsedHostname, timestamp string
			var pid int
			if n, err := fmt.Sscanf(rcvd, test.exp, &timestamp, &parsedHostname, &pid); n != 3 || err != nil || hostname != parsedHostname {
				t.Errorf("s.Info() = '%q', didn't match '%q' (%d %s)", rcvd, test.exp, n, err)
			}
		}
	}
}

func TestConcurrentWrite(t *testing.T) {
	addr, sock, _ := startServer("udp", "", make(chan string))
	defer sock.Close()
	w, err := Dial("udp", addr, LOG_USER|LOG_ERR, "how's it going?")
	if err != nil {
		t.Fatalf("syslog.Dial() failed: %v", err)
	}
	var wg sync.WaitGroup
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func() {
			err := w.Info("test")
			if err != nil {
				t.Errorf("Info() failed: %v", err)
				return
			}
			wg.Done()
		}()
	}
	wg.Wait()
}

func TestConcurrentReconnect(t *testing.T) {
	crashy = true
	defer func() { crashy = false }()

	net := "unix"
	done := make(chan string)
	addr, sock, srvWG := startServer(net, "", done)
	defer os.Remove(addr)

	// count all the messages arriving
	count := make(chan int)
	go func() {
		ct := 0
		for _ = range done {
			ct++
			// we are looking for 500 out of 1000 events
			// here because lots of log messages are lost
			// in buffers (kernel and/or bufio)
			if ct > 500 {
				break
			}
		}
		count <- ct
	}()

	var wg sync.WaitGroup
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func() {
			w, err := Dial(net, addr, LOG_USER|LOG_ERR, "tag")
			if err != nil {
				t.Fatalf("syslog.Dial() failed: %v", err)
			}
			for i := 0; i < 100; i++ {
				err := w.Info("test")
				if err != nil {
					t.Errorf("Info() failed: %v", err)
					return
				}
			}
			wg.Done()
		}()
	}
	wg.Wait()
	sock.Close()
	srvWG.Wait()
	close(done)

	select {
	case <-count:
	case <-time.After(100 * time.Millisecond):
		t.Error("timeout in concurrent reconnect")
	}
}
<commit_msg>Remove calls to t.Skip() which is only available in Go 1.1<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build !windows,!plan9

package syslog

import (
	"bufio"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net"
	"os"
	"sync"
	"testing"
	"time"
)

func runPktSyslog(c net.PacketConn, done chan<- string) {
	var buf [4096]byte
	var rcvd string
	ct := 0
	for {
		var n int
		var err error

		c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
		n, _, err = c.ReadFrom(buf[:])
		rcvd += string(buf[:n])
		if err != nil {
			if oe, ok := err.(*net.OpError); ok {
				if ct < 3 && oe.Temporary() {
					ct++
					continue
				}
			}
			break
		}
	}
	c.Close()
	done <- rcvd
}

var crashy = false

func runStreamSyslog(l net.Listener, done chan<- string, wg *sync.WaitGroup) {
	for {
		var c net.Conn
		var err error
		if c, err = l.Accept(); err != nil {
			return
		}
		wg.Add(1)
		go func(c net.Conn) {
			defer wg.Done()
			c.SetReadDeadline(time.Now().Add(5 * time.Second))
			b := bufio.NewReader(c)
			for ct := 1; !crashy || ct&7 != 0; ct++ {
				s, err := b.ReadString('\n')
				if err != nil {
					break
				}
				done <- s
			}
			c.Close()
		}(c)
	}
}

func startServer(n, la string, done chan<- string) (addr string, sock io.Closer, wg *sync.WaitGroup) {
	if n == "udp" || n == "tcp" {
		la = "127.0.0.1:0"
	} else {
		// unix and unixgram: choose an address if none given
		if la == "" {
			// use ioutil.TempFile to get a name that is unique
			f, err := ioutil.TempFile("", "syslogtest")
			if err != nil {
				log.Fatal("TempFile: ", err)
			}
			f.Close()
			la = f.Name()
		}
		os.Remove(la)
	}

	wg = new(sync.WaitGroup)
	if n == "udp" || n == "unixgram" {
		l, e := net.ListenPacket(n, la)
		if e != nil {
			log.Fatalf("startServer failed: %v", e)
		}
		addr = l.LocalAddr().String()
		sock = l
		wg.Add(1)
		go func() {
			defer wg.Done()
			runPktSyslog(l, done)
		}()
	} else {
		l, e := net.Listen(n, la)
		if e != nil {
			log.Fatalf("startServer failed: %v", e)
		}
		addr = l.Addr().String()
		sock = l
		wg.Add(1)
		go func() {
			defer wg.Done()
			runStreamSyslog(l, done, wg)
		}()
	}
	return
}

func TestWithSimulated(t *testing.T) {
	msg := "Test 123"
	transport := []string{"unix", "unixgram", "udp", "tcp"}

	for _, tr := range transport {
		done := make(chan string)
		addr, _, _ := startServer(tr, "", done)
		if tr == "unix" || tr == "unixgram" {
			defer os.Remove(addr)
		}
		s, err := Dial(tr, addr, LOG_INFO|LOG_USER, "syslog_test")
		if err != nil {
			t.Fatalf("Dial() failed: %v", err)
		}
		err = s.Info(msg)
		if err != nil {
			t.Fatalf("log failed: %v", err)
		}
		check(t, msg, <-done)
		s.Close()
	}
}

func TestFlap(t *testing.T) {
	net := "unix"
	done := make(chan string)
	addr, sock, _ := startServer(net, "", done)
	defer os.Remove(addr)
	defer sock.Close()

	s, err := Dial(net, addr, LOG_INFO|LOG_USER, "syslog_test")
	if err != nil {
		t.Fatalf("Dial() failed: %v", err)
	}
	msg := "Moo 2"
	err = s.Info(msg)
	if err != nil {
		t.Fatalf("log failed: %v", err)
	}
	check(t, msg, <-done)

	// restart the server
	_, sock2, _ := startServer(net, addr, done)
	defer sock2.Close()

	// and try retransmitting
	msg = "Moo 3"
	err = s.Info(msg)
	if err != nil {
		t.Fatalf("log failed: %v", err)
	}
	check(t, msg, <-done)

	s.Close()
}

func TestNew(t *testing.T) {
	if LOG_LOCAL7 != 23<<3 {
		t.Fatalf("LOG_LOCAL7 has wrong value")
	}

	s, err := New(LOG_INFO|LOG_USER, "the_tag")
	if err != nil {
		t.Fatalf("New() failed: %s", err)
	}
	// Don't send any messages.
	s.Close()
}

func TestNewLogger(t *testing.T) {
	f, err := NewLogger(LOG_USER|LOG_INFO, 0)
	if f == nil {
		t.Error(err)
	}
}

func TestDial(t *testing.T) {
	f, err := Dial("", "", (LOG_LOCAL7|LOG_DEBUG)+1, "syslog_test")
	if f != nil {
		t.Fatalf("Should have trapped bad priority")
	}
	f, err = Dial("", "", -1, "syslog_test")
	if f != nil {
		t.Fatalf("Should have trapped bad priority")
	}
	l, err := Dial("", "", LOG_USER|LOG_ERR, "syslog_test")
	if err != nil {
		t.Fatalf("Dial() failed: %s", err)
	}
	l.Close()
}

func check(t *testing.T, in, out string) {
	tmpl := fmt.Sprintf("<%d>%%s %%s syslog_test[%%d]: %s\n", LOG_USER+LOG_INFO, in)
	if hostname, err := os.Hostname(); err != nil {
		t.Error("Error retrieving hostname")
	} else {
		var parsedHostname, timestamp string
		var pid int
		if n, err := fmt.Sscanf(out, tmpl, &timestamp, &parsedHostname, &pid); n != 3 || err != nil || hostname != parsedHostname {
			t.Errorf("Got %q, does not match template %q (%d %s)", out, tmpl, n, err)
		}
	}
}

func TestWrite(t *testing.T) {
	tests := []struct {
		pri Priority
		pre string
		msg string
		exp string
	}{
		{LOG_USER | LOG_ERR, "syslog_test", "", "%s %s syslog_test[%d]: \n"},
		{LOG_USER | LOG_ERR, "syslog_test", "write test", "%s %s syslog_test[%d]: write test\n"},
		// Write should not add \n if there already is one
		{LOG_USER | LOG_ERR, "syslog_test", "write test 2\n", "%s %s syslog_test[%d]: write test 2\n"},
	}

	if hostname, err := os.Hostname(); err != nil {
		t.Fatalf("Error retrieving hostname")
	} else {
		for _, test := range tests {
			done := make(chan string)
			addr, sock, _ := startServer("udp", "", done)
			defer sock.Close()
			l, err := Dial("udp", addr, test.pri, test.pre)
			if err != nil {
				t.Fatalf("syslog.Dial() failed: %v", err)
			}
			_, err = io.WriteString(l, test.msg)
			if err != nil {
				t.Fatalf("WriteString() failed: %v", err)
			}
			rcvd := <-done
			test.exp = fmt.Sprintf("<%d>", test.pri) + test.exp
			var parsedHostname, timestamp string
			var pid int
			if n, err := fmt.Sscanf(rcvd, test.exp, &timestamp, &parsedHostname, &pid); n != 3 || err != nil || hostname != parsedHostname {
				t.Errorf("s.Info() = '%q', didn't match '%q' (%d %s)", rcvd, test.exp, n, err)
			}
		}
	}
}

func TestConcurrentWrite(t *testing.T) {
	addr, sock, _ := startServer("udp", "", make(chan string))
	defer sock.Close()
	w, err := Dial("udp", addr, LOG_USER|LOG_ERR, "how's it going?")
	if err != nil {
		t.Fatalf("syslog.Dial() failed: %v", err)
	}
	var wg sync.WaitGroup
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func() {
			err := w.Info("test")
			if err != nil {
				t.Errorf("Info() failed: %v", err)
				return
			}
			wg.Done()
		}()
	}
	wg.Wait()
}

func TestConcurrentReconnect(t *testing.T) {
	crashy = true
	defer func() { crashy = false }()

	net := "unix"
	done := make(chan string)
	addr, sock, srvWG := startServer(net, "", done)
	defer os.Remove(addr)

	// count all the messages arriving
	count := make(chan int)
	go func() {
		ct := 0
		for _ = range done {
			ct++
			// we are looking for 500 out of 1000 events
			// here because lots of log messages are lost
			// in buffers (kernel and/or bufio)
			if ct > 500 {
				break
			}
		}
		count <- ct
	}()

	var wg sync.WaitGroup
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func() {
			w, err := Dial(net, addr, LOG_USER|LOG_ERR, "tag")
			if err != nil {
				t.Fatalf("syslog.Dial() failed: %v", err)
			}
			for i := 0; i < 100; i++ {
				err := w.Info("test")
				if err != nil {
					t.Errorf("Info() failed: %v", err)
					return
				}
			}
			wg.Done()
		}()
	}
	wg.Wait()
	sock.Close()
	srvWG.Wait()
	close(done)

	select {
	case <-count:
	case <-time.After(100 * time.Millisecond):
		t.Error("timeout in concurrent reconnect")
	}
}
<|endoftext|>


<commit_before>package schema

import (
	"time"

	"code.google.com/p/go-uuid/uuid"
)

type Build struct {
	ID             uuid.UUID `json:"id"`
	SourceRepo     string    `json:"source_repo"`
	SourceRevision string    `json:"source_revision"`
	Name           string    `json:"name"`
	Dockerfile     string    `json:"dockerfile"`
	CreatedAt      time.Time `json:"created_at"`
	UpdatedAt      time.Time `json:"updated_at"`
}

type BuildCreateOpts struct {
	SourceRepo     string `json:"source_repo"`
	SourceRevision string `json:"source_revision"`
	Name           string `json:"name"`
	Dockerfile     string `json:"dockerfile"`
}
<commit_msg>Add missing attribute "Status" to build struct<commit_after>package schema

import (
	"time"

	"code.google.com/p/go-uuid/uuid"
)

type Build struct {
	ID             uuid.UUID `json:"id"`
	SourceRepo     string    `json:"source_repo"`
	SourceRevision string    `json:"source_revision"`
	Name           string    `json:"name"`
	Dockerfile     string    `json:"dockerfile"`
	Status         string    `json:"status"`
	CreatedAt      time.Time `json:"created_at"`
	UpdatedAt      time.Time `json:"updated_at"`
}

type BuildCreateOpts struct {
	SourceRepo     string `json:"source_repo"`
	SourceRevision string `json:"source_revision"`
	Name           string `json:"name"`
	Dockerfile     string `json:"dockerfile"`
}
<|endoftext|>


<commit_before>// Copyright 2013 Francisco Souza. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package testing provides a fake implementation of the Docker API, useful for
// testing purpose.
package testing

import (
	"crypto/rand"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/bmizerany/pat"
	"github.com/dotcloud/docker"
	mathrand "math/rand"
	"net"
	"net/http"
	"strconv"
	"strings"
	"sync"
	"time"
)

// DockerServer represents a programmable, concurrent (not much), HTTP server
// implementing a fake version of the Docker remote API.
//
// It can used in standalone mode, listening for connections or as an arbitrary
// HTTP handler.
//
// For more details on the remote API, check http://goo.gl/yMI1S.
type DockerServer struct {
	containers []*docker.Container
	cMut       sync.RWMutex
	images     []docker.Image
	iMut       sync.RWMutex
	imgIDs     map[string]string
	listener   net.Listener
	mux        *pat.PatternServeMux
	hook       func(*http.Request)
}

// NewServer returns a new instance of the fake server, in standalone mode. Use
// the method URL to get the URL of the server.
//
// Hook is a function that will be called on every request.
func NewServer(hook func(*http.Request)) (*DockerServer, error) {
	listener, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		return nil, err
	}
	server := DockerServer{listener: listener, imgIDs: make(map[string]string), hook: hook}
	server.buildMuxer()
	go http.Serve(listener, &server)
	return &server, nil
}

func (s *DockerServer) buildMuxer() {
	s.mux = pat.New()
	s.mux.Post("/:version/commit", http.HandlerFunc(s.commitContainer))
	s.mux.Get("/:version/containers/json", http.HandlerFunc(s.listContainers))
	s.mux.Post("/:version/containers/create", http.HandlerFunc(s.createContainer))
	s.mux.Get("/:version/containers/:id/json", http.HandlerFunc(s.inspectContainer))
	s.mux.Post("/:version/containers/:id/start", http.HandlerFunc(s.startContainer))
	s.mux.Post("/:version/containers/:id/stop", http.HandlerFunc(s.stopContainer))
	s.mux.Post("/:version/containers/:id/wait", http.HandlerFunc(s.waitContainer))
	s.mux.Post("/:version/containers/:id/attach", http.HandlerFunc(s.attachContainer))
	s.mux.Del("/:version/containers/:id", http.HandlerFunc(s.removeContainer))
	s.mux.Post("/:version/images/create", http.HandlerFunc(s.pullImage))
	s.mux.Post("/:version/images/:name/push", http.HandlerFunc(s.pushImage))
	s.mux.Get("/:version/images/json", http.HandlerFunc(s.listImages))
	s.mux.Del("/:version/images/:id", http.HandlerFunc(s.removeImage))
}

// Stop stops the server.
func (s *DockerServer) Stop() {
	if s.listener != nil {
		s.listener.Close()
	}
}

// URL returns the HTTP URL of the server.
func (s *DockerServer) URL() string {
	if s.listener == nil {
		return ""
	}
	return "http://" + s.listener.Addr().String() + "/"
}

// ServeHTTP handles HTTP requests sent to the server.
func (s *DockerServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	s.mux.ServeHTTP(w, r)
	if s.hook != nil {
		s.hook(r)
	}
}

func (s *DockerServer) listContainers(w http.ResponseWriter, r *http.Request) {
	s.cMut.RLock()
	result := make([]docker.APIContainers, len(s.containers))
	for i, container := range s.containers {
		result[i] = docker.APIContainers{
			ID:      container.ID,
			Image:   container.Image,
			Command: fmt.Sprintf("%s %s", container.Path, strings.Join(container.Args, " ")),
			Created: container.Created.Unix(),
			Status:  container.State.String(),
			Ports:   container.NetworkSettings.PortMappingHuman(),
		}
	}
	s.cMut.RUnlock()
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(result)
}

func (s *DockerServer) listImages(w http.ResponseWriter, r *http.Request) {
	s.cMut.RLock()
	result := make([]docker.APIImages, len(s.images))
	for i, image := range s.images {
		result[i] = docker.APIImages{
			ID:      image.ID,
			Created: image.Created.Unix(),
		}
	}
	s.cMut.RUnlock()
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(result)
}

func (s *DockerServer) findImage(id string) (string, error) {
	s.iMut.RLock()
	defer s.iMut.RUnlock()
	image, ok := s.imgIDs[id]
	if ok {
		return image, nil
	}
	image, _, err := s.findImageByID(id)
	return image, err
}

func (s *DockerServer) findImageByID(id string) (string, int, error) {
	s.iMut.RLock()
	defer s.iMut.RUnlock()
	for i, image := range s.images {
		if image.ID == id {
			return image.ID, i, nil
		}
	}
	return "", -1, errors.New("No such image")
}

func (s *DockerServer) createContainer(w http.ResponseWriter, r *http.Request) {
	var config docker.Config
	defer r.Body.Close()
	err := json.NewDecoder(r.Body).Decode(&config)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	image, err := s.findImage(config.Image)
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	w.WriteHeader(http.StatusCreated)
	portMapping := make(map[string]string, len(config.PortSpecs))
	for _, p := range config.PortSpecs {
		portMapping[p] = strconv.Itoa(mathrand.Int() % 65536)
	}
	container := docker.Container{
		ID:      s.generateID(),
		Created: time.Now(),
		Path:    config.Cmd[0],
		Args:    config.Cmd[1:],
		Config:  &config,
		State: docker.State{
			Running:   false,
			Pid:       mathrand.Int() % 50000,
			ExitCode:  0,
			StartedAt: time.Now(),
		},
		Image: image,
		NetworkSettings: &docker.NetworkSettings{
			IPAddress:   fmt.Sprintf("172.16.42.%d", mathrand.Int()%250+2),
			IPPrefixLen: 24,
			Gateway:     "172.16.42.1",
			Bridge:      "docker0",
			PortMapping: portMapping,
		},
	}
	s.cMut.Lock()
	s.containers = append(s.containers, &container)
	s.cMut.Unlock()
	var c = struct{ ID string }{ID: container.ID}
	json.NewEncoder(w).Encode(c)
}

func (s *DockerServer) generateID() string {
	var buf [16]byte
	rand.Read(buf[:])
	return fmt.Sprintf("%x", buf)
}

func (s *DockerServer) inspectContainer(w http.ResponseWriter, r *http.Request) {
	id := r.URL.Query().Get(":id")
	container, _, err := s.findContainer(id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(container)
}

func (s *DockerServer) startContainer(w http.ResponseWriter, r *http.Request) {
	id := r.URL.Query().Get(":id")
	container, _, err := s.findContainer(id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	s.cMut.Lock()
	defer s.cMut.Unlock()
	if container.State.Running {
		http.Error(w, "Container already running", http.StatusBadRequest)
		return
	}
	container.State.Running = true
}

func (s *DockerServer) stopContainer(w http.ResponseWriter, r *http.Request) {
	id := r.URL.Query().Get(":id")
	container, _, err := s.findContainer(id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	s.cMut.Lock()
	defer s.cMut.Unlock()
	if !container.State.Running {
		http.Error(w, "Container not running", http.StatusBadRequest)
		return
	}
	w.WriteHeader(http.StatusNoContent)
	container.State.Running = false
}

func (s *DockerServer) attachContainer(w http.ResponseWriter, r *http.Request) {
	id := r.URL.Query().Get(":id")
	container, _, err := s.findContainer(id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	if container.State.Running {
		fmt.Fprintf(w, "Container %q is running\n", container.ID)
	} else {
		fmt.Fprintf(w, "Container %q is not running\n", container.ID)
	}
	fmt.Fprintln(w, "What happened?")
	fmt.Fprintln(w, "Something happened")
}

func (s *DockerServer) waitContainer(w http.ResponseWriter, r *http.Request) {
	id := r.URL.Query().Get(":id")
	container, _, err := s.findContainer(id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	for {
		s.cMut.RLock()
		if container.State.Running {
			s.cMut.RUnlock()
			break
		}
		s.cMut.RUnlock()
	}
	w.Write([]byte(`{"StatusCode":0}`))
}

func (s *DockerServer) removeContainer(w http.ResponseWriter, r *http.Request) {
	id := r.URL.Query().Get(":id")
	_, index, err := s.findContainer(id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	w.WriteHeader(http.StatusNoContent)
	s.cMut.Lock()
	defer s.cMut.Unlock()
	s.containers[index] = s.containers[len(s.containers)-1]
	s.containers = s.containers[:len(s.containers)-1]
}

func (s *DockerServer) commitContainer(w http.ResponseWriter, r *http.Request) {
	id := r.URL.Query().Get("container")
	container, _, err := s.findContainer(id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	var config *docker.Config
	runConfig := r.URL.Query().Get("run")
	if runConfig != "" {
		config = new(docker.Config)
		err = json.Unmarshal([]byte(runConfig), config)
		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
	}
	w.WriteHeader(http.StatusOK)
	image := docker.Image{
		ID:        "img-" + container.ID,
		Parent:    container.Image,
		Container: container.ID,
		Comment:   r.URL.Query().Get("m"),
		Author:    r.URL.Query().Get("author"),
		Config:    config,
	}
	repository := r.URL.Query().Get("repo")
	s.iMut.Lock()
	s.images = append(s.images, image)
	if repository != "" {
		s.imgIDs[repository] = image.ID
	}
	s.iMut.Unlock()
	fmt.Fprintf(w, `{"ID":%q}`, image.ID)
}

func (s *DockerServer) findContainer(id string) (*docker.Container, int, error) {
	s.cMut.RLock()
	defer s.cMut.RUnlock()
	for i, container := range s.containers {
		if container.ID == id {
			return container, i, nil
		}
	}
	return nil, -1, errors.New("No such container")
}

func (s *DockerServer) pullImage(w http.ResponseWriter, r *http.Request) {
	repository := r.URL.Query().Get("fromImage")
	image := docker.Image{
		ID: s.generateID(),
	}
	s.iMut.Lock()
	s.images = append(s.images, image)
	if repository != "" {
		s.imgIDs[repository] = image.ID
	}
	s.iMut.Unlock()
}

func (s *DockerServer) pushImage(w http.ResponseWriter, r *http.Request) {
}

func (s *DockerServer) removeImage(w http.ResponseWriter, r *http.Request) {
	id := r.URL.Query().Get(":id")
	_, index, err := s.findImageByID(id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	w.WriteHeader(http.StatusNoContent)
	s.iMut.Lock()
	defer s.iMut.Unlock()
	s.images[index] = s.images[len(s.images)-1]
	s.images = s.images[:len(s.images)-1]
}
<commit_msg>testing/server: replace pat with gorilla<commit_after>// Copyright 2013 Francisco Souza. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package testing provides a fake implementation of the Docker API, useful for
// testing purpose.
package testing

import (
	"crypto/rand"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/dotcloud/docker"
	"github.com/gorilla/mux"
	mathrand "math/rand"
	"net"
	"net/http"
	"strconv"
	"strings"
	"sync"
	"time"
)

// DockerServer represents a programmable, concurrent (not much), HTTP server
// implementing a fake version of the Docker remote API.
//
// It can used in standalone mode, listening for connections or as an arbitrary
// HTTP handler.
//
// For more details on the remote API, check http://goo.gl/yMI1S.
type DockerServer struct {
	containers []*docker.Container
	cMut       sync.RWMutex
	images     []docker.Image
	iMut       sync.RWMutex
	imgIDs     map[string]string
	listener   net.Listener
	mux        *mux.Router
	hook       func(*http.Request)
}

// NewServer returns a new instance of the fake server, in standalone mode. Use
// the method URL to get the URL of the server.
//
// Hook is a function that will be called on every request.
func NewServer(hook func(*http.Request)) (*DockerServer, error) {
	listener, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		return nil, err
	}
	server := DockerServer{listener: listener, imgIDs: make(map[string]string), hook: hook}
	server.buildMuxer()
	go http.Serve(listener, &server)
	return &server, nil
}

func (s *DockerServer) buildMuxer() {
	s.mux = mux.NewRouter()
	s.mux.Path("/v{version:[0-9.]+}/commit").Methods("POST").HandlerFunc(s.commitContainer)
	s.mux.Path("/v{version:[0-9.]+}/containers/json").Methods("GET").HandlerFunc(s.listContainers)
	s.mux.Path("/v{version:[0-9.]+}/containers/create").Methods("POST").HandlerFunc(s.createContainer)
	s.mux.Path("/v{version:[0-9.]+}/containers/{id:.*}/json").Methods("GET").HandlerFunc(s.inspectContainer)
	s.mux.Path("/v{version:[0-9.]+}/containers/{id:.*}/start").Methods("POST").HandlerFunc(s.startContainer)
	s.mux.Path("/v{version:[0-9.]+}/containers/{id:.*}/stop").Methods("POST").HandlerFunc(s.stopContainer)
	s.mux.Path("/v{version:[0-9.]+}/containers/{id:.*}/wait").Methods("POST").HandlerFunc(s.waitContainer)
	s.mux.Path("/v{version:[0-9.]+}/containers/{id:.*}/attach").Methods("POST").HandlerFunc(s.attachContainer)
	s.mux.Path("/v{version:[0-9.]+}/containers/{id:.*}").Methods("DELETE").HandlerFunc(s.removeContainer)
	s.mux.Path("/v{version:[0-9.]+}/images/create").Methods("POST").HandlerFunc(s.pullImage)
	s.mux.Path("/v{version:[0-9.]+}/images/json").Methods("GET").HandlerFunc(s.listImages)
	s.mux.Path("/v{version:[0-9.]+}/images/{id:.*}").Methods("DELETE").HandlerFunc(s.removeImage)
	s.mux.Path("/v{version:[0-9.]+}/images/{name:.*}/push").Methods("POST").HandlerFunc(s.pushImage)
}

// Stop stops the server.
func (s *DockerServer) Stop() {
	if s.listener != nil {
		s.listener.Close()
	}
}

// URL returns the HTTP URL of the server.
func (s *DockerServer) URL() string {
	if s.listener == nil {
		return ""
	}
	return "http://" + s.listener.Addr().String() + "/"
}

// ServeHTTP handles HTTP requests sent to the server.
func (s *DockerServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	s.mux.ServeHTTP(w, r)
	if s.hook != nil {
		s.hook(r)
	}
}

func (s *DockerServer) listContainers(w http.ResponseWriter, r *http.Request) {
	s.cMut.RLock()
	result := make([]docker.APIContainers, len(s.containers))
	for i, container := range s.containers {
		result[i] = docker.APIContainers{
			ID:      container.ID,
			Image:   container.Image,
			Command: fmt.Sprintf("%s %s", container.Path, strings.Join(container.Args, " ")),
			Created: container.Created.Unix(),
			Status:  container.State.String(),
			Ports:   container.NetworkSettings.PortMappingHuman(),
		}
	}
	s.cMut.RUnlock()
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(result)
}

func (s *DockerServer) listImages(w http.ResponseWriter, r *http.Request) {
	s.cMut.RLock()
	result := make([]docker.APIImages, len(s.images))
	for i, image := range s.images {
		result[i] = docker.APIImages{
			ID:      image.ID,
			Created: image.Created.Unix(),
		}
	}
	s.cMut.RUnlock()
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(result)
}

func (s *DockerServer) findImage(id string) (string, error) {
	s.iMut.RLock()
	defer s.iMut.RUnlock()
	image, ok := s.imgIDs[id]
	if ok {
		return image, nil
	}
	image, _, err := s.findImageByID(id)
	return image, err
}

func (s *DockerServer) findImageByID(id string) (string, int, error) {
	s.iMut.RLock()
	defer s.iMut.RUnlock()
	for i, image := range s.images {
		if image.ID == id {
			return image.ID, i, nil
		}
	}
	return "", -1, errors.New("No such image")
}

func (s *DockerServer) createContainer(w http.ResponseWriter, r *http.Request) {
	var config docker.Config
	defer r.Body.Close()
	err := json.NewDecoder(r.Body).Decode(&config)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	image, err := s.findImage(config.Image)
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	w.WriteHeader(http.StatusCreated)
	portMapping := make(map[string]string, len(config.PortSpecs))
	for _, p := range config.PortSpecs {
		portMapping[p] = strconv.Itoa(mathrand.Int() % 65536)
	}
	container := docker.Container{
		ID:      s.generateID(),
		Created: time.Now(),
		Path:    config.Cmd[0],
		Args:    config.Cmd[1:],
		Config:  &config,
		State: docker.State{
			Running:   false,
			Pid:       mathrand.Int() % 50000,
			ExitCode:  0,
			StartedAt: time.Now(),
		},
		Image: image,
		NetworkSettings: &docker.NetworkSettings{
			IPAddress:   fmt.Sprintf("172.16.42.%d", mathrand.Int()%250+2),
			IPPrefixLen: 24,
			Gateway:     "172.16.42.1",
			Bridge:      "docker0",
			PortMapping: portMapping,
		},
	}
	s.cMut.Lock()
	s.containers = append(s.containers, &container)
	s.cMut.Unlock()
	var c = struct{ ID string }{ID: container.ID}
	json.NewEncoder(w).Encode(c)
}

func (s *DockerServer) generateID() string {
	var buf [16]byte
	rand.Read(buf[:])
	return fmt.Sprintf("%x", buf)
}

func (s *DockerServer) inspectContainer(w http.ResponseWriter, r *http.Request) {
	id := mux.Vars(r)["id"]
	container, _, err := s.findContainer(id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(container)
}

func (s *DockerServer) startContainer(w http.ResponseWriter, r *http.Request) {
	id := mux.Vars(r)["id"]
	container, _, err := s.findContainer(id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	s.cMut.Lock()
	defer s.cMut.Unlock()
	if container.State.Running {
		http.Error(w, "Container already running", http.StatusBadRequest)
		return
	}
	container.State.Running = true
}

func (s *DockerServer) stopContainer(w http.ResponseWriter, r *http.Request) {
	id := mux.Vars(r)["id"]
	container, _, err := s.findContainer(id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	s.cMut.Lock()
	defer s.cMut.Unlock()
	if !container.State.Running {
		http.Error(w, "Container not running", http.StatusBadRequest)
		return
	}
	w.WriteHeader(http.StatusNoContent)
	container.State.Running = false
}

func (s *DockerServer) attachContainer(w http.ResponseWriter, r *http.Request) {
	id := mux.Vars(r)["id"]
	container, _, err := s.findContainer(id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	if container.State.Running {
		fmt.Fprintf(w, "Container %q is running\n", container.ID)
	} else {
		fmt.Fprintf(w, "Container %q is not running\n", container.ID)
	}
	fmt.Fprintln(w, "What happened?")
	fmt.Fprintln(w, "Something happened")
}

func (s *DockerServer) waitContainer(w http.ResponseWriter, r *http.Request) {
	id := mux.Vars(r)["id"]
	container, _, err := s.findContainer(id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	for {
		s.cMut.RLock()
		if container.State.Running {
			s.cMut.RUnlock()
			break
		}
		s.cMut.RUnlock()
	}
	w.Write([]byte(`{"StatusCode":0}`))
}

func (s *DockerServer) removeContainer(w http.ResponseWriter, r *http.Request) {
	id := mux.Vars(r)["id"]
	_, index, err := s.findContainer(id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	w.WriteHeader(http.StatusNoContent)
	s.cMut.Lock()
	defer s.cMut.Unlock()
	s.containers[index] = s.containers[len(s.containers)-1]
	s.containers = s.containers[:len(s.containers)-1]
}

func (s *DockerServer) commitContainer(w http.ResponseWriter, r *http.Request) {
	id := r.URL.Query().Get("container")
	container, _, err := s.findContainer(id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	var config *docker.Config
	runConfig := r.URL.Query().Get("run")
	if runConfig != "" {
		config = new(docker.Config)
		err = json.Unmarshal([]byte(runConfig), config)
		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
	}
	w.WriteHeader(http.StatusOK)
	image := docker.Image{
		ID:        "img-" + container.ID,
		Parent:    container.Image,
		Container: container.ID,
		Comment:   r.URL.Query().Get("m"),
		Author:    r.URL.Query().Get("author"),
		Config:    config,
	}
	repository := r.URL.Query().Get("repo")
	s.iMut.Lock()
	s.images = append(s.images, image)
	if repository != "" {
		s.imgIDs[repository] = image.ID
	}
	s.iMut.Unlock()
	fmt.Fprintf(w, `{"ID":%q}`, image.ID)
}

func (s *DockerServer) findContainer(id string) (*docker.Container, int, error) {
	s.cMut.RLock()
	defer s.cMut.RUnlock()
	for i, container := range s.containers {
		if container.ID == id {
			return container, i, nil
		}
	}
	return nil, -1, errors.New("No such container")
}

func (s *DockerServer) pullImage(w http.ResponseWriter, r *http.Request) {
	repository := r.URL.Query().Get("fromImage")
	image := docker.Image{
		ID: s.generateID(),
	}
	s.iMut.Lock()
	s.images = append(s.images, image)
	if repository != "" {
		s.imgIDs[repository] = image.ID
	}
	s.iMut.Unlock()
}

func (s *DockerServer) pushImage(w http.ResponseWriter, r *http.Request) {
}

func (s *DockerServer) removeImage(w http.ResponseWriter, r *http.Request) {
	id := mux.Vars(r)["id"]
	_, index, err := s.findImageByID(id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	w.WriteHeader(http.StatusNoContent)
	s.iMut.Lock()
	defer s.iMut.Unlock()
	s.images[index] = s.images[len(s.images)-1]
	s.images = s.images[:len(s.images)-1]
}
<|endoftext|>