<commit_before>// Copyright 2017 PingCAP, Inc.
//
// 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,
// See the License for the specific language governing permissions and
// limitations under the License.

package gcworker

import (
	"context"
	"math"
	"strconv"
	"testing"
	"time"

	. "github.com/pingcap/check"
	gofail "github.com/pingcap/gofail/runtime"
	"github.com/pingcap/kvproto/pkg/errorpb"
	"github.com/pingcap/tidb/domain"
	"github.com/pingcap/tidb/session"
	"github.com/pingcap/tidb/store/mockoracle"
	"github.com/pingcap/tidb/store/mockstore"
	"github.com/pingcap/tidb/store/tikv"
)

func TestT(t *testing.T) {
	TestingT(t)
}

type testGCWorkerSuite struct {
	store    tikv.Storage
	oracle   *mockoracle.MockOracle
	gcWorker *GCWorker
	dom      *domain.Domain
}

var _ = Suite(&testGCWorkerSuite{})
var _ = SerialSuites(&testGCWorkerSerialSuite{})

func (s *testGCWorkerSuite) SetUpTest(c *C) {
	tikv.NewGCHandlerFunc = NewGCWorker
	store, err := mockstore.NewMockTikvStore()
	s.store = store.(tikv.Storage)
	c.Assert(err, IsNil)
	s.oracle = &mockoracle.MockOracle{}
	s.store.SetOracle(s.oracle)
	s.dom, err = session.BootstrapSession(s.store)
	c.Assert(err, IsNil)
	gcWorker, err := NewGCWorker(s.store, nil)
	c.Assert(err, IsNil)
	gcWorker.Start()
	gcWorker.Close()
	s.gcWorker = gcWorker.(*GCWorker)
}

func (s *testGCWorkerSuite) TearDownTest(c *C) {
	s.dom.Close()
	err := s.store.Close()
	c.Assert(err, IsNil)
}

func (s *testGCWorkerSuite) timeEqual(c *C, t1, t2 time.Time, epsilon time.Duration) {
	c.Assert(math.Abs(float64(t1.Sub(t2))), Less, float64(epsilon))
}

func (s *testGCWorkerSuite) TestGetOracleTime(c *C) {
	t1, err := s.gcWorker.getOracleTime()
	c.Assert(err, IsNil)
	s.timeEqual(c, time.Now(), t1, time.Millisecond*10)

	s.oracle.AddOffset(time.Second * 10)
	t2, err := s.gcWorker.getOracleTime()
	c.Assert(err, IsNil)
	s.timeEqual(c, t2, t1.Add(time.Second*10), time.Millisecond*10)
}

func (s *testGCWorkerSuite) TestPrepareGC(c *C) {
	now, err := s.gcWorker.getOracleTime()
	c.Assert(err, IsNil)
	close(s.gcWorker.done)
	ok, _, err := s.gcWorker.prepare()
	c.Assert(err, IsNil)
	c.Assert(ok, IsFalse)
	lastRun, err := s.gcWorker.loadTime(gcLastRunTimeKey)
	c.Assert(err, IsNil)
	c.Assert(lastRun, NotNil)
	safePoint, err := s.gcWorker.loadTime(gcSafePointKey)
	c.Assert(err, IsNil)
	s.timeEqual(c, safePoint.Add(gcDefaultLifeTime), now, 2*time.Second)

	// Change GC run interval.
	err = s.gcWorker.saveDuration(gcRunIntervalKey, time.Minute*5)
	c.Assert(err, IsNil)
	s.oracle.AddOffset(time.Minute * 4)
	ok, _, err = s.gcWorker.prepare()
	c.Assert(err, IsNil)
	c.Assert(ok, IsFalse)
	s.oracle.AddOffset(time.Minute * 2)
	ok, _, err = s.gcWorker.prepare()
	c.Assert(err, IsNil)
	c.Assert(ok, IsTrue)

	// Change GC life time.
	err = s.gcWorker.saveDuration(gcLifeTimeKey, time.Minute*30)
	c.Assert(err, IsNil)
	s.oracle.AddOffset(time.Minute * 5)
	ok, _, err = s.gcWorker.prepare()
	c.Assert(err, IsNil)
	c.Assert(ok, IsFalse)
	s.oracle.AddOffset(time.Minute * 40)
	now, err = s.gcWorker.getOracleTime()
	c.Assert(err, IsNil)
	ok, _, err = s.gcWorker.prepare()
	c.Assert(err, IsNil)
	c.Assert(ok, IsTrue)
	safePoint, err = s.gcWorker.loadTime(gcSafePointKey)
	c.Assert(err, IsNil)
	s.timeEqual(c, safePoint.Add(time.Minute*30), now, 2*time.Second)

	// Change GC concurrency.
	concurrency, err := s.gcWorker.loadGCConcurrencyWithDefault()
	c.Assert(err, IsNil)
	c.Assert(concurrency, Equals, gcDefaultConcurrency)

	err = s.gcWorker.saveValueToSysTable(gcConcurrencyKey, strconv.Itoa(gcMinConcurrency))
	c.Assert(err, IsNil)
	concurrency, err = s.gcWorker.loadGCConcurrencyWithDefault()
	c.Assert(err, IsNil)
	c.Assert(concurrency, Equals, gcMinConcurrency)

	err = s.gcWorker.saveValueToSysTable(gcConcurrencyKey, strconv.Itoa(-1))
	c.Assert(err, IsNil)
	concurrency, err = s.gcWorker.loadGCConcurrencyWithDefault()
	c.Assert(err, IsNil)
	c.Assert(concurrency, Equals, gcMinConcurrency)

	err = s.gcWorker.saveValueToSysTable(gcConcurrencyKey, strconv.Itoa(1000000))
	c.Assert(err, IsNil)
	concurrency, err = s.gcWorker.loadGCConcurrencyWithDefault()
	c.Assert(err, IsNil)
	c.Assert(concurrency, Equals, gcMaxConcurrency)

	// Change GC enable status.
	s.oracle.AddOffset(time.Minute * 40)
	err = s.gcWorker.saveValueToSysTable(gcEnableKey, gcDisableValue)
	c.Assert(err, IsNil)
	ok, _, err = s.gcWorker.prepare()
	c.Assert(err, IsNil)
	c.Assert(ok, IsFalse)
	err = s.gcWorker.saveValueToSysTable(gcEnableKey, gcEnableValue)
	c.Assert(err, IsNil)
	ok, _, err = s.gcWorker.prepare()
	c.Assert(err, IsNil)
	c.Assert(ok, IsTrue)
}

func (s *testGCWorkerSuite) TestDoGC(c *C) {
	var err error
	ctx := context.Background()

	gcSafePointCacheInterval = 1

	err = s.gcWorker.saveValueToSysTable(gcConcurrencyKey, strconv.Itoa(gcDefaultConcurrency))
	c.Assert(err, IsNil)
	err = s.gcWorker.doGC(ctx, 20)
	c.Assert(err, IsNil)

	err = s.gcWorker.saveValueToSysTable(gcConcurrencyKey, strconv.Itoa(gcMinConcurrency))
	c.Assert(err, IsNil)
	err = s.gcWorker.doGC(ctx, 20)
	c.Assert(err, IsNil)

	err = s.gcWorker.saveValueToSysTable(gcConcurrencyKey, strconv.Itoa(gcMaxConcurrency))
	c.Assert(err, IsNil)
	err = s.gcWorker.doGC(ctx, 20)
	c.Assert(err, IsNil)
}

type testGCWorkerSerialSuite struct {
	store    tikv.Storage
	oracle   *mockoracle.MockOracle
	gcWorker *GCWorker
	dom      *domain.Domain
}

func (s *testGCWorkerSerialSuite) SetUpTest(c *C) {
	tikv.NewGCHandlerFunc = NewGCWorker
	store, err := mockstore.NewMockTikvStore()
	s.store = store.(tikv.Storage)
	c.Assert(err, IsNil)
	s.oracle = &mockoracle.MockOracle{}
	s.store.SetOracle(s.oracle)
	s.dom, err = session.BootstrapSession(s.store)
	c.Assert(err, IsNil)
	gcWorker, err := NewGCWorker(s.store, nil)
	c.Assert(err, IsNil)
	gcWorker.Start()
	gcWorker.Close()
	s.gcWorker = gcWorker.(*GCWorker)
}

func (s *testGCWorkerSerialSuite) TearDownTest(c *C) {
	s.dom.Close()
	err := s.store.Close()
	c.Assert(err, IsNil)
}

func (s *testGCWorkerSerialSuite) TestDoGCForOneRegion(c *C) {
	var successRegions int32
	var failedRegions int32
	taskWorker := newGCTaskWorker(s.store, nil, nil, s.gcWorker.uuid, &successRegions, &failedRegions)

	ctx := context.Background()
	bo := tikv.NewBackoffer(ctx, tikv.GcOneRegionMaxBackoff)
	loc, err := s.store.GetRegionCache().LocateKey(bo, []byte(""))
	c.Assert(err, IsNil)
	var regionErr *errorpb.Error
	regionErr, err = taskWorker.doGCForRegion(bo, 20, loc.Region)
	c.Assert(regionErr, IsNil)
	c.Assert(err, IsNil)

	gofail.Enable("github.com/pingcap/tidb/store/tikv/tikvStoreSendReqResult", `return("timeout")`)
	regionErr, err = taskWorker.doGCForRegion(bo, 20, loc.Region)
	c.Assert(regionErr, IsNil)
	c.Assert(err, NotNil)
	gofail.Disable("github.com/pingcap/tidb/store/tikv/tikvStoreSendReqResult")

	gofail.Enable("github.com/pingcap/tidb/store/tikv/tikvStoreSendReqResult", `return("GCNotLeader")`)
	regionErr, err = taskWorker.doGCForRegion(bo, 20, loc.Region)
	c.Assert(regionErr.GetNotLeader(), NotNil)
	c.Assert(err, IsNil)
	gofail.Disable("github.com/pingcap/tidb/store/tikv/tikvStoreSendReqResult")

	gofail.Enable("github.com/pingcap/tidb/store/tikv/tikvStoreSendReqResult", `return("GCServerIsBusy")`)
	regionErr, err = taskWorker.doGCForRegion(bo, 20, loc.Region)
	c.Assert(regionErr.GetServerIsBusy(), NotNil)
	c.Assert(err, IsNil)
	gofail.Disable("github.com/pingcap/tidb/store/tikv/tikvStoreSendReqResult")
}
<commit_msg>Revert "gcworker: let gofail in gcworker run serially, make ci happy" (#8944)<commit_after>// Copyright 2017 PingCAP, Inc.
//
// 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,
// See the License for the specific language governing permissions and
// limitations under the License.

package gcworker

import (
	"context"
	"math"
	"strconv"
	"testing"
	"time"

	. "github.com/pingcap/check"
	gofail "github.com/pingcap/gofail/runtime"
	"github.com/pingcap/kvproto/pkg/errorpb"
	"github.com/pingcap/tidb/domain"
	"github.com/pingcap/tidb/session"
	"github.com/pingcap/tidb/store/mockoracle"
	"github.com/pingcap/tidb/store/mockstore"
	"github.com/pingcap/tidb/store/tikv"
)

func TestT(t *testing.T) {
	TestingT(t)
}

type testGCWorkerSuite struct {
	store    tikv.Storage
	oracle   *mockoracle.MockOracle
	gcWorker *GCWorker
	dom      *domain.Domain
}

var _ = Suite(&testGCWorkerSuite{})

func (s *testGCWorkerSuite) SetUpTest(c *C) {
	tikv.NewGCHandlerFunc = NewGCWorker
	store, err := mockstore.NewMockTikvStore()
	s.store = store.(tikv.Storage)
	c.Assert(err, IsNil)
	s.oracle = &mockoracle.MockOracle{}
	s.store.SetOracle(s.oracle)
	s.dom, err = session.BootstrapSession(s.store)
	c.Assert(err, IsNil)
	gcWorker, err := NewGCWorker(s.store, nil)
	c.Assert(err, IsNil)
	gcWorker.Start()
	gcWorker.Close()
	s.gcWorker = gcWorker.(*GCWorker)
}

func (s *testGCWorkerSuite) TearDownTest(c *C) {
	s.dom.Close()
	err := s.store.Close()
	c.Assert(err, IsNil)
}

func (s *testGCWorkerSuite) timeEqual(c *C, t1, t2 time.Time, epsilon time.Duration) {
	c.Assert(math.Abs(float64(t1.Sub(t2))), Less, float64(epsilon))
}

func (s *testGCWorkerSuite) TestGetOracleTime(c *C) {
	t1, err := s.gcWorker.getOracleTime()
	c.Assert(err, IsNil)
	s.timeEqual(c, time.Now(), t1, time.Millisecond*10)

	s.oracle.AddOffset(time.Second * 10)
	t2, err := s.gcWorker.getOracleTime()
	c.Assert(err, IsNil)
	s.timeEqual(c, t2, t1.Add(time.Second*10), time.Millisecond*10)
}

func (s *testGCWorkerSuite) TestPrepareGC(c *C) {
	now, err := s.gcWorker.getOracleTime()
	c.Assert(err, IsNil)
	close(s.gcWorker.done)
	ok, _, err := s.gcWorker.prepare()
	c.Assert(err, IsNil)
	c.Assert(ok, IsFalse)
	lastRun, err := s.gcWorker.loadTime(gcLastRunTimeKey)
	c.Assert(err, IsNil)
	c.Assert(lastRun, NotNil)
	safePoint, err := s.gcWorker.loadTime(gcSafePointKey)
	c.Assert(err, IsNil)
	s.timeEqual(c, safePoint.Add(gcDefaultLifeTime), now, 2*time.Second)

	// Change GC run interval.
	err = s.gcWorker.saveDuration(gcRunIntervalKey, time.Minute*5)
	c.Assert(err, IsNil)
	s.oracle.AddOffset(time.Minute * 4)
	ok, _, err = s.gcWorker.prepare()
	c.Assert(err, IsNil)
	c.Assert(ok, IsFalse)
	s.oracle.AddOffset(time.Minute * 2)
	ok, _, err = s.gcWorker.prepare()
	c.Assert(err, IsNil)
	c.Assert(ok, IsTrue)

	// Change GC life time.
	err = s.gcWorker.saveDuration(gcLifeTimeKey, time.Minute*30)
	c.Assert(err, IsNil)
	s.oracle.AddOffset(time.Minute * 5)
	ok, _, err = s.gcWorker.prepare()
	c.Assert(err, IsNil)
	c.Assert(ok, IsFalse)
	s.oracle.AddOffset(time.Minute * 40)
	now, err = s.gcWorker.getOracleTime()
	c.Assert(err, IsNil)
	ok, _, err = s.gcWorker.prepare()
	c.Assert(err, IsNil)
	c.Assert(ok, IsTrue)
	safePoint, err = s.gcWorker.loadTime(gcSafePointKey)
	c.Assert(err, IsNil)
	s.timeEqual(c, safePoint.Add(time.Minute*30), now, 2*time.Second)

	// Change GC concurrency.
	concurrency, err := s.gcWorker.loadGCConcurrencyWithDefault()
	c.Assert(err, IsNil)
	c.Assert(concurrency, Equals, gcDefaultConcurrency)

	err = s.gcWorker.saveValueToSysTable(gcConcurrencyKey, strconv.Itoa(gcMinConcurrency))
	c.Assert(err, IsNil)
	concurrency, err = s.gcWorker.loadGCConcurrencyWithDefault()
	c.Assert(err, IsNil)
	c.Assert(concurrency, Equals, gcMinConcurrency)

	err = s.gcWorker.saveValueToSysTable(gcConcurrencyKey, strconv.Itoa(-1))
	c.Assert(err, IsNil)
	concurrency, err = s.gcWorker.loadGCConcurrencyWithDefault()
	c.Assert(err, IsNil)
	c.Assert(concurrency, Equals, gcMinConcurrency)

	err = s.gcWorker.saveValueToSysTable(gcConcurrencyKey, strconv.Itoa(1000000))
	c.Assert(err, IsNil)
	concurrency, err = s.gcWorker.loadGCConcurrencyWithDefault()
	c.Assert(err, IsNil)
	c.Assert(concurrency, Equals, gcMaxConcurrency)

	// Change GC enable status.
	s.oracle.AddOffset(time.Minute * 40)
	err = s.gcWorker.saveValueToSysTable(gcEnableKey, gcDisableValue)
	c.Assert(err, IsNil)
	ok, _, err = s.gcWorker.prepare()
	c.Assert(err, IsNil)
	c.Assert(ok, IsFalse)
	err = s.gcWorker.saveValueToSysTable(gcEnableKey, gcEnableValue)
	c.Assert(err, IsNil)
	ok, _, err = s.gcWorker.prepare()
	c.Assert(err, IsNil)
	c.Assert(ok, IsTrue)
}

func (s *testGCWorkerSuite) TestDoGCForOneRegion(c *C) {
	var successRegions int32
	var failedRegions int32
	taskWorker := newGCTaskWorker(s.store, nil, nil, s.gcWorker.uuid, &successRegions, &failedRegions)

	ctx := context.Background()
	bo := tikv.NewBackoffer(ctx, tikv.GcOneRegionMaxBackoff)
	loc, err := s.store.GetRegionCache().LocateKey(bo, []byte(""))
	c.Assert(err, IsNil)
	var regionErr *errorpb.Error
	regionErr, err = taskWorker.doGCForRegion(bo, 20, loc.Region)
	c.Assert(regionErr, IsNil)
	c.Assert(err, IsNil)

	gofail.Enable("github.com/pingcap/tidb/store/tikv/tikvStoreSendReqResult", `return("timeout")`)
	regionErr, err = taskWorker.doGCForRegion(bo, 20, loc.Region)
	c.Assert(regionErr, IsNil)
	c.Assert(err, NotNil)
	gofail.Disable("github.com/pingcap/tidb/store/tikv/tikvStoreSendReqResult")

	gofail.Enable("github.com/pingcap/tidb/store/tikv/tikvStoreSendReqResult", `return("GCNotLeader")`)
	regionErr, err = taskWorker.doGCForRegion(bo, 20, loc.Region)
	c.Assert(regionErr.GetNotLeader(), NotNil)
	c.Assert(err, IsNil)
	gofail.Disable("github.com/pingcap/tidb/store/tikv/tikvStoreSendReqResult")

	gofail.Enable("github.com/pingcap/tidb/store/tikv/tikvStoreSendReqResult", `return("GCServerIsBusy")`)
	regionErr, err = taskWorker.doGCForRegion(bo, 20, loc.Region)
	c.Assert(regionErr.GetServerIsBusy(), NotNil)
	c.Assert(err, IsNil)
	gofail.Disable("github.com/pingcap/tidb/store/tikv/tikvStoreSendReqResult")
}

func (s *testGCWorkerSuite) TestDoGC(c *C) {
	var err error
	ctx := context.Background()

	gcSafePointCacheInterval = 1

	err = s.gcWorker.saveValueToSysTable(gcConcurrencyKey, strconv.Itoa(gcDefaultConcurrency))
	c.Assert(err, IsNil)
	err = s.gcWorker.doGC(ctx, 20)
	c.Assert(err, IsNil)

	err = s.gcWorker.saveValueToSysTable(gcConcurrencyKey, strconv.Itoa(gcMinConcurrency))
	c.Assert(err, IsNil)
	err = s.gcWorker.doGC(ctx, 20)
	c.Assert(err, IsNil)

	err = s.gcWorker.saveValueToSysTable(gcConcurrencyKey, strconv.Itoa(gcMaxConcurrency))
	c.Assert(err, IsNil)
	err = s.gcWorker.doGC(ctx, 20)
	c.Assert(err, IsNil)
}
<|endoftext|>


<commit_before>package version

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"regexp"
)

