<commit_before>// Copyright (C) 2017 Google 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 semantic holds the set of types used in the abstract semantic graph
// representation of the api language.
package semantic

import "github.com/google/gapid/gapil/ast"

// API is the root of the ASG, and holds a fully resolved api.
type API struct {
	members
	Named
	Enums        []*Enum        // the set of enums
	Definitions  []*Definition  // the set of definitions
	Classes      []*Class       // the set of classes
	Pseudonyms   []*Pseudonym   // the set of pseudo types
	Externs      []*Function    // the external function references
	Subroutines  []*Function    // the global subroutines
	Functions    []*Function    // the global functions
	Methods      []*Function    // the method functions
	Globals      []*Global      // the global variables
	StaticArrays []*StaticArray // the fixed size array types used
	Maps         []*Map         // the map types used
	Pointers     []*Pointer     // the pointer types used
	Slices       []*Slice       // the pointer types used
	References   []*Reference   // the reference types used
	Signatures   []*Signature   // the function signature types used
	Index        Uint8Value     // the index of this api
}

func (*API) isNode() {}

// Documentation represents the documentation strings for a type or function.
type Documentation []string

func (Documentation) isNode() {}

// Import wraps an API with it's imported name.
type Import struct {
	owned
	noMembers
	Named      // the full type name
	API   *API // the API being imported
}

// Member implements the Owner interface delegating member lookup to the imported API
func (i Import) Member(name string) Owned {
	return i.API.Member(name)
}

// Annotation represents a single annotation on an Annotated.
type Annotation struct {
	AST       *ast.Annotation // the underlying syntax node this was built from
	Named                     // the name of the annotation
	Arguments []Expression    // the arguments to the annotation
}

func (*Annotation) isNode() {}

// Annotated is the common interface to objects that can carry annotations.
type Annotated interface {
	// GetAnnotation returns the annotation with the matching name, if present.
	GetAnnotation(name string) *Annotation
}

// Annotations is an array of Annotation objects that implements the Annotated
// interface. It is used as an anonymous field on objects that carry
// annotations.
type Annotations []*Annotation

// IsInternal returns true if the object is annotated with @internal.
// It is illegal to assign a non-external pointer or slice to an internal
// pointer or slice.
func (a *Annotations) IsInternal() bool { return a.GetAnnotation("internal") != nil }

// GetAnnotation implements the Annotated interface for the Annotations type.
func (a Annotations) GetAnnotation(name string) *Annotation {
	for _, entry := range a {
		if entry.Name() == name {
			return entry
		}
	}
	return nil
}

// Global represents a global variable.
type Global struct {
	owned
	AST         *ast.Field // the underlying syntax node this was built from
	Annotations            // the annotations applied to this global
	Type        Type       // the type the global stores
	Named                  // the name of the global
	Default     Expression // the initial value of the global
}

func (*Global) isNode()       {}
func (*Global) isExpression() {}

// ExpressionType returns the type stored in the global.
func (g *Global) ExpressionType() Type { return g.Type }

// CommandIndex returns the index of the given command, or -1 if the function
// is not a command of the API.
func (a *API) CommandIndex(cmd *Function) int {
	for i, f := range a.Functions {
		if f == cmd {
			return i
		}
	}
	return -1
}
<commit_msg>gapil/semantic: Add more API.XXXIndex helpers<commit_after>// Copyright (C) 2017 Google 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 semantic holds the set of types used in the abstract semantic graph
// representation of the api language.
package semantic

import "github.com/google/gapid/gapil/ast"

// API is the root of the ASG, and holds a fully resolved api.
type API struct {
	members
	Named
	Enums        []*Enum        // the set of enums
	Definitions  []*Definition  // the set of definitions
	Classes      []*Class       // the set of classes
	Pseudonyms   []*Pseudonym   // the set of pseudo types
	Externs      []*Function    // the external function references
	Subroutines  []*Function    // the global subroutines
	Functions    []*Function    // the global functions
	Methods      []*Function    // the method functions
	Globals      []*Global      // the global variables
	StaticArrays []*StaticArray // the fixed size array types used
	Maps         []*Map         // the map types used
	Pointers     []*Pointer     // the pointer types used
	Slices       []*Slice       // the pointer types used
	References   []*Reference   // the reference types used
	Signatures   []*Signature   // the function signature types used
	Index        Uint8Value     // the index of this api
}

func (*API) isNode() {}

// Documentation represents the documentation strings for a type or function.
type Documentation []string

func (Documentation) isNode() {}

// Import wraps an API with it's imported name.
type Import struct {
	owned
	noMembers
	Named      // the full type name
	API   *API // the API being imported
}

// Member implements the Owner interface delegating member lookup to the imported API
func (i Import) Member(name string) Owned {
	return i.API.Member(name)
}

// Annotation represents a single annotation on an Annotated.
type Annotation struct {
	AST       *ast.Annotation // the underlying syntax node this was built from
	Named                     // the name of the annotation
	Arguments []Expression    // the arguments to the annotation
}

func (*Annotation) isNode() {}

// Annotated is the common interface to objects that can carry annotations.
type Annotated interface {
	// GetAnnotation returns the annotation with the matching name, if present.
	GetAnnotation(name string) *Annotation
}

// Annotations is an array of Annotation objects that implements the Annotated
// interface. It is used as an anonymous field on objects that carry
// annotations.
type Annotations []*Annotation

// IsInternal returns true if the object is annotated with @internal.
// It is illegal to assign a non-external pointer or slice to an internal
// pointer or slice.
func (a *Annotations) IsInternal() bool { return a.GetAnnotation("internal") != nil }

// GetAnnotation implements the Annotated interface for the Annotations type.
func (a Annotations) GetAnnotation(name string) *Annotation {
	for _, entry := range a {
		if entry.Name() == name {
			return entry
		}
	}
	return nil
}

// Global represents a global variable.
type Global struct {
	owned
	AST         *ast.Field // the underlying syntax node this was built from
	Annotations            // the annotations applied to this global
	Type        Type       // the type the global stores
	Named                  // the name of the global
	Default     Expression // the initial value of the global
}

func (*Global) isNode()       {}
func (*Global) isExpression() {}

// ExpressionType returns the type stored in the global.
func (g *Global) ExpressionType() Type { return g.Type }

// CommandIndex returns the index of the given command, or -1 if the function
// is not a command of the API.
func (a *API) CommandIndex(cmd *Function) int {
	for i, f := range a.Functions {
		if f == cmd {
			return i
		}
	}
	return -1
}

// ClassIndex returns the index of the given class, or -1 if the class does not
// belong to the API.
func (a *API) ClassIndex(class *Class) int {
	for i, c := range a.Classes {
		if c == class {
			return i
		}
	}
	return -1
}

// EnumIndex returns the index of the given enum, or -1 if the enum does not
// belong to the API.
func (a *API) EnumIndex(enum *Enum) int {
	for i, e := range a.Enums {
		if e == enum {
			return i
		}
	}
	return -1
}

// MapIndex returns the index of the given map, or -1 if the map does not belong
// to the API.
func (a *API) MapIndex(t *Map) int {
	for i, m := range a.Maps {
		if m == t {
			return i
		}
	}
	return -1
}

// SliceIndex returns the index of the given slice, or -1 if the slice does not
// belong to the API.
func (a *API) SliceIndex(slice *Slice) int {
	for i, s := range a.Slices {
		if s == slice {
			return i
		}
	}
	return -1
}
<|endoftext|>


