<commit_before>package middleware

import (
	"net/url"
	"strings"

	"gopkg.in/macaron.v1"

	m "github.com/grafana/grafana/pkg/models"
	"github.com/grafana/grafana/pkg/setting"
)

type AuthOptions struct {
	ReqGrafanaAdmin bool
	ReqSignedIn     bool
}

func getRequestUserId(c *Context) int64 {
	userId := c.Session.Get(SESS_KEY_USERID)

	if userId != nil {
		return userId.(int64)
	}

	return 0
}

func getApiKey(c *Context) string {
	header := c.Req.Header.Get("Authorization")
	parts := strings.SplitN(header, " ", 2)
	if len(parts) == 2 && parts[0] == "Bearer" {
		key := parts[1]
		return key
	}

	return ""
}

func accessForbidden(c *Context) {
	if c.IsApiRequest() {
		c.JsonApiErr(403, "Permission denied", nil)
		return
	}

	c.SetCookie("redirect_to", url.QueryEscape(setting.AppSubUrl+c.Req.RequestURI), 0, setting.AppSubUrl+"/")
	c.Redirect(setting.AppSubUrl + "/login")
}

func notAuthorized(c *Context) {
	if c.IsApiRequest() {
		c.JsonApiErr(401, "Unauthorized", nil)
		return
	}

	c.SetCookie("redirect_to", url.QueryEscape(setting.AppSubUrl+c.Req.RequestURI), 0, setting.AppSubUrl+"/")
	c.Redirect(setting.AppSubUrl + "/login")
}

func RoleAuth(roles ...m.RoleType) macaron.Handler {
	return func(c *Context) {
		ok := false
		for _, role := range roles {
			if role == c.OrgRole {
				ok = true
				break
			}
		}
		if !ok {
			accessForbidden(c)
		}
	}
}