const (
	url    = "https://raw.githubusercontent.com/efarrer/gmash/blob/master/version/version.go"
	String = "0.0.1"
)

func GetLatestVersion() (string, error) {
	return getLatestVersion(http.Get)
}

func getLatestVersion(get func(string) (*http.Response, error)) (string, error) {
	resp, err := get(url)
	if err != nil {
		return "", err
	}
	defer func() { _ = resp.Body.Close() }()

	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("Invalid response %s", resp.Status)
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	re := regexp.MustCompile("String = \"(.*)\"")
	matches := re.FindSubmatch(body)
	if len(matches) != 2 {
		return "", fmt.Errorf("Unable to find version in \"%s\"", string(body))
	}

	version := string(matches[1])

	return version, nil
}
<commit_msg>Fix the url for finding the latest version<commit_after>package version

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"regexp"
)

const (
	url    = "https://raw.githubusercontent.com/efarrer/gmash/master/version/version.go"
	String = "0.0.1"
)

func GetLatestVersion() (string, error) {
	return getLatestVersion(http.Get)
}

func getLatestVersion(get func(string) (*http.Response, error)) (string, error) {
	resp, err := get(url)
	if err != nil {
		return "", err
	}
	defer func() { _ = resp.Body.Close() }()

	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("Invalid response %s", resp.Status)
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	re := regexp.MustCompile("String = \"(.*)\"")
	matches := re.FindSubmatch(body)
	if len(matches) != 2 {
		return "", fmt.Errorf("Unable to find version in \"%s\"", string(body))
	}

	version := string(matches[1])

	return version, nil
}
<|endoftext|>


<commit_before>package version

// Version is the version of the build.
const Version = "1.2.2"
<commit_msg>Move to v1.2.3-dev<commit_after>package version

// Version is the version of the build.
const Version = "1.2.3-dev"
<|endoftext|>


<commit_before>package version

const Version = "0.3.1+git"
<commit_msg>chore(release): Bump version to v0.3.2<commit_after>package version

const Version = "0.3.2"
<|endoftext|>


<commit_before>// The version package implements version parsing.
// It also acts as guardian of the current client Juju version number.
package version

import (
	"fmt"
	"io/ioutil"
	"labix.org/v2/mgo/bson"
	"os"
	"path/filepath"
	"regexp"
	"runtime"
	"strconv"
	"strings"
)

// The presence and format of this constant is very important.
// The debian/rules build recipe uses this value for the version
// number of the release package.
const version = "1.10.0"

// CurrentNumber returns the version number.
func CurrentNumber() Number {
	return MustParse(version)
}

// CurrentSeries returns the current Ubuntu release name.
func CurrentSeries() string {
	return readSeries("/etc/lsb-release")
}

// CurrentArch returns the architecture of the machine.
func CurrentArch() string {
	return ubuntuArch(runtime.GOARCH)
}

// Current gives the current version of the system.  If the file
// "FORCE-VERSION" is present in the same directory as the running
// binary, it will override this.
var Current = Binary{
	Number: CurrentNumber(),
	Series: CurrentSeries(),
	Arch:   CurrentArch(),
}

func init() {
	toolsDir := filepath.Dir(os.Args[0])
	v, err := ioutil.ReadFile(filepath.Join(toolsDir, "FORCE-VERSION"))
	if err != nil {
		if os.IsNotExist(err) {
			return
		}
		panic(fmt.Errorf("version: cannot read forced version: %v", err))
	}
	Current.Number = MustParse(strings.TrimSpace(string(v)))
}

// Number represents a juju version.  When bugs are fixed the patch
// number is incremented; when new features are added the minor number
// is incremented and patch is reset; and when compatibility is broken
// the major version is incremented and minor and patch are reset.  The
// build number is automatically assigned and has no well defined
// sequence.  If the build number is greater than zero or the minor
// version is odd, it indicates that the release is still in
// development.
type Number struct {
	Major int
	Minor int
	Patch int
	Build int
}

// Zero is occasionally convenient and readable.
// Please don't change its value.
var Zero = Number{}

// Binary specifies a binary version of juju.
type Binary struct {
	Number
	Series string
	Arch   string
}

func (v Binary) String() string {
	return fmt.Sprintf("%v-%s-%s", v.Number, v.Series, v.Arch)
}

// GetBSON turns v into a bson.Getter so it can be saved directly
// on a MongoDB database with mgo.
func (v Binary) GetBSON() (interface{}, error) {
	return v.String(), nil
}

// SetBSON turns v into a bson.Setter so it can be loaded directly
// from a MongoDB database with mgo.
func (vp *Binary) SetBSON(raw bson.Raw) error {
	var s string
	err := raw.Unmarshal(&s)
	if err != nil {
		return err
	}
	v, err := ParseBinary(s)
	if err != nil {
		return err
	}
	*vp = v
	return nil
}

var (
	binaryPat = regexp.MustCompile(`^(\d{1,9})\.(\d{1,9})\.(\d{1,9})(\.\d{1,9})?-([^-]+)-([^-]+)$`)
	numberPat = regexp.MustCompile(`^(\d{1,9})\.(\d{1,9})\.(\d{1,9})(\.\d{1,9})?$`)
)

// MustParse parses a version and panics if it does
// not parse correctly.
func MustParse(s string) Number {
	v, err := Parse(s)
	if err != nil {
		panic(err)
	}
	return v
}

// MustParseBinary parses a binary version and panics if it does
// not parse correctly.
func MustParseBinary(s string) Binary {
	v, err := ParseBinary(s)
	if err != nil {
		panic(err)
	}
	return v
}

// ParseBinary parses a binary version of the form "1.2.3-series-arch".
func ParseBinary(s string) (Binary, error) {
	m := binaryPat.FindStringSubmatch(s)
	if m == nil {
		return Binary{}, fmt.Errorf("invalid binary version %q", s)
	}
	var v Binary
	v.Major = atoi(m[1])
	v.Minor = atoi(m[2])
	v.Patch = atoi(m[3])
	if m[4] != "" {
		v.Build = atoi(m[4][1:])
	}
	v.Series = m[5]
	v.Arch = m[6]
	return v, nil
}

// Parse parses the version, which is of the form 1.2.3
// giving the major, minor and release versions
// respectively.
func Parse(s string) (Number, error) {
	m := numberPat.FindStringSubmatch(s)
	if m == nil {
		return Number{}, fmt.Errorf("invalid version %q", s)
	}
	var v Number
	v.Major = atoi(m[1])
	v.Minor = atoi(m[2])
	v.Patch = atoi(m[3])
	if m[4] != "" {
		v.Build = atoi(m[4][1:])
	}
	return v, nil
}

// atoi is the same as strconv.Atoi but assumes that
// the string has been verified to be a valid integer.
func atoi(s string) int {
	n, err := strconv.Atoi(s)
	if err != nil {
		panic(err)
	}
	return n
}

func (v Number) String() string {
	s := fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch)
	if v.Build > 0 {
		s += fmt.Sprintf(".%d", v.Build)
	}
	return s
}

// Less returns whether v is semantically earlier in the
// version sequence than w.
func (v Number) Less(w Number) bool {
	switch {
	case v.Major != w.Major:
		return v.Major < w.Major
	case v.Minor != w.Minor:
		return v.Minor < w.Minor
	case v.Patch != w.Patch:
		return v.Patch < w.Patch
	case v.Build != w.Build:
		return v.Build < w.Build
	}
	return false
}

// GetBSON turns v into a bson.Getter so it can be saved directly
// on a MongoDB database with mgo.
func (v Number) GetBSON() (interface{}, error) {
	return v.String(), nil
}

// SetBSON turns v into a bson.Setter so it can be loaded directly
// from a MongoDB database with mgo.
func (vp *Number) SetBSON(raw bson.Raw) error {
	var s string
	err := raw.Unmarshal(&s)
	if err != nil {
		return err
	}
	v, err := Parse(s)
	if err != nil {
		return err
	}
	*vp = v
	return nil
}

func isOdd(x int) bool {
	return x%2 != 0
}

// IsDev returns whether the version represents a development
// version. A version with an odd-numbered minor component or
// a nonzero build component is considered to be a development
// version.
func (v Number) IsDev() bool {
	return isOdd(v.Minor) || v.Build > 0
}

func readSeries(releaseFile string) string {
	data, err := ioutil.ReadFile(releaseFile)
	if err != nil {
		return "unknown"
	}
	for _, line := range strings.Split(string(data), "\n") {
		const p = "DISTRIB_CODENAME="
		if strings.HasPrefix(line, p) {
			return strings.Trim(line[len(p):], "\t '\"")
		}
	}
	return "unknown"
}

func ubuntuArch(arch string) string {
	if arch == "386" {
		arch = "i386"
	}
	return arch
}
<commit_msg>change version number back to accommodate a few more fixes before EOD<commit_after>// The version package implements version parsing.
// It also acts as guardian of the current client Juju version number.
package version