<commit_before>/*
 *   Copyright 2016 Manik Surtani
 *
 *   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 redis

import (
	"github.com/maniksurtani/quotaservice/configs"
	"github.com/maniksurtani/quotaservice/buckets"
	"time"
	"sync"
	"gopkg.in/redis.v3"
	"fmt"
	"github.com/maniksurtani/quotaservice/logging"
	"strconv"
)

const (
	TOKENS_NEXT_AVBL_NANOS_SUFFIX = "TNA"
	ACCUMULATED_TOKENS_SUFFIX = "AT"
)

type redisBucket struct {
	cfg                         *configs.BucketConfig
	namespace                   string
	name                        string
	factory                     *BucketFactory
	nanosBetweenTokens          int64
	maxTokensToAccumulate       int64
	tokensNextAvblNanosRedisKey string
	accumulatedTokensRedisKey   string
	buckets.ActivityChannel
}

type BucketFactory struct {
	m           *sync.RWMutex // Embed a lock.
	client      *redis.Client
	initialized bool
	redisOpts   *redis.Options
}

func NewBucketFactory(redisOpts *redis.Options) *BucketFactory {
	return &BucketFactory{initialized: false, m: &sync.RWMutex{}, redisOpts: redisOpts}
}

func (bf *BucketFactory) Init(cfg *configs.ServiceConfig) {
	if !bf.initialized {
		bf.m.Lock()
		defer bf.m.Unlock()

		if !bf.initialized {
			bf.initialized = true
			logging.Print("Establishing connection to Redis")
			// Set up connection to Redis
			bf.client = redis.NewClient(bf.redisOpts)

			logging.Printf("Connection established. Time on server: %v", time.Unix(toInt64(bf.client.Time().Val()[0], 0) / 1000, 0))
		}
	}
}

func (bf *BucketFactory) NewBucket(namespace, bucketName string, cfg *configs.BucketConfig) buckets.Bucket {
	return &redisBucket{
		cfg,
		namespace,
		bucketName,
		bf,
		int64(1e9 / cfg.FillRate),
		int64(cfg.Size),
		toRedisKey(namespace, bucketName, TOKENS_NEXT_AVBL_NANOS_SUFFIX),
		toRedisKey(namespace, bucketName, ACCUMULATED_TOKENS_SUFFIX),
		buckets.NewActivityChannel()}
}

func toRedisKey(namespace, bucketName, suffix string) string {
	return fmt.Sprintf("%v:%v:%v", namespace, bucketName, suffix)
}

func (b *redisBucket) Take(requested int64, maxWaitTime time.Duration) (waitTime time.Duration) {
	// Start a Redis "transaction"
	client := b.factory.client
	// TODO(manik) detect failed clients and reconnect
	m := client.Multi()
	defer m.Exec(func() error {
		return nil
	})

	currentTimeNanos := time.Now().UnixNano()
	cachedVals := m.MGet(b.tokensNextAvblNanosRedisKey, b.accumulatedTokensRedisKey)

	tokensNextAvailableNanos := toInt64(cachedVals.Val()[0], 0)
	accumulatedTokens := toInt64(cachedVals.Val()[1], 0)

	if currentTimeNanos > tokensNextAvailableNanos {
		// Accumulate fresh tokens.
		freshTokens := (currentTimeNanos - tokensNextAvailableNanos) / b.nanosBetweenTokens

		// Never exceed maxTokensToAccumulate
		accumulatedTokens = min(b.maxTokensToAccumulate, accumulatedTokens + freshTokens)
		tokensNextAvailableNanos = currentTimeNanos
	}

	waitTime = time.Duration(tokensNextAvailableNanos - currentTimeNanos) * time.Nanosecond
	accumulatedTokensUsed := min(accumulatedTokens, requested)
	tokensToWaitFor := requested - accumulatedTokensUsed
	futureWaitNanos := tokensToWaitFor * b.nanosBetweenTokens

	// Is waitTime too long?
	if waitTime > 0 && waitTime > maxWaitTime && maxWaitTime > 0 {
		// Don't "claim" any tokens.
		waitTime = time.Duration(-1)
	} else {
		tokensNextAvailableNanos = tokensNextAvailableNanos + futureWaitNanos
		accumulatedTokens = accumulatedTokens - accumulatedTokensUsed

		// TODO(manik) see if we can re-implement using INCR?

		// "Claim" tokens by writing variables back to Redis and releasing lock.
		expiry := time.Duration(b.cfg.MaxIdleMillis) * time.Millisecond
		m.Set(b.tokensNextAvblNanosRedisKey, tokensNextAvailableNanos, expiry)
		m.Set(b.accumulatedTokensRedisKey, accumulatedTokens, expiry)
	}

	return
}

func min(x, y int64) int64 {
	if x < y {
		return x
	}
	return y
}
func max(x, y int64) int64 {
	if x > y {
		return x
	}
	return y
}

func toInt64(s interface{}, defaultValue int64) (v int64) {
	if s != nil {
		var err error
		v, err = strconv.ParseInt(s.(string), 10, 64)
		if err != nil {
			logging.Printf("Cannot convert '%v' to int64", s)
		}
	}
	return
}

func (b *redisBucket) Config() *configs.BucketConfig {
	return b.cfg
}
<commit_msg>Use a script instead of a Redis "transaction"<commit_after>/*
 *   Copyright 2016 Manik Surtani
 *
 *   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 redis

import (
	"github.com/maniksurtani/quotaservice/configs"
	"github.com/maniksurtani/quotaservice/buckets"
	"time"
	"sync"
	"gopkg.in/redis.v3"
	"fmt"
	"github.com/maniksurtani/quotaservice/logging"
	"strconv"
)

const (
	TOKENS_NEXT_AVBL_NANOS_SUFFIX = "TNA"
	ACCUMULATED_TOKENS_SUFFIX = "AT"
)

type redisBucket struct {
	cfg                   *configs.BucketConfig
	namespace             string
	name                  string
	factory               *BucketFactory
	nanosBetweenTokens    string
	maxTokensToAccumulate string
	redisKeys             []string // {tokensNextAvailableRedisKey, accumulatedTokensRedisKey}
	buckets.ActivityChannel
}

type BucketFactory struct {
	m           *sync.RWMutex // Embed a lock.
	client      *redis.Client
	initialized bool
	redisOpts   *redis.Options
	scriptSHA   string
}

func NewBucketFactory(redisOpts *redis.Options) *BucketFactory {
	return &BucketFactory{initialized: false, m: &sync.RWMutex{}, redisOpts: redisOpts}
}

func (bf *BucketFactory) Init(cfg *configs.ServiceConfig) {
	if !bf.initialized {
		bf.m.Lock()
		defer bf.m.Unlock()

		if !bf.initialized {
			bf.initialized = true
			logging.Print("Establishing connection to Redis")
			// Set up connection to Redis
			bf.client = redis.NewClient(bf.redisOpts)
			logging.Printf("Connection established. Time on server: %v", time.Unix(toInt64(bf.client.Time().Val()[0], 0) / 1000, 0))
			bf.scriptSHA = loadScript(bf.client)
		}
	}
}

func (bf *BucketFactory) NewBucket(namespace, bucketName string, cfg *configs.BucketConfig) buckets.Bucket {
	return &redisBucket{
		cfg,
		namespace,
		bucketName,
		bf,
		strconv.FormatInt(int64(1e9) / int64(cfg.FillRate), 10),
		strconv.FormatInt(int64(cfg.Size), 10),
		[]string{toRedisKey(namespace, bucketName, TOKENS_NEXT_AVBL_NANOS_SUFFIX),
			toRedisKey(namespace, bucketName, ACCUMULATED_TOKENS_SUFFIX)},
		buckets.NewActivityChannel()}
}

func toRedisKey(namespace, bucketName, suffix string) string {
	return fmt.Sprintf("%v:%v:%v", namespace, bucketName, suffix)
}

func (b *redisBucket) Take(requested int64, maxWaitTime time.Duration) (waitTime time.Duration) {
	currentTimeNanos := fmt.Sprintf("%v", time.Now().UnixNano())
	args := []string{currentTimeNanos, b.nanosBetweenTokens, b.maxTokensToAccumulate,
		strconv.FormatInt(requested, 10), strconv.FormatInt(maxWaitTime.Nanoseconds(), 10)}

	res := b.factory.client.EvalSha(b.factory.scriptSHA, b.redisKeys, args)
	waitTimeNanos := res.Val().(int64)
	waitTime = time.Nanosecond * time.Duration(waitTimeNanos)
	return
}

func toInt64(s interface{}, defaultValue int64) (v int64) {
	if s != nil {
		var err error
		v, err = strconv.ParseInt(s.(string), 10, 64)
		if err != nil {
			logging.Printf("Cannot convert '%v' to int64", s)
		}
	}
	return
}

func (b *redisBucket) Config() *configs.BucketConfig {
	return b.cfg
}

func loadScript(c *redis.Client) (sha string) {
	lua := `
	local tokensNextAvailableNanos = tonumber(redis.call("GET", KEYS[1]))
	if not tokensNextAvailableNanos then
		tokensNextAvailableNanos = tonumber("0")
	end

	local accumulatedTokens = redis.call("GET", KEYS[2])
	if not accumulatedTokens then
		accumulatedTokens = tonumber("0")
	end

	local currentTimeNanos = tonumber(ARGV[1])
	local nanosBetweenTokens = tonumber(ARGV[2])
	local maxTokensToAccumulate = tonumber(ARGV[3])
	local requested = tonumber(ARGV[4])
	local maxWaitTime = tonumber(ARGV[5])
	local freshTokens = tonumber("0")

	if currentTimeNanos > tokensNextAvailableNanos then
		freshTokens = math.floor((currentTimeNanos - tokensNextAvailableNanos) / nanosBetweenTokens)
		accumulatedTokens = math.min(maxTokensToAccumulate, accumulatedTokens + freshTokens)
		tokensNextAvailableNanos = currentTimeNanos
	end

	local waitTime = tokensNextAvailableNanos - currentTimeNanos
	local accumulatedTokensUsed = math.min(accumulatedTokens, requested)
	local tokensToWaitFor = requested - accumulatedTokensUsed
	local futureWaitNanos = tokensToWaitFor * nanosBetweenTokens

	if waitTime > 0 and waitTime > maxWaitTime and maxWaitTime > 0 then
    	waitTime = -1
	else
		tokensNextAvailableNanos = tokensNextAvailableNanos + futureWaitNanos
		accumulatedTokens = accumulatedTokens - accumulatedTokensUsed

		redis.call("SET", KEYS[1], tokensNextAvailableNanos)
		redis.call("SET", KEYS[2], math.floor(accumulatedTokens))
	end

	return waitTime
	`
	s := c.ScriptLoad(lua)
	sha = s.Val()
	logging.Printf("Loaded LUA script into Redis; script SHA %v", sha)
	return
}
<|endoftext|>


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

package runtime_test

import (
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	. "runtime"
	"runtime/debug"
	"strconv"
	"strings"
	"testing"
	"unsafe"
)

var errf error

func errfn() error {
	return errf
}

func errfn1() error {
	return io.EOF
}

func BenchmarkIfaceCmp100(b *testing.B) {
	for i := 0; i < b.N; i++ {
		for j := 0; j < 100; j++ {
			if errfn() == io.EOF {
				b.Fatal("bad comparison")
			}
		}
	}
}

func BenchmarkIfaceCmpNil100(b *testing.B) {
	for i := 0; i < b.N; i++ {
		for j := 0; j < 100; j++ {
			if errfn1() == nil {
				b.Fatal("bad comparison")
			}
		}
	}
}

func BenchmarkDefer(b *testing.B) {
	for i := 0; i < b.N; i++ {
		defer1()
	}
}

func defer1() {
	defer func(x, y, z int) {
		if recover() != nil || x != 1 || y != 2 || z != 3 {
			panic("bad recover")
		}
	}(1, 2, 3)
	return
}

func BenchmarkDefer10(b *testing.B) {
	for i := 0; i < b.N/10; i++ {
		defer2()
	}
}

func defer2() {
	for i := 0; i < 10; i++ {
		defer func(x, y, z int) {
			if recover() != nil || x != 1 || y != 2 || z != 3 {
				panic("bad recover")
			}
		}(1, 2, 3)
	}
}

func BenchmarkDeferMany(b *testing.B) {
	for i := 0; i < b.N; i++ {
		defer func(x, y, z int) {
			if recover() != nil || x != 1 || y != 2 || z != 3 {
				panic("bad recover")
			}
		}(1, 2, 3)
	}
}

// The profiling signal handler needs to know whether it is executing runtime.gogo.
// The constant RuntimeGogoBytes in arch_*.h gives the size of the function;
// we don't have a way to obtain it from the linker (perhaps someday).
// Test that the constant matches the size determined by 'go tool nm -S'.
// The value reported will include the padding between runtime.gogo and the
// next function in memory. That's fine.
func TestRuntimeGogoBytes(t *testing.T) {
	switch GOOS {
	case "android", "nacl":
		t.Skipf("skipping on %s", GOOS)
	}

	dir, err := ioutil.TempDir("", "go-build")
	if err != nil {
		t.Fatalf("failed to create temp directory: %v", err)
	}
	defer os.RemoveAll(dir)

	out, err := exec.Command("go", "build", "-o", dir+"/hello", "../../test/helloworld.go").CombinedOutput()
	if err != nil {
		t.Fatalf("building hello world: %v\n%s", err, out)
	}

	out, err = exec.Command("go", "tool", "nm", "-size", dir+"/hello").CombinedOutput()
	if err != nil {
		t.Fatalf("go tool nm: %v\n%s", err, out)
	}

	for _, line := range strings.Split(string(out), "\n") {
		f := strings.Fields(line)
		if len(f) == 4 && f[3] == "runtime.gogo" {
			size, _ := strconv.Atoi(f[1])
			if GogoBytes() != int32(size) {
				t.Fatalf("RuntimeGogoBytes = %d, should be %d", GogoBytes(), size)
			}
			return
		}
	}

	t.Fatalf("go tool nm did not report size for runtime.gogo")
}

// golang.org/issue/7063
func TestStopCPUProfilingWithProfilerOff(t *testing.T) {
	SetCPUProfileRate(0)
}

// Addresses to test for faulting behavior.
// This is less a test of SetPanicOnFault and more a check that
// the operating system and the runtime can process these faults
// correctly. That is, we're indirectly testing that without SetPanicOnFault
// these would manage to turn into ordinary crashes.
// Note that these are truncated on 32-bit systems, so the bottom 32 bits
// of the larger addresses must themselves be invalid addresses.
// We might get unlucky and the OS might have mapped one of these
// addresses, but probably not: they're all in the first page, very high
// adderesses that normally an OS would reserve for itself, or malformed
// addresses. Even so, we might have to remove one or two on different
// systems. We will see.

var faultAddrs = []uint64{
	// low addresses
	0,
	1,
	0xfff,
	// high (kernel) addresses
	// or else malformed.
	0xffffffffffffffff,
	0xfffffffffffff001,
	// no 0xffffffffffff0001; 0xffff0001 is mapped for 32-bit user space on OS X
	// no 0xfffffffffff00001; 0xfff00001 is mapped for 32-bit user space sometimes on Linux
	0xffffffffff000001,
	0xfffffffff0000001,
	0xffffffff00000001,
	0xfffffff000000001,
	0xffffff0000000001,
	0xfffff00000000001,
	0xffff000000000001,
	0xfff0000000000001,
	0xff00000000000001,
	0xf000000000000001,
	0x8000000000000001,
}

func TestSetPanicOnFault(t *testing.T) {
	// This currently results in a fault in the signal trampoline on
	// dragonfly/386 - see issue 7421.
	if GOOS == "dragonfly" && GOARCH == "386" {
		t.Skip("skipping test on dragonfly/386")
	}

	old := debug.SetPanicOnFault(true)
	defer debug.SetPanicOnFault(old)

	for _, addr := range faultAddrs {
		testSetPanicOnFault(t, uintptr(addr))
	}
}

func testSetPanicOnFault(t *testing.T, addr uintptr) {
	if GOOS == "nacl" {
		t.Skip("nacl doesn't seem to fault on high addresses")
	}

	defer func() {
		if err := recover(); err == nil {
			t.Fatalf("did not find error in recover")
		}
	}()

	var p *int
	p = (*int)(unsafe.Pointer(addr))
	println(*p)
	t.Fatalf("still here - should have faulted on address %#x", addr)
}

func eqstring_generic(s1, s2 string) bool {
	if len(s1) != len(s2) {
		return false
	}
	// optimization in assembly versions:
	// if s1.str == s2.str { return true }
	for i := 0; i < len(s1); i++ {
		if s1[i] != s2[i] {
			return false
		}
	}
	return true
}

func TestEqString(t *testing.T) {
	// This isn't really an exhaustive test of eqstring, it's
	// just a convenient way of documenting (via eqstring_generic)
	// what eqstring does.
	s := []string{
		"",
		"a",
		"c",
		"aaa",
		"ccc",
		"cccc"[:3], // same contents, different string
		"1234567890",
	}
	for _, s1 := range s {
		for _, s2 := range s {
			x := s1 == s2
			y := eqstring_generic(s1, s2)
			if x != y {
				t.Errorf(`eqstring("%s","%s") = %t, want %t`, s1, s2, x, y)
			}
		}
	}
}
<commit_msg>runtime: revise TestSetPanicOnFault<commit_after>// Copyright 2012 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package runtime_test

import (
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	. "runtime"
	"runtime/debug"
	"strconv"
	"strings"
	"testing"
	"unsafe"
)

var errf error

func errfn() error {
	return errf
}

func errfn1() error {
	return io.EOF
}

func BenchmarkIfaceCmp100(b *testing.B) {
	for i := 0; i < b.N; i++ {
		for j := 0; j < 100; j++ {
			if errfn() == io.EOF {
				b.Fatal("bad comparison")
			}
		}
	}
}

func BenchmarkIfaceCmpNil100(b *testing.B) {
	for i := 0; i < b.N; i++ {
		for j := 0; j < 100; j++ {
			if errfn1() == nil {
				b.Fatal("bad comparison")
			}
		}
	}
}

func BenchmarkDefer(b *testing.B) {
	for i := 0; i < b.N; i++ {
		defer1()
	}
}

func defer1() {
	defer func(x, y, z int) {
		if recover() != nil || x != 1 || y != 2 || z != 3 {
			panic("bad recover")
		}
	}(1, 2, 3)
	return
}

func BenchmarkDefer10(b *testing.B) {
	for i := 0; i < b.N/10; i++ {
		defer2()
	}
}

func defer2() {
	for i := 0; i < 10; i++ {
		defer func(x, y, z int) {
			if recover() != nil || x != 1 || y != 2 || z != 3 {
				panic("bad recover")
			}
		}(1, 2, 3)
	}
}

func BenchmarkDeferMany(b *testing.B) {
	for i := 0; i < b.N; i++ {
		defer func(x, y, z int) {
			if recover() != nil || x != 1 || y != 2 || z != 3 {
				panic("bad recover")
			}
		}(1, 2, 3)
	}
}

// The profiling signal handler needs to know whether it is executing runtime.gogo.
// The constant RuntimeGogoBytes in arch_*.h gives the size of the function;
// we don't have a way to obtain it from the linker (perhaps someday).
// Test that the constant matches the size determined by 'go tool nm -S'.
// The value reported will include the padding between runtime.gogo and the
// next function in memory. That's fine.
func TestRuntimeGogoBytes(t *testing.T) {
	switch GOOS {
	case "android", "nacl":
		t.Skipf("skipping on %s", GOOS)
	}

	dir, err := ioutil.TempDir("", "go-build")
	if err != nil {
		t.Fatalf("failed to create temp directory: %v", err)
	}
	defer os.RemoveAll(dir)

	out, err := exec.Command("go", "build", "-o", dir+"/hello", "../../test/helloworld.go").CombinedOutput()
	if err != nil {
		t.Fatalf("building hello world: %v\n%s", err, out)
	}

	out, err = exec.Command("go", "tool", "nm", "-size", dir+"/hello").CombinedOutput()
	if err != nil {
		t.Fatalf("go tool nm: %v\n%s", err, out)
	}

	for _, line := range strings.Split(string(out), "\n") {
		f := strings.Fields(line)
		if len(f) == 4 && f[3] == "runtime.gogo" {
			size, _ := strconv.Atoi(f[1])
			if GogoBytes() != int32(size) {
				t.Fatalf("RuntimeGogoBytes = %d, should be %d", GogoBytes(), size)
			}
			return
		}
	}

	t.Fatalf("go tool nm did not report size for runtime.gogo")
}

// golang.org/issue/7063
func TestStopCPUProfilingWithProfilerOff(t *testing.T) {
	SetCPUProfileRate(0)
}

// Addresses to test for faulting behavior.
// This is less a test of SetPanicOnFault and more a check that
// the operating system and the runtime can process these faults
// correctly. That is, we're indirectly testing that without SetPanicOnFault
// these would manage to turn into ordinary crashes.
// Note that these are truncated on 32-bit systems, so the bottom 32 bits
// of the larger addresses must themselves be invalid addresses.
// We might get unlucky and the OS might have mapped one of these
// addresses, but probably not: they're all in the first page, very high
// adderesses that normally an OS would reserve for itself, or malformed
// addresses. Even so, we might have to remove one or two on different
// systems. We will see.

var faultAddrs = []uint64{
	// low addresses
	0,
	1,
	0xfff,
	// high (kernel) addresses
	// or else malformed.
	0xffffffffffffffff,
	0xfffffffffffff001,
	0xffffffffffff0001,
	0xfffffffffff00001,
	0xffffffffff000001,
	0xfffffffff0000001,
	0xffffffff00000001,
	0xfffffff000000001,
	0xffffff0000000001,
	0xfffff00000000001,
	0xffff000000000001,
	0xfff0000000000001,
	0xff00000000000001,
	0xf000000000000001,
	0x8000000000000001,
}

func TestSetPanicOnFault(t *testing.T) {
	// This currently results in a fault in the signal trampoline on
	// dragonfly/386 - see issue 7421.
	if GOOS == "dragonfly" && GOARCH == "386" {
		t.Skip("skipping test on dragonfly/386")
	}

	old := debug.SetPanicOnFault(true)
	defer debug.SetPanicOnFault(old)

	nfault := 0
	for _, addr := range faultAddrs {
		testSetPanicOnFault(t, uintptr(addr), &nfault)
	}
	if nfault == 0 {
		t.Fatalf("none of the addresses faulted")
	}
}

func testSetPanicOnFault(t *testing.T, addr uintptr, nfault *int) {
	if GOOS == "nacl" {
		t.Skip("nacl doesn't seem to fault on high addresses")
	}

	defer func() {
		if err := recover(); err != nil {
			*nfault++
		}
	}()

	// The read should fault, except that sometimes we hit
	// addresses that have had C or kernel pages mapped there
	// readable by user code. So just log the content.
	// If no addresses fault, we'll fail the test.
	var p *int
	p = (*int)(unsafe.Pointer(addr))
	t.Logf("addr %#x: %#x\n", addr, *p)
}

func eqstring_generic(s1, s2 string) bool {
	if len(s1) != len(s2) {
		return false
	}
	// optimization in assembly versions:
	// if s1.str == s2.str { return true }
	for i := 0; i < len(s1); i++ {
		if s1[i] != s2[i] {
			return false
		}
	}
	return true
}

func TestEqString(t *testing.T) {
	// This isn't really an exhaustive test of eqstring, it's
	// just a convenient way of documenting (via eqstring_generic)
	// what eqstring does.
	s := []string{
		"",
		"a",
		"c",
		"aaa",
		"ccc",
		"cccc"[:3], // same contents, different string
		"1234567890",
	}
	for _, s1 := range s {
		for _, s2 := range s {
			x := s1 == s2
			y := eqstring_generic(s1, s2)
			if x != y {
				t.Errorf(`eqstring("%s","%s") = %t, want %t`, s1, s2, x, y)
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"io"

	"github.com/influxdata/influxdb/v2"
	"github.com/influxdata/influxdb/v2/cmd/influx/internal"
	"github.com/influxdata/influxdb/v2/dbrp"
	"github.com/influxdata/influxdb/v2/kit/cli"
	"github.com/spf13/cobra"
)

func cmdV1DBRP(f *globalFlags, opt genericCLIOpts) *cobra.Command {
	cmd := opt.newCmd("dbrp", nil, false)
	cmd.Short = "Commands to manage database and retention policy mappings for v1 APIs"
	cmd.Run = seeHelp

	cmd.AddCommand(
		v1DBRPCreateCmd(f, opt),
		v1DBRPFindCmd(f, opt),
		v1DBRPDeleteCmd(f, opt),
		v1DBRPUpdateCmd(f, opt),
	)

	return cmd
}

var v1DBRPCRUDFlags struct {
	id          string
	json        bool
	hideHeaders bool
}

var v1DBRPFindFlags struct {
	BucketID influxdb.ID  // Specifies the bucket ID to filter on
	DB       string       // Specifies the database to filter on
	Default  *bool        // Specifies filtering on default
	ID       influxdb.ID  // Specifies the mapping ID to filter on
	Org      organization // required  // Specifies the organization ID to filter on
	RP       string       // Specifies the retention policy to filter on
}

func v1DBRPFindCmd(f *globalFlags, opt genericCLIOpts) *cobra.Command {
	cmd := &cobra.Command{
		Use:   "list",
		Short: "List database and retention policy mappings",
		RunE:  checkSetupRunEMiddleware(&flags)(v1DBRPFindF),
	}

	f.registerFlags(opt.viper, cmd)
	registerPrintOptions(opt.viper, cmd, &v1DBRPCRUDFlags.hideHeaders, &v1DBRPCRUDFlags.json)
	v1DBRPFindFlags.Org.register(opt.viper, cmd, false)
	cli.IDVar(cmd.Flags(), &v1DBRPFindFlags.BucketID, "bucket-id", 0, "Limit results to the matching bucket id")
	cli.IDVar(cmd.Flags(), &v1DBRPFindFlags.ID, "id", 0, "Limit results to a single mapping")
	cmd.Flags().StringVar(&v1DBRPFindFlags.DB, "db", "", "Limit results to the matching database name")
	cmd.Flags().StringVar(&v1DBRPFindFlags.RP, "rp", "", "Limit results to the matching retention policy name")
	cmd.Flags().Bool("default", false, "Limit results to default mappings")

	return cmd
}

func v1DBRPFindF(cmd *cobra.Command, _ []string) error {
	if err := v1DBRPFindFlags.Org.validOrgFlags(&flags); err != nil {
		return err
	}
	if defaultFlg := cmd.Flags().Lookup("default"); defaultFlg.Changed {
		defaultBool, err := cmd.Flags().GetBool("default")
		if err != nil {
			return err
		}
		v1DBRPFindFlags.Default = &defaultBool
	}

	orgSvc, err := newOrganizationService()
	if err != nil {
		return err
	}

	orgID, err := v1DBRPFindFlags.Org.getID(orgSvc)
	if err != nil {
		return err
	}

	s, err := newV1DBRPService()
	if err != nil {
		return err
	}
	filter := influxdb.DBRPMappingFilterV2{OrgID: &orgID}

	if v1DBRPFindFlags.ID.Valid() {
		filter.ID = &v1DBRPFindFlags.ID
	}

	if v1DBRPFindFlags.BucketID.Valid() {
		filter.BucketID = &v1DBRPFindFlags.BucketID
	}

	if v1DBRPFindFlags.DB != "" {
		filter.Database = &v1DBRPFindFlags.DB
	}

	if v1DBRPFindFlags.RP != "" {
		filter.RetentionPolicy = &v1DBRPFindFlags.RP
	}

	if v1DBRPFindFlags.Default != nil {
		filter.Default = v1DBRPFindFlags.Default
	}
	dbrps, _, err := s.FindMany(context.Background(), filter, influxdb.FindOptions{})
	if err != nil {
		return err
	}

	return v1WriteDBRPs(cmd.OutOrStdout(), v1DBRPPrintOpt{
		jsonOut:     v1DBRPCRUDFlags.json,
		hideHeaders: v1DBRPCRUDFlags.hideHeaders,
		mappings:    dbrps,
	})
}

var v1DBRPCreateFlags struct {
	BucketID influxdb.ID  // Specifies the bucket ID to associate with the mapping
	DB       string       // Specifies the database of the database
	Default  bool         // Specifies filtering on default
	Org      organization // Specifies the organization ID to filter on
	RP       string       // Specifies the retention policy to filter on
}

func v1DBRPCreateCmd(f *globalFlags, opt genericCLIOpts) *cobra.Command {
	cmd := &cobra.Command{
		Use:   "create",
		Short: "Create a database and retention policy mapping to an existing bucket",
		RunE:  checkSetupRunEMiddleware(&flags)(v1DBRPCreateF),
		Args:  cobra.NoArgs,
	}

	f.registerFlags(opt.viper, cmd)
	registerPrintOptions(opt.viper, cmd, &v1DBRPCRUDFlags.hideHeaders, &v1DBRPCRUDFlags.json)
	v1DBRPCreateFlags.Org.register(opt.viper, cmd, false)
	cli.IDVar(cmd.Flags(), &v1DBRPCreateFlags.BucketID, "bucket-id", 0, "The ID of the bucket to be mapped")
	_ = cmd.MarkFlagRequired("bucket-id")
	cmd.Flags().StringVar(&v1DBRPCreateFlags.DB, "db", "", "The name of the database")
	_ = cmd.MarkFlagRequired("db")
	cmd.Flags().BoolVar(&v1DBRPCreateFlags.Default, "default", false, "Identify this mapping as the default retention policy")
	cmd.Flags().StringVar(&v1DBRPCreateFlags.RP, "rp", "", "Name of the retention policy")
	_ = cmd.MarkFlagRequired("rp")
	return cmd
}

func v1DBRPCreateF(cmd *cobra.Command, _ []string) error {
	if err := v1DBRPCreateFlags.Org.validOrgFlags(&flags); err != nil {
		return err
	}
	orgSvc, err := newOrganizationService()
	if err != nil {
		return err
	}

	orgID, err := v1DBRPCreateFlags.Org.getID(orgSvc)
	if err != nil {
		return err
	}

	mapping := &influxdb.DBRPMappingV2{
		BucketID:        v1DBRPCreateFlags.BucketID,
		Database:        v1DBRPCreateFlags.DB,
		Default:         v1DBRPCreateFlags.Default,
		OrganizationID:  orgID,
		RetentionPolicy: v1DBRPCreateFlags.RP,
	}

	s, err := newV1DBRPService()
	if err != nil {
		return err
	}
	if err := s.Create(context.Background(), mapping); err != nil {
		return err
	}
	return v1WriteDBRPs(cmd.OutOrStdout(), v1DBRPPrintOpt{
		jsonOut:     v1DBRPCRUDFlags.json,
		hideHeaders: v1DBRPCRUDFlags.hideHeaders,
		mapping:     mapping,
	})
}

type v1DBRPPrintOpt struct {
	jsonOut     bool
	hideHeaders bool
	mapping     *influxdb.DBRPMappingV2
	mappings    []*influxdb.DBRPMappingV2
}

func v1WriteDBRPs(w io.Writer, printOpts v1DBRPPrintOpt) error {
	if printOpts.jsonOut {
		var v interface{} = printOpts.mappings
		if printOpts.mappings == nil {
			v = printOpts.mappings
		}
		return writeJSON(w, v)
	}

	tabW := internal.NewTabWriter(w)
	defer tabW.Flush()

	tabW.HideHeaders(printOpts.hideHeaders)

	headers := []string{
		"ID",
		"Database",
		"Bucket ID",
		"Retention Policy",
		"Default",
		"Organization ID",
	}

	tabW.WriteHeaders(headers...)

	if printOpts.mappings == nil {
		printOpts.mappings = append(printOpts.mappings, printOpts.mapping)
	}

	for _, t := range printOpts.mappings {
		m := map[string]interface{}{
			"ID":               t.ID.String(),
			"Database":         t.Database,
			"Retention Policy": t.RetentionPolicy,
			"Default":          t.Default,
			"Organization ID":  t.OrganizationID,
			"Bucket ID":        t.BucketID,
		}
		tabW.Write(m)
	}

	return nil
}

var v1DBRPDeleteFlags struct {
	ID  influxdb.ID
	Org organization
}

func v1DBRPDeleteCmd(f *globalFlags, opt genericCLIOpts) *cobra.Command {
	cmd := &cobra.Command{
		Use:   "delete",
		Short: "Delete a database and retention policy mapping",
		RunE:  checkSetupRunEMiddleware(&flags)(v1DBRPDeleteF),
		Args:  cobra.NoArgs,
	}

	f.registerFlags(opt.viper, cmd)
	registerPrintOptions(opt.viper, cmd, &v1DBRPCRUDFlags.hideHeaders, &v1DBRPCRUDFlags.json)
	v1DBRPDeleteFlags.Org.register(opt.viper, cmd, false)
	cli.IDVar(cmd.Flags(), &v1DBRPDeleteFlags.ID, "id", 0, "The ID of the mapping to delete")
	_ = cmd.MarkFlagRequired("id")
	return cmd
}

func v1DBRPDeleteF(cmd *cobra.Command, _ []string) error {
	if err := v1DBRPDeleteFlags.Org.validOrgFlags(&flags); err != nil {
		return err
	}
	orgSvc, err := newOrganizationService()
	if err != nil {
		return err
	}

	orgID, err := v1DBRPDeleteFlags.Org.getID(orgSvc)
	if err != nil {
		return err
	}

	s, err := newV1DBRPService()
	if err != nil {
		return err
	}

	dbrpToDelete, err := s.FindByID(context.Background(), orgID, v1DBRPDeleteFlags.ID)
	if err != nil {
		return err
	}

	if err := s.Delete(context.Background(), orgID, v1DBRPDeleteFlags.ID); err != nil {
		return err
	}
	return v1WriteDBRPs(cmd.OutOrStdout(), v1DBRPPrintOpt{
		jsonOut:     v1DBRPCRUDFlags.json,
		hideHeaders: v1DBRPCRUDFlags.hideHeaders,
		mapping:     dbrpToDelete,
	})
}

var v1DBRPUpdateFlags struct {
	ID      influxdb.ID  // Specifies the mapping ID to update
	Org     organization // Specifies the organization ID
	Default *bool        // A nil value means that Default is unset in the Flags
	RP      string       // Updated name of the retention policy
}

func v1DBRPUpdateCmd(f *globalFlags, opt genericCLIOpts) *cobra.Command {
	cmd := &cobra.Command{
		Use:   "update",
		Short: "Update a database and retention policy mapping",
		RunE:  checkSetupRunEMiddleware(&flags)(v1DBRPUpdateF),
	}
	f.registerFlags(opt.viper, cmd)
	registerPrintOptions(opt.viper, cmd, &v1DBRPCRUDFlags.hideHeaders, &v1DBRPCRUDFlags.json)
	v1DBRPUpdateFlags.Org.register(opt.viper, cmd, false)
	cli.IDVar(cmd.Flags(), &v1DBRPUpdateFlags.ID, "id", 0, "The ID of the mapping to be updated")
	_ = cmd.MarkFlagRequired("id")
	cmd.Flags().StringVar(&v1DBRPUpdateFlags.RP, "rp", "", "The updated name of the retention policy")
	cmd.Flags().Bool("default", false, "Set this as the default mapping for the associated database name") // note for update we only care about update flags that the user set
	return cmd
}

func v1DBRPUpdateF(cmd *cobra.Command, _ []string) error {
	if err := v1DBRPUpdateFlags.Org.validOrgFlags(&flags); err != nil {
		return err
	}
	if defaultFlg := cmd.Flags().Lookup("default"); defaultFlg.Changed {
		defaultBool, err := cmd.Flags().GetBool("default")
		if err != nil {
			return err
		}
		v1DBRPUpdateFlags.Default = &defaultBool
	}

	orgSvc, err := newOrganizationService()
	if err != nil {
		return err
	}

	orgID, err := v1DBRPUpdateFlags.Org.getID(orgSvc)
	if err != nil {
		return err
	}

	dbrpUpdate := influxdb.DBRPMappingV2{
		OrganizationID: orgID,
		ID:             v1DBRPUpdateFlags.ID,
	}

	s, err := newV1DBRPService()
	if err != nil {
		return err
	}

	oldDBRP, err := s.FindByID(context.Background(), orgID, dbrpUpdate.ID)
	if err != nil {
		return err
	}

	if v1DBRPUpdateFlags.RP != "" {
		oldDBRP.RetentionPolicy = v1DBRPUpdateFlags.RP
	}

	if v1DBRPUpdateFlags.Default != nil {
		oldDBRP.Default = *v1DBRPUpdateFlags.Default
	}

	if err := s.Update(context.Background(), oldDBRP); err != nil {
		return err
	}

	// we do the lookup again, because Update doesn't give us all fields
	newDBRP, err := s.FindByID(context.Background(), orgID, dbrpUpdate.ID)
	if err != nil {
		return err
	}
	return v1WriteDBRPs(cmd.OutOrStdout(), v1DBRPPrintOpt{
		jsonOut:     v1DBRPCRUDFlags.json,
		hideHeaders: v1DBRPCRUDFlags.hideHeaders,
		mapping:     newDBRP,
	})
}

func newV1DBRPService() (*dbrp.Client, error) {
	httpClient, err := newHTTPClient()
	if err != nil {
		return nil, err
	}

	return dbrp.NewClient(httpClient), nil
}
<commit_msg>chore: adjust help text based on PR feedback<commit_after>package main

import (
	"context"
	"io"

	"github.com/influxdata/influxdb/v2"
	"github.com/influxdata/influxdb/v2/cmd/influx/internal"
	"github.com/influxdata/influxdb/v2/dbrp"
	"github.com/influxdata/influxdb/v2/kit/cli"
	"github.com/spf13/cobra"
)

func cmdV1DBRP(f *globalFlags, opt genericCLIOpts) *cobra.Command {
	cmd := opt.newCmd("dbrp", nil, false)
	cmd.Short = "Commands to manage database and retention policy mappings for v1 APIs"
	cmd.Run = seeHelp

	cmd.AddCommand(
		v1DBRPCreateCmd(f, opt),
		v1DBRPFindCmd(f, opt),
		v1DBRPDeleteCmd(f, opt),
		v1DBRPUpdateCmd(f, opt),
	)

	return cmd
}

var v1DBRPCRUDFlags struct {
	id          string
	json        bool
	hideHeaders bool
}

var v1DBRPFindFlags struct {
	BucketID influxdb.ID  // Specifies the bucket ID to filter on
	DB       string       // Specifies the database to filter on
	Default  *bool        // Specifies filtering on default
	ID       influxdb.ID  // Specifies the mapping ID to filter on
	Org      organization // required  // Specifies the organization ID to filter on
	RP       string       // Specifies the retention policy to filter on
}

func v1DBRPFindCmd(f *globalFlags, opt genericCLIOpts) *cobra.Command {
	cmd := &cobra.Command{
		Use:   "list",
		Short: "List database and retention policy mappings",
		RunE:  checkSetupRunEMiddleware(&flags)(v1DBRPFindF),
		Args:  cobra.NoArgs,
	}

	f.registerFlags(opt.viper, cmd)
	registerPrintOptions(opt.viper, cmd, &v1DBRPCRUDFlags.hideHeaders, &v1DBRPCRUDFlags.json)
	v1DBRPFindFlags.Org.register(opt.viper, cmd, false)
	cli.IDVar(cmd.Flags(), &v1DBRPFindFlags.BucketID, "bucket-id", 0, "Limit results to the matching bucket id")
	cli.IDVar(cmd.Flags(), &v1DBRPFindFlags.ID, "id", 0, "Limit results to a single mapping")
	cmd.Flags().StringVar(&v1DBRPFindFlags.DB, "db", "", "Limit results to the matching database name")
	cmd.Flags().StringVar(&v1DBRPFindFlags.RP, "rp", "", "Limit results to the matching retention policy name")
	cmd.Flags().Bool("default", false, "Limit results to default mappings")

	return cmd
}

func v1DBRPFindF(cmd *cobra.Command, _ []string) error {
	if err := v1DBRPFindFlags.Org.validOrgFlags(&flags); err != nil {
		return err
	}
	if defaultFlg := cmd.Flags().Lookup("default"); defaultFlg.Changed {
		defaultBool, err := cmd.Flags().GetBool("default")
		if err != nil {
			return err
		}
		v1DBRPFindFlags.Default = &defaultBool
	}

	orgSvc, err := newOrganizationService()
	if err != nil {
		return err
	}

	orgID, err := v1DBRPFindFlags.Org.getID(orgSvc)
	if err != nil {
		return err
	}

	s, err := newV1DBRPService()
	if err != nil {
		return err
	}
	filter := influxdb.DBRPMappingFilterV2{OrgID: &orgID}

	if v1DBRPFindFlags.ID.Valid() {
		filter.ID = &v1DBRPFindFlags.ID
	}

	if v1DBRPFindFlags.BucketID.Valid() {
		filter.BucketID = &v1DBRPFindFlags.BucketID
	}

	if v1DBRPFindFlags.DB != "" {
		filter.Database = &v1DBRPFindFlags.DB
	}

	if v1DBRPFindFlags.RP != "" {
		filter.RetentionPolicy = &v1DBRPFindFlags.RP
	}

	if v1DBRPFindFlags.Default != nil {
		filter.Default = v1DBRPFindFlags.Default
	}
	dbrps, _, err := s.FindMany(context.Background(), filter, influxdb.FindOptions{})
	if err != nil {
		return err
	}

	return v1WriteDBRPs(cmd.OutOrStdout(), v1DBRPPrintOpt{
		jsonOut:     v1DBRPCRUDFlags.json,
		hideHeaders: v1DBRPCRUDFlags.hideHeaders,
		mappings:    dbrps,
	})
}

var v1DBRPCreateFlags struct {
	BucketID influxdb.ID  // Specifies the bucket ID to associate with the mapping
	DB       string       // Specifies the database of the database
	Default  bool         // Specifies filtering on default
	Org      organization // Specifies the organization ID to filter on
	RP       string       // Specifies the retention policy to filter on
}

func v1DBRPCreateCmd(f *globalFlags, opt genericCLIOpts) *cobra.Command {
	cmd := &cobra.Command{
		Use:   "create",
		Short: "Create a database and retention policy mapping to an existing bucket",
		RunE:  checkSetupRunEMiddleware(&flags)(v1DBRPCreateF),
		Args:  cobra.NoArgs,
	}

	f.registerFlags(opt.viper, cmd)
	registerPrintOptions(opt.viper, cmd, &v1DBRPCRUDFlags.hideHeaders, &v1DBRPCRUDFlags.json)
	v1DBRPCreateFlags.Org.register(opt.viper, cmd, false)
	cli.IDVar(cmd.Flags(), &v1DBRPCreateFlags.BucketID, "bucket-id", 0, "The ID of the bucket to be mapped")
	_ = cmd.MarkFlagRequired("bucket-id")
	cmd.Flags().StringVar(&v1DBRPCreateFlags.DB, "db", "", "The name of the database")
	_ = cmd.MarkFlagRequired("db")
	cmd.Flags().BoolVar(&v1DBRPCreateFlags.Default, "default", false, "Identify this retention policy as the default for the database")
	cmd.Flags().StringVar(&v1DBRPCreateFlags.RP, "rp", "", "The name of the retention policy")
	_ = cmd.MarkFlagRequired("rp")
	return cmd
}

func v1DBRPCreateF(cmd *cobra.Command, _ []string) error {
	if err := v1DBRPCreateFlags.Org.validOrgFlags(&flags); err != nil {
		return err
	}
	orgSvc, err := newOrganizationService()
	if err != nil {
		return err
	}

	orgID, err := v1DBRPCreateFlags.Org.getID(orgSvc)
	if err != nil {
		return err
	}

	mapping := &influxdb.DBRPMappingV2{
		BucketID:        v1DBRPCreateFlags.BucketID,
		Database:        v1DBRPCreateFlags.DB,
		Default:         v1DBRPCreateFlags.Default,
		OrganizationID:  orgID,
		RetentionPolicy: v1DBRPCreateFlags.RP,
	}

	s, err := newV1DBRPService()
	if err != nil {
		return err
	}
	if err := s.Create(context.Background(), mapping); err != nil {
		return err
	}
	return v1WriteDBRPs(cmd.OutOrStdout(), v1DBRPPrintOpt{
		jsonOut:     v1DBRPCRUDFlags.json,
		hideHeaders: v1DBRPCRUDFlags.hideHeaders,
		mapping:     mapping,
	})
}

type v1DBRPPrintOpt struct {
	jsonOut     bool
	hideHeaders bool
	mapping     *influxdb.DBRPMappingV2
	mappings    []*influxdb.DBRPMappingV2
}

func v1WriteDBRPs(w io.Writer, printOpts v1DBRPPrintOpt) error {
	if printOpts.jsonOut {
		var v interface{} = printOpts.mappings
		if printOpts.mappings == nil {
			v = printOpts.mappings
		}
		return writeJSON(w, v)
	}

	tabW := internal.NewTabWriter(w)
	defer tabW.Flush()

	tabW.HideHeaders(printOpts.hideHeaders)

	headers := []string{
		"ID",
		"Database",
		"Bucket ID",
		"Retention Policy",
		"Default",
		"Organization ID",
	}

	tabW.WriteHeaders(headers...)

	if printOpts.mappings == nil {
		printOpts.mappings = append(printOpts.mappings, printOpts.mapping)
	}

	for _, t := range printOpts.mappings {
		m := map[string]interface{}{
			"ID":               t.ID.String(),
			"Database":         t.Database,
			"Retention Policy": t.RetentionPolicy,
			"Default":          t.Default,
			"Organization ID":  t.OrganizationID,
			"Bucket ID":        t.BucketID,
		}
		tabW.Write(m)
	}

	return nil
}

var v1DBRPDeleteFlags struct {
	ID  influxdb.ID
	Org organization
}

func v1DBRPDeleteCmd(f *globalFlags, opt genericCLIOpts) *cobra.Command {
	cmd := &cobra.Command{
		Use:   "delete",
		Short: "Delete a database and retention policy mapping",
		RunE:  checkSetupRunEMiddleware(&flags)(v1DBRPDeleteF),
		Args:  cobra.NoArgs,
	}

	f.registerFlags(opt.viper, cmd)
	registerPrintOptions(opt.viper, cmd, &v1DBRPCRUDFlags.hideHeaders, &v1DBRPCRUDFlags.json)
	v1DBRPDeleteFlags.Org.register(opt.viper, cmd, false)
	cli.IDVar(cmd.Flags(), &v1DBRPDeleteFlags.ID, "id", 0, "The ID of the mapping to delete")
	_ = cmd.MarkFlagRequired("id")
	return cmd
}

func v1DBRPDeleteF(cmd *cobra.Command, _ []string) error {
	if err := v1DBRPDeleteFlags.Org.validOrgFlags(&flags); err != nil {
		return err
	}
	orgSvc, err := newOrganizationService()
	if err != nil {
		return err
	}

	orgID, err := v1DBRPDeleteFlags.Org.getID(orgSvc)
	if err != nil {
		return err
	}

	s, err := newV1DBRPService()
	if err != nil {
		return err
	}

	dbrpToDelete, err := s.FindByID(context.Background(), orgID, v1DBRPDeleteFlags.ID)
	if err != nil {
		return err
	}

	if err := s.Delete(context.Background(), orgID, v1DBRPDeleteFlags.ID); err != nil {
		return err
	}
	return v1WriteDBRPs(cmd.OutOrStdout(), v1DBRPPrintOpt{
		jsonOut:     v1DBRPCRUDFlags.json,
		hideHeaders: v1DBRPCRUDFlags.hideHeaders,
		mapping:     dbrpToDelete,
	})
}

var v1DBRPUpdateFlags struct {
	ID      influxdb.ID  // Specifies the mapping ID to update
	Org     organization // Specifies the organization ID
	Default *bool        // A nil value means that Default is unset in the Flags
	RP      string       // Updated name of the retention policy
}

func v1DBRPUpdateCmd(f *globalFlags, opt genericCLIOpts) *cobra.Command {
	cmd := &cobra.Command{
		Use:   "update",
		Short: "Update a database and retention policy mapping",
		RunE:  checkSetupRunEMiddleware(&flags)(v1DBRPUpdateF),
		Args:  cobra.NoArgs,
	}
	f.registerFlags(opt.viper, cmd)
	registerPrintOptions(opt.viper, cmd, &v1DBRPCRUDFlags.hideHeaders, &v1DBRPCRUDFlags.json)
	v1DBRPUpdateFlags.Org.register(opt.viper, cmd, false)
	cli.IDVar(cmd.Flags(), &v1DBRPUpdateFlags.ID, "id", 0, "The ID of the mapping to be updated")
	_ = cmd.MarkFlagRequired("id")
	// note for update we only care about update flags that the user set
	cmd.Flags().StringVar(&v1DBRPUpdateFlags.RP, "rp", "", "The updated name of the retention policy")
	cmd.Flags().Bool("default", false, "Set this mapping's retention policy as the default for the mapping's database")
	return cmd
}

func v1DBRPUpdateF(cmd *cobra.Command, _ []string) error {
	if err := v1DBRPUpdateFlags.Org.validOrgFlags(&flags); err != nil {
		return err
	}
	if defaultFlg := cmd.Flags().Lookup("default"); defaultFlg.Changed {
		defaultBool, err := cmd.Flags().GetBool("default")
		if err != nil {
			return err
		}
		v1DBRPUpdateFlags.Default = &defaultBool
	}

	orgSvc, err := newOrganizationService()
	if err != nil {
		return err
	}

	orgID, err := v1DBRPUpdateFlags.Org.getID(orgSvc)
	if err != nil {
		return err
	}

	dbrpUpdate := influxdb.DBRPMappingV2{
		OrganizationID: orgID,
		ID:             v1DBRPUpdateFlags.ID,
	}

	s, err := newV1DBRPService()
	if err != nil {
		return err
	}

	oldDBRP, err := s.FindByID(context.Background(), orgID, dbrpUpdate.ID)
	if err != nil {
		return err
	}

	if v1DBRPUpdateFlags.RP != "" {
		oldDBRP.RetentionPolicy = v1DBRPUpdateFlags.RP
	}

	if v1DBRPUpdateFlags.Default != nil {
		oldDBRP.Default = *v1DBRPUpdateFlags.Default
	}

	if err := s.Update(context.Background(), oldDBRP); err != nil {
		return err
	}

	// we do the lookup again, because Update doesn't give us all fields
	newDBRP, err := s.FindByID(context.Background(), orgID, dbrpUpdate.ID)
	if err != nil {
		return err
	}
	return v1WriteDBRPs(cmd.OutOrStdout(), v1DBRPPrintOpt{
		jsonOut:     v1DBRPCRUDFlags.json,
		hideHeaders: v1DBRPCRUDFlags.hideHeaders,
		mapping:     newDBRP,
	})
}

func newV1DBRPService() (*dbrp.Client, error) {
	httpClient, err := newHTTPClient()
	if err != nil {
		return nil, err
	}

	return dbrp.NewClient(httpClient), nil
}
<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package main

import (
	"bytes"
	"flag"
	"io/ioutil"
	"log"
	"os"
	"strings"
	"syscall"
	"text/template"

	"github.com/mesosphere/etcd-mesos/rpc"
)

type proxyArgs struct {
	InitialCluster string
	DataDir        string
	ListenAddrs    string
	AdvertiseAddrs string
}

var cmdTemplate = template.Must(template.New("etcd-cmd").Parse(
	`--proxy=on ` +
		`--data-dir={{.DataDir}} ` +
		`--listen-client-urls={{.ListenAddrs}} ` +
		`--advertise-client-urls={{.AdvertiseAddrs}} ` +
		`--initial-cluster={{.InitialCluster}}`,
))

func main() {
	master :=
		flag.String("master", "127.0.0.1:5050", "Master address <ip:port>, "+
			"or zk://host:port,host:port/mesos uri for discovering the current "+
			"mesos master.")
	etcdBin :=
		flag.String("etcd-bin", "./bin/etcd", "Path to etcd binary to "+
			"configure and run.")
	clusterName :=
		flag.String("cluster-name", "default", "Unique name of the etcd cluster "+
			"to connect to, corresponding to the --cluster-name arg passed to the "+
			"etcd-mesos-scheduler")
	flag.String("data-dir", "default.etcd", "Path to the data directory.")
	clientUrls :=
		flag.String("listen-client-urls", "http://localhost:2379,http://localhost:4001",
			"List of URLs to listen on for client traffic.")
	flag.Parse()

	// Generate a temporary directory for the proxy
	path, err := ioutil.TempDir("", "etcd-mesos-proxy")
	if err != nil {
		log.Fatal(err)
	}

	// HACK: this tricks etcd into avoiding a bug that prevents
	// it from running in proxy mode.
	// see: https://github.com/coreos/etcd/issues/3258
	err = os.Mkdir(path+"/proxy", os.ModeDir|0777)
	if err != nil {
		log.Fatal(err)
	}

	// Pull current master from ZK if a ZK URI was provided
	if strings.HasPrefix(*master, "zk://") {
		log.Printf("Trying to connect to zk cluster %s", *master)
		result, err := rpc.GetMasterFromZK(*master)
		if err != nil {
			log.Fatal(err)
		}
		*master = result
	}

	// Pull the current tasks from the mesos master
	log.Printf("Pulling state.json from master: %s\n", *master)
	state, err := rpc.GetState("http://" + *master)
	if err != nil {
		log.Fatal(err)
	}
	peers, err := rpc.GetPeersFromState(state, *clusterName)
	if err != nil {
		log.Fatal(err)
	}

	// Format etcd proxy configuration options
	var args bytes.Buffer
	err = cmdTemplate.Execute(&args, proxyArgs{
		InitialCluster: strings.Join(peers, ","),
		DataDir:        path,
		ListenAddrs:    *clientUrls,
		AdvertiseAddrs: *clientUrls,
	})
	if err != nil {
		log.Fatal(err)
	}

	err = syscall.Exec(*etcdBin, strings.Fields(args.String()), []string{})
	log.Fatal(err)
}
<commit_msg>Fix proxy args to syscall.Exec<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package main

import (
	"bytes"
	"flag"
	"io/ioutil"
	"log"
	"strings"
	"syscall"
	"text/template"

	"github.com/mesosphere/etcd-mesos/rpc"
)

type proxyArgs struct {
	Bin            string
	InitialCluster string
	DataDir        string
	ListenAddrs    string
	AdvertiseAddrs string
}

var cmdTemplate = template.Must(template.New("etcd-cmd").Parse(
	`{{.Bin}} --proxy=on ` +
		`--data-dir={{.DataDir}} ` +
		`--listen-client-urls={{.ListenAddrs}} ` +
		`--advertise-client-urls={{.AdvertiseAddrs}} ` +
		`--initial-cluster={{.InitialCluster}}`,
))

func main() {
	master :=
		flag.String("master", "127.0.0.1:5050", "Master address <ip:port>, "+
			"or zk://host:port,host:port/mesos uri for discovering the current "+
			"mesos master.")
	etcdBin :=
		flag.String("etcd-bin", "./bin/etcd", "Path to etcd binary to "+
			"configure and run.")
	clusterName :=
		flag.String("cluster-name", "default", "Unique name of the etcd cluster "+
			"to connect to, corresponding to the --cluster-name arg passed to the "+
			"etcd-mesos-scheduler")
	flag.String("data-dir", "default.etcd", "Path to the data directory.")
	clientUrls :=
		flag.String("listen-client-urls", "http://localhost:2379,http://localhost:4001",
			"List of URLs to listen on for client traffic.")
	flag.Parse()

	// Generate a temporary directory for the proxy
	path, err := ioutil.TempDir("", "etcd-mesos-proxy")
	if err != nil {
		log.Fatal(err)
	}

	// Pull current master from ZK if a ZK URI was provided
	if strings.HasPrefix(*master, "zk://") {
		log.Printf("Trying to connect to zk cluster %s", *master)
		result, err := rpc.GetMasterFromZK(*master)
		if err != nil {
			log.Fatal(err)
		}
		*master = result
	}

	// Pull the current tasks from the mesos master
	log.Printf("Pulling state.json from master: %s\n", *master)
	state, err := rpc.GetState("http://" + *master)
	if err != nil {
		log.Fatal(err)
	}
	peers, err := rpc.GetPeersFromState(state, *clusterName)
	if err != nil {
		log.Fatal(err)
	}

	// Format etcd proxy configuration options
	var args bytes.Buffer
	err = cmdTemplate.Execute(&args, proxyArgs{
		Bin:            *etcdBin,
		InitialCluster: strings.Join(peers, ","),
		DataDir:        path,
		ListenAddrs:    *clientUrls,
		AdvertiseAddrs: *clientUrls,
	})
	if err != nil {
		log.Fatal(err)
	}

	err = syscall.Exec(*etcdBin, strings.Fields(args.String()), []string{})
	log.Fatal(err)
}
<|endoftext|>


<commit_before>// Copyright 2018 Datawire. All rights reserved.

// +build ignore

// gotest2tap.go translates `go test -json` on stdin to TAP v13 on
// stdout.
package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"os"
	"strings"
	"time"
)

// TestEvent is taken verbatim from `go doc test2json`
type TestEvent struct {
	Time    time.Time // encodes as an RFC3339-format string
	Action  string
	Package string
	Test    string
	Elapsed float64 // seconds
	Output  string
}

func main() {
	fmt.Println("TAP version 13")

	testCnt := 0
	pkgTestCnt := map[string]int{}
	bailed := false

	stdin := bufio.NewScanner(os.Stdin)
	for stdin.Scan() {
		var event TestEvent
		if err := json.Unmarshal(stdin.Bytes(), &event); err != nil {
			fmt.Printf("Bail out! Invalid JSON: %v: %q\n", err, stdin.Text())
			bailed = true
		}

		Time := event.Time.Format("2006-01-02T15:04:05.000000000")
		Elapsed := time.Duration(float64(time.Second) * event.Elapsed)
		Output := strings.TrimSuffix(event.Output, "\n")
		if event.Test == "" {
			if event.Action == "fail" && pkgTestCnt[event.Package] == 0 {
				fmt.Println("Bail out!", event.Package)
				bailed = true
			} else {
				fmt.Println("#",
					Time,
					"(took "+Elapsed.String()+")",
					fmt.Sprintf("%-6s", event.Action),
					event.Package,
					Output)
			}
		} else {
			Name := event.Package + "." + event.Test
			// TODO(lukeshu): I think maybe this should also handle "bench"?
			switch event.Action {
			case "pass":
				testCnt++
				pkgTestCnt[event.Package] = pkgTestCnt[event.Package] + 1
				fmt.Printf("ok %d %v # %v (%v) %v\n", testCnt, Name, Time, Elapsed, Output)
			case "fail":
				testCnt++
				pkgTestCnt[event.Package] = pkgTestCnt[event.Package] + 1
				fmt.Printf("not ok %d %v.%v # %v (%v) %v\n", testCnt, Name, Time, Elapsed, Output)
			case "skip":
				testCnt++
				pkgTestCnt[event.Package] = pkgTestCnt[event.Package] + 1
				fmt.Printf("ok %d %v.%v # SKIP %v (%v) %v\n", testCnt, Name, Time, Elapsed, Output)
			default:
				fmt.Sprintln("#",
					Time,
					"(took "+Elapsed.String()+")",
					fmt.Sprintf("%-6s", event.Action),
					Name,
					Output)
			}
		}
	}
	if err := stdin.Err(); err != nil {
		fmt.Println("Bail out!", err)
		bailed = true
	}
	if !bailed {
		fmt.Printf("1..%d\n", testCnt)
	}
}
<commit_msg>gotest2tap.go: Fix output bugs<commit_after>// Copyright 2018 Datawire. All rights reserved.

// +build ignore

// gotest2tap.go translates `go test -json` on stdin to TAP v13 on
// stdout.
package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"os"
	"strings"
	"time"
)

// TestEvent is taken verbatim from `go doc test2json`
type TestEvent struct {
	Time    time.Time // encodes as an RFC3339-format string
	Action  string
	Package string
	Test    string
	Elapsed float64 // seconds
	Output  string
}

func main() {
	fmt.Println("TAP version 13")

	testCnt := 0
	pkgTestCnt := map[string]int{}
	bailed := false

	stdin := bufio.NewScanner(os.Stdin)
	for stdin.Scan() {
		var event TestEvent
		if err := json.Unmarshal(stdin.Bytes(), &event); err != nil {
			fmt.Printf("Bail out! Invalid JSON: %v: %q\n", err, stdin.Text())
			bailed = true
		}

		Time := event.Time.Format("2006-01-02T15:04:05.000000000")
		Elapsed := time.Duration(float64(time.Second) * event.Elapsed)
		Output := strings.TrimSuffix(event.Output, "\n")
		if event.Test == "" {
			if event.Action == "fail" && pkgTestCnt[event.Package] == 0 {
				fmt.Println("Bail out!", event.Package)
				bailed = true
			} else {
				fmt.Println("#",
					Time,
					"(took "+Elapsed.String()+")",
					fmt.Sprintf("%-6s", event.Action),
					event.Package,
					Output)
			}
		} else {
			Name := event.Package + "." + event.Test
			// TODO(lukeshu): I think maybe this should also handle "bench"?
			switch event.Action {
			case "pass":
				testCnt++
				pkgTestCnt[event.Package] = pkgTestCnt[event.Package] + 1
				fmt.Printf("ok %d %v # %v (%v) %v\n", testCnt, Name, Time, Elapsed, Output)
			case "fail":
				testCnt++
				pkgTestCnt[event.Package] = pkgTestCnt[event.Package] + 1
				fmt.Printf("not ok %d %v # %v (%v) %v\n", testCnt, Name, Time, Elapsed, Output)
			case "skip":
				testCnt++
				pkgTestCnt[event.Package] = pkgTestCnt[event.Package] + 1
				fmt.Printf("ok %d %v # SKIP %v (%v) %v\n", testCnt, Name, Time, Elapsed, Output)
			default:
				fmt.Println("#",
					Time,
					"(took "+Elapsed.String()+")",
					fmt.Sprintf("%-6s", event.Action),
					Name,
					Output)
			}
		}
	}
	if err := stdin.Err(); err != nil {
		fmt.Println("Bail out!", err)
		bailed = true
	}
	if !bailed {
		fmt.Printf("1..%d\n", testCnt)
	}
}
<|endoftext|>


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

package pull

import (
	"code.gitea.io/gitea/models"
	"code.gitea.io/gitea/modules/git"
	"code.gitea.io/gitea/modules/structs"

	"github.com/pkg/errors"
)

// MergeRequiredContextsCommitStatus returns a commit status state for given required contexts
func MergeRequiredContextsCommitStatus(commitStatuses []*models.CommitStatus, requiredContexts []string) structs.CommitStatusState {
	if len(requiredContexts) == 0 {
		status := models.CalcCommitStatus(commitStatuses)
		if status != nil {
			return status.State
		}
		return structs.CommitStatusSuccess
	}

	var returnedStatus = structs.CommitStatusSuccess
	for _, ctx := range requiredContexts {
		var targetStatus structs.CommitStatusState
		for _, commitStatus := range commitStatuses {
			if commitStatus.Context == ctx {
				targetStatus = commitStatus.State
				break
			}
		}

		if targetStatus == "" {
			targetStatus = structs.CommitStatusPending
		}
		if targetStatus.NoBetterThan(returnedStatus) {
			returnedStatus = targetStatus
		}
	}
	return returnedStatus
}

// IsCommitStatusContextSuccess returns true if all required status check contexts succeed.
func IsCommitStatusContextSuccess(commitStatuses []*models.CommitStatus, requiredContexts []string) bool {
	// If no specific context is required, require that last commit status is a success
	if len(requiredContexts) == 0 {
		status := models.CalcCommitStatus(commitStatuses)
		if status == nil || status.State != structs.CommitStatusSuccess {
			return false
		}
		return true
	}

	for _, ctx := range requiredContexts {
		var found bool
		for _, commitStatus := range commitStatuses {
			if commitStatus.Context == ctx {
				if commitStatus.State != structs.CommitStatusSuccess {
					return false
				}

				found = true
				break
			}
		}
		if !found {
			return false
		}
	}
	return true
}

// IsPullCommitStatusPass returns if all required status checks PASS
func IsPullCommitStatusPass(pr *models.PullRequest) (bool, error) {
	if err := pr.LoadProtectedBranch(); err != nil {
		return false, errors.Wrap(err, "GetLatestCommitStatus")
	}
	if pr.ProtectedBranch == nil || !pr.ProtectedBranch.EnableStatusCheck {
		return true, nil
	}

	state, err := GetPullRequestCommitStatusState(pr)
	if err != nil {
		return false, err
	}
	return state.IsSuccess(), nil
}

// GetPullRequestCommitStatusState returns pull request merged commit status state
func GetPullRequestCommitStatusState(pr *models.PullRequest) (structs.CommitStatusState, error) {
	// Ensure HeadRepo is loaded
	if err := pr.LoadHeadRepo(); err != nil {
		return "", errors.Wrap(err, "LoadHeadRepo")
	}

	// check if all required status checks are successful
	headGitRepo, err := git.OpenRepository(pr.HeadRepo.RepoPath())
	if err != nil {
		return "", errors.Wrap(err, "OpenRepository")
	}
	defer headGitRepo.Close()

	if !headGitRepo.IsBranchExist(pr.HeadBranch) {
		return "", errors.New("Head branch does not exist, can not merge")
	}

	sha, err := headGitRepo.GetBranchCommitID(pr.HeadBranch)
	if err != nil {
		return "", errors.Wrap(err, "GetBranchCommitID")
	}

	if err := pr.LoadBaseRepo(); err != nil {
		return "", errors.Wrap(err, "LoadBaseRepo")
	}

	commitStatuses, err := models.GetLatestCommitStatus(pr.BaseRepo, sha, 0)
	if err != nil {
		return "", errors.Wrap(err, "GetLatestCommitStatus")
	}

	return MergeRequiredContextsCommitStatus(commitStatuses, pr.ProtectedBranch.StatusCheckContexts), nil
}
<commit_msg>Fix bug on pull view when required status check no ci result (#10648)<commit_after>// Copyright 2019 The Gitea Authors.
// All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package pull

import (
	"code.gitea.io/gitea/models"
	"code.gitea.io/gitea/modules/git"
	"code.gitea.io/gitea/modules/structs"

	"github.com/pkg/errors"
)

// MergeRequiredContextsCommitStatus returns a commit status state for given required contexts
func MergeRequiredContextsCommitStatus(commitStatuses []*models.CommitStatus, requiredContexts []string) structs.CommitStatusState {
	if len(requiredContexts) == 0 {
		status := models.CalcCommitStatus(commitStatuses)
		if status != nil {
			return status.State
		}
		return structs.CommitStatusSuccess
	}

	var returnedStatus = structs.CommitStatusSuccess
	for _, ctx := range requiredContexts {
		var targetStatus structs.CommitStatusState
		for _, commitStatus := range commitStatuses {
			if commitStatus.Context == ctx {
				targetStatus = commitStatus.State
				break
			}
		}

		if targetStatus == "" {
			targetStatus = structs.CommitStatusPending
			commitStatuses = append(commitStatuses, &models.CommitStatus{
				State:       targetStatus,
				Context:     ctx,
				Description: "Pending",
			})
		}
		if targetStatus.NoBetterThan(returnedStatus) {
			returnedStatus = targetStatus
		}
	}
	return returnedStatus
}

// IsCommitStatusContextSuccess returns true if all required status check contexts succeed.
func IsCommitStatusContextSuccess(commitStatuses []*models.CommitStatus, requiredContexts []string) bool {
	// If no specific context is required, require that last commit status is a success
	if len(requiredContexts) == 0 {
		status := models.CalcCommitStatus(commitStatuses)
		if status == nil || status.State != structs.CommitStatusSuccess {
			return false
		}
		return true
	}

	for _, ctx := range requiredContexts {
		var found bool
		for _, commitStatus := range commitStatuses {
			if commitStatus.Context == ctx {
				if commitStatus.State != structs.CommitStatusSuccess {
					return false
				}

				found = true
				break
			}
		}
		if !found {
			return false
		}
	}
	return true
}

// IsPullCommitStatusPass returns if all required status checks PASS
func IsPullCommitStatusPass(pr *models.PullRequest) (bool, error) {
	if err := pr.LoadProtectedBranch(); err != nil {
		return false, errors.Wrap(err, "GetLatestCommitStatus")
	}
	if pr.ProtectedBranch == nil || !pr.ProtectedBranch.EnableStatusCheck {
		return true, nil
	}

	state, err := GetPullRequestCommitStatusState(pr)
	if err != nil {
		return false, err
	}
	return state.IsSuccess(), nil
}

// GetPullRequestCommitStatusState returns pull request merged commit status state
func GetPullRequestCommitStatusState(pr *models.PullRequest) (structs.CommitStatusState, error) {
	// Ensure HeadRepo is loaded
	if err := pr.LoadHeadRepo(); err != nil {
		return "", errors.Wrap(err, "LoadHeadRepo")
	}

	// check if all required status checks are successful
	headGitRepo, err := git.OpenRepository(pr.HeadRepo.RepoPath())
	if err != nil {
		return "", errors.Wrap(err, "OpenRepository")
	}
	defer headGitRepo.Close()

	if !headGitRepo.IsBranchExist(pr.HeadBranch) {
		return "", errors.New("Head branch does not exist, can not merge")
	}

	sha, err := headGitRepo.GetBranchCommitID(pr.HeadBranch)
	if err != nil {
		return "", errors.Wrap(err, "GetBranchCommitID")
	}

	if err := pr.LoadBaseRepo(); err != nil {
		return "", errors.Wrap(err, "LoadBaseRepo")
	}

	commitStatuses, err := models.GetLatestCommitStatus(pr.BaseRepo, sha, 0)
	if err != nil {
		return "", errors.Wrap(err, "GetLatestCommitStatus")
	}

	return MergeRequiredContextsCommitStatus(commitStatuses, pr.ProtectedBranch.StatusCheckContexts), nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"os/user"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	"github.com/BurntSushi/toml"
	"github.com/influxdb/influxdb/graphite"
)

const (
	// DefaultPointBatchSize represents the number of points to batch together.
	DefaultPointBatchSize = 100

	// DefaultPointBatchSize represents the number of writes to batch together.
	DefaultWriteBatchSize = 10 * 1024 * 1024 // 10MB

	// DefaultConcurrentShardQueryLimit represents the number of shards that
	// can be queried concurrently at one time.
	DefaultConcurrentShardQueryLimit = 10

	// DefaultAPIReadTimeout represents the duration before an API request times out.
	DefaultAPIReadTimeout = 5 * time.Second

	// DefaultBrokerPort represents the default port the broker runs on.
	DefaultBrokerPort = 8086

	// DefaultHTTPAPIPort represents the default port the HTTP API runs on.
	DefaultHTTPAPIPort = 8086
)

// Config represents the configuration format for the influxd binary.
type (
	Graphite struct {
		Addr          string `toml:"address"`
		Database      string `toml:"database"`
		Enabled       bool   `toml:"enabled"`
		Port          uint16 `toml:"port"`
		Protocol      string `toml:"protocol"`
		NamePosition  string `toml:"name-position"`
		NameSeparator string `toml:"name-separator"`
	}

	Config struct {
		Hostname          string `toml:"hostname"`
		BindAddress       string `toml:"bind-address"`
		ReportingDisabled bool   `toml:"reporting-disabled"`
		Version           string `toml:"-"`
		InfluxDBVersion   string `toml:"-"`

		Admin struct {
			Port   int    `toml:"port"`
			Assets string `toml:"assets"`
		} `toml:"admin"`

		HTTPAPI struct {
			Port        int      `toml:"port"`
			SSLPort     int      `toml:"ssl-port"`
			SSLCertPath string   `toml:"ssl-cert"`
			ReadTimeout Duration `toml:"read-timeout"`
		} `toml:"api"`

		Graphites []Graphite `toml:"graphite"`

		InputPlugins struct {
			UDPInput struct {
				Enabled  bool   `toml:"enabled"`
				Port     uint16 `toml:"port"`
				Database string `toml:"database"`
			} `toml:"udp"`
			UDPServersInput []struct {
				Enabled  bool   `toml:"enabled"`
				Port     int    `toml:"port"`
				Database string `toml:"database"`
			} `toml:"udp_servers"`
		} `toml:"input_plugins"`

		Broker struct {
			Port    int      `toml:"port"`
			Dir     string   `toml:"dir"`
			Timeout Duration `toml:"election-timeout"`
		} `toml:"broker"`

		Data struct {
			Dir                  string                    `toml:"dir"`
			WriteBufferSize      int                       `toml:"write-buffer-size"`
			MaxOpenShards        int                       `toml:"max-open-shards"`
			PointBatchSize       int                       `toml:"point-batch-size"`
			WriteBatchSize       int                       `toml:"write-batch-size"`
			Engines              map[string]toml.Primitive `toml:"engines"`
			RetentionSweepPeriod Duration                  `toml:"retention-sweep-period"`
		} `toml:"data"`

		Cluster struct {
			Dir                       string   `toml:"dir"`
			ProtobufPort              int      `toml:"protobuf_port"`
			ProtobufTimeout           Duration `toml:"protobuf_timeout"`
			ProtobufHeartbeatInterval Duration `toml:"protobuf_heartbeat"`
			MinBackoff                Duration `toml:"protobuf_min_backoff"`
			MaxBackoff                Duration `toml:"protobuf_max_backoff"`
			WriteBufferSize           int      `toml:"write-buffer-size"`
			ConcurrentShardQueryLimit int      `toml:"concurrent-shard-query-limit"`
			MaxResponseBufferSize     int      `toml:"max-response-buffer-size"`
		} `toml:"cluster"`

		Logging struct {
			File  string `toml:"file"`
			Level string `toml:"level"`
		} `toml:"logging"`
	}
)

// NewConfig returns an instance of Config with reasonable defaults.
func NewConfig() *Config {
	u, _ := user.Current()

	c := &Config{}
	c.Data.RetentionSweepPeriod = Duration(10 * time.Minute)
	c.Cluster.ConcurrentShardQueryLimit = DefaultConcurrentShardQueryLimit
	c.Broker.Dir = filepath.Join(u.HomeDir, ".influxdb/broker")
	c.Broker.Port = DefaultBrokerPort
	c.Broker.Timeout = Duration(1 * time.Second)
	c.HTTPAPI.Port = DefaultHTTPAPIPort
	c.HTTPAPI.ReadTimeout = Duration(DefaultAPIReadTimeout)
	c.Cluster.MinBackoff = Duration(1 * time.Second)
	c.Cluster.MaxBackoff = Duration(10 * time.Second)
	c.Cluster.ProtobufHeartbeatInterval = Duration(10 * time.Millisecond)
	c.Data.Dir = filepath.Join(u.HomeDir, ".influxdb/data")
	c.Data.WriteBufferSize = 1000
	c.Cluster.WriteBufferSize = 1000
	c.Cluster.MaxResponseBufferSize = 100

	// Detect hostname (or set to localhost).
	if c.Hostname, _ = os.Hostname(); c.Hostname == "" {
		c.Hostname = "localhost"
	}

	// FIX(benbjohnson): Append where the udp servers are actually used.
	// config.UDPServers = append(config.UDPServers, UDPInputConfig{
	// 	Enabled:  tomlConfiguration.InputPlugins.UDPInput.Enabled,
	// 	Database: tomlConfiguration.InputPlugins.UDPInput.Database,
	// 	Port:     tomlConfiguration.InputPlugins.UDPInput.Port,
	// })

	return c
}

// PointBatchSize returns the data point batch size, if set.
// If not set, the LevelDB point batch size is returned.
// If that is not set then the default point batch size is returned.
func (c *Config) PointBatchSize() int {
	if c.Data.PointBatchSize != 0 {
		return c.Data.PointBatchSize
	}
	return DefaultPointBatchSize
}

// WriteBatchSize returns the data write batch size, if set.
// If not set, the LevelDB write batch size is returned.
// If that is not set then the default write batch size is returned.
func (c *Config) WriteBatchSize() int {
	if c.Data.WriteBatchSize != 0 {
		return c.Data.WriteBatchSize
	}
	return DefaultWriteBatchSize
}

// MaxOpenShards returns the maximum number of shards to keep open at once.
func (c *Config) MaxOpenShards() int {
	return c.Data.MaxOpenShards
}

// ApiHTTPListenAddr returns the binding address the API HTTP server
func (c *Config) ApiHTTPListenAddr() string {
	return fmt.Sprintf("%s:%d", c.BindAddress, c.HTTPAPI.Port)
}

// BrokerListenAddr returns the binding address the Broker server
func (c *Config) BrokerListenAddr() string {
	return fmt.Sprintf("%s:%d", c.BindAddress, c.Broker.Port)
}

// BrokerConnectionString returns the address required to contact the Broker server
func (c *Config) BrokerConnectionString() string {
	return fmt.Sprintf("http://%s:%d", c.Hostname, c.Broker.Port)
}

// Size represents a TOML parseable file size.
// Users can specify size using "m" for megabytes and "g" for gigabytes.
type Size int

// UnmarshalText parses a byte size from text.
func (s *Size) UnmarshalText(text []byte) error {
	// Parse numeric portion of value.
	length := len(string(text))
	size, err := strconv.ParseInt(string(text[:length-1]), 10, 64)
	if err != nil {
		return err
	}

	// Parse unit of measure ("m", "g", etc).
	switch suffix := text[len(text)-1]; suffix {
	case 'm':
		size *= 1 << 20 // MB
	case 'g':
		size *= 1 << 30 // GB
	default:
		return fmt.Errorf("unknown size suffix: %c", suffix)
	}

	// Check for overflow.
	if size > maxInt {
		return fmt.Errorf("size %d cannot be represented by an int", size)
	}

	*s = Size(size)
	return nil
}

// Duration is a TOML wrapper type for time.Duration.
type Duration time.Duration

// UnmarshalText parses a TOML value into a duration value.
func (d *Duration) UnmarshalText(text []byte) error {
	// Ignore if there is no value set.
	if len(text) == 0 {
		return nil
	}

	// Otherwise parse as a duration formatted string.
	duration, err := time.ParseDuration(string(text))
	if err != nil {
		return err
	}

	// Set duration and return.
	*d = Duration(duration)
	return nil
}

// ParseConfigFile parses a configuration file at a given path.
func ParseConfigFile(path string) (*Config, error) {
	c := NewConfig()
	if _, err := toml.DecodeFile(path, &c); err != nil {
		return nil, err
	}
	return c, nil
}

// ParseConfig parses a configuration string into a config object.
func ParseConfig(s string) (*Config, error) {
	c := NewConfig()
	if _, err := toml.Decode(s, &c); err != nil {
		return nil, err
	}
	return c, nil
}

// ConnnectionString returns the connection string for this Graphite config in the form host:port.
func (g *Graphite) ConnectionString(defaultBindAddr string) string {

	addr := g.Addr
	// If no address specified, use default.
	if addr == "" {
		addr = defaultBindAddr
	}

	port := g.Port
	// If no port specified, use default.
	if port == 0 {
		port = graphite.DefaultGraphitePort
	}

	return fmt.Sprintf("%s:%d", addr, port)
}

// NameSeparatorString returns the character separating fields for Graphite data, or the default
// if no separator is set.
func (g *Graphite) NameSeparatorString() string {
	if g.NameSeparator == "" {
		return graphite.DefaultGraphiteNameSeparator
	}
	return g.NameSeparator
}

func (g *Graphite) LastEnabled() bool {
	return g.NamePosition == strings.ToLower("last")
}

/*
func (c *Config) AdminHTTPPortString() string {
	if c.AdminHTTPPort <= 0 {
		return ""
	}
	return fmt.Sprintf("%s:%d", c.BindAddress, c.AdminHTTPPort)
}

func (c *Config) APIHTTPSPortString() string {
	return fmt.Sprintf("%s:%d", c.BindAddress, c.APIHTTPSPort)
}

func (c *Config) GraphitePortString() string {
	if c.GraphitePort <= 0 {
		return ""
	}
	return fmt.Sprintf("%s:%d", c.BindAddress, c.GraphitePort)
}

func (c *Config) UDPInputPortString(port int) string {
	if port <= 0 {
		return ""
	}
	return fmt.Sprintf("%s:%d", c.BindAddress, port)
}

func (c *Config) ProtobufConnectionString() string {
	return fmt.Sprintf("%s:%d", c.Hostname, c.ProtobufPort)
}

func (c *Config) ProtobufListenString() string {
	return fmt.Sprintf("%s:%d", c.BindAddress, c.ProtobufPort)
}

*/