func Auth(options *AuthOptions) macaron.Handler {
	return func(c *Context) {
		if !c.IsSignedIn && options.ReqSignedIn && !c.AllowAnonymous {
			notAuthorized(c)
			return
		}

		if !c.IsGrafanaAdmin && options.ReqGrafanaAdmin {
			accessForbidden(c)
			return
		}
	}
}
<commit_msg>redirect "permission denied" requests to "/" (#10773)<commit_after>package middleware

import (
	"net/url"
	"strings"

	"gopkg.in/macaron.v1"

	m "github.com/grafana/grafana/pkg/models"
	"github.com/grafana/grafana/pkg/setting"
)

type AuthOptions struct {
	ReqGrafanaAdmin bool
	ReqSignedIn     bool
}

func getRequestUserId(c *Context) int64 {
	userId := c.Session.Get(SESS_KEY_USERID)

	if userId != nil {
		return userId.(int64)
	}

	return 0
}

func getApiKey(c *Context) string {
	header := c.Req.Header.Get("Authorization")
	parts := strings.SplitN(header, " ", 2)
	if len(parts) == 2 && parts[0] == "Bearer" {
		key := parts[1]
		return key
	}

	return ""
}

func accessForbidden(c *Context) {
	if c.IsApiRequest() {
		c.JsonApiErr(403, "Permission denied", nil)
		return
	}

	c.Redirect(setting.AppSubUrl + "/")
}

func notAuthorized(c *Context) {
	if c.IsApiRequest() {
		c.JsonApiErr(401, "Unauthorized", nil)
		return
	}

	c.SetCookie("redirect_to", url.QueryEscape(setting.AppSubUrl+c.Req.RequestURI), 0, setting.AppSubUrl+"/")
	c.Redirect(setting.AppSubUrl + "/login")
}

func RoleAuth(roles ...m.RoleType) macaron.Handler {
	return func(c *Context) {
		ok := false
		for _, role := range roles {
			if role == c.OrgRole {
				ok = true
				break
			}
		}
		if !ok {
			accessForbidden(c)
		}
	}
}

func Auth(options *AuthOptions) macaron.Handler {
	return func(c *Context) {
		if !c.IsSignedIn && options.ReqSignedIn && !c.AllowAnonymous {
			notAuthorized(c)
			return
		}

		if !c.IsGrafanaAdmin && options.ReqGrafanaAdmin {
			accessForbidden(c)
			return
		}
	}
}
<|endoftext|>


<commit_before>package monitor

import (
	"context"
	"sync"
	"time"
)

type ConditionalSampler interface {
	ConditionWhenFailing(*Condition) SamplerFunc
}

type sampler struct {
	lock      sync.Mutex
	available bool
}

func StartSampling(ctx context.Context, recorder Recorder, interval time.Duration, sampleFn func(previous bool) (*Condition, bool)) ConditionalSampler {
	s := &sampler{
		available: true,
	}

	go func() {
		ticker := time.NewTicker(interval)
		defer ticker.Stop()
		for {
			select {
			case <-ticker.C:
			case <-ctx.Done():
				return
			}
			success := s.isAvailable()
			condition, ok := sampleFn(success)
			if condition != nil {
				recorder.Record(*condition)
			}
			s.setAvailable(ok)
		}
	}()

	return s
}

func (s *sampler) isAvailable() bool {
	s.lock.Lock()
	defer s.lock.Unlock()
	return s.available
}
func (s *sampler) setAvailable(b bool) {
	s.lock.Lock()
	defer s.lock.Unlock()
	s.available = b
}

func (s *sampler) ConditionWhenFailing(condition *Condition) SamplerFunc {
	return func(_ time.Time) []*Condition {
		if s.isAvailable() {
			return nil
		}
		return []*Condition{condition}
	}
}
<commit_msg>Start sampling immediately<commit_after>package monitor

import (
	"context"
	"sync"
	"time"
)

type ConditionalSampler interface {
	ConditionWhenFailing(*Condition) SamplerFunc
}

type sampler struct {
	lock      sync.Mutex
	available bool
}

func StartSampling(ctx context.Context, recorder Recorder, interval time.Duration, sampleFn func(previous bool) (*Condition, bool)) ConditionalSampler {
	s := &sampler{
		available: true,
	}

	go func() {
		ticker := time.NewTicker(interval)
		defer ticker.Stop()
		for {
			success := s.isAvailable()
			condition, ok := sampleFn(success)
			if condition != nil {
				recorder.Record(*condition)
			}
			s.setAvailable(ok)

			select {
			case <-ticker.C:
			case <-ctx.Done():
				return
			}
		}
	}()

	return s
}

func (s *sampler) isAvailable() bool {
	s.lock.Lock()
	defer s.lock.Unlock()
	return s.available
}
func (s *sampler) setAvailable(b bool) {
	s.lock.Lock()
	defer s.lock.Unlock()
	s.available = b
}

func (s *sampler) ConditionWhenFailing(condition *Condition) SamplerFunc {
	return func(_ time.Time) []*Condition {
		if s.isAvailable() {
			return nil
		}
		return []*Condition{condition}
	}
}
<|endoftext|>


<commit_before>package mutation

import (
	"fmt"
	"sort"
	"sync"

	"github.com/google/go-cmp/cmp"
	"github.com/pkg/errors"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)

// System keeps the list of mutations and
// provides an interface to apply mutations.
type System struct {
	schemaDB        SchemaDB
	orderedMutators []Mutator
	mutatorsMap     map[ID]Mutator
	sync.RWMutex
}

// NewSystem initializes an empty mutation system
func NewSystem() *System {
	return &System{
		orderedMutators: make([]Mutator, 0),
		mutatorsMap:     make(map[ID]Mutator),
	}
}

// Upsert updates or insert the given object, and returns
// an error in case of conflicts
func (s *System) Upsert(m Mutator) error {
	s.Lock()
	defer s.Unlock()

	current, ok := s.mutatorsMap[m.ID()]
	if ok && !m.HasDiff(current) {
		return nil
	}

	toAdd := m.DeepCopy()

	// Checking schema consistency only if the mutator has schema
	if withSchema, ok := toAdd.(MutatorWithSchema); ok {
		err := s.schemaDB.Upsert(withSchema)
		if err != nil {
			return errors.Wrapf(err, "Schema upsert failed")
		}
	}

	s.mutatorsMap[toAdd.ID()] = toAdd

	i := sort.Search(len(s.orderedMutators), func(i int) bool {
		return greaterOrEqual(s.orderedMutators[i].ID(), toAdd.ID())
	})

	if i == len(s.orderedMutators) { // Adding to the bottom of the list
		s.orderedMutators = append(s.orderedMutators, toAdd)
		return nil
	}

	found := equal(s.orderedMutators[i].ID(), toAdd.ID())
	if found {
		s.orderedMutators[i] = toAdd
		return nil
	}

	s.orderedMutators = append(s.orderedMutators, nil)
	copy(s.orderedMutators[i+1:], s.orderedMutators[i:])
	s.orderedMutators[i] = toAdd
	return nil
}

// Mutate applies the mutation in place to the given object
func (s *System) Mutate(obj *unstructured.Unstructured, ns *corev1.Namespace) (bool, error) {
	s.RLock()
	defer s.RUnlock()
	original := obj.DeepCopy()
	maxIterations := len(s.orderedMutators) + 1

	for i := 0; i < maxIterations; i++ {
		old := obj.DeepCopy()
		for _, m := range s.orderedMutators {
			if m.Matches(obj, ns) {
				err := m.Mutate(obj)
				if err != nil {
					return false, errors.Wrapf(err, "mutation failed for %s %s", obj.GroupVersionKind().Group, obj.GroupVersionKind().Kind)
				}
			}
		}
		if cmp.Equal(old, obj) {
			if i == 0 {
				return false, nil
			}
			if cmp.Equal(original, obj) {
				return false, fmt.Errorf("oscillating mutation for %s %s", obj.GroupVersionKind().Group, obj.GroupVersionKind().Kind)
			}
			return true, nil
		}
	}
	return false, fmt.Errorf("mutation not converging for %s %s", obj.GroupVersionKind().Group, obj.GroupVersionKind().Kind)
}

// Remove removes the mutator from the mutation system
func (s *System) Remove(id ID) error {
	s.Lock()
	defer s.Unlock()

	if _, ok := s.mutatorsMap[id]; !ok {
		return nil
	}

	err := s.schemaDB.Remove(id)
	// TODO: get back on this once schemaDB implementation is done
	// and understand how to recover from a failed remove.
	// One option is to rebuild the schema from scratch using the cache content.
	if err != nil {
		return errors.Wrapf(err, "Schema remove failed")
	}

	i := sort.Search(len(s.orderedMutators), func(i int) bool {
		res := equal(s.orderedMutators[i].ID(), id)
		if res {
			return true
		}
		return greaterOrEqual(s.orderedMutators[i].ID(), id)
	})

	delete(s.mutatorsMap, id)

	found := equal(s.orderedMutators[i].ID(), id)

	// The map is expected to be in sync with the list, so if we don't find it
	// we return an error.
	if !found {
		return fmt.Errorf("Failed to find mutator with ID %v on sorted list", id)
	}
	copy(s.orderedMutators[i:], s.orderedMutators[i+1:])
	s.orderedMutators[len(s.orderedMutators)-1] = nil
	s.orderedMutators = s.orderedMutators[:len(s.orderedMutators)-1]
	return nil
}

func greaterOrEqual(id1, id2 ID) bool {
	if id1.Group > id2.Group {
		return true
	}
	if id1.Group < id2.Group {
		return false
	}
	if id1.Kind > id2.Kind {
		return true
	}
	if id1.Kind < id2.Kind {
		return false
	}
	if id1.Namespace > id2.Namespace {
		return true
	}
	if id1.Namespace < id2.Namespace {
		return false
	}
	if id1.Name > id2.Name {
		return true
	}
	if id1.Name < id2.Name {
		return false
	}
	return true
}

func equal(id1, id2 ID) bool {
	if id1.Group == id2.Group &&
		id1.Kind == id2.Kind &&
		id1.Namespace == id2.Namespace &&
		id1.Name == id2.Name {
		return true
	}
	return false
}
<commit_msg>Update comment `Mutate` function (#1040)<commit_after>package mutation

import (
	"fmt"
	"sort"
	"sync"

	"github.com/google/go-cmp/cmp"
	"github.com/pkg/errors"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)

// System keeps the list of mutations and
// provides an interface to apply mutations.
type System struct {
	schemaDB        SchemaDB
	orderedMutators []Mutator
	mutatorsMap     map[ID]Mutator
	sync.RWMutex
}

// NewSystem initializes an empty mutation system
func NewSystem() *System {
	return &System{
		orderedMutators: make([]Mutator, 0),
		mutatorsMap:     make(map[ID]Mutator),
	}
}

// Upsert updates or insert the given object, and returns
// an error in case of conflicts
func (s *System) Upsert(m Mutator) error {
	s.Lock()
	defer s.Unlock()

	current, ok := s.mutatorsMap[m.ID()]
	if ok && !m.HasDiff(current) {
		return nil
	}

	toAdd := m.DeepCopy()

	// Checking schema consistency only if the mutator has schema
	if withSchema, ok := toAdd.(MutatorWithSchema); ok {
		err := s.schemaDB.Upsert(withSchema)
		if err != nil {
			return errors.Wrapf(err, "Schema upsert failed")
		}
	}

	s.mutatorsMap[toAdd.ID()] = toAdd

	i := sort.Search(len(s.orderedMutators), func(i int) bool {
		return greaterOrEqual(s.orderedMutators[i].ID(), toAdd.ID())
	})

	if i == len(s.orderedMutators) { // Adding to the bottom of the list
		s.orderedMutators = append(s.orderedMutators, toAdd)
		return nil
	}

	found := equal(s.orderedMutators[i].ID(), toAdd.ID())
	if found {
		s.orderedMutators[i] = toAdd
		return nil
	}

	s.orderedMutators = append(s.orderedMutators, nil)
	copy(s.orderedMutators[i+1:], s.orderedMutators[i:])
	s.orderedMutators[i] = toAdd
	return nil
}

// Mutate applies the mutation in place to the given object. Returns
// true if a mutation was performed.
func (s *System) Mutate(obj *unstructured.Unstructured, ns *corev1.Namespace) (bool, error) {
	s.RLock()
	defer s.RUnlock()
	original := obj.DeepCopy()
	maxIterations := len(s.orderedMutators) + 1

	for i := 0; i < maxIterations; i++ {
		old := obj.DeepCopy()
		for _, m := range s.orderedMutators {
			if m.Matches(obj, ns) {
				err := m.Mutate(obj)
				if err != nil {
					return false, errors.Wrapf(err, "mutation failed for %s %s", obj.GroupVersionKind().Group, obj.GroupVersionKind().Kind)
				}
			}
		}
		if cmp.Equal(old, obj) {
			if i == 0 {
				return false, nil
			}
			if cmp.Equal(original, obj) {
				return false, fmt.Errorf("oscillating mutation for %s %s", obj.GroupVersionKind().Group, obj.GroupVersionKind().Kind)
			}
			return true, nil
		}
	}
	return false, fmt.Errorf("mutation not converging for %s %s", obj.GroupVersionKind().Group, obj.GroupVersionKind().Kind)
}

// Remove removes the mutator from the mutation system
func (s *System) Remove(id ID) error {
	s.Lock()
	defer s.Unlock()

	if _, ok := s.mutatorsMap[id]; !ok {
		return nil
	}

	err := s.schemaDB.Remove(id)
	// TODO: get back on this once schemaDB implementation is done
	// and understand how to recover from a failed remove.
	// One option is to rebuild the schema from scratch using the cache content.
	if err != nil {
		return errors.Wrapf(err, "Schema remove failed")
	}

	i := sort.Search(len(s.orderedMutators), func(i int) bool {
		res := equal(s.orderedMutators[i].ID(), id)
		if res {
			return true
		}
		return greaterOrEqual(s.orderedMutators[i].ID(), id)
	})

	delete(s.mutatorsMap, id)

	found := equal(s.orderedMutators[i].ID(), id)

	// The map is expected to be in sync with the list, so if we don't find it
	// we return an error.
	if !found {
		return fmt.Errorf("Failed to find mutator with ID %v on sorted list", id)
	}
	copy(s.orderedMutators[i:], s.orderedMutators[i+1:])
	s.orderedMutators[len(s.orderedMutators)-1] = nil
	s.orderedMutators = s.orderedMutators[:len(s.orderedMutators)-1]
	return nil
}

func greaterOrEqual(id1, id2 ID) bool {
	if id1.Group > id2.Group {
		return true
	}
	if id1.Group < id2.Group {
		return false
	}
	if id1.Kind > id2.Kind {
		return true
	}
	if id1.Kind < id2.Kind {
		return false
	}
	if id1.Namespace > id2.Namespace {
		return true
	}
	if id1.Namespace < id2.Namespace {
		return false
	}
	if id1.Name > id2.Name {
		return true
	}
	if id1.Name < id2.Name {
		return false
	}
	return true
}

func equal(id1, id2 ID) bool {
	if id1.Group == id2.Group &&
		id1.Kind == id2.Kind &&
		id1.Namespace == id2.Namespace &&
		id1.Name == id2.Name {
		return true
	}
	return false
}
<|endoftext|>


<commit_before>//TODO make it a key value storage
package server

import (
	"bufio"
	"fmt"
	"log"
	"math/rand"
	"net/rpc"
	"os"
	"sync"
	"time"

	"github.com/mateusbraga/freestore/pkg/view"
)

var register Value

//  ---------- RPC Requests -------------
type ClientRequest int

func (r *ClientRequest) Read(clientView *view.View, reply *Value) error {
	if !clientView.Equal(currentView.View()) {
		log.Printf("Got old view: %v, sending new one: %v\n", clientView, currentView.View())
		reply.Err = view.OldViewError{NewView: currentView.View()}
		return nil
	}

	register.mu.RLock()
	defer register.mu.RUnlock()

	reply.Value = register.Value
	reply.Timestamp = register.Timestamp

	throughput++

	return nil
}

func (r *ClientRequest) Write(value Value, reply *Value) error {
	if !value.View.Equal(currentView.View()) {
		log.Printf("Got old view: %v, sending new one: %v\n", value.View, currentView.View())
		reply.Err = view.OldViewError{NewView: currentView.View()}
		return nil
	}

	register.mu.Lock()
	defer register.mu.Unlock()

	// Two writes with the same timestamp -> give preference to first one. This makes the Write operation idempotent and still read/write coherent.
	if value.Timestamp > register.Timestamp {
		register.Value = value.Value
		register.Timestamp = value.Timestamp
	}

	return nil
}

func (r *ClientRequest) GetCurrentView(value int, reply *view.View) error {
	*reply = *currentView.View()
	log.Println("Done GetCurrentView request")
	return nil
}

// --------- Init ---------
func init() {
	register.mu.Lock() // The register starts locked
	register.Value = nil
	register.Timestamp = 0
}

func init() {
	rpc.Register(new(ClientRequest))
}

// --------- Types ---------
type Value struct {
	Value     interface{}
	Timestamp int

	View *view.View
	Err  error

	mu sync.RWMutex
}

var throughput uint64
var throughputBuffer = make(map[time.Time]uint64, 70)

func collectThroughputWorker() {
	writeLength := rand.Intn(20)
	var lastThroughput uint64

	for now := range time.Tick(time.Second) {
		aux := throughput
		throughputBuffer[now] = aux - lastThroughput
		lastThroughput = aux

		if len(throughputBuffer) == writeLength {
			writeLength = rand.Intn(20)
			saveThroughput()
		}
	}
}

func saveThroughput() {
	file, err := os.OpenFile("/proj/freestore/throughputs.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0664)
	if err != nil {
		//log.Println(err)
		for loopTime, loopThroughput := range throughputBuffer {
			fmt.Printf("%v %v %v\n", thisProcess, loopThroughput, loopTime.Format(time.RFC3339))
			delete(throughputBuffer, loopTime)
		}
		return
	}
	defer file.Close()

	w := bufio.NewWriter(file)
	defer w.Flush()

	for loopTime, loopThroughput := range throughputBuffer {
		if _, err = w.Write([]byte(fmt.Sprintf("%v %v %v\n", thisProcess, loopThroughput, loopTime.Format(time.RFC3339)))); err != nil {
			log.Fatalln(err)
		}
		delete(throughputBuffer, loopTime)
	}
}

func init() {
	go collectThroughputWorker()
}
<commit_msg>Change throughput output file<commit_after>//TODO make it a key value storage
package server

import (
	"bufio"
	"fmt"
	"log"
	"math/rand"
	"net/rpc"
	"os"
	"sync"
	"time"

	"github.com/mateusbraga/freestore/pkg/view"
)

var register Value

//  ---------- RPC Requests -------------
type ClientRequest int

func (r *ClientRequest) Read(clientView *view.View, reply *Value) error {
	if !clientView.Equal(currentView.View()) {
		log.Printf("Got old view: %v, sending new one: %v\n", clientView, currentView.View())
		reply.Err = view.OldViewError{NewView: currentView.View()}
		return nil
	}

	register.mu.RLock()
	defer register.mu.RUnlock()

	reply.Value = register.Value
	reply.Timestamp = register.Timestamp

	throughput++

	return nil
}

func (r *ClientRequest) Write(value Value, reply *Value) error {
	if !value.View.Equal(currentView.View()) {
		log.Printf("Got old view: %v, sending new one: %v\n", value.View, currentView.View())
		reply.Err = view.OldViewError{NewView: currentView.View()}
		return nil
	}

	register.mu.Lock()
	defer register.mu.Unlock()

	// Two writes with the same timestamp -> give preference to first one. This makes the Write operation idempotent and still read/write coherent.
	if value.Timestamp > register.Timestamp {
		register.Value = value.Value
		register.Timestamp = value.Timestamp
	}

	return nil
}

func (r *ClientRequest) GetCurrentView(value int, reply *view.View) error {
	*reply = *currentView.View()
	log.Println("Done GetCurrentView request")
	return nil
}

// --------- Init ---------
func init() {
	register.mu.Lock() // The register starts locked
	register.Value = nil
	register.Timestamp = 0
}

func init() {
	rpc.Register(new(ClientRequest))
}

// --------- Types ---------
type Value struct {
	Value     interface{}
	Timestamp int

	View *view.View
	Err  error

	mu sync.RWMutex
}

var throughput uint64
var throughputBuffer = make(map[time.Time]uint64, 70)

func collectThroughputWorker() {
	writeLength := rand.Intn(20)
	var lastThroughput uint64

	for now := range time.Tick(time.Second) {
		aux := throughput
		throughputBuffer[now] = aux - lastThroughput
		lastThroughput = aux

		if len(throughputBuffer) == writeLength {
			writeLength = rand.Intn(20)
			saveThroughput()
		}
	}
}

func saveThroughput() {
	filename := fmt.Sprintf("/proj/freestore/throughputs_%v.txt", currentView.View().GetProcessPosition(thisProcess))
	file, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0664)
	if err != nil {
		//log.Println(err)
		for loopTime, loopThroughput := range throughputBuffer {
			fmt.Printf("%v %v %v\n", thisProcess, loopThroughput, loopTime.Format(time.RFC3339))
			delete(throughputBuffer, loopTime)
		}
		return
	}
	defer file.Close()

	w := bufio.NewWriter(file)
	defer w.Flush()

	for loopTime, loopThroughput := range throughputBuffer {
		if _, err = w.Write([]byte(fmt.Sprintf("%v %v %v\n", thisProcess, loopThroughput, loopTime.Format(time.RFC3339)))); err != nil {
			log.Fatalln(err)
		}
		delete(throughputBuffer, loopTime)
	}
}

func init() {
	go collectThroughputWorker()
}
<|endoftext|>


<commit_before>// Copyright (C) 2014 Constantin Schomburg <me@cschomburg.com>
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.

// Package testutils provides a BDD test framework for stark services.
package testutils

import (
	"testing"
	"time"

	"github.com/xconstruct/stark/proto"
)

type Tester struct {
	*testing.T
	conn        proto.Conn
	WaitTimeout time.Duration
	IgnoreSubs  bool
	Id          string

	Unit       string
	Behaviour  string
	Received   chan proto.Message
	ExpectCurr *proto.Message
}

func New(t *testing.T) *Tester {
	return &Tester{
		t,
		nil,
		time.Second,
		true,
		"testutils-" + proto.GenerateId(),

		"",
		"",
		make(chan proto.Message, 5),
		nil,
	}
}

func (t *Tester) UseConn(conn proto.Conn) {
	t.conn = conn
	go t.listen()
}

func (t *Tester) CreateConn() proto.Conn {
	a, b := proto.NewPipe()
	t.UseConn(a)
	return b
}

func (t *Tester) listen() {
	for {
		msg, err := t.conn.Read()
		if err != nil {
			t.T.Fatal(err)
		}
		if t.IgnoreSubs && msg.IsAction("proto/sub") {
			continue
		}
		if msg.Source == t.Id {
			continue
		}
		t.Received <- msg
	}
}

func (t *Tester) Publish(msg proto.Message) {
	if msg.Source == "" {
		msg.Source = t.Id
	}
	if err := t.conn.Write(msg); err != nil {
		t.T.Fatal(err)
	}
}

func (t *Tester) Wait() {
	time.Sleep(50 * time.Millisecond)
}

func (t *Tester) Reset() {
	t.Received = make(chan proto.Message, 20)
}

func (t *Tester) Describe(unit string, f func()) {
	t.Unit = unit
	f()
}

func (t *Tester) It(behaviour string, f func()) {
	t.Reset()
	t.Behaviour = behaviour
	f()

	if t.HasReplies() {
		t.T.Log(t.Received)
		t.T.Fatal(t.Unit, t.Behaviour+": still replies left")
	}
}

func (t *Tester) When(msgs ...proto.Message) {
	for _, msg := range msgs {
		t.Publish(msg)
	}
}

func (t *Tester) HasReplies() bool {
	return len(t.Received) > 0
}

func (t *Tester) Expect(f func(proto.Message)) {
	if t.ExpectCurr != nil {
		f(*t.ExpectCurr)
		return
	}

	select {
	case msg := <-t.Received:
		t.ExpectCurr = &msg
		f(msg)
		t.ExpectCurr = nil
	case <-time.After(t.WaitTimeout):
		t.T.Fatal(t.Unit, t.Behaviour+": no message received")
	}
}

func (t *Tester) ExpectAction(action string) {
	t.Expect(func(msg proto.Message) {
		if !msg.IsAction(action) {
			t.T.Fatal(t.Unit, t.Behaviour+": expected action", action, "not", msg.Action+":", msg.Text)
		}
	})
}

func (t *Tester) ExpectText(text string) {
	t.Expect(func(msg proto.Message) {
		if msg.Text != text {
			t.T.Fatalf("%s %s: expected text '%s', not '%s'", t.Unit, t.Behaviour, text, msg.Text)
		}
	})
}
<commit_msg>Testutils: Fix possible race condition.<commit_after>// Copyright (C) 2014 Constantin Schomburg <me@cschomburg.com>
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.

// Package testutils provides a BDD test framework for stark services.
package testutils

import (
	"sync"
	"testing"
	"time"

	"github.com/xconstruct/stark/proto"
)

type Tester struct {
	*testing.T
	conn        proto.Conn
	WaitTimeout time.Duration
	IgnoreSubs  bool
	Id          string

	Unit       string
	Behaviour  string
	Received   chan proto.Message
	ExpectCurr *proto.Message
	RecMutex   sync.Mutex
}

func New(t *testing.T) *Tester {
	return &Tester{
		T:           t,
		WaitTimeout: time.Second,
		IgnoreSubs:  true,
		Id:          "testutils-" + proto.GenerateId(),

		Received: make(chan proto.Message, 5),
		RecMutex: sync.Mutex{},
	}
}

func (t *Tester) UseConn(conn proto.Conn) {
	t.conn = conn
	go t.listen()
}

func (t *Tester) CreateConn() proto.Conn {
	a, b := proto.NewPipe()
	t.UseConn(a)
	return b
}

func (t *Tester) listen() {
	for {
		msg, err := t.conn.Read()
		if err != nil {
			t.T.Fatal(err)
		}
		if t.IgnoreSubs && msg.IsAction("proto/sub") {
			continue
		}
		if msg.Source == t.Id {
			continue
		}
		t.RecMutex.Lock()
		t.Received <- msg
		t.RecMutex.Unlock()
	}
}

func (t *Tester) Publish(msg proto.Message) {
	if msg.Source == "" {
		msg.Source = t.Id
	}
	if err := t.conn.Write(msg); err != nil {
		t.T.Fatal(err)
	}
}

func (t *Tester) Wait() {
	time.Sleep(50 * time.Millisecond)
}

func (t *Tester) Reset() {
	t.RecMutex.Lock()
	t.Received = make(chan proto.Message, 20)
	t.RecMutex.Unlock()
}

func (t *Tester) Describe(unit string, f func()) {
	t.Unit = unit
	f()
}

func (t *Tester) It(behaviour string, f func()) {
	t.Reset()
	t.Behaviour = behaviour
	f()

	if t.HasReplies() {
		t.T.Log(t.Received)
		t.T.Fatal(t.Unit, t.Behaviour+": still replies left")
	}
}

func (t *Tester) When(msgs ...proto.Message) {
	for _, msg := range msgs {
		t.Publish(msg)
	}
}

func (t *Tester) HasReplies() bool {
	return len(t.Received) > 0
}

func (t *Tester) Expect(f func(proto.Message)) {
	if t.ExpectCurr != nil {
		f(*t.ExpectCurr)
		return
	}

	select {
	case msg := <-t.Received:
		t.ExpectCurr = &msg
		f(msg)
		t.ExpectCurr = nil
	case <-time.After(t.WaitTimeout):
		t.T.Fatal(t.Unit, t.Behaviour+": no message received")
	}
}

func (t *Tester) ExpectAction(action string) {
	t.Expect(func(msg proto.Message) {
		if !msg.IsAction(action) {
			t.T.Fatal(t.Unit, t.Behaviour+": expected action", action, "not", msg.Action+":", msg.Text)
		}
	})
}

func (t *Tester) ExpectText(text string) {
	t.Expect(func(msg proto.Message) {
		if msg.Text != text {
			t.T.Fatalf("%s %s: expected text '%s', not '%s'", t.Unit, t.Behaviour, text, msg.Text)
		}
	})
}
<|endoftext|>


<commit_before>package document

import (
	"encoding/json"
	"github.com/DJDNS/go-deje/state"
	"io"
)

// A document is a single managed DEJE object, associated with
// a single immutable topic string, and self-describing its
// actions and permissions as part of the content.
//
// The content of a Document is the result of applying the
// "official" chain of history, in much the same way that the
// Bitcoin ledger is the result of playing through the transactions
// in every block of the longest valid blockchain.
type Document struct {
	Topic string               `json:"topic"`
	State *state.DocumentState `json:"-"`

	// Do not modify the contents of the following fields!
	// They're there for you to have convenient and uninhibited
	// READ-ONLY access. If you try to add or remove things manually,
	// you run the risk of doing so inconsistently.
	//
	// Please just use the Thing.Register() and Thing.Unregister()
	// methods, and when it comes to these fields, LOOK BUT DON'T TOUCH.
	Events         EventSet             `json:"events"`
	EventsByParent map[string]EventSet  `json:"-"`
	Quorums        QuorumSet            `json:"quorums"`
	QuorumsByEvent map[string]QuorumSet `json:"-"`
}

// Create a new, blank Document, with fields initialized.
func NewDocument() Document {
	return Document{
		State:          state.NewDocumentState(),
		Events:         make(EventSet),
		EventsByParent: make(map[string]EventSet),
		Quorums:        make(QuorumSet),
		QuorumsByEvent: make(map[string]QuorumSet),
	}
}

// Serialize JSON data to an io.Writer.
func (doc *Document) Serialize(w io.Writer) error {
	encoder := json.NewEncoder(w)
	return encoder.Encode(doc)
}

// Deserialize JSON data from an io.Reader.
func (doc *Document) Deserialize(r io.Reader) error {
	decoder := json.NewDecoder(r)
	if err := decoder.Decode(doc); err != nil {
		return err
	}

	// Copy Events to avoid clobbering when we fix keys
	var index int
	events_copy := make([]Event, len(doc.Events))
	for _, item := range doc.Events {
		events_copy[index] = *item
		index++
	}
	doc.Events = make(EventSet)

	// Same for Quorums
	index = 0
	quorums_copy := make([]Quorum, len(doc.Quorums))
	for _, item := range doc.Quorums {
		quorums_copy[index] = *item
		index++
	}
	doc.Quorums = make(QuorumSet)

	// Integrate through registration
	for _, item := range events_copy {
		item.Doc = doc
		item.Register()
	}
	for _, item := range quorums_copy {
		item.Doc = doc
		item.Register()
	}
	return nil
}
<commit_msg>Close #23: Don't load every item into the same memory location<commit_after>package document

import (
	"encoding/json"
	"io"

	"github.com/DJDNS/go-deje/state"
)

// A document is a single managed DEJE object, associated with
// a single immutable topic string, and self-describing its
// actions and permissions as part of the content.
//
// The content of a Document is the result of applying the
// "official" chain of history, in much the same way that the
// Bitcoin ledger is the result of playing through the transactions
// in every block of the longest valid blockchain.
type Document struct {
	Topic string               `json:"topic"`
	State *state.DocumentState `json:"-"`

	// Do not modify the contents of the following fields!
	// They're there for you to have convenient and uninhibited
	// READ-ONLY access. If you try to add or remove things manually,
	// you run the risk of doing so inconsistently.
	//
	// Please just use the Thing.Register() and Thing.Unregister()
	// methods, and when it comes to these fields, LOOK BUT DON'T TOUCH.
	Events         EventSet             `json:"events"`
	EventsByParent map[string]EventSet  `json:"-"`
	Quorums        QuorumSet            `json:"quorums"`
	QuorumsByEvent map[string]QuorumSet `json:"-"`
}

// Create a new, blank Document, with fields initialized.
func NewDocument() Document {
	return Document{
		State:          state.NewDocumentState(),
		Events:         make(EventSet),
		EventsByParent: make(map[string]EventSet),
		Quorums:        make(QuorumSet),
		QuorumsByEvent: make(map[string]QuorumSet),
	}
}

// Serialize JSON data to an io.Writer.
func (doc *Document) Serialize(w io.Writer) error {
	encoder := json.NewEncoder(w)
	return encoder.Encode(doc)
}

// Deserialize JSON data from an io.Reader.
func (doc *Document) Deserialize(r io.Reader) error {
	decoder := json.NewDecoder(r)
	if err := decoder.Decode(doc); err != nil {
		return err
	}

	// Copy Events to avoid clobbering when we fix keys
	var index int
	events_copy := make([]Event, len(doc.Events))
	for _, item := range doc.Events {
		events_copy[index] = *item
		index++
	}
	doc.Events = make(EventSet)

	// Same for Quorums
	index = 0
	quorums_copy := make([]Quorum, len(doc.Quorums))
	for _, item := range doc.Quorums {
		quorums_copy[index] = *item
		index++
	}
	doc.Quorums = make(QuorumSet)

	// Integrate through registration
	for i := range events_copy {
		events_copy[i].Doc = doc
		events_copy[i].Register()
	}
	for i := range quorums_copy {
		quorums_copy[i].Doc = doc
		quorums_copy[i].Register()
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/tls"
	"encoding/json"
	"io/ioutil"
	"net/http"
	"errors"

	"code.google.com/p/go.net/websocket"
)

type ApiUserResponse struct {
	Id        int
	Email     string
	Name      string
	CreatedAt string `json:"created_at"`
	UpdatedAt string `json:"updated_at"`
	Error     string
}

type AuthError struct {
	Message string
	Err     error
}

func (ae AuthError) Error() string {
	return "Authentication error: " + ae.Message + " " + ae.Err.Error()
}

func Authenticate(ws *websocket.Conn) (*ApiUserResponse, *AuthError) {
	// Read the seesion cookie
	cookie, err := ws.Request().Cookie("session_token")
	if err != nil {
		return nil, &AuthError{Message: "Not signed in.", Err: err}
	}

	// Submit the cookie to the auth server, for verification
	token := cookie.Value
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	cli := &http.Client{Transport: tr}
	req, err := http.NewRequest("GET", "https://www.buildblast.com/api/users/"+token, nil)
	if err != nil {
		return nil, &AuthError{Message: "Invalid token", Err: err}
	}
	req.SetBasicAuth("name", "password")
	res, err := cli.Do(req)
	if err != nil {
		return nil, &AuthError{Message: "Auth server connection issue.", Err: err}
	}

	// Parse the response
	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, &AuthError{Message: "Could not read auth response.", Err: err}
	}
	var data ApiUserResponse
	err = json.Unmarshal(body, &data)
	if err != nil {
		return nil, &AuthError{Message: "Could not parse auth response.", Err: err}
	}

	// Determine if we successfully logged in
	if data.Error != "" {
		return nil, &AuthError{Message: "Not signed in.", Err: errors.New("Server did not verify token")}
	}

	return &data, nil
}
<commit_msg>go fmt<commit_after>package main

import (
	"crypto/tls"
	"encoding/json"
	"errors"
	"io/ioutil"
	"net/http"

	"code.google.com/p/go.net/websocket"
)

type ApiUserResponse struct {
	Id        int
	Email     string
	Name      string
	CreatedAt string `json:"created_at"`
	UpdatedAt string `json:"updated_at"`
	Error     string
}

type AuthError struct {
	Message string
	Err     error
}

func (ae AuthError) Error() string {
	return "Authentication error: " + ae.Message + " " + ae.Err.Error()
}

func Authenticate(ws *websocket.Conn) (*ApiUserResponse, *AuthError) {
	// Read the seesion cookie
	cookie, err := ws.Request().Cookie("session_token")
	if err != nil {
		return nil, &AuthError{Message: "Not signed in.", Err: err}
	}

	// Submit the cookie to the auth server, for verification
	token := cookie.Value
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	cli := &http.Client{Transport: tr}
	req, err := http.NewRequest("GET", "https://www.buildblast.com/api/users/"+token, nil)
	if err != nil {
		return nil, &AuthError{Message: "Invalid token", Err: err}
	}
	req.SetBasicAuth("name", "password")
	res, err := cli.Do(req)
	if err != nil {
		return nil, &AuthError{Message: "Auth server connection issue.", Err: err}
	}

	// Parse the response
	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, &AuthError{Message: "Could not read auth response.", Err: err}
	}
	var data ApiUserResponse
	err = json.Unmarshal(body, &data)
	if err != nil {
		return nil, &AuthError{Message: "Could not parse auth response.", Err: err}
	}

	// Determine if we successfully logged in
	if data.Error != "" {
		return nil, &AuthError{Message: "Not signed in.", Err: errors.New("Server did not verify token")}
	}

	return &data, nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"socialapi/config"
	followingfeed "socialapi/workers/followingfeed/lib"
	"socialapi/workers/helper"

	"github.com/koding/bongo"
	"github.com/koding/logging"
	"github.com/koding/worker"
)

var (
	Bongo       *bongo.Bongo
	log         logging.Logger
	conf        *config.Config
	flagProfile = flag.String("c", "", "Configuration profile from file")
	flagDebug   = flag.Bool("d", false, "Debug mode")
	handler     *followingfeed.FollowingFeedController
)

func main() {
	flag.Parse()
	if *flagProfile == "" {
		log.Fatal("Please define config file with -c", "")
	}

	conf = config.Read(*flagProfile)

	// create logger for our package
	log = helper.CreateLogger("TopicFeedWorker", *flagDebug)

	// panics if not successful
	Bongo = helper.MustInitBongo(conf, log)
	// do not forgot to close the bongo connection
	defer Bongo.Close()

	// create message handler
	handler = followingfeed.NewFollowingFeedController(log)

	listener := worker.NewListener("FollowingFeed", conf.EventExchangeName, log)
	// blocking
	// listen for events
	listener.Listen(helper.NewRabbitMQ(conf, log), handler)
	// close consumer
	defer listener.Close()
}
<commit_msg>Social: remove global variables<commit_after>package main

import (
	"flag"
	"socialapi/config"
	followingfeed "socialapi/workers/followingfeed/lib"
	"socialapi/workers/helper"

	"github.com/koding/worker"
)

var (
	flagProfile = flag.String("c", "", "Configuration profile from file")
	flagDebug   = flag.Bool("d", false, "Debug mode")
)

func main() {
	flag.Parse()
	if *flagProfile == "" {
		panic("Please define config file with -c")
	}

	conf := config.Read(*flagProfile)

	// create logger for our package
	log := helper.CreateLogger("TopicFeedWorker", *flagDebug)

	// panics if not successful
	bongo := helper.MustInitBongo(conf, log)
	// do not forgot to close the bongo connection
	defer bongo.Close()

	// create message handler
	handler := followingfeed.NewFollowingFeedController(log)

	listener := worker.NewListener("FollowingFeed", conf.EventExchangeName, log)
	// blocking
	// listen for events
	listener.Listen(helper.NewRabbitMQ(conf, log), handler)
	// close consumer
	defer listener.Close()
}
<|endoftext|>


<commit_before>package pb

func possibleBipartition(n int, dis [][]int) bool {
	return false
}
<commit_msg>temp not finished<commit_after>package pb

import "fmt"

func possibleBipartition(n int, dis [][]int) bool {
	return useHashmap(n, dis)
}

func useHashmap(n int, dis [][]int) bool {
	g1, g2 := make(map[int]bool, n), make(map[int]bool, n)
	for _, p := range dis {
		fmt.Printf("g1: %v and g2: %v\n", g1, g2)
		p0, p1 := p[0], p[1]
		if g1[p0] == true && g1[p1] == true || g2[p1] == true && g2[p0] == true {
			return false
		}
		if !g2[p0] {
			g1[p0] = true
		}
		if !g1[p1] {
			g2[p1] = true
		}
	}
	return true
}
<|endoftext|>


<commit_before>/*
   Copyright 2020 Docker Compose CLI authors

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

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

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

package compose

import (
	"context"
	"fmt"
	"os"
	"os/signal"
	"path/filepath"
	"strconv"
	"strings"
	"syscall"
	"time"

	"github.com/compose-spec/compose-go/types"
	"github.com/docker/compose-cli/utils"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
	"golang.org/x/sync/errgroup"

	"github.com/docker/compose-cli/api/client"
	"github.com/docker/compose-cli/api/compose"
	"github.com/docker/compose-cli/api/context/store"
	"github.com/docker/compose-cli/api/progress"
	"github.com/docker/compose-cli/cli/cmd"
	"github.com/docker/compose-cli/cli/formatter"
)

// composeOptions hold options common to `up` and `run` to run compose project
type composeOptions struct {
	*projectOptions
	Build   bool
	noBuild bool
	// ACI only
	DomainName string
}

type upOptions struct {
	*composeOptions
	Detach             bool
	Environment        []string
	removeOrphans      bool
	forceRecreate      bool
	noRecreate         bool
	recreateDeps       bool
	noStart            bool
	noDeps             bool
	cascadeStop        bool
	exitCodeFrom       string
	scale              []string
	noColor            bool
	noPrefix           bool
	timeChanged        bool
	timeout            int
	noInherit          bool
	attachDependencies bool
	quietPull          bool
}

func (opts upOptions) recreateStrategy() string {
	if opts.noRecreate {
		return compose.RecreateNever
	}
	if opts.forceRecreate {
		return compose.RecreateForce
	}
	return compose.RecreateDiverged
}

func (opts upOptions) dependenciesRecreateStrategy() string {
	if opts.noRecreate {
		return compose.RecreateNever
	}
	if opts.recreateDeps {
		return compose.RecreateForce
	}
	return compose.RecreateDiverged
}

func (opts upOptions) GetTimeout() *time.Duration {
	if opts.timeChanged {
		t := time.Duration(opts.timeout) * time.Second
		return &t
	}
	return nil
}

func (opts upOptions) apply(project *types.Project, services []string) error {
	if opts.noDeps {
		enabled, err := project.GetServices(services...)
		if err != nil {
			return err
		}
		for _, s := range project.Services {
			if !utils.StringContains(services, s.Name) {
				project.DisabledServices = append(project.DisabledServices, s)
			}
		}
		project.Services = enabled
	}

	if opts.exitCodeFrom != "" {
		_, err := project.GetService(opts.exitCodeFrom)
		if err != nil {
			return err
		}
	}

	for _, scale := range opts.scale {
		split := strings.Split(scale, "=")
		if len(split) != 2 {
			return fmt.Errorf("invalid --scale option %q. Should be SERVICE=NUM", scale)
		}
		name := split[0]
		replicas, err := strconv.Atoi(split[1])
		if err != nil {
			return err
		}
		err = setServiceScale(project, name, replicas)
		if err != nil {
			return err
		}
	}

	return nil
}

func upCommand(p *projectOptions, contextType string) *cobra.Command {
	opts := upOptions{
		composeOptions: &composeOptions{
			projectOptions: p,
		},
	}
	upCmd := &cobra.Command{
		Use:   "up [SERVICE...]",
		Short: "Create and start containers",
		RunE: func(cmd *cobra.Command, args []string) error {
			opts.timeChanged = cmd.Flags().Changed("timeout")
			switch contextType {
			case store.LocalContextType, store.DefaultContextType, store.EcsLocalSimulationContextType:
				if opts.exitCodeFrom != "" {
					opts.cascadeStop = true
				}
				if opts.Build && opts.noBuild {
					return fmt.Errorf("--build and --no-build are incompatible")
				}
				if opts.Detach && (opts.attachDependencies || opts.cascadeStop) {
					return fmt.Errorf("--detach cannot be combined with --abort-on-container-exit or --attach-dependencies")
				}
				if opts.forceRecreate && opts.noRecreate {
					return fmt.Errorf("--force-recreate and --no-recreate are incompatible")
				}
				if opts.recreateDeps && opts.noRecreate {
					return fmt.Errorf("--always-recreate-deps and --no-recreate are incompatible")
				}
				return runCreateStart(cmd.Context(), opts, args)
			default:
				return runUp(cmd.Context(), opts, args)
			}
		},
	}
	flags := upCmd.Flags()
	flags.StringArrayVarP(&opts.Environment, "environment", "e", []string{}, "Environment variables")
	flags.BoolVarP(&opts.Detach, "detach", "d", false, "Detached mode: Run containers in the background")
	flags.BoolVar(&opts.Build, "build", false, "Build images before starting containers.")
	flags.BoolVar(&opts.noBuild, "no-build", false, "Don't build an image, even if it's missing.")
	flags.BoolVar(&opts.removeOrphans, "remove-orphans", false, "Remove containers for services not defined in the Compose file.")
	flags.StringArrayVar(&opts.scale, "scale", []string{}, "Scale SERVICE to NUM instances. Overrides the `scale` setting in the Compose file if present.")
	flags.BoolVar(&opts.noColor, "no-color", false, "Produce monochrome output.")
	flags.BoolVar(&opts.noPrefix, "no-log-prefix", false, "Don't print prefix in logs.")

	switch contextType {
	case store.AciContextType:
		flags.StringVar(&opts.DomainName, "domainname", "", "Container NIS domain name")
	case store.LocalContextType, store.DefaultContextType, store.EcsLocalSimulationContextType:
		flags.BoolVar(&opts.forceRecreate, "force-recreate", false, "Recreate containers even if their configuration and image haven't changed.")
		flags.BoolVar(&opts.noRecreate, "no-recreate", false, "If containers already exist, don't recreate them. Incompatible with --force-recreate.")
		flags.BoolVar(&opts.noStart, "no-start", false, "Don't start the services after creating them.")
		flags.BoolVar(&opts.cascadeStop, "abort-on-container-exit", false, "Stops all containers if any container was stopped. Incompatible with -d")
		flags.StringVar(&opts.exitCodeFrom, "exit-code-from", "", "Return the exit code of the selected service container. Implies --abort-on-container-exit")
		flags.IntVarP(&opts.timeout, "timeout", "t", 10, "Use this timeout in seconds for container shutdown when attached or when containers are already running.")
		flags.BoolVar(&opts.noDeps, "no-deps", false, "Don't start linked services.")
		flags.BoolVar(&opts.recreateDeps, "always-recreate-deps", false, "Recreate dependent containers. Incompatible with --no-recreate.")
		flags.BoolVarP(&opts.noInherit, "renew-anon-volumes", "V", false, "Recreate anonymous volumes instead of retrieving data from the previous containers.")
		flags.BoolVar(&opts.attachDependencies, "attach-dependencies", false, "Attach to dependent containers.")
		flags.BoolVar(&opts.quietPull, "quiet-pull", false, "Pull without printing progress information.")
	}

	return upCmd
}

func runUp(ctx context.Context, opts upOptions, services []string) error {
	c, project, err := setup(ctx, *opts.composeOptions, services)
	if err != nil {
		return err
	}

	err = opts.apply(project, services)
	if err != nil {
		return err
	}

	_, err = progress.Run(ctx, func(ctx context.Context) (string, error) {
		return "", c.ComposeService().Up(ctx, project, compose.UpOptions{
			Detach:    opts.Detach,
			QuietPull: opts.quietPull,
		})
	})
	return err
}

func runCreateStart(ctx context.Context, opts upOptions, services []string) error {
	c, project, err := setup(ctx, *opts.composeOptions, services)
	if err != nil {
		return err
	}

	err = opts.apply(project, services)
	if err != nil {
		return err
	}

	_, err = progress.Run(ctx, func(ctx context.Context) (string, error) {
		err := c.ComposeService().Create(ctx, project, compose.CreateOptions{
			Services:             services,
			RemoveOrphans:        opts.removeOrphans,
			Recreate:             opts.recreateStrategy(),
			RecreateDependencies: opts.dependenciesRecreateStrategy(),
			Inherit:              !opts.noInherit,
			Timeout:              opts.GetTimeout(),
			QuietPull:            opts.quietPull,
		})
		if err != nil {
			return "", err
		}
		if opts.Detach {
			err = c.ComposeService().Start(ctx, project, compose.StartOptions{})
		}
		return "", err
	})
	if err != nil {
		return err
	}

	if opts.noStart {
		return nil
	}

	if opts.attachDependencies {
		services = nil
	}

	if opts.Detach {
		return nil
	}

	queue := make(chan compose.ContainerEvent)
	printer := printer{
		queue: queue,
	}

	signalChan := make(chan os.Signal, 1)
	signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)
	stopFunc := func() error {
		ctx := context.Background()
		_, err := progress.Run(ctx, func(ctx context.Context) (string, error) {
			go func() {
				<-signalChan
				c.ComposeService().Kill(ctx, project, compose.KillOptions{}) // nolint:errcheck
			}()

			return "", c.ComposeService().Stop(ctx, project, compose.StopOptions{})
		})
		return err
	}
	go func() {
		<-signalChan
		queue <- compose.ContainerEvent{
			Type: compose.UserCancel,
		}
		fmt.Println("Gracefully stopping... (press Ctrl+C again to force)")
		stopFunc() // nolint:errcheck
	}()

	consumer := formatter.NewLogConsumer(ctx, os.Stdout, !opts.noColor, !opts.noPrefix)

	var exitCode int
	eg, ctx := errgroup.WithContext(ctx)
	eg.Go(func() error {
		code, err := printer.run(ctx, opts.cascadeStop, opts.exitCodeFrom, consumer, stopFunc)
		exitCode = code
		return err
	})

	err = c.ComposeService().Start(ctx, project, compose.StartOptions{
		Attach: func(event compose.ContainerEvent) {
			queue <- event
		},
		Services: services,
	})
	if err != nil {
		return err
	}

	err = eg.Wait()
	if exitCode != 0 {
		return cmd.ExitCodeError{ExitCode: exitCode}
	}
	return err
}

func setServiceScale(project *types.Project, name string, replicas int) error {
	for i, s := range project.Services {
		if s.Name == name {
			service, err := project.GetService(name)
			if err != nil {
				return err
			}
			if service.Deploy == nil {
				service.Deploy = &types.DeployConfig{}
			}
			count := uint64(replicas)
			service.Deploy.Replicas = &count
			project.Services[i] = service
			return nil
		}
	}
	return fmt.Errorf("unknown service %q", name)
}

func setup(ctx context.Context, opts composeOptions, services []string) (*client.Client, *types.Project, error) {
	c, err := client.New(ctx)
	if err != nil {
		return nil, nil, err
	}

	project, err := opts.toProject(services)
	if err != nil {
		return nil, nil, err
	}

	if opts.DomainName != "" {
		// arbitrarily set the domain name on the first service ; ACI backend will expose the entire project
		project.Services[0].DomainName = opts.DomainName
	}
	if opts.Build {
		for i, service := range project.Services {
			service.PullPolicy = types.PullPolicyBuild
			project.Services[i] = service
		}
	}
	if opts.noBuild {
		for i, service := range project.Services {
			service.Build = nil
			project.Services[i] = service
		}
	}

	if opts.EnvFile != "" {
		var services types.Services
		for _, s := range project.Services {
			ef := opts.EnvFile
			if ef != "" {
				if !filepath.IsAbs(ef) {
					ef = filepath.Join(project.WorkingDir, opts.EnvFile)
				}
				if s.Labels == nil {
					s.Labels = make(map[string]string)
				}
				s.Labels[compose.EnvironmentFileLabel] = ef
				services = append(services, s)
			}
		}
		project.Services = services
	}

	return c, project, nil
}

type printer struct {
	queue chan compose.ContainerEvent
}

func (p printer) run(ctx context.Context, cascadeStop bool, exitCodeFrom string, consumer compose.LogConsumer, stopFn func() error) (int, error) { //nolint:unparam
	var aborting bool
	var count int
	for {
		event := <-p.queue
		switch event.Type {
		case compose.UserCancel:
			aborting = true
		case compose.ContainerEventAttach:
			consumer.Register(event.Container)
			count++
		case compose.ContainerEventExit:
			if !aborting {
				consumer.Status(event.Container, fmt.Sprintf("exited with code %d", event.ExitCode))
			}
			if cascadeStop {
				if !aborting {
					aborting = true
					fmt.Println("Aborting on container exit...")
					err := stopFn()
					if err != nil {
						return 0, err
					}
				}
				if exitCodeFrom == "" || exitCodeFrom == event.Service {
					logrus.Error(event.ExitCode)
					return event.ExitCode, nil
				}
			}
			count--
			if count == 0 {
				// Last container terminated, done
				return 0, nil
			}
		case compose.ContainerEventLog:
			if !aborting {
				consumer.Log(event.Container, event.Service, event.Line)
			}
		}
	}
}
<commit_msg>deadlock waiting for services when none selected<commit_after>/*
   Copyright 2020 Docker Compose CLI authors

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

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

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

package compose

import (
	"context"
	"fmt"
	"os"
	"os/signal"
	"path/filepath"
	"strconv"
	"strings"
	"syscall"
	"time"

	"github.com/compose-spec/compose-go/types"
	"github.com/docker/compose-cli/utils"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
	"golang.org/x/sync/errgroup"

	"github.com/docker/compose-cli/api/client"
	"github.com/docker/compose-cli/api/compose"
	"github.com/docker/compose-cli/api/context/store"
	"github.com/docker/compose-cli/api/progress"
	"github.com/docker/compose-cli/cli/cmd"
	"github.com/docker/compose-cli/cli/formatter"
)

// composeOptions hold options common to `up` and `run` to run compose project
type composeOptions struct {
	*projectOptions
	Build   bool
	noBuild bool
	// ACI only
	DomainName string
}

type upOptions struct {
	*composeOptions
	Detach             bool
	Environment        []string
	removeOrphans      bool
	forceRecreate      bool
	noRecreate         bool
	recreateDeps       bool
	noStart            bool
	noDeps             bool
	cascadeStop        bool
	exitCodeFrom       string
	scale              []string
	noColor            bool
	noPrefix           bool
	timeChanged        bool
	timeout            int
	noInherit          bool
	attachDependencies bool
	quietPull          bool
}

func (opts upOptions) recreateStrategy() string {
	if opts.noRecreate {
		return compose.RecreateNever
	}
	if opts.forceRecreate {
		return compose.RecreateForce
	}
	return compose.RecreateDiverged
}

func (opts upOptions) dependenciesRecreateStrategy() string {
	if opts.noRecreate {
		return compose.RecreateNever
	}
	if opts.recreateDeps {
		return compose.RecreateForce
	}
	return compose.RecreateDiverged
}

func (opts upOptions) GetTimeout() *time.Duration {
	if opts.timeChanged {
		t := time.Duration(opts.timeout) * time.Second
		return &t
	}
	return nil
}

func (opts upOptions) apply(project *types.Project, services []string) error {
	if opts.noDeps {
		enabled, err := project.GetServices(services...)
		if err != nil {
			return err
		}
		for _, s := range project.Services {
			if !utils.StringContains(services, s.Name) {
				project.DisabledServices = append(project.DisabledServices, s)
			}
		}
		project.Services = enabled
	}

	if opts.exitCodeFrom != "" {
		_, err := project.GetService(opts.exitCodeFrom)
		if err != nil {
			return err
		}
	}

	for _, scale := range opts.scale {
		split := strings.Split(scale, "=")
		if len(split) != 2 {
			return fmt.Errorf("invalid --scale option %q. Should be SERVICE=NUM", scale)
		}
		name := split[0]
		replicas, err := strconv.Atoi(split[1])
		if err != nil {
			return err
		}
		err = setServiceScale(project, name, replicas)
		if err != nil {
			return err
		}
	}

	return nil
}

func upCommand(p *projectOptions, contextType string) *cobra.Command {
	opts := upOptions{
		composeOptions: &composeOptions{
			projectOptions: p,
		},
	}
	upCmd := &cobra.Command{
		Use:   "up [SERVICE...]",
		Short: "Create and start containers",
		RunE: func(cmd *cobra.Command, args []string) error {
			opts.timeChanged = cmd.Flags().Changed("timeout")
			switch contextType {
			case store.LocalContextType, store.DefaultContextType, store.EcsLocalSimulationContextType:
				if opts.exitCodeFrom != "" {
					opts.cascadeStop = true
				}
				if opts.Build && opts.noBuild {
					return fmt.Errorf("--build and --no-build are incompatible")
				}
				if opts.Detach && (opts.attachDependencies || opts.cascadeStop) {
					return fmt.Errorf("--detach cannot be combined with --abort-on-container-exit or --attach-dependencies")
				}
				if opts.forceRecreate && opts.noRecreate {
					return fmt.Errorf("--force-recreate and --no-recreate are incompatible")
				}
				if opts.recreateDeps && opts.noRecreate {
					return fmt.Errorf("--always-recreate-deps and --no-recreate are incompatible")
				}
				return runCreateStart(cmd.Context(), opts, args)
			default:
				return runUp(cmd.Context(), opts, args)
			}
		},
	}
	flags := upCmd.Flags()
	flags.StringArrayVarP(&opts.Environment, "environment", "e", []string{}, "Environment variables")
	flags.BoolVarP(&opts.Detach, "detach", "d", false, "Detached mode: Run containers in the background")
	flags.BoolVar(&opts.Build, "build", false, "Build images before starting containers.")
	flags.BoolVar(&opts.noBuild, "no-build", false, "Don't build an image, even if it's missing.")
	flags.BoolVar(&opts.removeOrphans, "remove-orphans", false, "Remove containers for services not defined in the Compose file.")
	flags.StringArrayVar(&opts.scale, "scale", []string{}, "Scale SERVICE to NUM instances. Overrides the `scale` setting in the Compose file if present.")
	flags.BoolVar(&opts.noColor, "no-color", false, "Produce monochrome output.")
	flags.BoolVar(&opts.noPrefix, "no-log-prefix", false, "Don't print prefix in logs.")

	switch contextType {
	case store.AciContextType:
		flags.StringVar(&opts.DomainName, "domainname", "", "Container NIS domain name")
	case store.LocalContextType, store.DefaultContextType, store.EcsLocalSimulationContextType:
		flags.BoolVar(&opts.forceRecreate, "force-recreate", false, "Recreate containers even if their configuration and image haven't changed.")
		flags.BoolVar(&opts.noRecreate, "no-recreate", false, "If containers already exist, don't recreate them. Incompatible with --force-recreate.")
		flags.BoolVar(&opts.noStart, "no-start", false, "Don't start the services after creating them.")
		flags.BoolVar(&opts.cascadeStop, "abort-on-container-exit", false, "Stops all containers if any container was stopped. Incompatible with -d")
		flags.StringVar(&opts.exitCodeFrom, "exit-code-from", "", "Return the exit code of the selected service container. Implies --abort-on-container-exit")
		flags.IntVarP(&opts.timeout, "timeout", "t", 10, "Use this timeout in seconds for container shutdown when attached or when containers are already running.")
		flags.BoolVar(&opts.noDeps, "no-deps", false, "Don't start linked services.")
		flags.BoolVar(&opts.recreateDeps, "always-recreate-deps", false, "Recreate dependent containers. Incompatible with --no-recreate.")
		flags.BoolVarP(&opts.noInherit, "renew-anon-volumes", "V", false, "Recreate anonymous volumes instead of retrieving data from the previous containers.")
		flags.BoolVar(&opts.attachDependencies, "attach-dependencies", false, "Attach to dependent containers.")
		flags.BoolVar(&opts.quietPull, "quiet-pull", false, "Pull without printing progress information.")
	}

	return upCmd
}

func runUp(ctx context.Context, opts upOptions, services []string) error {
	c, project, err := setup(ctx, *opts.composeOptions, services)
	if err != nil {
		return err
	}

	err = opts.apply(project, services)
	if err != nil {
		return err
	}

	_, err = progress.Run(ctx, func(ctx context.Context) (string, error) {
		return "", c.ComposeService().Up(ctx, project, compose.UpOptions{
			Detach:    opts.Detach,
			QuietPull: opts.quietPull,
		})
	})
	return err
}

func runCreateStart(ctx context.Context, opts upOptions, services []string) error {
	c, project, err := setup(ctx, *opts.composeOptions, services)
	if err != nil {
		return err
	}

	err = opts.apply(project, services)
	if err != nil {
		return err
	}

	if len(project.Services) == 0 {
		return fmt.Errorf("no service selected")
	}

	_, err = progress.Run(ctx, func(ctx context.Context) (string, error) {
		err := c.ComposeService().Create(ctx, project, compose.CreateOptions{
			Services:             services,
			RemoveOrphans:        opts.removeOrphans,
			Recreate:             opts.recreateStrategy(),
			RecreateDependencies: opts.dependenciesRecreateStrategy(),
			Inherit:              !opts.noInherit,
			Timeout:              opts.GetTimeout(),
			QuietPull:            opts.quietPull,
		})
		if err != nil {
			return "", err
		}
		if opts.Detach {
			err = c.ComposeService().Start(ctx, project, compose.StartOptions{})
		}
		return "", err
	})
	if err != nil {
		return err
	}

	if opts.noStart {
		return nil
	}

	if opts.attachDependencies {
		services = nil
	}

	if opts.Detach {
		return nil
	}

	queue := make(chan compose.ContainerEvent)
	printer := printer{
		queue: queue,
	}

	signalChan := make(chan os.Signal, 1)
	signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)
	stopFunc := func() error {
		ctx := context.Background()
		_, err := progress.Run(ctx, func(ctx context.Context) (string, error) {
			go func() {
				<-signalChan
				c.ComposeService().Kill(ctx, project, compose.KillOptions{}) // nolint:errcheck
			}()

			return "", c.ComposeService().Stop(ctx, project, compose.StopOptions{})
		})
		return err
	}
	go func() {
		<-signalChan
		queue <- compose.ContainerEvent{
			Type: compose.UserCancel,
		}
		fmt.Println("Gracefully stopping... (press Ctrl+C again to force)")
		stopFunc() // nolint:errcheck
	}()

	consumer := formatter.NewLogConsumer(ctx, os.Stdout, !opts.noColor, !opts.noPrefix)

	var exitCode int
	eg, ctx := errgroup.WithContext(ctx)
	eg.Go(func() error {
		code, err := printer.run(opts.cascadeStop, opts.exitCodeFrom, consumer, stopFunc)
		exitCode = code
		return err
	})

	err = c.ComposeService().Start(ctx, project, compose.StartOptions{
		Attach: func(event compose.ContainerEvent) {
			queue <- event
		},
		Services: services,
	})
	if err != nil {
		return err
	}

	err = eg.Wait()
	if exitCode != 0 {
		return cmd.ExitCodeError{ExitCode: exitCode}
	}
	return err
}

func setServiceScale(project *types.Project, name string, replicas int) error {
	for i, s := range project.Services {
		if s.Name == name {
			service, err := project.GetService(name)
			if err != nil {
				return err
			}
			if service.Deploy == nil {
				service.Deploy = &types.DeployConfig{}
			}
			count := uint64(replicas)
			service.Deploy.Replicas = &count
			project.Services[i] = service
			return nil
		}
	}
	return fmt.Errorf("unknown service %q", name)
}

func setup(ctx context.Context, opts composeOptions, services []string) (*client.Client, *types.Project, error) {
	c, err := client.New(ctx)
	if err != nil {
		return nil, nil, err
	}

	project, err := opts.toProject(services)
	if err != nil {
		return nil, nil, err
	}

	if opts.DomainName != "" {
		// arbitrarily set the domain name on the first service ; ACI backend will expose the entire project
		project.Services[0].DomainName = opts.DomainName
	}
	if opts.Build {
		for i, service := range project.Services {
			service.PullPolicy = types.PullPolicyBuild
			project.Services[i] = service
		}
	}
	if opts.noBuild {
		for i, service := range project.Services {
			service.Build = nil
			project.Services[i] = service
		}
	}

	if opts.EnvFile != "" {
		var services types.Services
		for _, s := range project.Services {
			ef := opts.EnvFile
			if ef != "" {
				if !filepath.IsAbs(ef) {
					ef = filepath.Join(project.WorkingDir, opts.EnvFile)
				}
				if s.Labels == nil {
					s.Labels = make(map[string]string)
				}
				s.Labels[compose.EnvironmentFileLabel] = ef
				services = append(services, s)
			}
		}
		project.Services = services
	}

	return c, project, nil
}

type printer struct {
	queue chan compose.ContainerEvent
}

func (p printer) run(cascadeStop bool, exitCodeFrom string, consumer compose.LogConsumer, stopFn func() error) (int, error) {
	var aborting bool
	var count int
	for {
		event := <-p.queue
		switch event.Type {
		case compose.UserCancel:
			aborting = true
		case compose.ContainerEventAttach:
			consumer.Register(event.Container)
			count++
		case compose.ContainerEventExit:
			if !aborting {
				consumer.Status(event.Container, fmt.Sprintf("exited with code %d", event.ExitCode))
			}
			if cascadeStop {
				if !aborting {
					aborting = true
					fmt.Println("Aborting on container exit...")
					err := stopFn()
					if err != nil {
						return 0, err
					}
				}
				if exitCodeFrom == "" || exitCodeFrom == event.Service {
					logrus.Error(event.ExitCode)
					return event.ExitCode, nil
				}
			}
			count--
			if count == 0 {
				// Last container terminated, done
				return 0, nil
			}
		case compose.ContainerEventLog:
			if !aborting {
				consumer.Log(event.Container, event.Service, event.Line)
			}
		}
	}
}
<|endoftext|>


<commit_before>package cq_test

import (
	"fmt"
	"log"
	"time"
	. "launchpad.net/gocheck"
)

type BenchmarkSuite struct{}

var _ = Suite(&BenchmarkSuite{})

func (s *BenchmarkSuite) SetUpTest(c *C) {
	db := testConn()
	_, err := db.Exec("start n=node(*) where has(n.`benchmark~test~id`) delete n")
	if err != nil {
		log.Println(err)
	}

	_, err = db.Exec("create constraint on (t:Test) assert t.`benchmark~test~id` is unique")
	if err != nil {
		log.Println(err)
	}
}

func (s *BenchmarkSuite) TearDownTest(c *C) {
	db := testConn()
	_, err := db.Exec("start n=node(*) where has(n.`benchmark~test~id`) delete n")
	if err != nil {
		log.Println(err)
	}

	_, err = db.Exec("drop constraint on (t:Test) assert t.`benchmark~test~id` is unique")
	if err != nil {
		log.Println(err)
	}
}

func (s *BenchmarkSuite) BenchmarkSimpleQuery(c *C) {
	stmt := prepareTest("return 1")
	defer stmt.Close()
	var test int
	for i := 0; i < c.N; i++ {
		rows, err := stmt.Query()
		c.Assert(err, IsNil)

		rows.Scan(&test)
		rows.Close()
	}
}

func (s *BenchmarkSuite) BenchmarkSimpleCreate(c *C) {
	stmt := prepareTest("create ({`benchmark~test~id`:{0}, timestamp:{1}})")
	defer stmt.Close()
	var test int
	for i := 0; i < c.N; i++ {
		rows, err := stmt.Query(i, fmt.Sprint(time.Now().UnixNano()))
		c.Assert(err, IsNil)

		rows.Scan(&test)
		rows.Close()
	}
}

func (s *BenchmarkSuite) BenchmarkSimpleCreateLabel(c *C) {
	stmt := prepareTest("create (:Test {`benchmark~test~id`:{0}, timestamp:{1}})")
	defer stmt.Close()
	var test int
	for i := 0; i < c.N; i++ {
		rows, err := stmt.Query(i, fmt.Sprint(time.Now().UnixNano()))
		c.Assert(err, IsNil)

		rows.Scan(&test)
		rows.Close()
	}
}

func (s *BenchmarkSuite) BenchmarkTx10SimpleCreate(c *C) {
	txSizeSimpleCreate(c, 10)
}

func (s *BenchmarkSuite) BenchmarkTx100SimpleCreate(c *C) {
	txSizeSimpleCreate(c, 100)
}

func (s *BenchmarkSuite) BenchmarkTx1000SimpleCreate(c *C) {
	txSizeSimpleCreate(c, 1000)
}

func (s *BenchmarkSuite) BenchmarkTx10000SimpleCreate(c *C) {
	txSizeSimpleCreate(c, 10000)
}

func txSizeSimpleCreate(c *C, size int) {
	conn := testConn()
	defer conn.Close()

	tx, err := conn.Begin()
	if err != nil {
		log.Fatal(err)
	}
	stmt, err := tx.Prepare("create ({`benchmark~test~id`:{0}})")
	c.Assert(err, IsNil)

	for i := 0; i < c.N; i++ {
		_, err = stmt.Exec(i)
		c.Assert(err, IsNil)

		if (i > 0 && i%size == 0) || i == c.N-1 {
			err = tx.Commit()
			c.Assert(err, IsNil)

			if i < c.N-1 {
				tx, err = conn.Begin()
				c.Assert(err, IsNil)

				stmt.Close()
				stmt, err = tx.Prepare("create ({`benchmark~test~id`:{0}})")
				c.Assert(err, IsNil)
			}
		}
	}
}

func (s *BenchmarkSuite) BenchmarkTx10SimpleMerge(c *C) {
	txSizeSimpleMerge(c, 10)
}

func (s *BenchmarkSuite) BenchmarkTx100SimpleMerge(c *C) {
	txSizeSimpleMerge(c, 100)
}

func (s *BenchmarkSuite) BenchmarkTx1000SimpleMerge(c *C) {
	txSizeSimpleMerge(c, 1000)
}

func (s *BenchmarkSuite) BenchmarkTx10000SimpleMerge(c *C) {
	txSizeSimpleMerge(c, 10000)
}

func txSizeSimpleMerge(c *C, size int) {
	conn := testConn()
	defer conn.Close()

	tx, err := conn.Begin()
	if err != nil {
		log.Fatal(err)
	}

	stmt, err := tx.Prepare("merge (:Test {`benchmark~test~id`:{0}})")
	c.Assert(err, IsNil)

	for i := 0; i < c.N; i++ {
		_, err = stmt.Exec(i)
		c.Assert(err, IsNil)

		if (i > 0 && i%size == 0) || i == c.N-1 {
			err = tx.Commit()
			c.Assert(err, IsNil)

			if i < c.N-1 {
				tx, err = conn.Begin()
				c.Assert(err, IsNil)

				stmt.Close()
				stmt, err = tx.Prepare("create ({`benchmark~test~id`:{0}})")
				c.Assert(err, IsNil)
			}
		}
	}
}
<commit_msg>fixing merge benchmarks<commit_after>package cq_test

import (
	"fmt"
	"log"
	"time"
	. "launchpad.net/gocheck"
)

type BenchmarkSuite struct{}

var _ = Suite(&BenchmarkSuite{})

func (s *BenchmarkSuite) SetUpTest(c *C) {
	db := testConn()
	_, err := db.Exec("start n=node(*) where has(n.`benchmark~test~id`) delete n")
	if err != nil {
		log.Println(err)
	}

	_, err = db.Exec("create constraint on (t:Test) assert t.`benchmark~test~id` is unique")
	if err != nil {
		log.Println(err)
	}
}

func (s *BenchmarkSuite) TearDownTest(c *C) {
	db := testConn()
	_, err := db.Exec("start n=node(*) where has(n.`benchmark~test~id`) delete n")
	if err != nil {
		log.Println(err)
	}

	_, err = db.Exec("drop constraint on (t:Test) assert t.`benchmark~test~id` is unique")
	if err != nil {
		log.Println(err)
	}
}

func (s *BenchmarkSuite) BenchmarkSimpleQuery(c *C) {
	stmt := prepareTest("return 1")
	defer stmt.Close()
	var test int
	for i := 0; i < c.N; i++ {
		rows, err := stmt.Query()
		c.Assert(err, IsNil)

		rows.Scan(&test)
		rows.Close()
	}
}

func (s *BenchmarkSuite) BenchmarkSimpleCreate(c *C) {
	stmt := prepareTest("create ({`benchmark~test~id`:{0}, timestamp:{1}})")
	defer stmt.Close()
	var test int
	for i := 0; i < c.N; i++ {
		rows, err := stmt.Query(i, fmt.Sprint(time.Now().UnixNano()))
		c.Assert(err, IsNil)

		rows.Scan(&test)
		rows.Close()
	}
}

func (s *BenchmarkSuite) BenchmarkSimpleCreateLabel(c *C) {
	stmt := prepareTest("create (:Test {`benchmark~test~id`:{0}, timestamp:{1}})")
	defer stmt.Close()
	var test int
	for i := 0; i < c.N; i++ {
		rows, err := stmt.Query(i, fmt.Sprint(time.Now().UnixNano()))
		c.Assert(err, IsNil)

		rows.Scan(&test)
		rows.Close()
	}
}

func (s *BenchmarkSuite) BenchmarkTx10SimpleCreate(c *C) {
	txSizeSimpleCreate(c, 10)
}

func (s *BenchmarkSuite) BenchmarkTx100SimpleCreate(c *C) {
	txSizeSimpleCreate(c, 100)
}

func (s *BenchmarkSuite) BenchmarkTx1000SimpleCreate(c *C) {
	txSizeSimpleCreate(c, 1000)
}

func (s *BenchmarkSuite) BenchmarkTx10000SimpleCreate(c *C) {
	txSizeSimpleCreate(c, 10000)
}

func txSizeSimpleCreate(c *C, size int) {
	conn := testConn()
	defer conn.Close()

	tx, err := conn.Begin()
	if err != nil {
		log.Fatal(err)
	}
	stmt, err := tx.Prepare("create ({`benchmark~test~id`:{0}})")
	c.Assert(err, IsNil)

	for i := 0; i < c.N; i++ {
		_, err = stmt.Exec(i)
		c.Assert(err, IsNil)

		if (i > 0 && i%size == 0) || i == c.N-1 {
			err = tx.Commit()
			c.Assert(err, IsNil)

			if i < c.N-1 {
				tx, err = conn.Begin()
				c.Assert(err, IsNil)

				stmt.Close()
				stmt, err = tx.Prepare("create ({`benchmark~test~id`:{0}})")
				c.Assert(err, IsNil)
			}
		}
	}
}

func (s *BenchmarkSuite) BenchmarkTx10SimpleMerge(c *C) {
	txSizeSimpleMerge(c, 10)
}

func (s *BenchmarkSuite) BenchmarkTx100SimpleMerge(c *C) {
	txSizeSimpleMerge(c, 100)
}

func (s *BenchmarkSuite) BenchmarkTx1000SimpleMerge(c *C) {
	txSizeSimpleMerge(c, 1000)
}

func (s *BenchmarkSuite) BenchmarkTx10000SimpleMerge(c *C) {
	txSizeSimpleMerge(c, 10000)
}

func txSizeSimpleMerge(c *C, size int) {
	conn := testConn()
	defer conn.Close()

	tx, err := conn.Begin()
	if err != nil {
		log.Fatal(err)
	}

	stmt, err := tx.Prepare("merge (:Test {`benchmark~test~id`:{0}})")
	c.Assert(err, IsNil)

	for i := 0; i < c.N; i++ {
		_, err = stmt.Exec(i)
		c.Assert(err, IsNil)

		if (i > 0 && i%size == 0) || i == c.N-1 {
			err = tx.Commit()
			c.Assert(err, IsNil)

			if i < c.N-1 {
				tx, err = conn.Begin()
				c.Assert(err, IsNil)

				stmt.Close()
				stmt, err = tx.Prepare("merge (:Test {`benchmark~test~id`:{0}})")
				c.Assert(err, IsNil)
			}
		}
	}
}
<|endoftext|>


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

package info

import (
	"testing"
	"time"
)

func TestStatsStartTime(t *testing.T) {
	N := 10
	stats := make([]*ContainerStats, 0, N)
	ct := time.Now()
	for i := 0; i < N; i++ {
		s := &ContainerStats{
			Timestamp: ct.Add(time.Duration(i) * time.Second),
		}
		stats = append(stats, s)
	}
	cinfo := &ContainerInfo{
		Name:  "/some/container",
		Stats: stats,
	}
	ref := ct.Add(time.Duration(N-1) * time.Second)
	end := cinfo.StatsEndTime()

	if !ref.Equal(end) {
		t.Errorf("end time is %v; should be %v", end, ref)
	}
}

func TestStatsEndTime(t *testing.T) {
	N := 10
	stats := make([]*ContainerStats, 0, N)
	ct := time.Now()
	for i := 0; i < N; i++ {
		s := &ContainerStats{
			Timestamp: ct.Add(time.Duration(i) * time.Second),
		}
		stats = append(stats, s)
	}
	cinfo := &ContainerInfo{
		Name:  "/some/container",
		Stats: stats,
	}
	ref := ct
	start := cinfo.StatsStartTime()

	if !ref.Equal(start) {
		t.Errorf("start time is %v; should be %v", start, ref)
	}
}

func TestPercentiles(t *testing.T) {
	N := 100
	data := make([]uint64, N)

	for i := 0; i < N; i++ {
		data[i] = uint64(i)
	}
	ps := []int{
		80,
		90,
		50,
	}
	ss := uint64Slice(data).Percentiles(ps...)
	for i, s := range ss {
		p := ps[i]
		d := uint64(float64(N) * (float64(p) / 100.0))
		if d != s {
			t.Errorf("%v \\%tile data should be %v, but got %v", float64(p)/100.0, d, s)
		}
	}
}
<commit_msg>unit tests for stats sample<commit_after>// Copyright 2014 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package info

import (
	"testing"
	"time"
)

func TestStatsStartTime(t *testing.T) {
	N := 10
	stats := make([]*ContainerStats, 0, N)
	ct := time.Now()
	for i := 0; i < N; i++ {
		s := &ContainerStats{
			Timestamp: ct.Add(time.Duration(i) * time.Second),
		}
		stats = append(stats, s)
	}
	cinfo := &ContainerInfo{
		Name:  "/some/container",
		Stats: stats,
	}
	ref := ct.Add(time.Duration(N-1) * time.Second)
	end := cinfo.StatsEndTime()

	if !ref.Equal(end) {
		t.Errorf("end time is %v; should be %v", end, ref)
	}
}

func TestStatsEndTime(t *testing.T) {
	N := 10
	stats := make([]*ContainerStats, 0, N)
	ct := time.Now()
	for i := 0; i < N; i++ {
		s := &ContainerStats{
			Timestamp: ct.Add(time.Duration(i) * time.Second),
		}
		stats = append(stats, s)
	}
	cinfo := &ContainerInfo{
		Name:  "/some/container",
		Stats: stats,
	}
	ref := ct
	start := cinfo.StatsStartTime()

	if !ref.Equal(start) {
		t.Errorf("start time is %v; should be %v", start, ref)
	}
}

func TestPercentiles(t *testing.T) {
	N := 100
	data := make([]uint64, N)

	for i := 0; i < N; i++ {
		data[i] = uint64(i)
	}
	ps := []int{
		80,
		90,
		50,
	}
	ss := uint64Slice(data).Percentiles(ps...)
	for i, s := range ss {
		p := ps[i]
		d := uint64(float64(N) * (float64(p) / 100.0))
		if d != s {
			t.Errorf("%v \\%tile data should be %v, but got %v", float64(p)/100.0, d, s)
		}
	}
}

func TestAddSampleNilStats(t *testing.T) {
	s := &ContainerStatsSummary{}

	stats := &ContainerStats{
		Cpu:    &CpuStats{},
		Memory: &MemoryStats{},
	}
	stats.Cpu.Usage.PerCpu = []uint64{uint64(10)}
	stats.Cpu.Usage.Total = uint64(10)
	stats.Cpu.Usage.System = uint64(2)
	stats.Cpu.Usage.User = uint64(8)
	stats.Memory.Usage = uint64(200)
	s.AddSample(nil, stats)

	if len(s.Samples) != 0 {
		t.Errorf("added an unexpected sample: %+v", s.Samples)
	}

	s.Samples = nil
	s.AddSample(stats, nil)

	if len(s.Samples) != 0 {
		t.Errorf("added an unexpected sample: %+v", s.Samples)
	}
}

func TestAddSample(t *testing.T) {
	s := &ContainerStatsSummary{}

	cpuPrevUsage := uint64(10)
	cpuCurrentUsage := uint64(15)
	memCurrentUsage := uint64(200)

	prev := &ContainerStats{
		Cpu:    &CpuStats{},
		Memory: &MemoryStats{},
	}
	prev.Cpu.Usage.PerCpu = []uint64{cpuPrevUsage}
	prev.Cpu.Usage.Total = cpuPrevUsage
	prev.Cpu.Usage.System = 0
	prev.Cpu.Usage.User = cpuPrevUsage
	prev.Timestamp = time.Now()

	current := &ContainerStats{
		Cpu:    &CpuStats{},
		Memory: &MemoryStats{},
	}
	current.Cpu.Usage.PerCpu = []uint64{cpuCurrentUsage}
	current.Cpu.Usage.Total = cpuCurrentUsage
	current.Cpu.Usage.System = 0
	current.Cpu.Usage.User = cpuCurrentUsage
	current.Memory.Usage = memCurrentUsage
	current.Timestamp = prev.Timestamp.Add(1 * time.Second)

	s.AddSample(prev, current)

	if len(s.Samples) != 1 {
		t.Fatalf("unexpected samples: %+v", s.Samples)
	}

	if s.Samples[0].Memory.Usage != memCurrentUsage {
		t.Errorf("wrong memory usage: %v. should be %v", s.Samples[0].Memory.Usage, memCurrentUsage)
	}

	if s.Samples[0].Cpu.Usage != cpuCurrentUsage-cpuPrevUsage {
		t.Errorf("wrong CPU usage: %v. should be %v", s.Samples[0].Cpu.Usage, cpuCurrentUsage-cpuPrevUsage)
	}
}

func TestAddSampleIncompleteStats(t *testing.T) {
	s := &ContainerStatsSummary{}

	cpuPrevUsage := uint64(10)
	cpuCurrentUsage := uint64(15)
	memCurrentUsage := uint64(200)

	prev := &ContainerStats{
		Cpu:    &CpuStats{},
		Memory: &MemoryStats{},
	}
	prev.Cpu.Usage.PerCpu = []uint64{cpuPrevUsage}
	prev.Cpu.Usage.Total = cpuPrevUsage
	prev.Cpu.Usage.System = 0
	prev.Cpu.Usage.User = cpuPrevUsage
	prev.Timestamp = time.Now()

	current := &ContainerStats{
		Cpu:    &CpuStats{},
		Memory: &MemoryStats{},
	}
	current.Cpu.Usage.PerCpu = []uint64{cpuCurrentUsage}
	current.Cpu.Usage.Total = cpuCurrentUsage
	current.Cpu.Usage.System = 0
	current.Cpu.Usage.User = cpuCurrentUsage
	current.Memory.Usage = memCurrentUsage
	current.Timestamp = prev.Timestamp.Add(1 * time.Second)

	stats := &ContainerStats{
		Cpu:    prev.Cpu,
		Memory: nil,
	}
	s.AddSample(stats, current)
	if len(s.Samples) != 0 {
		t.Errorf("added an unexpected sample: %+v", s.Samples)
	}
	s.Samples = nil

	s.AddSample(prev, stats)
	if len(s.Samples) != 0 {
		t.Errorf("added an unexpected sample: %+v", s.Samples)
	}
	s.Samples = nil

	stats = &ContainerStats{
		Cpu:    nil,
		Memory: prev.Memory,
	}
	s.AddSample(stats, current)
	if len(s.Samples) != 0 {
		t.Errorf("added an unexpected sample: %+v", s.Samples)
	}
	s.Samples = nil

	s.AddSample(prev, stats)
	if len(s.Samples) != 0 {
		t.Errorf("added an unexpected sample: %+v", s.Samples)
	}
	s.Samples = nil
}

func TestAddSampleWrongOrder(t *testing.T) {
	s := &ContainerStatsSummary{}

	cpuPrevUsage := uint64(10)
	cpuCurrentUsage := uint64(15)
	memCurrentUsage := uint64(200)

	prev := &ContainerStats{
		Cpu:    &CpuStats{},
		Memory: &MemoryStats{},
	}
	prev.Cpu.Usage.PerCpu = []uint64{cpuPrevUsage}
	prev.Cpu.Usage.Total = cpuPrevUsage
	prev.Cpu.Usage.System = 0
	prev.Cpu.Usage.User = cpuPrevUsage
	prev.Timestamp = time.Now()

	current := &ContainerStats{
		Cpu:    &CpuStats{},
		Memory: &MemoryStats{},
	}
	current.Cpu.Usage.PerCpu = []uint64{cpuCurrentUsage}
	current.Cpu.Usage.Total = cpuCurrentUsage
	current.Cpu.Usage.System = 0
	current.Cpu.Usage.User = cpuCurrentUsage
	current.Memory.Usage = memCurrentUsage
	current.Timestamp = prev.Timestamp.Add(1 * time.Second)

	s.AddSample(current, prev)
	if len(s.Samples) != 0 {
		t.Errorf("added an unexpected sample: %+v", s.Samples)
	}
}
<|endoftext|>


<commit_before>package eth

import (
	"math/big"

	"github.com/ethereum/go-ethereum/accounts"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/ethclient"
	lpTypes "github.com/livepeer/go-livepeer/eth/types"
)

type StubClient struct {
	StrmID            string
	TOpts             string
	MaxPrice          *big.Int
	Jid               *big.Int
	SegSeqNum         *big.Int
	VeriRate          uint64
	DStorageHash      string
	DHash             [32]byte
	TDHash            [32]byte
	BSig              []byte
	Proof             []byte
	VerifyCounter     int
	ClaimJid          []*big.Int
	ClaimStart        []*big.Int
	ClaimEnd          []*big.Int
	ClaimRoot         map[[32]byte]bool
	ClaimCounter      int
	SubLogsCh         chan types.Log
	JobsMap           map[string]*lpTypes.Job
	BlockNum          *big.Int
	BlockHashToReturn common.Hash
}

func (e *StubClient) Setup(password string, gasLimit, gasPrice *big.Int) error { return nil }
func (e *StubClient) Account() accounts.Account                                { return accounts.Account{} }
func (e *StubClient) Backend() (*ethclient.Client, error)                      { return nil, ErrMissingBackend }

// Rounds

func (e *StubClient) InitializeRound() (*types.Transaction, error) { return nil, nil }
func (e *StubClient) CurrentRound() (*big.Int, error)              { return big.NewInt(0), nil }
func (e *StubClient) LastInitializedRound() (*big.Int, error)      { return big.NewInt(0), nil }
func (e *StubClient) CurrentRoundInitialized() (bool, error)       { return false, nil }
func (e *StubClient) CurrentRoundLocked() (bool, error)            { return false, nil }

// Token

func (e *StubClient) Transfer(toAddr common.Address, amount *big.Int) (*types.Transaction, error) {
	return nil, nil
}
func (e *StubClient) Request() (*types.Transaction, error)            { return nil, nil }
func (e *StubClient) BalanceOf(addr common.Address) (*big.Int, error) { return big.NewInt(0), nil }

// Staking

func (e *StubClient) Transcoder(blockRewardCut *big.Int, feeShare *big.Int, pricePerSegment *big.Int) (*types.Transaction, error) {
	return nil, nil
}
func (e *StubClient) ResignAsTranscoder() (*types.Transaction, error) { return nil, nil }
func (e *StubClient) Reward() (*types.Transaction, error)             { return nil, nil }
func (e *StubClient) Bond(amount *big.Int, toAddr common.Address) (*types.Transaction, error) {
	return nil, nil
}
func (e *StubClient) Unbond() (*types.Transaction, error)        { return nil, nil }
func (e *StubClient) WithdrawStake() (*types.Transaction, error) { return nil, nil }
func (e *StubClient) WithdrawFees() (*types.Transaction, error)  { return nil, nil }
func (e *StubClient) ClaimTokenPoolsShares(endRound *big.Int) (*types.Transaction, error) {
	return nil, nil
}
func (e *StubClient) GetTranscoder(addr common.Address) (*lpTypes.Transcoder, error) { return nil, nil }
func (e *StubClient) GetDelegator(addr common.Address) (*lpTypes.Delegator, error)   { return nil, nil }
func (e *StubClient) GetTranscoderTokenPoolsForRound(addr common.Address, round *big.Int) (*lpTypes.TokenPools, error) {
	return nil, nil
}
func (e *StubClient) RegisteredTranscoders() ([]*lpTypes.Transcoder, error) { return nil, nil }
func (e *StubClient) IsActiveTranscoder() (bool, error)                     { return false, nil }
func (e *StubClient) IsAssignedTranscoder(jobID *big.Int) (bool, error)     { return false, nil }

// Jobs

func (e *StubClient) Job(streamId string, transcodingOptions string, maxPricePerSegment *big.Int, endBlock *big.Int) (*types.Transaction, error) {
	return nil, nil
}
func (e *StubClient) ClaimWork(jobId *big.Int, segmentRange [2]*big.Int, claimRoot [32]byte) (*types.Transaction, error) {
	e.ClaimCounter++
	e.ClaimJid = append(e.ClaimJid, jobId)
	e.ClaimStart = append(e.ClaimStart, segmentRange[0])
	e.ClaimEnd = append(e.ClaimEnd, segmentRange[1])
	e.ClaimRoot[claimRoot] = true
	return nil, nil
}
func (e *StubClient) Verify(jobId *big.Int, claimId *big.Int, segmentNumber *big.Int, dataStorageHash string, dataHashes [2][32]byte, broadcasterSig []byte, proof []byte) (*types.Transaction, error) {
	e.Jid = jobId
	e.SegSeqNum = segmentNumber
	e.DStorageHash = dataStorageHash
	e.DHash = dataHashes[0]
	e.TDHash = dataHashes[1]
	e.BSig = broadcasterSig
	e.Proof = proof
	e.VerifyCounter++

	return nil, nil
}
func (e *StubClient) DistributeFees(jobId *big.Int, claimId *big.Int) (*types.Transaction, error) {
	return nil, nil
}
func (c *StubClient) Deposit(amount *big.Int) (*types.Transaction, error) {
	return nil, nil
}
func (c *StubClient) Withdraw() (*types.Transaction, error) { return nil, nil }
func (c *StubClient) BroadcasterDeposit(broadcaster common.Address) (*big.Int, error) {
	return big.NewInt(0), nil
}
func (e *StubClient) GetJob(jobID *big.Int) (*lpTypes.Job, error) {
	return nil, nil
}
func (c *StubClient) GetClaim(jobID *big.Int, claimID *big.Int) (*lpTypes.Claim, error) {
	return nil, nil
}

// Parameters

func (c *StubClient) NumActiveTranscoders() (*big.Int, error)          { return big.NewInt(0), nil }
func (c *StubClient) RoundLength() (*big.Int, error)                   { return big.NewInt(0), nil }
func (c *StubClient) RoundLockAmount() (*big.Int, error)               { return big.NewInt(0), nil }
func (c *StubClient) UnbondingPeriod() (uint64, error)                 { return 0, nil }
func (c *StubClient) VerificationRate() (uint64, error)                { return 0, nil }
func (c *StubClient) VerificationPeriod() (*big.Int, error)            { return big.NewInt(0), nil }
func (c *StubClient) SlashingPeriod() (*big.Int, error)                { return big.NewInt(0), nil }
func (c *StubClient) FailedVerificationSlashAmount() (*big.Int, error) { return big.NewInt(0), nil }
func (c *StubClient) MissedVerificationSlashAmount() (*big.Int, error) { return big.NewInt(0), nil }
func (c *StubClient) DoubleClaimSegmentSlashAmount() (*big.Int, error) { return big.NewInt(0), nil }
func (c *StubClient) FinderFee() (*big.Int, error)                     { return big.NewInt(0), nil }
func (c *StubClient) Inflation() (*big.Int, error)                     { return big.NewInt(0), nil }
func (c *StubClient) InflationChange() (*big.Int, error)               { return big.NewInt(0), nil }
func (c *StubClient) TargetBondingRate() (*big.Int, error)             { return big.NewInt(0), nil }
func (c *StubClient) VerificationCodeHash() (string, error)            { return "", nil }

// Helpers

func (c *StubClient) ContractAddresses() map[string]common.Address { return nil }
func (c *StubClient) CheckTx(tx *types.Transaction) error          { return nil }
func (e *StubClient) Sign(msg []byte) ([]byte, error)              { return nil, nil }
<commit_msg>Add missing StubClient methods to fix tests<commit_after>package eth

import (
	"math/big"

	"github.com/ethereum/go-ethereum/accounts"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/ethclient"
	lpTypes "github.com/livepeer/go-livepeer/eth/types"
)

type StubClient struct {
	StrmID            string
	TOpts             string
	MaxPrice          *big.Int
	Jid               *big.Int
	SegSeqNum         *big.Int
	VeriRate          uint64
	DStorageHash      string
	DHash             [32]byte
	TDHash            [32]byte
	BSig              []byte
	Proof             []byte
	VerifyCounter     int
	ClaimJid          []*big.Int
	ClaimStart        []*big.Int
	ClaimEnd          []*big.Int
	ClaimRoot         map[[32]byte]bool
	ClaimCounter      int
	SubLogsCh         chan types.Log
	JobsMap           map[string]*lpTypes.Job
	BlockNum          *big.Int
	BlockHashToReturn common.Hash
}

func (e *StubClient) Setup(password string, gasLimit, gasPrice *big.Int) error { return nil }
func (e *StubClient) Account() accounts.Account                                { return accounts.Account{} }
func (e *StubClient) Backend() (*ethclient.Client, error)                      { return nil, ErrMissingBackend }

// Rounds

func (e *StubClient) InitializeRound() (*types.Transaction, error) { return nil, nil }
func (e *StubClient) CurrentRound() (*big.Int, error)              { return big.NewInt(0), nil }
func (e *StubClient) LastInitializedRound() (*big.Int, error)      { return big.NewInt(0), nil }
func (e *StubClient) CurrentRoundInitialized() (bool, error)       { return false, nil }
func (e *StubClient) CurrentRoundLocked() (bool, error)            { return false, nil }

// Token

func (e *StubClient) Transfer(toAddr common.Address, amount *big.Int) (*types.Transaction, error) {
	return nil, nil
}
func (e *StubClient) Request() (*types.Transaction, error)            { return nil, nil }
func (e *StubClient) BalanceOf(addr common.Address) (*big.Int, error) { return big.NewInt(0), nil }
func (e *StubClient) TotalSupply() (*big.Int, error)                  { return big.NewInt(0), nil }

// Staking

func (e *StubClient) Transcoder(blockRewardCut *big.Int, feeShare *big.Int, pricePerSegment *big.Int) (*types.Transaction, error) {
	return nil, nil
}
func (e *StubClient) ResignAsTranscoder() (*types.Transaction, error) { return nil, nil }
func (e *StubClient) Reward() (*types.Transaction, error)             { return nil, nil }
func (e *StubClient) Bond(amount *big.Int, toAddr common.Address) (*types.Transaction, error) {
	return nil, nil
}
func (e *StubClient) Unbond() (*types.Transaction, error)        { return nil, nil }
func (e *StubClient) WithdrawStake() (*types.Transaction, error) { return nil, nil }
func (e *StubClient) WithdrawFees() (*types.Transaction, error)  { return nil, nil }
func (e *StubClient) ClaimTokenPoolsShares(endRound *big.Int) (*types.Transaction, error) {
	return nil, nil
}
func (e *StubClient) GetTranscoder(addr common.Address) (*lpTypes.Transcoder, error) { return nil, nil }
func (e *StubClient) GetDelegator(addr common.Address) (*lpTypes.Delegator, error)   { return nil, nil }
func (e *StubClient) GetTranscoderTokenPoolsForRound(addr common.Address, round *big.Int) (*lpTypes.TokenPools, error) {
	return nil, nil
}
func (e *StubClient) RegisteredTranscoders() ([]*lpTypes.Transcoder, error) { return nil, nil }
func (e *StubClient) IsActiveTranscoder() (bool, error)                     { return false, nil }
func (e *StubClient) IsAssignedTranscoder(jobID *big.Int) (bool, error)     { return false, nil }
func (e *StubClient) GetTotalBonded() (*big.Int, error)                     { return big.NewInt(0), nil }

// Jobs

func (e *StubClient) Job(streamId string, transcodingOptions string, maxPricePerSegment *big.Int, endBlock *big.Int) (*types.Transaction, error) {
	return nil, nil
}
func (e *StubClient) ClaimWork(jobId *big.Int, segmentRange [2]*big.Int, claimRoot [32]byte) (*types.Transaction, error) {
	e.ClaimCounter++
	e.ClaimJid = append(e.ClaimJid, jobId)
	e.ClaimStart = append(e.ClaimStart, segmentRange[0])
	e.ClaimEnd = append(e.ClaimEnd, segmentRange[1])
	e.ClaimRoot[claimRoot] = true
	return nil, nil
}
func (e *StubClient) Verify(jobId *big.Int, claimId *big.Int, segmentNumber *big.Int, dataStorageHash string, dataHashes [2][32]byte, broadcasterSig []byte, proof []byte) (*types.Transaction, error) {
	e.Jid = jobId
	e.SegSeqNum = segmentNumber
	e.DStorageHash = dataStorageHash
	e.DHash = dataHashes[0]
	e.TDHash = dataHashes[1]
	e.BSig = broadcasterSig
	e.Proof = proof
	e.VerifyCounter++

	return nil, nil
}
func (e *StubClient) DistributeFees(jobId *big.Int, claimId *big.Int) (*types.Transaction, error) {
	return nil, nil
}
func (c *StubClient) Deposit(amount *big.Int) (*types.Transaction, error) {
	return nil, nil
}
func (c *StubClient) Withdraw() (*types.Transaction, error) { return nil, nil }
func (c *StubClient) BroadcasterDeposit(broadcaster common.Address) (*big.Int, error) {
	return big.NewInt(0), nil
}
func (e *StubClient) GetJob(jobID *big.Int) (*lpTypes.Job, error) {
	return nil, nil
}
func (c *StubClient) GetClaim(jobID *big.Int, claimID *big.Int) (*lpTypes.Claim, error) {
	return nil, nil
}

// Parameters

func (c *StubClient) NumActiveTranscoders() (*big.Int, error)          { return big.NewInt(0), nil }
func (c *StubClient) RoundLength() (*big.Int, error)                   { return big.NewInt(0), nil }
func (c *StubClient) RoundLockAmount() (*big.Int, error)               { return big.NewInt(0), nil }
func (c *StubClient) UnbondingPeriod() (uint64, error)                 { return 0, nil }
func (c *StubClient) VerificationRate() (uint64, error)                { return 0, nil }
func (c *StubClient) VerificationPeriod() (*big.Int, error)            { return big.NewInt(0), nil }
func (c *StubClient) SlashingPeriod() (*big.Int, error)                { return big.NewInt(0), nil }
func (c *StubClient) FailedVerificationSlashAmount() (*big.Int, error) { return big.NewInt(0), nil }
func (c *StubClient) MissedVerificationSlashAmount() (*big.Int, error) { return big.NewInt(0), nil }
func (c *StubClient) DoubleClaimSegmentSlashAmount() (*big.Int, error) { return big.NewInt(0), nil }
func (c *StubClient) FinderFee() (*big.Int, error)                     { return big.NewInt(0), nil }
func (c *StubClient) Inflation() (*big.Int, error)                     { return big.NewInt(0), nil }
func (c *StubClient) InflationChange() (*big.Int, error)               { return big.NewInt(0), nil }
func (c *StubClient) TargetBondingRate() (*big.Int, error)             { return big.NewInt(0), nil }
func (c *StubClient) VerificationCodeHash() (string, error)            { return "", nil }

// Helpers

func (c *StubClient) ContractAddresses() map[string]common.Address { return nil }
func (c *StubClient) CheckTx(tx *types.Transaction) error          { return nil }
func (e *StubClient) Sign(msg []byte) ([]byte, error)              { return nil, nil }
<|endoftext|>