import (
	"fmt"
	"io/ioutil"
	"labix.org/v2/mgo/bson"
	"os"
	"path/filepath"
	"regexp"
	"runtime"
	"strconv"
	"strings"
)

// The presence and format of this constant is very important.
// The debian/rules build recipe uses this value for the version
// number of the release package.
const version = "1.9.15"

// CurrentNumber returns the version number.
func CurrentNumber() Number {
	return MustParse(version)
}

// CurrentSeries returns the current Ubuntu release name.
func CurrentSeries() string {
	return readSeries("/etc/lsb-release")
}

// CurrentArch returns the architecture of the machine.
func CurrentArch() string {
	return ubuntuArch(runtime.GOARCH)
}

// Current gives the current version of the system.  If the file
// "FORCE-VERSION" is present in the same directory as the running
// binary, it will override this.
var Current = Binary{
	Number: CurrentNumber(),
	Series: CurrentSeries(),
	Arch:   CurrentArch(),
}

func init() {
	toolsDir := filepath.Dir(os.Args[0])
	v, err := ioutil.ReadFile(filepath.Join(toolsDir, "FORCE-VERSION"))
	if err != nil {
		if os.IsNotExist(err) {
			return
		}
		panic(fmt.Errorf("version: cannot read forced version: %v", err))
	}
	Current.Number = MustParse(strings.TrimSpace(string(v)))
}

// Number represents a juju version.  When bugs are fixed the patch
// number is incremented; when new features are added the minor number
// is incremented and patch is reset; and when compatibility is broken
// the major version is incremented and minor and patch are reset.  The
// build number is automatically assigned and has no well defined
// sequence.  If the build number is greater than zero or the minor
// version is odd, it indicates that the release is still in
// development.
type Number struct {
	Major int
	Minor int
	Patch int
	Build int
}

// Zero is occasionally convenient and readable.
// Please don't change its value.
var Zero = Number{}

// Binary specifies a binary version of juju.
type Binary struct {
	Number
	Series string
	Arch   string
}

func (v Binary) String() string {
	return fmt.Sprintf("%v-%s-%s", v.Number, v.Series, v.Arch)
}

// GetBSON turns v into a bson.Getter so it can be saved directly
// on a MongoDB database with mgo.
func (v Binary) GetBSON() (interface{}, error) {
	return v.String(), nil
}

// SetBSON turns v into a bson.Setter so it can be loaded directly
// from a MongoDB database with mgo.
func (vp *Binary) SetBSON(raw bson.Raw) error {
	var s string
	err := raw.Unmarshal(&s)
	if err != nil {
		return err
	}
	v, err := ParseBinary(s)
	if err != nil {
		return err
	}
	*vp = v
	return nil
}

var (
	binaryPat = regexp.MustCompile(`^(\d{1,9})\.(\d{1,9})\.(\d{1,9})(\.\d{1,9})?-([^-]+)-([^-]+)$`)
	numberPat = regexp.MustCompile(`^(\d{1,9})\.(\d{1,9})\.(\d{1,9})(\.\d{1,9})?$`)
)

// MustParse parses a version and panics if it does
// not parse correctly.
func MustParse(s string) Number {
	v, err := Parse(s)
	if err != nil {
		panic(err)
	}
	return v
}

// MustParseBinary parses a binary version and panics if it does
// not parse correctly.
func MustParseBinary(s string) Binary {
	v, err := ParseBinary(s)
	if err != nil {
		panic(err)
	}
	return v
}

// ParseBinary parses a binary version of the form "1.2.3-series-arch".
func ParseBinary(s string) (Binary, error) {
	m := binaryPat.FindStringSubmatch(s)
	if m == nil {
		return Binary{}, fmt.Errorf("invalid binary version %q", s)
	}
	var v Binary
	v.Major = atoi(m[1])
	v.Minor = atoi(m[2])
	v.Patch = atoi(m[3])
	if m[4] != "" {
		v.Build = atoi(m[4][1:])
	}
	v.Series = m[5]
	v.Arch = m[6]
	return v, nil
}

// Parse parses the version, which is of the form 1.2.3
// giving the major, minor and release versions
// respectively.
func Parse(s string) (Number, error) {
	m := numberPat.FindStringSubmatch(s)
	if m == nil {
		return Number{}, fmt.Errorf("invalid version %q", s)
	}
	var v Number
	v.Major = atoi(m[1])
	v.Minor = atoi(m[2])
	v.Patch = atoi(m[3])
	if m[4] != "" {
		v.Build = atoi(m[4][1:])
	}
	return v, nil
}

// atoi is the same as strconv.Atoi but assumes that
// the string has been verified to be a valid integer.
func atoi(s string) int {
	n, err := strconv.Atoi(s)
	if err != nil {
		panic(err)
	}
	return n
}

func (v Number) String() string {
	s := fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch)
	if v.Build > 0 {
		s += fmt.Sprintf(".%d", v.Build)
	}
	return s
}

// Less returns whether v is semantically earlier in the
// version sequence than w.
func (v Number) Less(w Number) bool {
	switch {
	case v.Major != w.Major:
		return v.Major < w.Major
	case v.Minor != w.Minor:
		return v.Minor < w.Minor
	case v.Patch != w.Patch:
		return v.Patch < w.Patch
	case v.Build != w.Build:
		return v.Build < w.Build
	}
	return false
}

// GetBSON turns v into a bson.Getter so it can be saved directly
// on a MongoDB database with mgo.
func (v Number) GetBSON() (interface{}, error) {
	return v.String(), nil
}

// SetBSON turns v into a bson.Setter so it can be loaded directly
// from a MongoDB database with mgo.
func (vp *Number) SetBSON(raw bson.Raw) error {
	var s string
	err := raw.Unmarshal(&s)
	if err != nil {
		return err
	}
	v, err := Parse(s)
	if err != nil {
		return err
	}
	*vp = v
	return nil
}

func isOdd(x int) bool {
	return x%2 != 0
}

// IsDev returns whether the version represents a development
// version. A version with an odd-numbered minor component or
// a nonzero build component is considered to be a development
// version.
func (v Number) IsDev() bool {
	return isOdd(v.Minor) || v.Build > 0
}

func readSeries(releaseFile string) string {
	data, err := ioutil.ReadFile(releaseFile)
	if err != nil {
		return "unknown"
	}
	for _, line := range strings.Split(string(data), "\n") {
		const p = "DISTRIB_CODENAME="
		if strings.HasPrefix(line, p) {
			return strings.Trim(line[len(p):], "\t '\"")
		}
	}
	return "unknown"
}

func ubuntuArch(arch string) string {
	if arch == "386" {
		arch = "i386"
	}
	return arch
}
<|endoftext|>


<commit_before>// The version package provides a location to set the release versions for all
// packages to consume, without creating import cycles.
//
// This package should not import any other terraform packages.
package version

import (
	"fmt"

	version "github.com/hashicorp/go-version"
)

// The main version number that is being run at the moment.
var Version = "1.1.0"

// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
// such as "dev" (in development), "beta", "rc1", etc.
var Prerelease = "alpha20210630"

// SemVer is an instance of version.Version. This has the secondary
// benefit of verifying during tests and init time that our version is a
// proper semantic version, which should always be the case.
var SemVer *version.Version

func init() {
	SemVer = version.Must(version.NewVersion(Version))
}

// Header is the header name used to send the current terraform version
// in http requests.
const Header = "Terraform-Version"

// String returns the complete version string, including prerelease
func String() string {
	if Prerelease != "" {
		return fmt.Sprintf("%s-%s", Version, Prerelease)
	}
	return Version
}
<commit_msg>Cleanup after v1.1.0-alpha20210630 release<commit_after>// The version package provides a location to set the release versions for all
// packages to consume, without creating import cycles.
//
// This package should not import any other terraform packages.
package version

import (
	"fmt"

	version "github.com/hashicorp/go-version"
)

// The main version number that is being run at the moment.
var Version = "1.1.0"

// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
// such as "dev" (in development), "beta", "rc1", etc.
var Prerelease = "dev"

// SemVer is an instance of version.Version. This has the secondary
// benefit of verifying during tests and init time that our version is a
// proper semantic version, which should always be the case.
var SemVer *version.Version

func init() {
	SemVer = version.Must(version.NewVersion(Version))
}

// Header is the header name used to send the current terraform version
// in http requests.
const Header = "Terraform-Version"

// String returns the complete version string, including prerelease
func String() string {
	if Prerelease != "" {
		return fmt.Sprintf("%s-%s", Version, Prerelease)
	}
	return Version
}
<|endoftext|>


<commit_before>package version

import "fmt"

const (
	// VersionMajor is for an API incompatible changes
	VersionMajor = 5
	// VersionMinor is for functionality in a backwards-compatible manner
	VersionMinor = 4
	// VersionPatch is for backwards-compatible bug fixes
	VersionPatch = 1

	// VersionDev indicates development branch. Releases will be empty string.
	VersionDev = ""
)

// Version is the specification version that the package types support.
var Version = fmt.Sprintf("%d.%d.%d%s", VersionMajor, VersionMinor, VersionPatch, VersionDev)
<commit_msg>Bump version to 5.4.2-dev<commit_after>package version

import "fmt"

const (
	// VersionMajor is for an API incompatible changes
	VersionMajor = 5
	// VersionMinor is for functionality in a backwards-compatible manner
	VersionMinor = 4
	// VersionPatch is for backwards-compatible bug fixes
	VersionPatch = 2

	// VersionDev indicates development branch. Releases will be empty string.
	VersionDev = "-dev"
)

// Version is the specification version that the package types support.
var Version = fmt.Sprintf("%d.%d.%d%s", VersionMajor, VersionMinor, VersionPatch, VersionDev)
<|endoftext|>


<commit_before>package version

// Package is the overall, canonical project import path under which the
// package was built.
var Package = "github.com/docker/distribution"

// Version indicates which version of the binary is running. This is set to
// the latest release tag by hand, always suffixed by "+unknown". During
// build, it will be replaced by the actual version. The value here will be
// used if the registry is run after a go get based install.
var Version = "v2.6.0+unknown"

// Revision is filled with the VCS (e.g. git) revision being used to build
// the program at linking time.
var Revision = ""
<commit_msg>Update version to 2.7.0-rc.0<commit_after>package version

// Package is the overall, canonical project import path under which the
// package was built.
var Package = "github.com/docker/distribution"

// Version indicates which version of the binary is running. This is set to
// the latest release tag by hand, always suffixed by "+unknown". During
// build, it will be replaced by the actual version. The value here will be
// used if the registry is run after a go get based install.
var Version = "v2.7.0-rc.0+unknown"

// Revision is filled with the VCS (e.g. git) revision being used to build
// the program at linking time.
var Revision = ""
<|endoftext|>


<commit_before>package version

import (
	"bytes"
	"fmt"
)

// The git commit that was compiled. This will be filled in by the compiler.
var GitCommit string
var GitDescribe string

// The main version number that is being run at the moment.
const Version = "0.4.0"

// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
// such as "dev" (in development), "beta", "rc1", etc.
const VersionPrerelease = "dev"

// VersionInfo
type VersionInfo struct {
	Revision          string
	Version           string
	VersionPrerelease string
}

func GetVersion() *VersionInfo {
	ver := Version
	rel := VersionPrerelease
	if GitDescribe != "" {
		ver = GitDescribe
	}
	if GitDescribe == "" && rel == "" && VersionPrerelease != "" {
		rel = "dev"
	}

	return &VersionInfo{
		Revision:          GitCommit,
		Version:           ver,
		VersionPrerelease: rel,
	}
}

func (c *VersionInfo) String() string {
	var versionString bytes.Buffer

	fmt.Fprintf(&versionString, "Vault v%s", c.Version)
	if c.VersionPrerelease != "" {
		fmt.Fprintf(&versionString, "-%s", c.VersionPrerelease)

		if c.Revision != "" {
			fmt.Fprintf(&versionString, " (%s)", c.Revision)
		}
	}

	return versionString.String()
}
<commit_msg>Bump version to 0.4.0-rc1<commit_after>package version

import (
	"bytes"
	"fmt"
)

// The git commit that was compiled. This will be filled in by the compiler.
var GitCommit string
var GitDescribe string

// The main version number that is being run at the moment.
const Version = "0.4.0"

// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
// such as "dev" (in development), "beta", "rc1", etc.
const VersionPrerelease = "rc1"

// VersionInfo
type VersionInfo struct {
	Revision          string
	Version           string
	VersionPrerelease string
}

func GetVersion() *VersionInfo {
	ver := Version
	rel := VersionPrerelease
	if GitDescribe != "" {
		ver = GitDescribe
	}
	if GitDescribe == "" && rel == "" && VersionPrerelease != "" {
		rel = "dev"
	}

	return &VersionInfo{
		Revision:          GitCommit,
		Version:           ver,
		VersionPrerelease: rel,
	}
}

func (c *VersionInfo) String() string {
	var versionString bytes.Buffer

	fmt.Fprintf(&versionString, "Vault v%s", c.Version)
	if c.VersionPrerelease != "" {
		fmt.Fprintf(&versionString, "-%s", c.VersionPrerelease)

		if c.Revision != "" {
			fmt.Fprintf(&versionString, " (%s)", c.Revision)
		}
	}

	return versionString.String()
}
<|endoftext|>


<commit_before>package version

var (
	Version   = "3.0.5"
	GitCommit = "HEAD"
)
<commit_msg>bump to v 3.1<commit_after>package version

var (
	Version   = "3.1.0"
	GitCommit = "HEAD"
)
<|endoftext|>


<commit_before>package version

// Version is the version of the build.
const Version = "0.1.27"
<commit_msg>version: bump to v0.1.28-dev<commit_after>package version

// Version is the version of the build.
const Version = "0.1.28-dev"
<|endoftext|>


<commit_before>package version

// Version is the version of the build.
const Version = "0.1.17"
<commit_msg>bump to v0.1.18-dev<commit_after>package version

// Version is the version of the build.
const Version = "0.1.18-dev"
<|endoftext|>


<commit_before>// The version package provides a location to set the release versions for all
// packages to consume, without creating import cycles.
//
// This pckage should not import any other terraform packages.
package version

import (
	"fmt"

	version "github.com/hashicorp/go-version"
)