// maxInt is the largest integer representable by a word (architeture dependent).
const maxInt = int64(^uint(0) >> 1)
<commit_msg>GoDoc "LastEnabled"<commit_after>package main

import (
	"fmt"
	"os"
	"os/user"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	"github.com/BurntSushi/toml"
	"github.com/influxdb/influxdb/graphite"
)

const (
	// DefaultPointBatchSize represents the number of points to batch together.
	DefaultPointBatchSize = 100

	// DefaultPointBatchSize represents the number of writes to batch together.
	DefaultWriteBatchSize = 10 * 1024 * 1024 // 10MB

	// DefaultConcurrentShardQueryLimit represents the number of shards that
	// can be queried concurrently at one time.
	DefaultConcurrentShardQueryLimit = 10

	// DefaultAPIReadTimeout represents the duration before an API request times out.
	DefaultAPIReadTimeout = 5 * time.Second

	// DefaultBrokerPort represents the default port the broker runs on.
	DefaultBrokerPort = 8086

	// DefaultHTTPAPIPort represents the default port the HTTP API runs on.
	DefaultHTTPAPIPort = 8086
)

// Config represents the configuration format for the influxd binary.
type (
	Graphite struct {
		Addr          string `toml:"address"`
		Database      string `toml:"database"`
		Enabled       bool   `toml:"enabled"`
		Port          uint16 `toml:"port"`
		Protocol      string `toml:"protocol"`
		NamePosition  string `toml:"name-position"`
		NameSeparator string `toml:"name-separator"`
	}

	Config struct {
		Hostname          string `toml:"hostname"`
		BindAddress       string `toml:"bind-address"`
		ReportingDisabled bool   `toml:"reporting-disabled"`
		Version           string `toml:"-"`
		InfluxDBVersion   string `toml:"-"`

		Admin struct {
			Port   int    `toml:"port"`
			Assets string `toml:"assets"`
		} `toml:"admin"`

		HTTPAPI struct {
			Port        int      `toml:"port"`
			SSLPort     int      `toml:"ssl-port"`
			SSLCertPath string   `toml:"ssl-cert"`
			ReadTimeout Duration `toml:"read-timeout"`
		} `toml:"api"`

		Graphites []Graphite `toml:"graphite"`

		InputPlugins struct {
			UDPInput struct {
				Enabled  bool   `toml:"enabled"`
				Port     uint16 `toml:"port"`
				Database string `toml:"database"`
			} `toml:"udp"`
			UDPServersInput []struct {
				Enabled  bool   `toml:"enabled"`
				Port     int    `toml:"port"`
				Database string `toml:"database"`
			} `toml:"udp_servers"`
		} `toml:"input_plugins"`

		Broker struct {
			Port    int      `toml:"port"`
			Dir     string   `toml:"dir"`
			Timeout Duration `toml:"election-timeout"`
		} `toml:"broker"`

		Data struct {
			Dir                  string                    `toml:"dir"`
			WriteBufferSize      int                       `toml:"write-buffer-size"`
			MaxOpenShards        int                       `toml:"max-open-shards"`
			PointBatchSize       int                       `toml:"point-batch-size"`
			WriteBatchSize       int                       `toml:"write-batch-size"`
			Engines              map[string]toml.Primitive `toml:"engines"`
			RetentionSweepPeriod Duration                  `toml:"retention-sweep-period"`
		} `toml:"data"`

		Cluster struct {
			Dir                       string   `toml:"dir"`
			ProtobufPort              int      `toml:"protobuf_port"`
			ProtobufTimeout           Duration `toml:"protobuf_timeout"`
			ProtobufHeartbeatInterval Duration `toml:"protobuf_heartbeat"`
			MinBackoff                Duration `toml:"protobuf_min_backoff"`
			MaxBackoff                Duration `toml:"protobuf_max_backoff"`
			WriteBufferSize           int      `toml:"write-buffer-size"`
			ConcurrentShardQueryLimit int      `toml:"concurrent-shard-query-limit"`
			MaxResponseBufferSize     int      `toml:"max-response-buffer-size"`
		} `toml:"cluster"`

		Logging struct {
			File  string `toml:"file"`
			Level string `toml:"level"`
		} `toml:"logging"`
	}
)