// The main version number that is being run at the moment.
const Version = "0.11.2"

// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
// such as "dev" (in development), "beta", "rc1", etc.
var Prerelease = ""

// SemVer is an instance of version.Version. This has the secondary
// benefit of verifying during tests and init time that our version is a
// proper semantic version, which should always be the case.
var SemVer = version.Must(version.NewVersion(Version))

// Header is the header name used to send the current terraform version
// in http requests.
const Header = "Terraform-Version"

// String returns the complete version string, including prerelease
func String() string {
	if Prerelease != "" {
		return fmt.Sprintf("%s-%s", Version, Prerelease)
	}
	return Version
}
<commit_msg>release: clean up after v0.11.2<commit_after>// The version package provides a location to set the release versions for all
// packages to consume, without creating import cycles.
//
// This pckage should not import any other terraform packages.
package version

import (
	"fmt"

	version "github.com/hashicorp/go-version"
)

// The main version number that is being run at the moment.
const Version = "0.11.3"

// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
// such as "dev" (in development), "beta", "rc1", etc.
var Prerelease = "dev"

// SemVer is an instance of version.Version. This has the secondary
// benefit of verifying during tests and init time that our version is a
// proper semantic version, which should always be the case.
var SemVer = version.Must(version.NewVersion(Version))

// Header is the header name used to send the current terraform version
// in http requests.
const Header = "Terraform-Version"

// String returns the complete version string, including prerelease
func String() string {
	if Prerelease != "" {
		return fmt.Sprintf("%s-%s", Version, Prerelease)
	}
	return Version
}
<|endoftext|>


<commit_before>package version

const (
	Version = "0.1.8+git"
)
<commit_msg>version: 0.1.9 bump<commit_after>package version

const (
	Version = "0.1.9"
)
<|endoftext|>


<commit_before>package version

// Version is the version of the build.
const Version = "0.1.19"
<commit_msg>bump again to v0.1.20-dev<commit_after>package version

// Version is the version of the build.
const Version = "0.1.20-dev"
<|endoftext|>


<commit_before>package btrfs

import (
	"bytes"
	"io/ioutil"
	"os"
	"strings"
	"testing"

	"github.com/pachyderm/pachyderm/src/pfs"
	"github.com/pachyderm/pachyderm/src/pkg/require"
)

var (
	counter int32
)

func TestSimple(t *testing.T) {
	driver1, err := NewDriver(getBtrfsRootDir(t), "drive.TestSimple")
	require.NoError(t, err)
	shards := make(map[uint64]bool)
	shards[0] = true
	repo := &pfs.Repo{Name: "repo1"}
	require.NoError(t, driver1.CreateRepo(repo))
	commit1 := &pfs.Commit{
		Repo: repo,
		Id:   "commit1",
	}
	require.NoError(t, driver1.StartCommit(nil, commit1, shards))
	file1 := &pfs.File{
		Commit: commit1,
		Path:   "foo",
	}
	require.NoError(t, driver1.PutFile(file1, 0, 0, strings.NewReader("foo")))
	require.NoError(t, driver1.FinishCommit(commit1, shards))
	reader, err := driver1.GetFile(file1, 0)
	require.NoError(t, err)
	contents, err := ioutil.ReadAll(reader)
	require.NoError(t, err)
	require.Equal(t, string(contents), "foo")
	commit2 := &pfs.Commit{
		Repo: repo,
		Id:   "commit2",
	}
	require.NoError(t, driver1.StartCommit(commit1, commit2, shards))
	file2 := &pfs.File{
		Commit: commit2,
		Path:   "bar",
	}
	require.NoError(t, driver1.PutFile(file2, 0, 0, strings.NewReader("bar")))
	require.NoError(t, driver1.FinishCommit(commit2, shards))
	changes, err := driver1.ListChange(file2, commit1, 0)
	require.NoError(t, err)
	require.Equal(t, len(changes), 1)
	require.Equal(t, changes[0].File, file2)
	require.Equal(t, changes[0].OffsetBytes, uint64(0))
	require.Equal(t, changes[0].SizeBytes, uint64(3))
	//Replicate repo
	driver2, err := NewDriver(getBtrfsRootDir(t), "drive.TestSimpleReplica")
	require.NoError(t, err)
	require.NoError(t, driver2.CreateRepo(repo))
	var buffer bytes.Buffer
	require.NoError(t, driver1.PullDiff(commit1, 0, &buffer))
	require.NoError(t, driver2.PushDiff(commit1, 0, &buffer))
	buffer = bytes.Buffer{}
	require.NoError(t, driver1.PullDiff(commit2, 0, &buffer))
	require.NoError(t, driver2.PushDiff(commit2, 0, &buffer))
	reader, err = driver2.GetFile(file1, 0)
	require.NoError(t, err)
	contents, err = ioutil.ReadAll(reader)
	require.NoError(t, err)
	require.Equal(t, string(contents), "foo")
	changes, err = driver2.ListChange(file2, commit1, 0)
	require.NoError(t, err)
	require.Equal(t, len(changes), 1)
	require.Equal(t, changes[0].File, file2)
	require.Equal(t, changes[0].OffsetBytes, uint64(0))
	require.Equal(t, changes[0].SizeBytes, uint64(3))
}

func getBtrfsRootDir(tb testing.TB) string {
	// TODO
	rootDir := os.Getenv("PFS_DRIVER_ROOT")
	if rootDir == "" {
		tb.Fatal("PFS_DRIVER_ROOT not set")
	}
	return rootDir
}
<commit_msg>Adds a test for reordered commits.<commit_after>package btrfs

import (
	"bytes"
	"io/ioutil"
	"os"
	"strings"
	"testing"

	"github.com/pachyderm/pachyderm/src/pfs"
	"github.com/pachyderm/pachyderm/src/pkg/require"
)

var (
	counter int32
)

func TestSimple(t *testing.T) {
	driver1, err := NewDriver(getBtrfsRootDir(t), "drive.TestSimple")
	require.NoError(t, err)
	shards := make(map[uint64]bool)
	shards[0] = true
	repo := &pfs.Repo{Name: "repo1"}
	require.NoError(t, driver1.CreateRepo(repo))
	commit1 := &pfs.Commit{
		Repo: repo,
		Id:   "commit1",
	}
	require.NoError(t, driver1.StartCommit(nil, commit1, shards))
	file1 := &pfs.File{
		Commit: commit1,
		Path:   "foo",
	}
	require.NoError(t, driver1.PutFile(file1, 0, 0, strings.NewReader("foo")))
	require.NoError(t, driver1.FinishCommit(commit1, shards))
	reader, err := driver1.GetFile(file1, 0)
	require.NoError(t, err)
	contents, err := ioutil.ReadAll(reader)
	require.NoError(t, err)
	require.Equal(t, string(contents), "foo")
	commit2 := &pfs.Commit{
		Repo: repo,
		Id:   "commit2",
	}
	require.NoError(t, driver1.StartCommit(commit1, commit2, shards))
	file2 := &pfs.File{
		Commit: commit2,
		Path:   "bar",
	}
	require.NoError(t, driver1.PutFile(file2, 0, 0, strings.NewReader("bar")))
	require.NoError(t, driver1.FinishCommit(commit2, shards))
	changes, err := driver1.ListChange(file2, commit1, 0)
	require.NoError(t, err)
	require.Equal(t, len(changes), 1)
	require.Equal(t, changes[0].File, file2)
	require.Equal(t, changes[0].OffsetBytes, uint64(0))
	require.Equal(t, changes[0].SizeBytes, uint64(3))
	//Replicate repo
	driver2, err := NewDriver(getBtrfsRootDir(t), "drive.TestSimpleReplica")
	require.NoError(t, err)
	require.NoError(t, driver2.CreateRepo(repo))
	var buffer bytes.Buffer
	require.NoError(t, driver1.PullDiff(commit1, 0, &buffer))
	require.NoError(t, driver2.PushDiff(commit1, 0, &buffer))
	buffer = bytes.Buffer{}
	require.NoError(t, driver1.PullDiff(commit2, 0, &buffer))
	require.NoError(t, driver2.PushDiff(commit2, 0, &buffer))
	reader, err = driver2.GetFile(file1, 0)
	require.NoError(t, err)
	contents, err = ioutil.ReadAll(reader)
	require.NoError(t, err)
	require.Equal(t, string(contents), "foo")
	changes, err = driver2.ListChange(file2, commit1, 0)
	require.NoError(t, err)
	require.Equal(t, len(changes), 1)
	require.Equal(t, changes[0].File, file2)
	require.Equal(t, changes[0].OffsetBytes, uint64(0))
	require.Equal(t, changes[0].SizeBytes, uint64(3))
}

func TestCommitReordering(t *testing.T) {
	driver1, err := NewDriver(getBtrfsRootDir(t), "drive.TestCommitReordering")
	require.NoError(t, err)
	shards := make(map[uint64]bool)
	shards[0] = true
	repo := &pfs.Repo{Name: "repo1"}
	require.NoError(t, driver1.CreateRepo(repo))
	commit1 := &pfs.Commit{
		Repo: repo,
		Id:   "commit1",
	}
	require.NoError(t, driver1.StartCommit(nil, commit1, shards))
	require.NoError(t, driver1.FinishCommit(commit1, shards))
	commit2 := &pfs.Commit{
		Repo: repo,
		Id:   "commit2",
	}
	require.NoError(t, driver1.StartCommit(commit1, commit2, shards))
	commit3 := &pfs.Commit{
		Repo: repo,
		Id:   "commit3",
	}
	require.NoError(t, driver1.StartCommit(commit1, commit3, shards))
	require.NoError(t, driver1.FinishCommit(commit3, shards))
	require.NoError(t, driver1.FinishCommit(commit2, shards))

	commitInfos, err := driver1.ListCommit(repo, nil, shards)
	require.NoError(t, err)
	require.Equal(t, 3, len(commitInfos))
	require.Equal(t, commitInfos[0].Commit.Id, "commit3")
	require.Equal(t, commitInfos[1].Commit.Id, "commit2")
	require.Equal(t, commitInfos[2].Commit.Id, "commit1")
	//Replicate repo
	driver2, err := NewDriver(getBtrfsRootDir(t), "drive.TestCommitReorderingReplica")
	require.NoError(t, err)
	require.NoError(t, driver2.CreateRepo(repo))
	var buffer bytes.Buffer
	require.NoError(t, driver1.PullDiff(commit1, 0, &buffer))
	require.NoError(t, driver2.PushDiff(commit1, 0, &buffer))
	buffer = bytes.Buffer{}
	require.NoError(t, driver1.PullDiff(commit3, 0, &buffer))
	require.NoError(t, driver2.PushDiff(commit3, 0, &buffer))
	buffer = bytes.Buffer{}
	require.NoError(t, driver1.PullDiff(commit2, 0, &buffer))
	require.NoError(t, driver2.PushDiff(commit2, 0, &buffer))
	commitInfos, err = driver2.ListCommit(repo, nil, shards)
	require.NoError(t, err)
	require.Equal(t, 3, len(commitInfos))
	require.Equal(t, commitInfos[0].Commit.Id, "commit2")
	require.Equal(t, commitInfos[1].Commit.Id, "commit3")
	require.Equal(t, commitInfos[2].Commit.Id, "commit1")
}

func getBtrfsRootDir(tb testing.TB) string {
	// TODO
	rootDir := os.Getenv("PFS_DRIVER_ROOT")
	if rootDir == "" {
		tb.Fatal("PFS_DRIVER_ROOT not set")
	}
	return rootDir
}
<|endoftext|>


<commit_before>package containers

import (
	"atlantis/crypto"
	"atlantis/supervisor/rpc/types"
	"fmt"
	"github.com/jigish/go-dockerclient"
	"log"
	"os"
	"os/exec"
	"regexp"
	"strings"
	"sync"
)

var (
	dockerIdRegexp = regexp.MustCompile("^[A-Za-z0-9]+$")
	dockerLock     = sync.Mutex{}
	dockerClient   *docker.Client
)

type Container types.Container
type SSHCmd []string

func DockerInit() (err error) {
	dockerClient, err = docker.NewClient("unix:///var/run/docker.sock")
	return
}

func pretending() bool {
	return os.Getenv("SUPERVISOR_PRETEND") != ""
}

func (s SSHCmd) Execute() error {
	if pretending() {
		log.Printf("[pretend] ssh %s", strings.Join(s, " "))
		return nil
	}
	log.Printf("ssh %s", strings.Join(s, " "))
	cmd := exec.Command("ssh", s...)
	output, err := cmd.CombinedOutput()
	log.Printf("-> %s", output)
	if err != nil {
		log.Println("-> Error:", err)
	}
	return err
}

func removeExited() {
	if pretending() {
		return
	}
	dockerLock.Lock()
	defer dockerLock.Unlock()
	containers, err := dockerClient.ListContainers(docker.ListContainersOptions{All: true})
	if err != nil {
		log.Printf("[RemoveExited] could not list containers: %v", err)
		return
	}
	for _, cont := range containers {
		log.Printf("[RemoveExited] checking %s (%v) : %s", cont.ID, cont.Names, cont.Status)
		if !strings.HasPrefix(cont.Status, "Exit") {
			continue
		}
		log.Printf("[RemoveExited] remove %s (%v)", cont.ID, cont.Names)
		err := dockerClient.RemoveContainer(cont.ID)
		if err != nil {
			log.Printf("[RemoveExited] -> error: %v", err)
		} else {
			log.Printf("[RemoveExited] -> success")
		}
	}
}

func restartGhost() {
	if pretending() {
		return
	}
	dockerLock.Lock()
	defer dockerLock.Unlock()
	containers, err := dockerClient.ListContainers(docker.ListContainersOptions{All: true})
	if err != nil {
		log.Printf("[RestartGhost] could not list containers: %v", err)
		return
	}
	hadError := false
	for _, cont := range containers {
		log.Printf("[RestartGhost] checking %s (%v) : %s", cont.ID, cont.Names, cont.Status)
		if !strings.HasPrefix(cont.Status, "Ghost") {
			continue
		}
		log.Printf("[RestartGhost] restart %s (%v)", cont.ID, cont.Names)
		err := dockerClient.RestartContainer(cont.ID, 0)
		if err != nil {
			hadError = true
			log.Printf("[RestartGhost] -> error: %v", err)
		} else {
			log.Printf("[RestartGhost] -> success")
		}
	}
	if hadError {
		log.Printf("[RestartGhost] attempting to force restart (restarting docker daemon)")
		cmd := exec.Command("sudo", "service docker restart")
		output, err := cmd.CombinedOutput()
		log.Printf("-> %s", output)
		if err != nil {
			log.Println("-> Error:", err)
		}
	}
}

func (c *Container) dockerCfgs(repo string) (*docker.Config, *docker.HostConfig) {
	// get env cfg
	envs := []string{
		"ATLANTIS=true",
		fmt.Sprintf("CONTAINER_ID=%s", c.Id),
		fmt.Sprintf("CONTAINER_HOST=%s", c.Host),
		fmt.Sprintf("CONTAINER_ENV=%s", c.Env),
		fmt.Sprintf("HTTP_PORT=%d", c.PrimaryPort),
		fmt.Sprintf("SSHD_PORT=%d", c.SSHPort),
	}
	if c.Manifest.Deps != nil {
		for name, value := range c.Manifest.Deps {
			envs = append(envs, fmt.Sprintf("%s=%s", name, crypto.Decrypt([]byte(value))))
		}
	}

	// get port cfg
	exposedPorts := map[docker.Port]struct{}{}
	portBindings := map[docker.Port][]docker.PortBinding{}
	sPrimaryPort := fmt.Sprintf("%d", c.PrimaryPort)
	dPrimaryPort := docker.NewPort("tcp", sPrimaryPort)
	exposedPorts[dPrimaryPort] = struct{}{}
	portBindings[dPrimaryPort] = []docker.PortBinding{docker.PortBinding{
		HostIp:   "",
		HostPort: fmt.Sprintf("%d", sPrimaryPort),
	}}
	sSSHPort := fmt.Sprintf("%d", c.SSHPort)
	dSSHPort := docker.NewPort("tcp", sSSHPort)
	exposedPorts[dSSHPort] = struct{}{}
	portBindings[dSSHPort] = []docker.PortBinding{docker.PortBinding{
		HostIp:   "",
		HostPort: sSSHPort,
	}}
	for i, port := range c.SecondaryPorts {
		sPort := fmt.Sprintf("%d", port)
		dPort := docker.NewPort("tcp", sPort)
		exposedPorts[dPort] = struct{}{}
		portBindings[dPort] = []docker.PortBinding{docker.PortBinding{
			HostIp:   "",
			HostPort: sPort,
		}}
		envs = append(envs, fmt.Sprintf("SECONDARY_PORT%d=%d", i, port))
	}

	// setup actual cfg
	dCfg := &docker.Config{
		CpuShares:    int64(c.Manifest.CPUShares),
		Memory:       int64(c.Manifest.MemoryLimit) * int64(1024*1024), // this is in bytes
		MemorySwap:   int64(-1),                                        // -1 turns swap off
		ExposedPorts: exposedPorts,
		Env:          envs,
		Cmd:          []string{}, // images already specify run command
		Image:        fmt.Sprintf("%s/%s", RegistryHost, repo),
		Volumes:      map[string]struct{}{"/var/log/atlantis/syslog": struct{}{}},
	}
	dHostCfg := &docker.HostConfig{
		PortBindings: portBindings,
		LxcConf:      []docker.KeyValuePair{},
		Binds:        []string{fmt.Sprintf("/var/log/atlantis/containers/%s:/var/log/atlantis/syslog", c.Id)},
	}
	return dCfg, dHostCfg
}

// Deploy the given app+sha with the dependencies defined in deps. This will spin up a new docker container.
func (c *Container) Deploy(host, app, sha, env string) error {
	c.Host = host
	c.App = app
	c.Sha = sha
	c.Env = env
	dRepo := fmt.Sprintf("apps/%s-%s", c.App, c.Sha)
	if pretending() {
	} else {
	}
	// Pull docker container
	if pretending() {
		log.Printf("[pretend] deploy %s with %s @ %s...", c.Id, c.App, c.Sha)
		log.Printf("[pretend] docker pull %s/%s", RegistryHost, dRepo)
		log.Printf("[pretend] docker run %s/%s", RegistryHost, dRepo)
		c.DockerId = fmt.Sprintf("pretend-docker-id-%d", c.PrimaryPort)
	} else {
		log.Printf("deploy %s with %s @ %s...", c.Id, c.App, c.Sha)
		log.Printf("docker pull http://%s/%s", RegistryHost, dRepo)
		dockerLock.Lock()
		err := dockerClient.PullImage(docker.PullImageOptions{Repository: fmt.Sprintf("%s/%s", RegistryHost, dRepo)},
			os.Stdout)
		dockerLock.Unlock()
		if err != nil {
			return err
		}

		err = os.MkdirAll(fmt.Sprintf("/var/log/atlantis/containers/%s", c.Id), 0755)
		if err != nil {
			return err
		}

		log.Printf("docker run http://%s/%s", RegistryHost, dRepo)
		// create docker container
		dCfg, dHostCfg := c.dockerCfgs(dRepo)
		dockerLock.Lock()
		dCont, err := dockerClient.CreateContainer(docker.CreateContainerOptions{Name: c.Id}, dCfg)
		dockerLock.Unlock()
		if err != nil {
			return err
		}
		c.DockerId = dCont.ID

		// start docker container
		dockerLock.Lock()
		err = dockerClient.StartContainer(c.DockerId, dHostCfg)
		dockerLock.Unlock()
		if err != nil {
			return err
		}
	}
	save() // save here because this is when we know the deployed container is actually alive
	return nil
}

// Teardown the container. This will kill the docker container but will not free the ports/containers
func (c *Container) teardown() {
	if pretending() {
		log.Printf("[pretend] teardown %s...", c.Id)
		return
	} else {
		log.Printf("teardown %s...", c.Id)
	}
	defer removeExited()
	dockerLock.Lock()
	err := dockerClient.KillContainer(c.DockerId)
	dockerLock.Unlock()
	if err != nil {
		log.Printf("failed to teardown %s: %v", c.Id, err)
	}
}

// This calls the Teardown(id string) method to ensure that the ports/containers are freed. That will in turn
// call c.teardown(id string)
func (c *Container) Teardown() {
	Teardown(c.Id)
}

func (c *Container) AuthorizeSSHUser(user, publicKey string) error {
	// copy file to container
	// rebuild authorize_keys
	return SSHCmd{"-p", fmt.Sprintf("%d", c.SSHPort), "-i", "/opt/atlantis/supervisor/master_id_rsa", "-o",
		"UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no", "root@localhost",
		fmt.Sprintf("echo \"%s\" >/root/.ssh/authorized_keys.d/%s.pub && rebuild_authorized_keys", publicKey,
			user)}.Execute()
}

func (c *Container) DeauthorizeSSHUser(user string) error {
	// delete file from container
	// rebuild authorize_keys
	return SSHCmd{"-p", fmt.Sprintf("%d", c.SSHPort), "-i", "/opt/atlantis/supervisor/master_id_rsa", "-o",
		"UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no", "root@localhost",
		fmt.Sprintf("rm /root/.ssh/authorized_keys.d/%s.pub && rebuild_authorized_keys",
			user)}.Execute()
}

func (c *Container) SetMaintenance(maint bool) error {
	if maint {
		// touch /etc/maint
		return SSHCmd{"-p", fmt.Sprintf("%d", c.SSHPort), "-i", "/opt/atlantis/supervisor/master_id_rsa", "-o",
			"UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no", "root@localhost",
			"touch /etc/maint"}.Execute()
	}
	// rm -f /etc/maint
	return SSHCmd{"-p", fmt.Sprintf("%d", c.SSHPort), "-i", "/opt/atlantis/supervisor/master_id_rsa", "-o",
		"UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no", "root@localhost",
		"rm -f /etc/maint"}.Execute()
}
<commit_msg>fix primary port<commit_after>package containers

import (
	"atlantis/crypto"
	"atlantis/supervisor/rpc/types"
	"fmt"
	"github.com/jigish/go-dockerclient"
	"log"
	"os"
	"os/exec"
	"regexp"
	"strings"
	"sync"
)

var (
	dockerIdRegexp = regexp.MustCompile("^[A-Za-z0-9]+$")
	dockerLock     = sync.Mutex{}
	dockerClient   *docker.Client
)

type Container types.Container
type SSHCmd []string

func DockerInit() (err error) {
	dockerClient, err = docker.NewClient("unix:///var/run/docker.sock")
	return
}

func pretending() bool {
	return os.Getenv("SUPERVISOR_PRETEND") != ""
}

func (s SSHCmd) Execute() error {
	if pretending() {
		log.Printf("[pretend] ssh %s", strings.Join(s, " "))
		return nil
	}
	log.Printf("ssh %s", strings.Join(s, " "))
	cmd := exec.Command("ssh", s...)
	output, err := cmd.CombinedOutput()
	log.Printf("-> %s", output)
	if err != nil {
		log.Println("-> Error:", err)
	}
	return err
}

func removeExited() {
	if pretending() {
		return
	}
	dockerLock.Lock()
	defer dockerLock.Unlock()
	containers, err := dockerClient.ListContainers(docker.ListContainersOptions{All: true})
	if err != nil {
		log.Printf("[RemoveExited] could not list containers: %v", err)
		return
	}
	for _, cont := range containers {
		log.Printf("[RemoveExited] checking %s (%v) : %s", cont.ID, cont.Names, cont.Status)
		if !strings.HasPrefix(cont.Status, "Exit") {
			continue
		}
		log.Printf("[RemoveExited] remove %s (%v)", cont.ID, cont.Names)
		err := dockerClient.RemoveContainer(cont.ID)
		if err != nil {
			log.Printf("[RemoveExited] -> error: %v", err)
		} else {
			log.Printf("[RemoveExited] -> success")
		}
	}
}

func restartGhost() {
	if pretending() {
		return
	}
	dockerLock.Lock()
	defer dockerLock.Unlock()
	containers, err := dockerClient.ListContainers(docker.ListContainersOptions{All: true})
	if err != nil {
		log.Printf("[RestartGhost] could not list containers: %v", err)
		return
	}
	hadError := false
	for _, cont := range containers {
		log.Printf("[RestartGhost] checking %s (%v) : %s", cont.ID, cont.Names, cont.Status)
		if !strings.HasPrefix(cont.Status, "Ghost") {
			continue
		}
		log.Printf("[RestartGhost] restart %s (%v)", cont.ID, cont.Names)
		err := dockerClient.RestartContainer(cont.ID, 0)
		if err != nil {
			hadError = true
			log.Printf("[RestartGhost] -> error: %v", err)
		} else {
			log.Printf("[RestartGhost] -> success")
		}
	}
	if hadError {
		log.Printf("[RestartGhost] attempting to force restart (restarting docker daemon)")
		cmd := exec.Command("sudo", "service docker restart")
		output, err := cmd.CombinedOutput()
		log.Printf("-> %s", output)
		if err != nil {
			log.Println("-> Error:", err)
		}
	}
}

func (c *Container) dockerCfgs(repo string) (*docker.Config, *docker.HostConfig) {
	// get env cfg
	envs := []string{
		"ATLANTIS=true",
		fmt.Sprintf("CONTAINER_ID=%s", c.Id),
		fmt.Sprintf("CONTAINER_HOST=%s", c.Host),
		fmt.Sprintf("CONTAINER_ENV=%s", c.Env),
		fmt.Sprintf("HTTP_PORT=%d", c.PrimaryPort),
		fmt.Sprintf("SSHD_PORT=%d", c.SSHPort),
	}
	if c.Manifest.Deps != nil {
		for name, value := range c.Manifest.Deps {
			envs = append(envs, fmt.Sprintf("%s=%s", name, crypto.Decrypt([]byte(value))))
		}
	}

	// get port cfg
	exposedPorts := map[docker.Port]struct{}{}
	portBindings := map[docker.Port][]docker.PortBinding{}
	sPrimaryPort := fmt.Sprintf("%d", c.PrimaryPort)
	dPrimaryPort := docker.NewPort("tcp", sPrimaryPort)
	exposedPorts[dPrimaryPort] = struct{}{}
	portBindings[dPrimaryPort] = []docker.PortBinding{docker.PortBinding{
		HostIp:   "",
		HostPort: sPrimaryPort,
	}}
	sSSHPort := fmt.Sprintf("%d", c.SSHPort)
	dSSHPort := docker.NewPort("tcp", sSSHPort)
	exposedPorts[dSSHPort] = struct{}{}
	portBindings[dSSHPort] = []docker.PortBinding{docker.PortBinding{
		HostIp:   "",
		HostPort: sSSHPort,
	}}
	for i, port := range c.SecondaryPorts {
		sPort := fmt.Sprintf("%d", port)
		dPort := docker.NewPort("tcp", sPort)
		exposedPorts[dPort] = struct{}{}
		portBindings[dPort] = []docker.PortBinding{docker.PortBinding{
			HostIp:   "",
			HostPort: sPort,
		}}
		envs = append(envs, fmt.Sprintf("SECONDARY_PORT%d=%d", i, port))
	}

	// setup actual cfg
	dCfg := &docker.Config{
		CpuShares:    int64(c.Manifest.CPUShares),
		Memory:       int64(c.Manifest.MemoryLimit) * int64(1024*1024), // this is in bytes
		MemorySwap:   int64(-1),                                        // -1 turns swap off
		ExposedPorts: exposedPorts,
		Env:          envs,
		Cmd:          []string{}, // images already specify run command
		Image:        fmt.Sprintf("%s/%s", RegistryHost, repo),
		Volumes:      map[string]struct{}{"/var/log/atlantis/syslog": struct{}{}},
	}
	dHostCfg := &docker.HostConfig{
		PortBindings: portBindings,
		LxcConf:      []docker.KeyValuePair{},
		Binds:        []string{fmt.Sprintf("/var/log/atlantis/containers/%s:/var/log/atlantis/syslog", c.Id)},
	}
	return dCfg, dHostCfg
}