// NewConfig returns an instance of Config with reasonable defaults.
func NewConfig() *Config {
	u, _ := user.Current()

	c := &Config{}
	c.Data.RetentionSweepPeriod = Duration(10 * time.Minute)
	c.Cluster.ConcurrentShardQueryLimit = DefaultConcurrentShardQueryLimit
	c.Broker.Dir = filepath.Join(u.HomeDir, ".influxdb/broker")
	c.Broker.Port = DefaultBrokerPort
	c.Broker.Timeout = Duration(1 * time.Second)
	c.HTTPAPI.Port = DefaultHTTPAPIPort
	c.HTTPAPI.ReadTimeout = Duration(DefaultAPIReadTimeout)
	c.Cluster.MinBackoff = Duration(1 * time.Second)
	c.Cluster.MaxBackoff = Duration(10 * time.Second)
	c.Cluster.ProtobufHeartbeatInterval = Duration(10 * time.Millisecond)
	c.Data.Dir = filepath.Join(u.HomeDir, ".influxdb/data")
	c.Data.WriteBufferSize = 1000
	c.Cluster.WriteBufferSize = 1000
	c.Cluster.MaxResponseBufferSize = 100

	// Detect hostname (or set to localhost).
	if c.Hostname, _ = os.Hostname(); c.Hostname == "" {
		c.Hostname = "localhost"
	}

	// FIX(benbjohnson): Append where the udp servers are actually used.
	// config.UDPServers = append(config.UDPServers, UDPInputConfig{
	// 	Enabled:  tomlConfiguration.InputPlugins.UDPInput.Enabled,
	// 	Database: tomlConfiguration.InputPlugins.UDPInput.Database,
	// 	Port:     tomlConfiguration.InputPlugins.UDPInput.Port,
	// })

	return c
}