// Deploy the given app+sha with the dependencies defined in deps. This will spin up a new docker container.
func (c *Container) Deploy(host, app, sha, env string) error {
	c.Host = host
	c.App = app
	c.Sha = sha
	c.Env = env
	dRepo := fmt.Sprintf("apps/%s-%s", c.App, c.Sha)
	if pretending() {
	} else {
	}
	// Pull docker container
	if pretending() {
		log.Printf("[pretend] deploy %s with %s @ %s...", c.Id, c.App, c.Sha)
		log.Printf("[pretend] docker pull %s/%s", RegistryHost, dRepo)
		log.Printf("[pretend] docker run %s/%s", RegistryHost, dRepo)
		c.DockerId = fmt.Sprintf("pretend-docker-id-%d", c.PrimaryPort)
	} else {
		log.Printf("deploy %s with %s @ %s...", c.Id, c.App, c.Sha)
		log.Printf("docker pull http://%s/%s", RegistryHost, dRepo)
		dockerLock.Lock()
		err := dockerClient.PullImage(docker.PullImageOptions{Repository: fmt.Sprintf("%s/%s", RegistryHost, dRepo)},
			os.Stdout)
		dockerLock.Unlock()
		if err != nil {
			return err
		}

		err = os.MkdirAll(fmt.Sprintf("/var/log/atlantis/containers/%s", c.Id), 0755)
		if err != nil {
			return err
		}

		log.Printf("docker run http://%s/%s", RegistryHost, dRepo)
		// create docker container
		dCfg, dHostCfg := c.dockerCfgs(dRepo)
		dockerLock.Lock()
		dCont, err := dockerClient.CreateContainer(docker.CreateContainerOptions{Name: c.Id}, dCfg)
		dockerLock.Unlock()
		if err != nil {
			return err
		}
		c.DockerId = dCont.ID

		// start docker container
		dockerLock.Lock()
		err = dockerClient.StartContainer(c.DockerId, dHostCfg)
		dockerLock.Unlock()
		if err != nil {
			return err
		}
	}
	save() // save here because this is when we know the deployed container is actually alive
	return nil
}

// Teardown the container. This will kill the docker container but will not free the ports/containers
func (c *Container) teardown() {
	if pretending() {
		log.Printf("[pretend] teardown %s...", c.Id)
		return
	} else {
		log.Printf("teardown %s...", c.Id)
	}
	defer removeExited()
	dockerLock.Lock()
	err := dockerClient.KillContainer(c.DockerId)
	dockerLock.Unlock()
	if err != nil {
		log.Printf("failed to teardown %s: %v", c.Id, err)
	}
}

// This calls the Teardown(id string) method to ensure that the ports/containers are freed. That will in turn
// call c.teardown(id string)
func (c *Container) Teardown() {
	Teardown(c.Id)
}

func (c *Container) AuthorizeSSHUser(user, publicKey string) error {
	// copy file to container
	// rebuild authorize_keys
	return SSHCmd{"-p", fmt.Sprintf("%d", c.SSHPort), "-i", "/opt/atlantis/supervisor/master_id_rsa", "-o",
		"UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no", "root@localhost",
		fmt.Sprintf("echo \"%s\" >/root/.ssh/authorized_keys.d/%s.pub && rebuild_authorized_keys", publicKey,
			user)}.Execute()
}

func (c *Container) DeauthorizeSSHUser(user string) error {
	// delete file from container
	// rebuild authorize_keys
	return SSHCmd{"-p", fmt.Sprintf("%d", c.SSHPort), "-i", "/opt/atlantis/supervisor/master_id_rsa", "-o",
		"UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no", "root@localhost",
		fmt.Sprintf("rm /root/.ssh/authorized_keys.d/%s.pub && rebuild_authorized_keys",
			user)}.Execute()
}

func (c *Container) SetMaintenance(maint bool) error {
	if maint {
		// touch /etc/maint
		return SSHCmd{"-p", fmt.Sprintf("%d", c.SSHPort), "-i", "/opt/atlantis/supervisor/master_id_rsa", "-o",
			"UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no", "root@localhost",
			"touch /etc/maint"}.Execute()
	}
	// rm -f /etc/maint
	return SSHCmd{"-p", fmt.Sprintf("%d", c.SSHPort), "-i", "/opt/atlantis/supervisor/master_id_rsa", "-o",
		"UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no", "root@localhost",
		"rm -f /etc/maint"}.Execute()
}
<|endoftext|>