// PointBatchSize returns the data point batch size, if set.
// If not set, the LevelDB point batch size is returned.
// If that is not set then the default point batch size is returned.
func (c *Config) PointBatchSize() int {
	if c.Data.PointBatchSize != 0 {
		return c.Data.PointBatchSize
	}
	return DefaultPointBatchSize
}

// WriteBatchSize returns the data write batch size, if set.
// If not set, the LevelDB write batch size is returned.
// If that is not set then the default write batch size is returned.
func (c *Config) WriteBatchSize() int {
	if c.Data.WriteBatchSize != 0 {
		return c.Data.WriteBatchSize
	}
	return DefaultWriteBatchSize
}

// MaxOpenShards returns the maximum number of shards to keep open at once.
func (c *Config) MaxOpenShards() int {
	return c.Data.MaxOpenShards
}

// ApiHTTPListenAddr returns the binding address the API HTTP server
func (c *Config) ApiHTTPListenAddr() string {
	return fmt.Sprintf("%s:%d", c.BindAddress, c.HTTPAPI.Port)
}

// BrokerListenAddr returns the binding address the Broker server
func (c *Config) BrokerListenAddr() string {
	return fmt.Sprintf("%s:%d", c.BindAddress, c.Broker.Port)
}

// BrokerConnectionString returns the address required to contact the Broker server
func (c *Config) BrokerConnectionString() string {
	return fmt.Sprintf("http://%s:%d", c.Hostname, c.Broker.Port)
}

// Size represents a TOML parseable file size.
// Users can specify size using "m" for megabytes and "g" for gigabytes.
type Size int

// UnmarshalText parses a byte size from text.
func (s *Size) UnmarshalText(text []byte) error {
	// Parse numeric portion of value.
	length := len(string(text))
	size, err := strconv.ParseInt(string(text[:length-1]), 10, 64)
	if err != nil {
		return err
	}

	// Parse unit of measure ("m", "g", etc).
	switch suffix := text[len(text)-1]; suffix {
	case 'm':
		size *= 1 << 20 // MB
	case 'g':
		size *= 1 << 30 // GB
	default:
		return fmt.Errorf("unknown size suffix: %c", suffix)
	}

	// Check for overflow.
	if size > maxInt {
		return fmt.Errorf("size %d cannot be represented by an int", size)
	}

	*s = Size(size)
	return nil
}

// Duration is a TOML wrapper type for time.Duration.
type Duration time.Duration

// UnmarshalText parses a TOML value into a duration value.
func (d *Duration) UnmarshalText(text []byte) error {
	// Ignore if there is no value set.
	if len(text) == 0 {
		return nil
	}

	// Otherwise parse as a duration formatted string.
	duration, err := time.ParseDuration(string(text))
	if err != nil {
		return err
	}

	// Set duration and return.
	*d = Duration(duration)
	return nil
}