<commit_before>/*
 * MinIO Go Library for Amazon S3 Compatible Cloud Storage
 * Copyright 2015-2017 MinIO, Inc.
 *
 * 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 minio

// awsS3EndpointMap Amazon S3 endpoint map.
var awsS3EndpointMap = map[string]string{
	"us-east-1":      "s3.dualstack.us-east-1.amazonaws.com",
	"us-east-2":      "s3.dualstack.us-east-2.amazonaws.com",
	"us-west-2":      "s3.dualstack.us-west-2.amazonaws.com",
	"us-west-1":      "s3.dualstack.us-west-1.amazonaws.com",
	"ca-central-1":   "s3.dualstack.ca-central-1.amazonaws.com",
	"eu-west-1":      "s3.dualstack.eu-west-1.amazonaws.com",
	"eu-west-2":      "s3.dualstack.eu-west-2.amazonaws.com",
	"eu-west-3":      "s3.dualstack.eu-west-3.amazonaws.com",
	"eu-central-1":   "s3.dualstack.eu-central-1.amazonaws.com",
	"eu-north-1":     "s3.dualstack.eu-north-1.amazonaws.com",
	"eu-south-1":     "s3.dualstack.eu-south-1.amazonaws.com",
	"ap-east-1":      "s3.dualstack.ap-east-1.amazonaws.com",
	"ap-south-1":     "s3.dualstack.ap-south-1.amazonaws.com",
	"ap-southeast-1": "s3.dualstack.ap-southeast-1.amazonaws.com",
	"ap-southeast-2": "s3.dualstack.ap-southeast-2.amazonaws.com",
	"ap-northeast-1": "s3.dualstack.ap-northeast-1.amazonaws.com",
	"ap-northeast-2": "s3.dualstack.ap-northeast-2.amazonaws.com",
	"ap-northeast-3": "s3.dualstack.ap-northeast-3.amazonaws.com",
	"af-south-1":     "s3.dualstack.af-south-1.amazonaws.com",
	"me-south-1":     "s3.dualstack.me-south-1.amazonaws.com",
	"sa-east-1":      "s3.dualstack.sa-east-1.amazonaws.com",
	"us-gov-west-1":  "s3.dualstack.us-gov-west-1.amazonaws.com",
	"us-gov-east-1":  "s3.dualstack.us-gov-east-1.amazonaws.com",
	"cn-north-1":     "s3.dualstack.cn-north-1.amazonaws.com.cn",
	"cn-northwest-1": "s3.dualstack.cn-northwest-1.amazonaws.com.cn",
	"ap-southeast-3": "s3.dualstack.ap-southeast-3.amazonaws.com",
}

// getS3Endpoint get Amazon S3 endpoint based on the bucket location.
func getS3Endpoint(bucketLocation string) (s3Endpoint string) {
	s3Endpoint, ok := awsS3EndpointMap[bucketLocation]
	if !ok {
		// Default to 's3.dualstack.us-east-1.amazonaws.com' endpoint.
		s3Endpoint = "s3.dualstack.us-east-1.amazonaws.com"
	}
	return s3Endpoint
}
<commit_msg>add missing S3 regions (#1726)<commit_after>/*
 * MinIO Go Library for Amazon S3 Compatible Cloud Storage
 * Copyright 2015-2017 MinIO, Inc.
 *
 * 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 minio

// awsS3EndpointMap Amazon S3 endpoint map.
var awsS3EndpointMap = map[string]string{
	"us-east-1":      "s3.dualstack.us-east-1.amazonaws.com",
	"us-east-2":      "s3.dualstack.us-east-2.amazonaws.com",
	"us-west-2":      "s3.dualstack.us-west-2.amazonaws.com",
	"us-west-1":      "s3.dualstack.us-west-1.amazonaws.com",
	"ca-central-1":   "s3.dualstack.ca-central-1.amazonaws.com",
	"eu-west-1":      "s3.dualstack.eu-west-1.amazonaws.com",
	"eu-west-2":      "s3.dualstack.eu-west-2.amazonaws.com",
	"eu-west-3":      "s3.dualstack.eu-west-3.amazonaws.com",
	"eu-central-1":   "s3.dualstack.eu-central-1.amazonaws.com",
	"eu-central-2":   "s3.dualstack.eu-central-2.amazonaws.com",
	"eu-north-1":     "s3.dualstack.eu-north-1.amazonaws.com",
	"eu-south-1":     "s3.dualstack.eu-south-1.amazonaws.com",
	"eu-south-2":     "s3.dualstack.eu-south-2.amazonaws.com",
	"ap-east-1":      "s3.dualstack.ap-east-1.amazonaws.com",
	"ap-south-1":     "s3.dualstack.ap-south-1.amazonaws.com",
	"ap-southeast-1": "s3.dualstack.ap-southeast-1.amazonaws.com",
	"ap-southeast-2": "s3.dualstack.ap-southeast-2.amazonaws.com",
	"ap-northeast-1": "s3.dualstack.ap-northeast-1.amazonaws.com",
	"ap-northeast-2": "s3.dualstack.ap-northeast-2.amazonaws.com",
	"ap-northeast-3": "s3.dualstack.ap-northeast-3.amazonaws.com",
	"af-south-1":     "s3.dualstack.af-south-1.amazonaws.com",
	"me-central-1":   "s3.dualstack.me-central-1.amazonaws.com",
	"me-south-1":     "s3.dualstack.me-south-1.amazonaws.com",
	"sa-east-1":      "s3.dualstack.sa-east-1.amazonaws.com",
	"us-gov-west-1":  "s3.dualstack.us-gov-west-1.amazonaws.com",
	"us-gov-east-1":  "s3.dualstack.us-gov-east-1.amazonaws.com",
	"cn-north-1":     "s3.dualstack.cn-north-1.amazonaws.com.cn",
	"cn-northwest-1": "s3.dualstack.cn-northwest-1.amazonaws.com.cn",
	"ap-southeast-3": "s3.dualstack.ap-southeast-3.amazonaws.com",
}

// getS3Endpoint get Amazon S3 endpoint based on the bucket location.
func getS3Endpoint(bucketLocation string) (s3Endpoint string) {
	s3Endpoint, ok := awsS3EndpointMap[bucketLocation]
	if !ok {
		// Default to 's3.dualstack.us-east-1.amazonaws.com' endpoint.
		s3Endpoint = "s3.dualstack.us-east-1.amazonaws.com"
	}
	return s3Endpoint
}
<|endoftext|>


<commit_before>package s3

import (
	"encoding/json"
	"fmt"
	"io"
	"os"
	"os/exec"
)

type Client interface {
	Upload(fileGlob string, to string, sourcesDir string) error
}

type client struct {
	accessKeyID     string
	secretAccessKey string
	regionName      string
	bucket          string

	stdout io.Writer
	stderr io.Writer

	outBinaryPath string
}

type NewClientConfig struct {
	AccessKeyID     string
	SecretAccessKey string
	RegionName      string
	Bucket          string

	Stdout io.Writer
	Stderr io.Writer

	OutBinaryPath string
}

func NewClient(config NewClientConfig) Client {
	return &client{
		accessKeyID:     config.AccessKeyID,
		secretAccessKey: config.SecretAccessKey,
		regionName:      config.RegionName,
		bucket:          config.Bucket,
		stdout:          config.Stdout,
		stderr:          config.Stderr,
		outBinaryPath:   config.OutBinaryPath,
	}
}

func (c client) Upload(fileGlob string, to string, sourcesDir string) error {
	s3Input := Request{
		Source: Source{
			AccessKeyID:     c.accessKeyID,
			SecretAccessKey: c.secretAccessKey,
			Bucket:          c.bucket,
			RegionName:      c.regionName,
		},
		Params: Params{
			File: fileGlob,
			To:   to,
		},
	}

	fmt.Fprintf(os.Stderr, "input: %+v, sourcesDir: %s\n", s3Input, sourcesDir)

	cmd := exec.Command(c.outBinaryPath, sourcesDir)

	cmdIn, err := cmd.StdinPipe()
	if err != nil {
		return err
	}

	cmd.Stdout = c.stderr
	cmd.Stderr = c.stderr

	err = cmd.Start()
	if err != nil {
		return err
	}

	err = json.NewEncoder(cmdIn).Encode(s3Input)
	if err != nil {
		return err
	}

	err = cmd.Wait()
	if err != nil {
		return err
	}

	return nil
}
<commit_msg>Do not log s3 input.<commit_after>package s3

import (
	"encoding/json"
	"io"
	"os/exec"
)

type Client interface {
	Upload(fileGlob string, to string, sourcesDir string) error
}

type client struct {
	accessKeyID     string
	secretAccessKey string
	regionName      string
	bucket          string

	stdout io.Writer
	stderr io.Writer

	outBinaryPath string
}

type NewClientConfig struct {
	AccessKeyID     string
	SecretAccessKey string
	RegionName      string
	Bucket          string

	Stdout io.Writer
	Stderr io.Writer

	OutBinaryPath string
}

func NewClient(config NewClientConfig) Client {
	return &client{
		accessKeyID:     config.AccessKeyID,
		secretAccessKey: config.SecretAccessKey,
		regionName:      config.RegionName,
		bucket:          config.Bucket,
		stdout:          config.Stdout,
		stderr:          config.Stderr,
		outBinaryPath:   config.OutBinaryPath,
	}
}

func (c client) Upload(fileGlob string, to string, sourcesDir string) error {
	s3Input := Request{
		Source: Source{
			AccessKeyID:     c.accessKeyID,
			SecretAccessKey: c.secretAccessKey,
			Bucket:          c.bucket,
			RegionName:      c.regionName,
		},
		Params: Params{
			File: fileGlob,
			To:   to,
		},
	}

	cmd := exec.Command(c.outBinaryPath, sourcesDir)

	cmdIn, err := cmd.StdinPipe()
	if err != nil {
		return err
	}

	cmd.Stdout = c.stderr
	cmd.Stderr = c.stderr

	err = cmd.Start()
	if err != nil {
		return err
	}

	err = json.NewEncoder(cmdIn).Encode(s3Input)
	if err != nil {
		return err
	}

	err = cmd.Wait()
	if err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package db

import (
	"fmt"
	"math/rand"
	"testing"
	"time"

	"github.com/megamsys/gocassa"
	"gopkg.in/check.v1"
)

func Test(t *testing.T) { check.TestingT(t) }

type S struct {
	sy *ScyllaDB
}

type Customer struct {
	Id   string
	Name string
}

type Customer2 struct {
	Id   string
	Name string
	Age  int
}

var _ = check.Suite(&S{})

var noips = []string{"103.56.92.24"}

func (s *S) SetUpSuite(c *check.C) {
	s.sy, _ = NewScyllaDB(ScyllaDBOpts{
		KeySpaceName: "testing",
		NodeIps:      noips,
		Username:     "",
		Password:     "",
		Debug:        true,
	})
	c.Assert(s.sy, check.NotNil)

	if s.sy == nil {
		fmt.Println("------------- scylladb is not running")
		c.Skip("- ScyllaDB isn't running. Did you start it ? ")
	}
}

func (s *S) TestReadWhereRowNotFound(c *check.C) {
	rand.Seed(time.Now().Unix())
	t := s.sy.Table("customer2", []string{"Id","Name"}, []string{}, &Customer2{})
	err := t.T.(gocassa.TableChanger).CreateIfNotExist()
	c.Assert(err, check.IsNil)
	err = t.Upsert(&Customer2{
		Id:   "1001",
		Name: "Hari",
		Age: 26,
	})
	c.Assert(err, check.IsNil)
	res := &Customer2{}
	err = t.ReadWhere(ScyllaWhere{clauses: map[string]string{"Id": "1001", "Name": "Hari"}}, res)
	c.Assert(err, check.NotNil)
}
func (s *S) TestTablWithMultiplePKButReadUsingOnePK(c *check.C) {
	rand.Seed(time.Now().Unix())
	t := s.sy.Table("customer", []string{"Id", "Name"}, []string{}, &Customer{})
	err := t.T.(gocassa.TableChanger).CreateIfNotExist()
	c.Assert(err, check.IsNil)
	err = t.Upsert(&Customer{
		Id:   "1001",
		Name: "Joe",
	})
	c.Assert(err, check.IsNil)
	res := Customer{}
	err = t.ReadWhere(ScyllaWhere{clauses: map[string]string{"Id": "1001", "Name":"" }}, &res)
	c.Assert(err, check.NotNil)
}

func (s *S) TestReadWhereRowFound(c *check.C) {
	rand.Seed(time.Now().Unix())
	t := s.sy.Table("customer", []string{"Id", "Name"}, []string{}, &Customer{})
	err := t.T.(gocassa.TableChanger).CreateIfNotExist()
	c.Assert(err, check.IsNil)
	err = t.Upsert(&Customer{
		Id:   "1001",
		Name: "Joe",
	})
	c.Assert(err, check.IsNil)
	res := &Customer{}
	err = t.ReadWhere(ScyllaWhere{clauses: map[string]string{"Id": "1001", "Name": "Joe"}}, res)
	c.Assert(err, check.NotNil)
}
<commit_msg>scylladb test<commit_after>package db

import (
	"fmt"
	"math/rand"
	"testing"
	"time"

	"github.com/megamsys/gocassa"
	"gopkg.in/check.v1"
)

func Test(t *testing.T) { check.TestingT(t) }

type S struct {
	sy *ScyllaDB
}

type Customer struct {
	Id   string
	Name string
}

type Customer2 struct {
	Id   string
	Name string
	Age  int
}

var _ = check.Suite(&S{})

var noips = []string{"127.0.0.1"}

func (s *S) SetUpSuite(c *check.C) {
	s.sy, _ = NewScyllaDB(ScyllaDBOpts{
		KeySpaceName: "testing",
		NodeIps:      noips,
		Username:     "",
		Password:     "",
		Debug:        true,
	})
	c.Assert(s.sy, check.NotNil)

	if s.sy == nil {
		fmt.Println("------------- scylladb is not running")
		c.Skip("- ScyllaDB isn't running. Did you start it ? ")
	}
}

func (s *S) TestReadWhereRowNotFound(c *check.C) {
	rand.Seed(time.Now().Unix())
	t := s.sy.Table("customer2", []string{"Id","Name"}, []string{}, &Customer2{})
	err := t.T.(gocassa.TableChanger).CreateIfNotExist()
	c.Assert(err, check.IsNil)
	err = t.Upsert(&Customer2{
		Id:   "1001",
		Name: "Hari",
		Age: 26,
	})
	c.Assert(err, check.IsNil)
	res := &Customer2{}
	err = t.ReadWhere(ScyllaWhere{clauses: map[string]string{"Id": "1001", "Name": ""}}, res)
	c.Assert(err, check.NotNil)
}
func (s *S) TestTablWithMultiplePKButReadUsingOnePK(c *check.C) {
	rand.Seed(time.Now().Unix())
	t := s.sy.Table("customer", []string{"Id", "Name"}, []string{}, &Customer{})
	err := t.T.(gocassa.TableChanger).CreateIfNotExist()
	c.Assert(err, check.IsNil)
	err = t.Upsert(&Customer{
		Id:   "1001",
		Name: "Joe",
	})
	c.Assert(err, check.IsNil)
	res := Customer{}
	err = t.ReadWhere(ScyllaWhere{clauses: map[string]string{"Id": "1001"}}, &res)
	c.Assert(err, check.NotNil)
}

func (s *S) TestReadWhereRowFound(c *check.C) {
	rand.Seed(time.Now().Unix())
	t := s.sy.Table("customer", []string{"Id", "Name"}, []string{}, &Customer{})
	err := t.T.(gocassa.TableChanger).CreateIfNotExist()
	c.Assert(err, check.IsNil)
	err = t.Upsert(&Customer{
		Id:   "1001",
		Name: "Joe",
	})
	c.Assert(err, check.IsNil)
	res := &Customer{}
	err = t.ReadWhere(ScyllaWhere{clauses: map[string]string{"Id": "1001", "Name": "Joe"}}, res)
	c.Assert(err, check.NotNil)
}
<|endoftext|>


<commit_before>package entity

import (
	"sync"

	. "chunkymonkey/types"
)

type EntityManager struct {
	nextEntityId EntityId
	entities     map[EntityId]bool
	lock         sync.Mutex
}

func (mgr *EntityManager) Init() {
	mgr.lock.Lock()
	defer mgr.lock.Unlock()

	mgr.nextEntityId = 0
	mgr.entities = make(map[EntityId]bool)
}

func (mgr *EntityManager) createEntityId() EntityId {
	// Search for next free ID
	entityId := mgr.nextEntityId
	_, exists := mgr.entities[entityId]
	for exists {
		entityId++
		if entityId == mgr.nextEntityId {
			// TODO Better handling of this? It shouldn't happen, realistically - but
			// neither should it explode.
			panic("EntityId space exhausted")
		}
		_, exists = mgr.entities[entityId]
	}
	mgr.nextEntityId = entityId + 1

	return entityId
}

// AddEntity adds an entity to the manager, and assigns it a world-unique
// EntityId.
// NewEntity creates a world-unique entityId in the manager and returns it.
func (mgr *EntityManager) NewEntity() EntityId {
	mgr.lock.Lock()
	defer mgr.lock.Unlock()

	entityId := mgr.createEntityId()
	mgr.entities[entityId] = true
	return entityId
}

// RemoveEntity removes an entity from the manager.
func (mgr *EntityManager) RemoveEntityById(entityId EntityId) {
	mgr.lock.Lock()
	defer mgr.lock.Unlock()

	mgr.entities[entityId] = false, false
}
<commit_msg>Fixed, no tests are available<commit_after>package entity

import (
	"sync"

	. "chunkymonkey/types"
)

type EntityManager struct {
	nextEntityId EntityId
	entities     map[EntityId]bool
	lock         sync.Mutex
}

func (mgr *EntityManager) Init() {
	mgr.lock.Lock()
	defer mgr.lock.Unlock()

	mgr.nextEntityId = 0
	mgr.entities = make(map[EntityId]bool)
}

func (mgr *EntityManager) createEntityId() EntityId {
	// Search for next free ID
	entityId := mgr.nextEntityId
	_, exists := mgr.entities[entityId]
	for exists {
		entityId++
		if entityId == mgr.nextEntityId {
			// TODO Better handling of this? It shouldn't happen, realistically - but
			// neither should it explode.
			panic("EntityId space exhausted")
		}
		_, exists = mgr.entities[entityId]
	}
	mgr.nextEntityId = entityId + 1

	return entityId
}

// AddEntity adds an entity to the manager, and assigns it a world-unique
// EntityId.
// NewEntity creates a world-unique entityId in the manager and returns it.
func (mgr *EntityManager) NewEntity() EntityId {
	mgr.lock.Lock()
	defer mgr.lock.Unlock()

	entityId := mgr.createEntityId()
	mgr.entities[entityId] = true
	return entityId
}

// RemoveEntity removes an entity from the manager.
func (mgr *EntityManager) RemoveEntityById(entityId EntityId) {
	mgr.lock.Lock()
	defer mgr.lock.Unlock()

	delete(mgr.entities, entityId)
}
<|endoftext|>


<commit_before>package auth_test

import (
	"crypto/rand"
	"crypto/rsa"
	"net/http"
	"net/http/httptest"
	"time"

	"code.cloudfoundry.org/lager/lagertest"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"github.com/concourse/atc/auth"
	"github.com/concourse/atc/auth/authfakes"
	"github.com/concourse/atc/db/dbfakes"
)

var _ = Describe("LogOutHandler", func() {
	Describe("GET /auth/logout", func() {
		var (
			fakeProviderFactory *authfakes.FakeProviderFactory
			signingKey          *rsa.PrivateKey
			server              *httptest.Server
			client              *http.Client
			request             *http.Request
			response            *http.Response
			err                 error
			expire              time.Duration
		)

		BeforeEach(func() {
			fakeProviderFactory = new(authfakes.FakeProviderFactory)
			fakeTeamDBFactory := new(dbfakes.FakeTeamDBFactory)
			signingKey, err = rsa.GenerateKey(rand.Reader, 1024)
			Expect(err).ToNot(HaveOccurred())
			expire = 24 * time.Hour

			handler, err := auth.NewOAuthHandler(
				lagertest.NewTestLogger("test"),
				fakeProviderFactory,
				fakeTeamDBFactory,
				signingKey,
				expire,
			)
			Expect(err).ToNot(HaveOccurred())

			mux := http.NewServeMux()
			mux.Handle("/auth/", handler)

			server = httptest.NewServer(mux)

			client = &http.Client{
				Transport: &http.Transport{},
			}

			request, err = http.NewRequest("GET", server.URL+"/auth/logout", nil)
			Expect(err).NotTo(HaveOccurred())
		})

		JustBeforeEach(func() {
			response, err = client.Do(request)
			Expect(err).NotTo(HaveOccurred())
		})

		It("deletes ATC-Authorization cookie", func() {
			cookies := response.Cookies()
			Expect(len(cookies)).To(Equal(1))

			deletedCookie := cookies[0]
			Expect(deletedCookie.Name).To(Equal(auth.CookieName))
			Expect(deletedCookie.MaxAge).To(Equal(-1))
		})
	})
})
<commit_msg>move containerkeepaliver, lostandfound, buildreaper to gc<commit_after>package auth_test

import (
	"crypto/rand"
	"crypto/rsa"
	"net/http"
	"net/http/httptest"
	"time"

	"code.cloudfoundry.org/lager/lagertest"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"github.com/concourse/atc/auth"
	"github.com/concourse/atc/auth/authfakes"
	"github.com/concourse/atc/db/dbfakes"
)

var _ = Describe("LogOutHandler", func() {
	Describe("GET /auth/logout", func() {
		var (
			fakeProviderFactory *authfakes.FakeProviderFactory
			signingKey          *rsa.PrivateKey
			server              *httptest.Server
			client              *http.Client
			request             *http.Request
			response            *http.Response
			err                 error
			expire              time.Duration
		)

		BeforeEach(func() {
			fakeProviderFactory = new(authfakes.FakeProviderFactory)
			fakeTeamDBFactory := new(dbfakes.FakeTeamDBFactory)
			signingKey, err = rsa.GenerateKey(rand.Reader, 1024)
			Expect(err).ToNot(HaveOccurred())
			expire = 24 * time.Hour

			handler, err := auth.NewOAuthHandler(
				lagertest.NewTestLogger("test"),
				fakeProviderFactory,
				fakeTeamDBFactory,
				signingKey,
				expire,
			)
			Expect(err).ToNot(HaveOccurred())

			mux := http.NewServeMux()
			mux.Handle("/auth/", handler)

			server = httptest.NewServer(mux)

			client = &http.Client{
				Transport: &http.Transport{},
			}

			request, err = http.NewRequest("GET", server.URL+"/auth/logout", nil)
			Expect(err).NotTo(HaveOccurred())
		})

		JustBeforeEach(func() {
			response, err = client.Do(request)
			Expect(err).NotTo(HaveOccurred())
		})

		It("deletes ATC-Authorization cookie", func() {
			cookies := response.Cookies()
			Expect(len(cookies)).To(Equal(1))

			deletedCookie := cookies[0]
			Expect(deletedCookie.Name).To(Equal(auth.CookieName))
			Expect(deletedCookie.MaxAge).To(Equal(-1))
		})
	})
})
<|endoftext|>


<commit_before>package bitrise

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"strings"
	"time"

	"gopkg.in/yaml.v2"

	log "github.com/Sirupsen/logrus"
	models "github.com/bitrise-io/bitrise/models/models_1_0_0"
	envmanModels "github.com/bitrise-io/envman/models"
	"github.com/bitrise-io/go-utils/cmdex"
	"github.com/bitrise-io/go-utils/fileutil"
	"github.com/bitrise-io/go-utils/pathutil"
	stepmanModels "github.com/bitrise-io/stepman/models"
)

// AppendEnvironmentSlice ...
func AppendEnvironmentSlice(slice, appendSlice []envmanModels.EnvironmentItemModel) []envmanModels.EnvironmentItemModel {
	for _, env := range appendSlice {
		slice = append(slice, env)
	}
	return slice
}

// CollectEnvironmentsFromFile ...
func CollectEnvironmentsFromFile(pth string) ([]envmanModels.EnvironmentItemModel, error) {
	bytes, err := fileutil.ReadBytesFromFile(pth)
	if err != nil {
		return []envmanModels.EnvironmentItemModel{}, err
	}

	var envstore envmanModels.EnvsYMLModel
	if err := yaml.Unmarshal(bytes, &envstore); err != nil {
		return []envmanModels.EnvironmentItemModel{}, err
	}

	for _, env := range envstore.Envs {
		if err := env.Normalize(); err != nil {
			return []envmanModels.EnvironmentItemModel{}, err
		}
		if err := env.FillMissingDefaults(); err != nil {
			return []envmanModels.EnvironmentItemModel{}, err
		}
		if err := env.Validate(); err != nil {
			return []envmanModels.EnvironmentItemModel{}, err
		}
	}

	return envstore.Envs, nil
}

// ExportEnvironmentsList ...
func ExportEnvironmentsList(envsList []envmanModels.EnvironmentItemModel) error {
	log.Debugln("[BITRISE_CLI] - Exporting environments:", envsList)

	for _, env := range envsList {
		key, value, err := env.GetKeyValuePair()
		if err != nil {
			return err
		}

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

		if value != "" {
			if err := EnvmanAdd(InputEnvstorePath, key, value, *opts.IsExpand); err != nil {
				log.Errorln("[BITRISE_CLI] - Failed to run envman add")
				return err
			}
		}
	}
	return nil
}

// CleanupStepWorkDir ...
func CleanupStepWorkDir() error {
	stepYMLPth := BitriseWorkDirPath + "/current_step.yml"
	if err := cmdex.RemoveFile(stepYMLPth); err != nil {
		return errors.New(fmt.Sprint("Failed to remove step yml: ", err))
	}

	stepDir := BitriseWorkStepsDirPath
	if err := cmdex.RemoveDir(stepDir); err != nil {
		return errors.New(fmt.Sprint("Failed to remove step work dir: ", err))
	}
	return nil
}

// GetBuildFailedEnvironments ...
func GetBuildFailedEnvironments(failed bool) []string {
	statusStr := "0"
	if failed {
		statusStr = "1"
	}

	environments := []string{}
	steplibBuildStatusEnv := "STEPLIB_BUILD_STATUS" + "=" + statusStr
	environments = append(environments, steplibBuildStatusEnv)

	bitriseBuildStatusEnv := "BITRISE_BUILD_STATUS" + "=" + statusStr
	environments = append(environments, bitriseBuildStatusEnv)
	return environments
}

// SetBuildFailedEnv ...
func SetBuildFailedEnv(failed bool) error {
	statusStr := "0"
	if failed {
		statusStr = "1"
	}

	if err := os.Setenv("STEPLIB_BUILD_STATUS", statusStr); err != nil {
		return err
	}

	if err := os.Setenv("BITRISE_BUILD_STATUS", statusStr); err != nil {
		return err
	}
	return nil
}

// TimeToFormattedSeconds ...
func TimeToFormattedSeconds(t time.Duration, postfix string) string {
	sec := t.Seconds()
	if sec > 10.0 {
		return fmt.Sprintf("%.f%s", sec, postfix)
	} else if sec < 1.0 {
		return fmt.Sprintf("%.2f%s", sec, postfix)
	}
	return fmt.Sprintf("%.1f%s", sec, postfix)
}

// SaveConfigToFile ...
func SaveConfigToFile(pth string, bitriseConf models.BitriseDataModel) error {
	contBytes, err := generateYAML(bitriseConf)
	if err != nil {
		return err
	}
	if err := fileutil.WriteBytesToFile(pth, contBytes); err != nil {
		return err
	}

	log.Println()
	log.Infoln("=> Init success!")
	log.Infoln("File created at path:", pth)

	return nil
}

func generateYAML(v interface{}) ([]byte, error) {
	bytes, err := yaml.Marshal(v)
	if err != nil {
		return []byte{}, err
	}
	return bytes, nil
}

func normalizeValidateFillMissingDefaults(bitriseData *models.BitriseDataModel) error {
	if err := bitriseData.Normalize(); err != nil {
		return err
	}
	if err := bitriseData.Validate(); err != nil {
		return err
	}
	if err := bitriseData.FillMissingDefaults(); err != nil {
		return err
	}
	return nil
}

// ConfigModelFromYAMLBytes ...
func ConfigModelFromYAMLBytes(configBytes []byte) (bitriseData models.BitriseDataModel, err error) {
	if err = yaml.Unmarshal(configBytes, &bitriseData); err != nil {
		return
	}

	if err = normalizeValidateFillMissingDefaults(&bitriseData); err != nil {
		return
	}

	return
}

// ConfigModelFromJSONBytes ...
func ConfigModelFromJSONBytes(configBytes []byte) (bitriseData models.BitriseDataModel, err error) {
	if err = json.Unmarshal(configBytes, &bitriseData); err != nil {
		return
	}

	if err = normalizeValidateFillMissingDefaults(&bitriseData); err != nil {
		return
	}

	return
}

// ReadBitriseConfig ...
func ReadBitriseConfig(pth string) (models.BitriseDataModel, error) {
	log.Debugln("-> ReadBitriseConfig")
	if isExists, err := pathutil.IsPathExists(pth); err != nil {
		return models.BitriseDataModel{}, err
	} else if !isExists {
		return models.BitriseDataModel{}, errors.New(fmt.Sprint("No file found at path", pth))
	}

	bytes, err := ioutil.ReadFile(pth)
	if err != nil {
		return models.BitriseDataModel{}, err
	}

	if strings.HasSuffix(pth, ".json") {
		log.Debugln("=> Using JSON parser for: ", pth)
		return ConfigModelFromJSONBytes(bytes)
	}

	log.Debugln("=> Using YAML parser for: ", pth)
	return ConfigModelFromYAMLBytes(bytes)
}

// ReadSpecStep ...
func ReadSpecStep(pth string) (stepmanModels.StepModel, error) {
	if isExists, err := pathutil.IsPathExists(pth); err != nil {
		return stepmanModels.StepModel{}, err
	} else if !isExists {
		return stepmanModels.StepModel{}, errors.New(fmt.Sprint("No file found at path", pth))
	}

	bytes, err := ioutil.ReadFile(pth)
	if err != nil {
		return stepmanModels.StepModel{}, err
	}

	var stepModel stepmanModels.StepModel
	if err := yaml.Unmarshal(bytes, &stepModel); err != nil {
		return stepmanModels.StepModel{}, err
	}

	if err := stepModel.Normalize(); err != nil {
		return stepmanModels.StepModel{}, err
	}

	if err := stepModel.ValidateStep(false); err != nil {
		return stepmanModels.StepModel{}, err
	}

	if err := stepModel.FillMissingDefaults(); err != nil {
		return stepmanModels.StepModel{}, err
	}

	return stepModel, nil
}
<commit_msg>missing go-utils methods<commit_after>package bitrise

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

	"gopkg.in/yaml.v2"

	log "github.com/Sirupsen/logrus"
	models "github.com/bitrise-io/bitrise/models/models_1_0_0"
	envmanModels "github.com/bitrise-io/envman/models"
	"github.com/bitrise-io/go-utils/cmdex"
	"github.com/bitrise-io/go-utils/fileutil"
	"github.com/bitrise-io/go-utils/pathutil"
	stepmanModels "github.com/bitrise-io/stepman/models"
)

// AppendEnvironmentSlice ...
func AppendEnvironmentSlice(slice, appendSlice []envmanModels.EnvironmentItemModel) []envmanModels.EnvironmentItemModel {
	for _, env := range appendSlice {
		slice = append(slice, env)
	}
	return slice
}

// CollectEnvironmentsFromFile ...
func CollectEnvironmentsFromFile(pth string) ([]envmanModels.EnvironmentItemModel, error) {
	bytes, err := fileutil.ReadBytesFromFile(pth)
	if err != nil {
		return []envmanModels.EnvironmentItemModel{}, err
	}

	var envstore envmanModels.EnvsYMLModel
	if err := yaml.Unmarshal(bytes, &envstore); err != nil {
		return []envmanModels.EnvironmentItemModel{}, err
	}

	for _, env := range envstore.Envs {
		if err := env.Normalize(); err != nil {
			return []envmanModels.EnvironmentItemModel{}, err
		}
		if err := env.FillMissingDefaults(); err != nil {
			return []envmanModels.EnvironmentItemModel{}, err
		}
		if err := env.Validate(); err != nil {
			return []envmanModels.EnvironmentItemModel{}, err
		}
	}

	return envstore.Envs, nil
}

// ExportEnvironmentsList ...
func ExportEnvironmentsList(envsList []envmanModels.EnvironmentItemModel) error {
	log.Debugln("[BITRISE_CLI] - Exporting environments:", envsList)

	for _, env := range envsList {
		key, value, err := env.GetKeyValuePair()
		if err != nil {
			return err
		}

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

		if value != "" {
			if err := EnvmanAdd(InputEnvstorePath, key, value, *opts.IsExpand); err != nil {
				log.Errorln("[BITRISE_CLI] - Failed to run envman add")
				return err
			}
		}
	}
	return nil
}

// CleanupStepWorkDir ...
func CleanupStepWorkDir() error {
	stepYMLPth := BitriseWorkDirPath + "/current_step.yml"
	if err := cmdex.RemoveFile(stepYMLPth); err != nil {
		return errors.New(fmt.Sprint("Failed to remove step yml: ", err))
	}

	stepDir := BitriseWorkStepsDirPath
	if err := cmdex.RemoveDir(stepDir); err != nil {
		return errors.New(fmt.Sprint("Failed to remove step work dir: ", err))
	}
	return nil
}

// GetBuildFailedEnvironments ...
func GetBuildFailedEnvironments(failed bool) []string {
	statusStr := "0"
	if failed {
		statusStr = "1"
	}

	environments := []string{}
	steplibBuildStatusEnv := "STEPLIB_BUILD_STATUS" + "=" + statusStr
	environments = append(environments, steplibBuildStatusEnv)

	bitriseBuildStatusEnv := "BITRISE_BUILD_STATUS" + "=" + statusStr
	environments = append(environments, bitriseBuildStatusEnv)
	return environments
}

// SetBuildFailedEnv ...
func SetBuildFailedEnv(failed bool) error {
	statusStr := "0"
	if failed {
		statusStr = "1"
	}

	if err := os.Setenv("STEPLIB_BUILD_STATUS", statusStr); err != nil {
		return err
	}

	if err := os.Setenv("BITRISE_BUILD_STATUS", statusStr); err != nil {
		return err
	}
	return nil
}

// TimeToFormattedSeconds ...
func TimeToFormattedSeconds(t time.Duration, postfix string) string {
	sec := t.Seconds()
	if sec > 10.0 {
		return fmt.Sprintf("%.f%s", sec, postfix)
	} else if sec < 1.0 {
		return fmt.Sprintf("%.2f%s", sec, postfix)
	}
	return fmt.Sprintf("%.1f%s", sec, postfix)
}

// SaveConfigToFile ...
func SaveConfigToFile(pth string, bitriseConf models.BitriseDataModel) error {
	contBytes, err := generateYAML(bitriseConf)
	if err != nil {
		return err
	}
	if err := fileutil.WriteBytesToFile(pth, contBytes); err != nil {
		return err
	}

	log.Println()
	log.Infoln("=> Init success!")
	log.Infoln("File created at path:", pth)

	return nil
}

func generateYAML(v interface{}) ([]byte, error) {
	bytes, err := yaml.Marshal(v)
	if err != nil {
		return []byte{}, err
	}
	return bytes, nil
}

func normalizeValidateFillMissingDefaults(bitriseData *models.BitriseDataModel) error {
	if err := bitriseData.Normalize(); err != nil {
		return err
	}
	if err := bitriseData.Validate(); err != nil {
		return err
	}
	if err := bitriseData.FillMissingDefaults(); err != nil {
		return err
	}
	return nil
}

// ConfigModelFromYAMLBytes ...
func ConfigModelFromYAMLBytes(configBytes []byte) (bitriseData models.BitriseDataModel, err error) {
	if err = yaml.Unmarshal(configBytes, &bitriseData); err != nil {
		return
	}

	if err = normalizeValidateFillMissingDefaults(&bitriseData); err != nil {
		return
	}

	return
}

// ConfigModelFromJSONBytes ...
func ConfigModelFromJSONBytes(configBytes []byte) (bitriseData models.BitriseDataModel, err error) {
	if err = json.Unmarshal(configBytes, &bitriseData); err != nil {
		return
	}

	if err = normalizeValidateFillMissingDefaults(&bitriseData); err != nil {
		return
	}

	return
}

// ReadBitriseConfig ...
func ReadBitriseConfig(pth string) (models.BitriseDataModel, error) {
	log.Debugln("-> ReadBitriseConfig")
	if isExists, err := pathutil.IsPathExists(pth); err != nil {
		return models.BitriseDataModel{}, err
	} else if !isExists {
		return models.BitriseDataModel{}, errors.New(fmt.Sprint("No file found at path", pth))
	}

	bytes, err := fileutil.ReadBytesFromFile(pth)
	if err != nil {
		return models.BitriseDataModel{}, err
	}

	if strings.HasSuffix(pth, ".json") {
		log.Debugln("=> Using JSON parser for: ", pth)
		return ConfigModelFromJSONBytes(bytes)
	}

	log.Debugln("=> Using YAML parser for: ", pth)
	return ConfigModelFromYAMLBytes(bytes)
}

// ReadSpecStep ...
func ReadSpecStep(pth string) (stepmanModels.StepModel, error) {
	if isExists, err := pathutil.IsPathExists(pth); err != nil {
		return stepmanModels.StepModel{}, err
	} else if !isExists {
		return stepmanModels.StepModel{}, errors.New(fmt.Sprint("No file found at path", pth))
	}

	bytes, err := fileutil.ReadBytesFromFile(pth)
	if err != nil {
		return stepmanModels.StepModel{}, err
	}

	var stepModel stepmanModels.StepModel
	if err := yaml.Unmarshal(bytes, &stepModel); err != nil {
		return stepmanModels.StepModel{}, err
	}

	if err := stepModel.Normalize(); err != nil {
		return stepmanModels.StepModel{}, err
	}

	if err := stepModel.ValidateStep(false); err != nil {
		return stepmanModels.StepModel{}, err
	}

	if err := stepModel.FillMissingDefaults(); err != nil {
		return stepmanModels.StepModel{}, err
	}

	return stepModel, nil
}
<|endoftext|>