// ParseConfigFile parses a configuration file at a given path.
func ParseConfigFile(path string) (*Config, error) {
	c := NewConfig()
	if _, err := toml.DecodeFile(path, &c); err != nil {
		return nil, err
	}
	return c, nil
}

// ParseConfig parses a configuration string into a config object.
func ParseConfig(s string) (*Config, error) {
	c := NewConfig()
	if _, err := toml.Decode(s, &c); err != nil {
		return nil, err
	}
	return c, nil
}

// ConnnectionString returns the connection string for this Graphite config in the form host:port.
func (g *Graphite) ConnectionString(defaultBindAddr string) string {

	addr := g.Addr
	// If no address specified, use default.
	if addr == "" {
		addr = defaultBindAddr
	}

	port := g.Port
	// If no port specified, use default.
	if port == 0 {
		port = graphite.DefaultGraphitePort
	}

	return fmt.Sprintf("%s:%d", addr, port)
}

// NameSeparatorString returns the character separating fields for Graphite data, or the default
// if no separator is set.
func (g *Graphite) NameSeparatorString() string {
	if g.NameSeparator == "" {
		return graphite.DefaultGraphiteNameSeparator
	}
	return g.NameSeparator
}

// LastEnabled returns whether the Graphite Server shoudl intepret the last field as "name".
func (g *Graphite) LastEnabled() bool {
	return g.NamePosition == strings.ToLower("last")
}

/*
func (c *Config) AdminHTTPPortString() string {
	if c.AdminHTTPPort <= 0 {
		return ""
	}
	return fmt.Sprintf("%s:%d", c.BindAddress, c.AdminHTTPPort)
}

func (c *Config) APIHTTPSPortString() string {
	return fmt.Sprintf("%s:%d", c.BindAddress, c.APIHTTPSPort)
}

func (c *Config) GraphitePortString() string {
	if c.GraphitePort <= 0 {
		return ""
	}
	return fmt.Sprintf("%s:%d", c.BindAddress, c.GraphitePort)
}

func (c *Config) UDPInputPortString(port int) string {
	if port <= 0 {
		return ""
	}
	return fmt.Sprintf("%s:%d", c.BindAddress, port)
}

func (c *Config) ProtobufConnectionString() string {
	return fmt.Sprintf("%s:%d", c.Hostname, c.ProtobufPort)
}

func (c *Config) ProtobufListenString() string {
	return fmt.Sprintf("%s:%d", c.BindAddress, c.ProtobufPort)
}

*/

// maxInt is the largest integer representable by a word (architeture dependent).
const maxInt = int64(^uint(0) >> 1)
<|endoftext|>


<commit_before>package cmd

// DO NOT EDIT manually! Generated by hack/update-version.sh
var version = "0.10.1"
<commit_msg>Bump version to 0.10.1-dev<commit_after>package cmd

// DO NOT EDIT manually! Generated by hack/update-version.sh
var version = "0.10.1-dev"
<|endoftext|>


<commit_before>package main

import (
	"io"
	"math/rand"
	"net/http"
	"sync"
	"testing"
	"time"
)

var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
var once sync.Once
var docSize int64 = 1 << 12

func randSeq(n int) string {
	once.Do(func() { rand.Seed(time.Now().UTC().UnixNano()) })
	b := make([]rune, n)
	for i := range b {
		b[i] = letters[rand.Intn(len(letters))]
	}
	return string(b)
}

type ConstReader struct{}

func (r ConstReader) Read(p []byte) (n int, err error) {
	for i := range p {
		p[i] = 'a'
	}
	return len(p), nil
}

var reader ConstReader

func timeParam(r *http.Request) string {
	if p := r.URL.Query().Get("time"); p != "" {
		return p
	}
	return "30"
}

// insert inserts a single file in to the filesystem
func insert(t *testing.T) {
	url := "http://172.17.42.1/pfs/" + randSeq(10)
	resp, err := http.Post(url, "application/text", io.LimitReader(reader, docSize))
	if err != nil {
		t.Fatal(err)
	}
	if resp.Status != "200" {
		t.Error(resp)
	}
}

func traffic(t *testing.T) {
	workers := 3
	var wg sync.WaitGroup
	wg.Add(workers)
	startTime := time.Now()
	for i := 0; i < workers; i++ {
		go func() {
			defer wg.Done()
			for time.Since(startTime) < (10 * time.Second) {
				insert(t)
			}
		}()
	}
	wg.Wait()
}

func commit(t *testing.T) {
	resp, err := http.Post("http://172.17.42.1/commit", "application/test", nil)
	if err != nil {
		t.Fatal(err)
	}
	if resp.Status != "200" {
		t.Error(resp)
	}
}

func TestSmoke(t *testing.T) {
	for i := 0; i < 20; i++ {
		traffic(t)
		commit(t)
	}
}
<commit_msg>Router_test actually passes.<commit_after>package main

import (
	"io"
	"math/rand"
	"net/http"
	"sync"
	"testing"
	"time"
)

var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
var once sync.Once
var docSize int64 = 1 << 12

func randSeq(n int) string {
	once.Do(func() { rand.Seed(time.Now().UTC().UnixNano()) })
	b := make([]rune, n)
	for i := range b {
		b[i] = letters[rand.Intn(len(letters))]
	}
	return string(b)
}

type ConstReader struct{}

func (r ConstReader) Read(p []byte) (n int, err error) {
	for i := range p {
		p[i] = 'a'
	}
	return len(p), nil
}

var reader ConstReader

func timeParam(r *http.Request) string {
	if p := r.URL.Query().Get("time"); p != "" {
		return p
	}
	return "30"
}

// insert inserts a single file in to the filesystem
func insert(t *testing.T) {
	url := "http://172.17.42.1/pfs/" + randSeq(10)
	resp, err := http.Post(url, "application/text", io.LimitReader(reader, docSize))
	if err != nil {
		t.Fatal(err)
	}
	if resp.StatusCode != 200 {
		t.Error(resp.Status)
	}
}

func traffic(t *testing.T) {
	workers := 8
	var wg sync.WaitGroup
	wg.Add(workers)
	startTime := time.Now()
	for i := 0; i < workers; i++ {
		go func() {
			defer wg.Done()
			for time.Since(startTime) < (2 * time.Second) {
				insert(t)
			}
		}()
	}
	wg.Wait()
}

func commit(t *testing.T) {
	resp, err := http.Post("http://172.17.42.1/commit", "application/test", nil)
	if err != nil {
		t.Fatal(err)
	}
	if resp.StatusCode != 200 {
		t.Error(resp.Status)
	}
}

func TestSmoke(t *testing.T) {
	for i := 0; i < 5; i++ {
		for j := 0; j < 5; j++ {
			insert(t)
		}
		commit(t)
	}
}

func TestFire(t *testing.T) {
	for i := 0; i < 5; i++ {
		traffic(t)
		commit(t)
	}
}
<|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes Authors All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cmd

import (
	"github.com/spf13/cobra"
	"k8s.io/minikube/pkg/minikube/out"
	"k8s.io/minikube/pkg/version"
)

var versionCmd = &cobra.Command{
	Use:   "version",
	Short: "Print the version of minikube",
	Long:  `Print the version of minikube.`,
	Run: func(command *cobra.Command, args []string) {
		out.Ln("minikube version: %v", version.GetVersion())
		gitCommitID := version.GetGitCommitID()
		if gitCommitID != "" {
			out.Ln("commit: %v", gitCommitID)
		}
	},
}
<commit_msg>Implement options for the minikube version command<commit_after>/*
Copyright 2016 The Kubernetes Authors All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cmd

import (
	"encoding/json"
	"github.com/spf13/cobra"
	"gopkg.in/yaml.v2"
	"k8s.io/minikube/pkg/minikube/exit"
	"k8s.io/minikube/pkg/minikube/out"
	"k8s.io/minikube/pkg/version"
)

var (
	versionOutput string
	shortVersion  bool
)

var versionCmd = &cobra.Command{
	Use:   "version",
	Short: "Print the version of minikube",
	Long:  `Print the version of minikube.`,
	Run: func(command *cobra.Command, args []string) {
		minikubeVersion := version.GetVersion()
		gitCommitID := version.GetGitCommitID()
		data := map[string]string{
			"minikubeVersion": minikubeVersion,
			"commit":          gitCommitID,
		}
		switch versionOutput {
		case "":
			out.Ln("minikube version: %v", minikubeVersion)
			if !shortVersion && gitCommitID != "" {
				out.Ln("commit: %v", gitCommitID)
			}
		case "json":
			json, err := json.Marshal(data)
			if err != nil {
				exit.WithError("version json failure", err)
			}
			out.Ln(string(json))
		case "yaml":
			yaml, err := yaml.Marshal(data)
			if err != nil {
				exit.WithError("version yaml failure", err)
			}
			out.Ln(string(yaml))
		default:
			exit.WithCodeT(exit.BadUsage, "error: --output must be 'yaml' or 'json'")
		}
	},
}

func init() {
	versionCmd.Flags().StringVarP(&versionOutput, "output", "o", "", "One of 'yaml' or 'json'.")
	versionCmd.Flags().BoolVar(&shortVersion, "short", false, "Print just the version number.")
}
<|endoftext|>