<commit_before>package bosh_cli

import "os/exec"

func UploadRelease(releasePath string) error {
	cmd := exec.Command("bosh", "upload", "release", releasePath)
	err := cmd.Run()
	if err != nil {
		return err
	}
	return nil
}

func GetTarget() (string, error) {
	cmd := exec.Command("bosh", "target")
	output, err := cmd.Output()
	if err != nil {
		return "", err
	}
	return string(output), nil
}
<commit_msg>add upload stemcell command<commit_after>package bosh_cli

import "os/exec"

func UploadRelease(path string) error {
	cmd := exec.Command("bosh", "upload", "release", path)
	err := cmd.Run()
	if err != nil {
		return err
	}
	return nil
}

func UploadStemcell(path string) error {
	cmd := exec.Command("bosh", "upload", "stemcell", path)
	err := cmd.Run()
	if err != nil {
		return err
	}
	return nil
}

func GetTarget() (string, error) {
	cmd := exec.Command("bosh", "target")
	output, err := cmd.Output()
	if err != nil {
		return "", err
	}
	return string(output), nil
}
<|endoftext|>


<commit_before>package redis

import (
	"errors"
	"github.com/garyburd/redigo/redis"
	"time"
)

// RedisStore holds a handle to the Redis pool
type RedisStore struct {
	Pool  *redis.Pool
	Mutex *Mutex
}

var (
	RedisCache   RedisStore
	ErrCacheMiss = errors.New("cache: key not found.")
)

type Redis struct {
	// Redis address and max pool connections
	Protocol       string
	Address        string
	MaxIdle        int
	MaxConnections int
}

// NewRedisCache creates a new pool
func (r *Redis) NewRedisCache() {
	var err error

	RedisCache.Pool = &redis.Pool{
		MaxIdle:     r.MaxIdle,
		MaxActive:   r.MaxConnections,
		IdleTimeout: 240 * time.Second,
		Dial: func() (c redis.Conn, err error) {
			c, err = redis.Dial(r.Protocol, r.Address)
			if err != nil {
				return
			}
			return
		},
	}

	// create our distributed lock
	RedisCache.Mutex = NewMutex([]Pool{
		RedisCache.Pool,
	})

	return
}
<commit_msg>shared mutex<commit_after>package redis

import (
	"errors"
	"github.com/garyburd/redigo/redis"
	"time"
)

// RedisStore holds a handle to the Redis pool
type RedisStore struct {
	Pool  *redis.Pool
	Mutex *Mutex
}

var (
	RedisCache   RedisStore
	ErrCacheMiss = errors.New("cache: key not found.")
)

type Redis struct {
	// Redis address and max pool connections
	Protocol       string
	Address        string
	MaxIdle        int
	MaxConnections int
}

// NewRedisCache creates a new pool
func (r *Redis) NewRedisCache() {

	RedisCache.Pool = &redis.Pool{
		MaxIdle:     r.MaxIdle,
		MaxActive:   r.MaxConnections,
		IdleTimeout: 240 * time.Second,
		Dial: func() (c redis.Conn, err error) {
			c, err = redis.Dial(r.Protocol, r.Address)
			if err != nil {
				return
			}
			return
		},
	}

	// create our distributed lock
	RedisCache.Mutex = NewMutex([]Pool{
		RedisCache.Pool,
	})

	return
}
<|endoftext|>


<commit_before>// Copyright 2015 Dorival de Moraes Pedroso. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package goga

import "github.com/cpmech/gosl/rnd"

// DiffEvol performs the differential-evolution operation
func DiffEvol(xnew, x, x0, x1, x2 []float64, prms *Parameters) {
	C := rnd.Float64(0.0, 1.0)
	F := rnd.Float64(0.0, 1.0)
	K := 0.5 * (F + 1.0)
	n := len(x)
	I := rnd.Int(0, n-1)
	mutation := rnd.FlipCoin(0.5)
	for i := 0; i < n; i++ {
		if rnd.FlipCoin(C) || i == I {
			if mutation {
				xnew[i] = x0[i] + K*(x1[i]+x2[i]-2.0*x0[i])
			} else {
				xnew[i] = x0[i] + F*(x1[i]-x2[i])
			}
		} else {
			xnew[i] = x[i]
		}
		if xnew[i] < prms.FltMin[i] || xnew[i] > prms.FltMax[i] {
			xnew[i] = x[i]
		}
	}
}
<commit_msg>important change: best compromise for single-obj functions and multi-obj functions implemented: Cmax coefficient has to decrease with number of variables<commit_after>// Copyright 2015 Dorival de Moraes Pedroso. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package goga

import (
	"math"

	"github.com/cpmech/gosl/rnd"
)

// DiffEvol performs the differential-evolution operation
func DiffEvol(xnew, x, x0, x1, x2 []float64, prms *Parameters) {
	n := len(x)
	C := rnd.Float64(0.0, 1.0/math.Pow(float64(n), 0.1))
	F := rnd.Float64(0.0, 1.0)
	I := rnd.Int(0, n-1)
	for i := 0; i < n; i++ {
		if rnd.FlipCoin(C) || i == I {
			xnew[i] = x0[i] + F*(x1[i]-x2[i])
			if xnew[i] < prms.FltMin[i] {
				xnew[i] = prms.FltMin[i]
			}
			if xnew[i] > prms.FltMax[i] {
				xnew[i] = prms.FltMax[i]
			}
		} else {
			xnew[i] = x[i]
		}
	}
}
<|endoftext|>


<commit_before>// Copyright 2014 The project 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 opml provides all the required structures and functions for parsing
OPML files, as defined by the specification of the OPML format:

	[OPML 1.0] http://dev.opml.org/spec1.html
	[OPML 2.0] http://dev.opml.org/spec2.html

It is able to parse both, OPML 1.0 and OPML 2.0, files.
*/
package opml

import (
	"encoding/xml"
	"io/ioutil"
	"net/http"
)

// OPML is the root node of an OPML document. It only has a single required
// attribute: the version.
type OPML struct {
	XMLName xml.Name `xml:"opml"`
	Version string   `xml:"version,attr"`
	Head    Head     `xml:"head"`
	Body    Body     `xml:"body"`
}

// Head holds some meta information about the document.
type Head struct {
	Title           string `xml:"title"`
	DateCreated     string `xml:"dateCreated,omitempty"`
	DateModified    string `xml:"dateModified,omitempty"`
	OwnerName       string `xml:"ownerName,omitempty"`
	OwnerEmail      string `xml:"ownerEmail,omitempty"`
	OwnerID         string `xml:"ownerId,omitempty"`
	Docs            string `xml:"docs,omitempty"`
	ExpansionState  string `xml:"expansionState,omitempty"`
	VertScrollState string `xml:"vertScrollState,omitempty"`
	WindowTop       string `xml:"windowTop,omitempty"`
	WindowBottom    string `xml:"windowBottom,omitempty"`
	WindowLeft      string `xml:"windowLeft,omitempty"`
	WindowRight     string `xml:"windowRight,omitempty"`
}

// Body is the parent structure of all outlines.
type Body struct {
	Outlines []Outline `xml:"outline"`
}

// Outline holds all information about an outline.
type Outline struct {
	Outlines     []Outline `xml:"outline"`
	Text         string    `xml:"text,attr"`
	Type         string    `xml:"type,attr,omitempty"`
	IsComment    string    `xml:"isComment,attr,omitempty"`
	IsBreakpoint string    `xml:"isBreakpoint,attr,omitempty"`
	Created      string    `xml:"created,attr,omitempty"`
	Category     string    `xml:"category,attr,omitempty"`
	XMLURL       string    `xml:"xmlUrl,attr,omitempty"`
	HTMLURL      string    `xml:"htmlUrl,attr,omitempty"`
	URL          string    `xml:"url,attr,omitempty"`
	Language     string    `xml:"language,attr,omitempty"`
	Title        string    `xml:"title,attr,omitempty"`
	Version      string    `xml:"version,attr,omitempty"`
	Description  string    `xml:"description,attr,omitempty"`
}

// NewOPML creates a new OPML structure from a slice of bytes.
func NewOPML(b []byte) (*OPML, error) {
	var root OPML
	err := xml.Unmarshal(b, &root)
	if err != nil {
		return nil, err
	}

	return &root, nil
}

// NewOPMLFromURL creates a new OPML structure from an URL.
func NewOPMLFromURL(url string) (*OPML, error) {
	resp, err := http.Get(url)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

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

	return NewOPML(b)
}

// NewOPMLFromFile creates a new OPML structure from a file.
func NewOPMLFromFile(filePath string) (*OPML, error) {
	b, err := ioutil.ReadFile(filePath)
	if err != nil {
		return nil, err
	}

	return NewOPML(b)
}

// Outlines returns a slice of the outlines.
func (doc OPML) Outlines() []Outline {
	return doc.Body.Outlines
}

func (doc OPML) XML() (string, error) {
	b, err := xml.MarshalIndent(doc, "", "\t")
	return xml.Header + string(b), err
}
<commit_msg>add missing comment<commit_after>// Copyright 2014 The project 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 opml provides all the required structures and functions for parsing
OPML files, as defined by the specification of the OPML format:

	[OPML 1.0] http://dev.opml.org/spec1.html
	[OPML 2.0] http://dev.opml.org/spec2.html

It is able to parse both, OPML 1.0 and OPML 2.0, files.
*/
package opml

import (
	"encoding/xml"
	"io/ioutil"
	"net/http"
)

// OPML is the root node of an OPML document. It only has a single required
// attribute: the version.
type OPML struct {
	XMLName xml.Name `xml:"opml"`
	Version string   `xml:"version,attr"`
	Head    Head     `xml:"head"`
	Body    Body     `xml:"body"`
}

// Head holds some meta information about the document.
type Head struct {
	Title           string `xml:"title"`
	DateCreated     string `xml:"dateCreated,omitempty"`
	DateModified    string `xml:"dateModified,omitempty"`
	OwnerName       string `xml:"ownerName,omitempty"`
	OwnerEmail      string `xml:"ownerEmail,omitempty"`
	OwnerID         string `xml:"ownerId,omitempty"`
	Docs            string `xml:"docs,omitempty"`
	ExpansionState  string `xml:"expansionState,omitempty"`
	VertScrollState string `xml:"vertScrollState,omitempty"`
	WindowTop       string `xml:"windowTop,omitempty"`
	WindowBottom    string `xml:"windowBottom,omitempty"`
	WindowLeft      string `xml:"windowLeft,omitempty"`
	WindowRight     string `xml:"windowRight,omitempty"`
}

// Body is the parent structure of all outlines.
type Body struct {
	Outlines []Outline `xml:"outline"`
}

// Outline holds all information about an outline.
type Outline struct {
	Outlines     []Outline `xml:"outline"`
	Text         string    `xml:"text,attr"`
	Type         string    `xml:"type,attr,omitempty"`
	IsComment    string    `xml:"isComment,attr,omitempty"`
	IsBreakpoint string    `xml:"isBreakpoint,attr,omitempty"`
	Created      string    `xml:"created,attr,omitempty"`
	Category     string    `xml:"category,attr,omitempty"`
	XMLURL       string    `xml:"xmlUrl,attr,omitempty"`
	HTMLURL      string    `xml:"htmlUrl,attr,omitempty"`
	URL          string    `xml:"url,attr,omitempty"`
	Language     string    `xml:"language,attr,omitempty"`
	Title        string    `xml:"title,attr,omitempty"`
	Version      string    `xml:"version,attr,omitempty"`
	Description  string    `xml:"description,attr,omitempty"`
}

// NewOPML creates a new OPML structure from a slice of bytes.
func NewOPML(b []byte) (*OPML, error) {
	var root OPML
	err := xml.Unmarshal(b, &root)
	if err != nil {
		return nil, err
	}

	return &root, nil
}

// NewOPMLFromURL creates a new OPML structure from an URL.
func NewOPMLFromURL(url string) (*OPML, error) {
	resp, err := http.Get(url)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

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

	return NewOPML(b)
}

// NewOPMLFromFile creates a new OPML structure from a file.
func NewOPMLFromFile(filePath string) (*OPML, error) {
	b, err := ioutil.ReadFile(filePath)
	if err != nil {
		return nil, err
	}

	return NewOPML(b)
}

// Outlines returns a slice of the outlines.
func (doc OPML) Outlines() []Outline {
	return doc.Body.Outlines
}

// XML exports the OPML document to a XML string.
func (doc OPML) XML() (string, error) {
	b, err := xml.MarshalIndent(doc, "", "\t")
	return xml.Header + string(b), err
}
<|endoftext|>


<commit_before>package pool

import (
	"context"
	"fmt"
	"sync/atomic"
)

const (
	stateDefault = 0
	stateInited  = 1
	stateClosed  = 2
)

type BadConnError struct {
	wrapped error
}

var _ error = (*BadConnError)(nil)

func (e BadConnError) Error() string {
	return "pg: Conn is in a bad state"
}

func (e BadConnError) Unwrap() error {
	return e.wrapped
}

type SingleConnPool struct {
	pool  Pooler
	level int32 // atomic

	state uint32 // atomic
	ch    chan *Conn

	_badConnError atomic.Value
}

var _ Pooler = (*SingleConnPool)(nil)

func NewSingleConnPool(pool Pooler) *SingleConnPool {
	p, ok := pool.(*SingleConnPool)
	if !ok {
		p = &SingleConnPool{
			pool: pool,
			ch:   make(chan *Conn, 1),
		}
	}
	atomic.AddInt32(&p.level, 1)
	return p
}

func (p *SingleConnPool) SetConn(cn *Conn) {
	if atomic.CompareAndSwapUint32(&p.state, stateDefault, stateInited) {
		p.ch <- cn
	} else {
		panic("not reached")
	}
}

func (p *SingleConnPool) NewConn(c context.Context) (*Conn, error) {
	return p.pool.NewConn(c)
}

func (p *SingleConnPool) CloseConn(cn *Conn) error {
	return p.pool.CloseConn(cn)
}

func (p *SingleConnPool) Get(c context.Context) (*Conn, error) {
	// In worst case this races with Close which is not a very common operation.
	for i := 0; i < 1000; i++ {
		switch atomic.LoadUint32(&p.state) {
		case stateDefault:
			cn, err := p.pool.Get(c)
			if err != nil {
				return nil, err
			}
			if atomic.CompareAndSwapUint32(&p.state, stateDefault, stateInited) {
				return cn, nil
			}
			p.pool.Remove(cn, ErrClosed)
		case stateInited:
			if err := p.badConnError(); err != nil {
				return nil, err
			}
			cn, ok := <-p.ch
			if !ok {
				return nil, ErrClosed
			}
			return cn, nil
		case stateClosed:
			return nil, ErrClosed
		default:
			panic("not reached")
		}
	}
	return nil, fmt.Errorf("pg: SingleConnPool.Get: infinite loop")
}

func (p *SingleConnPool) Put(cn *Conn) {
	defer func() {
		if recover() != nil {
			p.freeConn(cn)
		}
	}()
	p.ch <- cn
}

func (p *SingleConnPool) freeConn(cn *Conn) {
	if err := p.badConnError(); err != nil {
		p.pool.Remove(cn, err)
	} else {
		p.pool.Put(cn)
	}
}

func (p *SingleConnPool) Remove(cn *Conn, reason error) {
	defer func() {
		if recover() != nil {
			p.pool.Remove(cn, ErrClosed)
		}
	}()
	p._badConnError.Store(BadConnError{wrapped: reason})
	p.ch <- cn
}

func (p *SingleConnPool) Len() int {
	switch atomic.LoadUint32(&p.state) {
	case stateDefault:
		return 0
	case stateInited:
		return 1
	case stateClosed:
		return 0
	default:
		panic("not reached")
	}
}

func (p *SingleConnPool) IdleLen() int {
	return len(p.ch)
}

func (p *SingleConnPool) Stats() *Stats {
	return &Stats{}
}

func (p *SingleConnPool) Close() error {
	level := atomic.AddInt32(&p.level, -1)
	if level > 0 {
		return nil
	}

	for i := 0; i < 1000; i++ {
		state := atomic.LoadUint32(&p.state)
		if state == stateClosed {
			return ErrClosed
		}
		if atomic.CompareAndSwapUint32(&p.state, state, stateClosed) {
			close(p.ch)
			cn, ok := <-p.ch
			if ok {
				p.freeConn(cn)
			}
			return nil
		}
	}

	return fmt.Errorf("pg: SingleConnPool.Close: infinite loop")
}

func (p *SingleConnPool) Reset() error {
	if p.badConnError() == nil {
		return nil
	}

	select {
	case cn, ok := <-p.ch:
		if !ok {
			return ErrClosed
		}
		p.pool.Remove(cn, ErrClosed)
		p._badConnError.Store(BadConnError{wrapped: nil})
	default:
		return fmt.Errorf("pg: SingleConnPool does not have a Conn")
	}

	if !atomic.CompareAndSwapUint32(&p.state, stateInited, stateDefault) {
		state := atomic.LoadUint32(&p.state)
		return fmt.Errorf("pg: invalid SingleConnPool state: %d", state)
	}

	return nil
}

func (p *SingleConnPool) badConnError() error {
	if v := p._badConnError.Load(); v != nil {
		err := v.(BadConnError)
		if err.wrapped != nil {
			return err
		}
	}
	return nil
}
<commit_msg>internal/pool: include details when conn is in a bad state<commit_after>package pool

import (
	"context"
	"fmt"
	"sync/atomic"
)

const (
	stateDefault = 0
	stateInited  = 1
	stateClosed  = 2
)

type BadConnError struct {
	wrapped error
}

var _ error = (*BadConnError)(nil)

func (e BadConnError) Error() string {
	s := "pg: Conn is in a bad state"
	if e.wrapped != nil {
		s += ": " + e.wrapped.Error()
	}
	return s
}

func (e BadConnError) Unwrap() error {
	return e.wrapped
}

type SingleConnPool struct {
	pool  Pooler
	level int32 // atomic

	state uint32 // atomic
	ch    chan *Conn

	_badConnError atomic.Value
}

var _ Pooler = (*SingleConnPool)(nil)

func NewSingleConnPool(pool Pooler) *SingleConnPool {
	p, ok := pool.(*SingleConnPool)
	if !ok {
		p = &SingleConnPool{
			pool: pool,
			ch:   make(chan *Conn, 1),
		}
	}
	atomic.AddInt32(&p.level, 1)
	return p
}

func (p *SingleConnPool) SetConn(cn *Conn) {
	if atomic.CompareAndSwapUint32(&p.state, stateDefault, stateInited) {
		p.ch <- cn
	} else {
		panic("not reached")
	}
}

func (p *SingleConnPool) NewConn(c context.Context) (*Conn, error) {
	return p.pool.NewConn(c)
}

func (p *SingleConnPool) CloseConn(cn *Conn) error {
	return p.pool.CloseConn(cn)
}

func (p *SingleConnPool) Get(c context.Context) (*Conn, error) {
	// In worst case this races with Close which is not a very common operation.
	for i := 0; i < 1000; i++ {
		switch atomic.LoadUint32(&p.state) {
		case stateDefault:
			cn, err := p.pool.Get(c)
			if err != nil {
				return nil, err
			}
			if atomic.CompareAndSwapUint32(&p.state, stateDefault, stateInited) {
				return cn, nil
			}
			p.pool.Remove(cn, ErrClosed)
		case stateInited:
			if err := p.badConnError(); err != nil {
				return nil, err
			}
			cn, ok := <-p.ch
			if !ok {
				return nil, ErrClosed
			}
			return cn, nil
		case stateClosed:
			return nil, ErrClosed
		default:
			panic("not reached")
		}
	}
	return nil, fmt.Errorf("pg: SingleConnPool.Get: infinite loop")
}

func (p *SingleConnPool) Put(cn *Conn) {
	defer func() {
		if recover() != nil {
			p.freeConn(cn)
		}
	}()
	p.ch <- cn
}

func (p *SingleConnPool) freeConn(cn *Conn) {
	if err := p.badConnError(); err != nil {
		p.pool.Remove(cn, err)
	} else {
		p.pool.Put(cn)
	}
}

func (p *SingleConnPool) Remove(cn *Conn, reason error) {
	defer func() {
		if recover() != nil {
			p.pool.Remove(cn, ErrClosed)
		}
	}()
	p._badConnError.Store(BadConnError{wrapped: reason})
	p.ch <- cn
}

func (p *SingleConnPool) Len() int {
	switch atomic.LoadUint32(&p.state) {
	case stateDefault:
		return 0
	case stateInited:
		return 1
	case stateClosed:
		return 0
	default:
		panic("not reached")
	}
}

func (p *SingleConnPool) IdleLen() int {
	return len(p.ch)
}

func (p *SingleConnPool) Stats() *Stats {
	return &Stats{}
}

func (p *SingleConnPool) Close() error {
	level := atomic.AddInt32(&p.level, -1)
	if level > 0 {
		return nil
	}

	for i := 0; i < 1000; i++ {
		state := atomic.LoadUint32(&p.state)
		if state == stateClosed {
			return ErrClosed
		}
		if atomic.CompareAndSwapUint32(&p.state, state, stateClosed) {
			close(p.ch)
			cn, ok := <-p.ch
			if ok {
				p.freeConn(cn)
			}
			return nil
		}
	}

	return fmt.Errorf("pg: SingleConnPool.Close: infinite loop")
}

func (p *SingleConnPool) Reset() error {
	if p.badConnError() == nil {
		return nil
	}

	select {
	case cn, ok := <-p.ch:
		if !ok {
			return ErrClosed
		}
		p.pool.Remove(cn, ErrClosed)
		p._badConnError.Store(BadConnError{wrapped: nil})
	default:
		return fmt.Errorf("pg: SingleConnPool does not have a Conn")
	}

	if !atomic.CompareAndSwapUint32(&p.state, stateInited, stateDefault) {
		state := atomic.LoadUint32(&p.state)
		return fmt.Errorf("pg: invalid SingleConnPool state: %d", state)
	}

	return nil
}

func (p *SingleConnPool) badConnError() error {
	if v := p._badConnError.Load(); v != nil {
		err := v.(BadConnError)
		if err.wrapped != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


<commit_before>// Copyright 2011 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// 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 oglemock_test

import (
	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/oglemock"
	. "github.com/jacobsa/ogletest"
	"reflect"
)

////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////

var emptyReturnSig reflect.Type = reflect.TypeOf(func(i int) {})
var float64ReturnSig reflect.Type = reflect.TypeOf(func(i int) float64 { return 17.0 })

type InternalExpectationTest struct {
}

func init() { RegisterTestSuite(&InternalExpectationTest{}) }

////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////

func (t *InternalExpectationTest) StoresFileNameAndLineNumber() {
	args := []interface{}{}
	exp := InternalNewExpectation(emptyReturnSig, args, "taco", 17)

	ExpectThat(exp.FileName, Equals("taco"))
	ExpectThat(exp.LineNumber, Equals(17))
}

func (t *InternalExpectationTest) NoArgs() {
	args := []interface{}{}
	exp := InternalNewExpectation(emptyReturnSig, args, "", 0)

	ExpectThat(len(exp.ArgMatchers), Equals(0))
}

func (t *InternalExpectationTest) MixOfMatchersAndNonMatchers() {
	args := []interface{}{Equals(17), 19, Equals(23)}
	exp := InternalNewExpectation(emptyReturnSig, args, "", 0)

	// Matcher args
	ExpectThat(len(exp.ArgMatchers), Equals(3))
	ExpectThat(exp.ArgMatchers[0], Equals(args[0]))
	ExpectThat(exp.ArgMatchers[2], Equals(args[2]))

	// Non-matcher arg
	var res MatchResult
	matcher1 := exp.ArgMatchers[1]

	res, _ = matcher1.Matches(17)
	ExpectThat(res, Equals(MATCH_FALSE))

	res, _ = matcher1.Matches(19)
	ExpectThat(res, Equals(MATCH_TRUE))

	res, _ = matcher1.Matches(23)
	ExpectThat(res, Equals(MATCH_FALSE))
}

func (t *InternalExpectationTest) NoTimes() {
	exp := InternalNewExpectation(emptyReturnSig, []interface{}{}, "", 0)

	ExpectThat(exp.ExpectedNumMatches, Equals(-1))
}

func (t *InternalExpectationTest) TimesN() {
	exp := InternalNewExpectation(emptyReturnSig, []interface{}{}, "", 0)
	exp.Times(17)

	ExpectThat(exp.ExpectedNumMatches, Equals(17))
}

func (t *InternalExpectationTest) NoActions() {
	exp := InternalNewExpectation(emptyReturnSig, []interface{}{}, "", 0)

	ExpectThat(len(exp.OneTimeActions), Equals(0))
	ExpectThat(exp.FallbackAction, Equals(nil))
}

func (t *InternalExpectationTest) WillOnce() {
	action0 := Return(17.0)
	action1 := Return(19.0)

	exp := InternalNewExpectation(float64ReturnSig, []interface{}{}, "", 0)
	exp.WillOnce(action0).WillOnce(action1)

	ExpectThat(len(exp.OneTimeActions), Equals(2))
	ExpectThat(exp.OneTimeActions[0], Equals(action0))
	ExpectThat(exp.OneTimeActions[1], Equals(action1))
}

func (t *InternalExpectationTest) WillRepeatedly() {
	action := Return(17.0)

	exp := InternalNewExpectation(float64ReturnSig, []interface{}{}, "", 0)
	exp.WillRepeatedly(action)

	ExpectThat(exp.FallbackAction, Equals(action))
}

func (t *InternalExpectationTest) BothKindsOfAction() {
	action0 := Return(17.0)
	action1 := Return(19.0)
	action2 := Return(23.0)

	exp := InternalNewExpectation(float64ReturnSig, []interface{}{}, "", 0)
	exp.WillOnce(action0).WillOnce(action1).WillRepeatedly(action2)

	ExpectThat(len(exp.OneTimeActions), Equals(2))
	ExpectThat(exp.OneTimeActions[0], Equals(action0))
	ExpectThat(exp.OneTimeActions[1], Equals(action1))
	ExpectThat(exp.FallbackAction, Equals(action2))
}

func (t *InternalExpectationTest) TimesCalledWithHugeNumber() {
	exp := InternalNewExpectation(emptyReturnSig, []interface{}{}, "", 0)

	ExpectThat(
		func() { exp.Times(1 << 30) },
		Panics(HasSubstr("Times: N must be at most 1000")))
}

func (t *InternalExpectationTest) TimesCalledTwice() {
	exp := InternalNewExpectation(emptyReturnSig, []interface{}{}, "", 0)

	ExpectThat(
		func() { exp.Times(17).Times(17) },
		Panics(HasSubstr("Times called more than")))
}

func (t *InternalExpectationTest) TimesCalledAfterWillOnce() {
	exp := InternalNewExpectation(emptyReturnSig, []interface{}{}, "", 0)

	ExpectThat(
		func() { exp.WillOnce(Return()).Times(17) },
		Panics(HasSubstr("Times called after WillOnce")))
}

func (t *InternalExpectationTest) TimesCalledAfterWillRepeatedly() {
	exp := InternalNewExpectation(emptyReturnSig, []interface{}{}, "", 0)

	ExpectThat(
		func() { exp.WillRepeatedly(Return()).Times(17) },
		Panics(HasSubstr("Times called after WillRepeatedly")))
}

func (t *InternalExpectationTest) WillOnceCalledAfterWillRepeatedly() {
	exp := InternalNewExpectation(emptyReturnSig, []interface{}{}, "", 0)

	ExpectThat(
		func() { exp.WillRepeatedly(Return()).WillOnce(Return()) },
		Panics(HasSubstr("WillOnce called after WillRepeatedly")))
}

func (t *InternalExpectationTest) OneTimeActionRejectsSignature() {
	action := Return("taco")
	exp := InternalNewExpectation(float64ReturnSig, []interface{}{}, "", 0)

	ExpectThat(
		func() { exp.WillOnce(action) },
		Panics(HasSubstr("arg 0; expected float64")))
}

func (t *InternalExpectationTest) WillRepeatedlyCalledTwice() {
	exp := InternalNewExpectation(emptyReturnSig, []interface{}{}, "", 0)

	ExpectThat(
		func() { exp.WillRepeatedly(Return()).WillRepeatedly(Return()) },
		Panics(HasSubstr("WillRepeatedly called more than once")))
}

func (t *InternalExpectationTest) FallbackActionRejectsSignature() {
	action := Return("taco")
	exp := InternalNewExpectation(float64ReturnSig, []interface{}{}, "", 0)

	ExpectThat(
		func() { exp.WillRepeatedly(action) },
		Panics(HasSubstr("arg 0; expected float64")))
}
<commit_msg>Fixed some errors in internal_expectation_test.go.<commit_after>// Copyright 2011 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// 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 oglemock_test

import (
	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/oglemock"
	. "github.com/jacobsa/ogletest"
	"reflect"
)

////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////

var emptyReturnSig reflect.Type = reflect.TypeOf(func(i int) {})
var float64ReturnSig reflect.Type = reflect.TypeOf(func(i int) float64 { return 17.0 })

type InternalExpectationTest struct {
}

func init() { RegisterTestSuite(&InternalExpectationTest{}) }

////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////

func (t *InternalExpectationTest) StoresFileNameAndLineNumber() {
	args := []interface{}{}
	exp := InternalNewExpectation(emptyReturnSig, args, "taco", 17)

	ExpectThat(exp.FileName, Equals("taco"))
	ExpectThat(exp.LineNumber, Equals(17))
}

func (t *InternalExpectationTest) NoArgs() {
	args := []interface{}{}
	exp := InternalNewExpectation(emptyReturnSig, args, "", 0)

	ExpectThat(len(exp.ArgMatchers), Equals(0))
}

func (t *InternalExpectationTest) MixOfMatchersAndNonMatchers() {
	args := []interface{}{Equals(17), 19, Equals(23)}
	exp := InternalNewExpectation(emptyReturnSig, args, "", 0)

	// Matcher args
	ExpectThat(len(exp.ArgMatchers), Equals(3))
	ExpectThat(exp.ArgMatchers[0], Equals(args[0]))
	ExpectThat(exp.ArgMatchers[2], Equals(args[2]))

	// Non-matcher arg
	var res bool
	matcher1 := exp.ArgMatchers[1]

	res, _ = matcher1.Matches(17)
	ExpectFalse(res)

	res, _ = matcher1.Matches(19)
	ExpectTrue(res)

	res, _ = matcher1.Matches(23)
	ExpectFalse(res)
}

func (t *InternalExpectationTest) NoTimes() {
	exp := InternalNewExpectation(emptyReturnSig, []interface{}{}, "", 0)

	ExpectThat(exp.ExpectedNumMatches, Equals(-1))
}

func (t *InternalExpectationTest) TimesN() {
	exp := InternalNewExpectation(emptyReturnSig, []interface{}{}, "", 0)
	exp.Times(17)

	ExpectThat(exp.ExpectedNumMatches, Equals(17))
}

func (t *InternalExpectationTest) NoActions() {
	exp := InternalNewExpectation(emptyReturnSig, []interface{}{}, "", 0)

	ExpectThat(len(exp.OneTimeActions), Equals(0))
	ExpectThat(exp.FallbackAction, Equals(nil))
}

func (t *InternalExpectationTest) WillOnce() {
	action0 := Return(17.0)
	action1 := Return(19.0)

	exp := InternalNewExpectation(float64ReturnSig, []interface{}{}, "", 0)
	exp.WillOnce(action0).WillOnce(action1)

	ExpectThat(len(exp.OneTimeActions), Equals(2))
	ExpectThat(exp.OneTimeActions[0], Equals(action0))
	ExpectThat(exp.OneTimeActions[1], Equals(action1))
}

func (t *InternalExpectationTest) WillRepeatedly() {
	action := Return(17.0)

	exp := InternalNewExpectation(float64ReturnSig, []interface{}{}, "", 0)
	exp.WillRepeatedly(action)

	ExpectThat(exp.FallbackAction, Equals(action))
}

func (t *InternalExpectationTest) BothKindsOfAction() {
	action0 := Return(17.0)
	action1 := Return(19.0)
	action2 := Return(23.0)

	exp := InternalNewExpectation(float64ReturnSig, []interface{}{}, "", 0)
	exp.WillOnce(action0).WillOnce(action1).WillRepeatedly(action2)

	ExpectThat(len(exp.OneTimeActions), Equals(2))
	ExpectThat(exp.OneTimeActions[0], Equals(action0))
	ExpectThat(exp.OneTimeActions[1], Equals(action1))
	ExpectThat(exp.FallbackAction, Equals(action2))
}

func (t *InternalExpectationTest) TimesCalledWithHugeNumber() {
	exp := InternalNewExpectation(emptyReturnSig, []interface{}{}, "", 0)

	ExpectThat(
		func() { exp.Times(1 << 30) },
		Panics(HasSubstr("Times: N must be at most 1000")))
}

func (t *InternalExpectationTest) TimesCalledTwice() {
	exp := InternalNewExpectation(emptyReturnSig, []interface{}{}, "", 0)

	ExpectThat(
		func() { exp.Times(17).Times(17) },
		Panics(HasSubstr("Times called more than")))
}

func (t *InternalExpectationTest) TimesCalledAfterWillOnce() {
	exp := InternalNewExpectation(emptyReturnSig, []interface{}{}, "", 0)

	ExpectThat(
		func() { exp.WillOnce(Return()).Times(17) },
		Panics(HasSubstr("Times called after WillOnce")))
}

func (t *InternalExpectationTest) TimesCalledAfterWillRepeatedly() {
	exp := InternalNewExpectation(emptyReturnSig, []interface{}{}, "", 0)

	ExpectThat(
		func() { exp.WillRepeatedly(Return()).Times(17) },
		Panics(HasSubstr("Times called after WillRepeatedly")))
}

func (t *InternalExpectationTest) WillOnceCalledAfterWillRepeatedly() {
	exp := InternalNewExpectation(emptyReturnSig, []interface{}{}, "", 0)

	ExpectThat(
		func() { exp.WillRepeatedly(Return()).WillOnce(Return()) },
		Panics(HasSubstr("WillOnce called after WillRepeatedly")))
}

func (t *InternalExpectationTest) OneTimeActionRejectsSignature() {
	action := Return("taco")
	exp := InternalNewExpectation(float64ReturnSig, []interface{}{}, "", 0)

	ExpectThat(
		func() { exp.WillOnce(action) },
		Panics(HasSubstr("arg 0; expected float64")))
}

func (t *InternalExpectationTest) WillRepeatedlyCalledTwice() {
	exp := InternalNewExpectation(emptyReturnSig, []interface{}{}, "", 0)

	ExpectThat(
		func() { exp.WillRepeatedly(Return()).WillRepeatedly(Return()) },
		Panics(HasSubstr("WillRepeatedly called more than once")))
}

func (t *InternalExpectationTest) FallbackActionRejectsSignature() {
	action := Return("taco")
	exp := InternalNewExpectation(float64ReturnSig, []interface{}{}, "", 0)

	ExpectThat(
		func() { exp.WillRepeatedly(action) },
		Panics(HasSubstr("arg 0; expected float64")))
}
<|endoftext|>


<commit_before>package builder

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

	"github.com/docker/docker/pkg/archive"
	"github.com/docker/docker/pkg/chrootarchive"
	"github.com/docker/docker/pkg/ioutils"
	"github.com/docker/docker/pkg/symlink"
	"github.com/docker/docker/pkg/tarsum"
)

type tarSumContext struct {
	root string
	sums tarsum.FileInfoSums
}

func (c *tarSumContext) Close() error {
	return os.RemoveAll(c.root)
}

func convertPathError(err error, cleanpath string) error {
	if err, ok := err.(*os.PathError); ok {
		err.Path = cleanpath
		return err
	}
	return err
}

func (c *tarSumContext) Open(path string) (io.ReadCloser, error) {
	cleanpath, fullpath, err := c.normalize(path)
	if err != nil {
		return nil, err
	}
	r, err := os.Open(fullpath)
	if err != nil {
		return nil, convertPathError(err, cleanpath)
	}
	return r, nil
}

func (c *tarSumContext) Stat(path string) (string, FileInfo, error) {
	cleanpath, fullpath, err := c.normalize(path)
	if err != nil {
		return "", nil, err
	}

	st, err := os.Lstat(fullpath)
	if err != nil {
		return "", nil, convertPathError(err, cleanpath)
	}

	rel, err := filepath.Rel(c.root, fullpath)
	if err != nil {
		return "", nil, convertPathError(err, cleanpath)
	}

	// We set sum to path by default for the case where GetFile returns nil.
	// The usual case is if relative path is empty.
	sum := path
	// Use the checksum of the followed path(not the possible symlink) because
	// this is the file that is actually copied.
	if tsInfo := c.sums.GetFile(filepath.ToSlash(rel)); tsInfo != nil {
		sum = tsInfo.Sum()
	}
	fi := &HashedFileInfo{PathFileInfo{st, fullpath, filepath.Base(cleanpath)}, sum}
	return rel, fi, nil
}

// MakeTarSumContext returns a build Context from a tar stream.
//
// It extracts the tar stream to a temporary folder that is deleted as soon as
// the Context is closed.
// As the extraction happens, a tarsum is calculated for every file, and the set of
// all those sums then becomes the source of truth for all operations on this Context.
//
// Closing tarStream has to be done by the caller.
func MakeTarSumContext(tarStream io.Reader) (ModifiableContext, error) {
	root, err := ioutils.TempDir("", "docker-builder")
	if err != nil {
		return nil, err
	}

	tsc := &tarSumContext{root: root}

	// Make sure we clean-up upon error.  In the happy case the caller
	// is expected to manage the clean-up
	defer func() {
		if err != nil {
			tsc.Close()
		}
	}()

	decompressedStream, err := archive.DecompressStream(tarStream)
	if err != nil {
		return nil, err
	}

	sum, err := tarsum.NewTarSum(decompressedStream, true, tarsum.Version1)
	if err != nil {
		return nil, err
	}

	if err := chrootarchive.Untar(sum, root, nil); err != nil {
		return nil, err
	}

	tsc.sums = sum.GetSums()

	return tsc, nil
}

func (c *tarSumContext) normalize(path string) (cleanpath, fullpath string, err error) {
	cleanpath = filepath.Clean(string(os.PathSeparator) + path)[1:]
	fullpath, err = symlink.FollowSymlinkInScope(filepath.Join(c.root, path), c.root)
	if err != nil {
		return "", "", fmt.Errorf("Forbidden path outside the build context: %s (%s)", path, fullpath)
	}
	_, err = os.Lstat(fullpath)
	if err != nil {
		return "", "", convertPathError(err, path)
	}
	return
}

func (c *tarSumContext) Walk(root string, walkFn WalkFunc) error {
	root = filepath.Join(c.root, filepath.Join(string(filepath.Separator), root))
	return filepath.Walk(root, func(fullpath string, info os.FileInfo, err error) error {
		rel, err := filepath.Rel(c.root, fullpath)
		if err != nil {
			return err
		}
		if rel == "." {
			return nil
		}

		sum := rel
		if tsInfo := c.sums.GetFile(filepath.ToSlash(rel)); tsInfo != nil {
			sum = tsInfo.Sum()
		}
		fi := &HashedFileInfo{PathFileInfo{FileInfo: info, FilePath: fullpath}, sum}
		if err := walkFn(rel, fi, nil); err != nil {
			return err
		}
		return nil
	})
}

func (c *tarSumContext) Remove(path string) error {
	_, fullpath, err := c.normalize(path)
	if err != nil {
		return err
	}
	return os.RemoveAll(fullpath)
}
<commit_msg>Clean up tmp files for interrupted `docker build`<commit_after>package builder

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

	"github.com/docker/docker/pkg/archive"
	"github.com/docker/docker/pkg/chrootarchive"
	"github.com/docker/docker/pkg/ioutils"
	"github.com/docker/docker/pkg/symlink"
	"github.com/docker/docker/pkg/tarsum"
)

type tarSumContext struct {
	root string
	sums tarsum.FileInfoSums
}

func (c *tarSumContext) Close() error {
	return os.RemoveAll(c.root)
}

func convertPathError(err error, cleanpath string) error {
	if err, ok := err.(*os.PathError); ok {
		err.Path = cleanpath
		return err
	}
	return err
}

func (c *tarSumContext) Open(path string) (io.ReadCloser, error) {
	cleanpath, fullpath, err := c.normalize(path)
	if err != nil {
		return nil, err
	}
	r, err := os.Open(fullpath)
	if err != nil {
		return nil, convertPathError(err, cleanpath)
	}
	return r, nil
}

func (c *tarSumContext) Stat(path string) (string, FileInfo, error) {
	cleanpath, fullpath, err := c.normalize(path)
	if err != nil {
		return "", nil, err
	}

	st, err := os.Lstat(fullpath)
	if err != nil {
		return "", nil, convertPathError(err, cleanpath)
	}

	rel, err := filepath.Rel(c.root, fullpath)
	if err != nil {
		return "", nil, convertPathError(err, cleanpath)
	}

	// We set sum to path by default for the case where GetFile returns nil.
	// The usual case is if relative path is empty.
	sum := path
	// Use the checksum of the followed path(not the possible symlink) because
	// this is the file that is actually copied.
	if tsInfo := c.sums.GetFile(filepath.ToSlash(rel)); tsInfo != nil {
		sum = tsInfo.Sum()
	}
	fi := &HashedFileInfo{PathFileInfo{st, fullpath, filepath.Base(cleanpath)}, sum}
	return rel, fi, nil
}

// MakeTarSumContext returns a build Context from a tar stream.
//
// It extracts the tar stream to a temporary folder that is deleted as soon as
// the Context is closed.
// As the extraction happens, a tarsum is calculated for every file, and the set of
// all those sums then becomes the source of truth for all operations on this Context.
//
// Closing tarStream has to be done by the caller.
func MakeTarSumContext(tarStream io.Reader) (ModifiableContext, error) {
	root, err := ioutils.TempDir("", "docker-builder")
	if err != nil {
		return nil, err
	}

	tsc := &tarSumContext{root: root}

	// Make sure we clean-up upon error.  In the happy case the caller
	// is expected to manage the clean-up
	defer func() {
		if err != nil {
			tsc.Close()
		}
	}()

	decompressedStream, err := archive.DecompressStream(tarStream)
	if err != nil {
		return nil, err
	}

	sum, err := tarsum.NewTarSum(decompressedStream, true, tarsum.Version1)
	if err != nil {
		return nil, err
	}

	err = chrootarchive.Untar(sum, root, nil)
	if err != nil {
		return nil, err
	}

	tsc.sums = sum.GetSums()

	return tsc, nil
}

func (c *tarSumContext) normalize(path string) (cleanpath, fullpath string, err error) {
	cleanpath = filepath.Clean(string(os.PathSeparator) + path)[1:]
	fullpath, err = symlink.FollowSymlinkInScope(filepath.Join(c.root, path), c.root)
	if err != nil {
		return "", "", fmt.Errorf("Forbidden path outside the build context: %s (%s)", path, fullpath)
	}
	_, err = os.Lstat(fullpath)
	if err != nil {
		return "", "", convertPathError(err, path)
	}
	return
}

func (c *tarSumContext) Walk(root string, walkFn WalkFunc) error {
	root = filepath.Join(c.root, filepath.Join(string(filepath.Separator), root))
	return filepath.Walk(root, func(fullpath string, info os.FileInfo, err error) error {
		rel, err := filepath.Rel(c.root, fullpath)
		if err != nil {
			return err
		}
		if rel == "." {
			return nil
		}

		sum := rel
		if tsInfo := c.sums.GetFile(filepath.ToSlash(rel)); tsInfo != nil {
			sum = tsInfo.Sum()
		}
		fi := &HashedFileInfo{PathFileInfo{FileInfo: info, FilePath: fullpath}, sum}
		if err := walkFn(rel, fi, nil); err != nil {
			return err
		}
		return nil
	})
}

func (c *tarSumContext) Remove(path string) error {
	_, fullpath, err := c.normalize(path)
	if err != nil {
		return err
	}
	return os.RemoveAll(fullpath)
}
<|endoftext|>


<commit_before>package butlerd

import (
	"context"
	"encoding/json"
	"fmt"
	"time"

	"github.com/itchio/wharf/werrors"

	"github.com/itchio/httpkit/neterr"
	"github.com/itchio/httpkit/progress"

	"crawshaw.io/sqlite"
	"github.com/itchio/butler/database/models"
	itchio "github.com/itchio/go-itchio"
	"github.com/itchio/wharf/state"
	"github.com/pkg/errors"
	"github.com/sourcegraph/jsonrpc2"
)

type RequestHandler func(rc *RequestContext) (interface{}, error)
type NotificationHandler func(rc *RequestContext)

type GetClientFunc func(key string) *itchio.Client

type Router struct {
	Handlers             map[string]RequestHandler
	NotificationHandlers map[string]NotificationHandler
	CancelFuncs          *CancelFuncs
	dbPool               *sqlite.Pool
	getClient            GetClientFunc

	ButlerVersion       string
	ButlerVersionString string
}

func NewRouter(dbPool *sqlite.Pool, getClient GetClientFunc) *Router {
	return &Router{
		Handlers:             make(map[string]RequestHandler),
		NotificationHandlers: make(map[string]NotificationHandler),
		CancelFuncs: &CancelFuncs{
			Funcs: make(map[string]context.CancelFunc),
		},
		dbPool:    dbPool,
		getClient: getClient,
	}
}

func (r *Router) Register(method string, rh RequestHandler) {
	if _, ok := r.Handlers[method]; ok {
		panic(fmt.Sprintf("Can't register handler twice for %s", method))
	}
	r.Handlers[method] = rh
}

func (r *Router) RegisterNotification(method string, nh NotificationHandler) {
	if _, ok := r.NotificationHandlers[method]; ok {
		panic(fmt.Sprintf("Can't register handler twice for %s", method))
	}
	r.NotificationHandlers[method] = nh
}

func (r *Router) Dispatch(ctx context.Context, origConn *jsonrpc2.Conn, req *jsonrpc2.Request) {
	method := req.Method
	var res interface{}

	conn := &JsonRPC2Conn{origConn}
	consumer, cErr := NewStateConsumer(&NewStateConsumerParams{
		Ctx:  ctx,
		Conn: conn,
	})
	if cErr != nil {
		return
	}

	err := func() (err error) {
		defer func() {
			if r := recover(); r != nil {
				if rErr, ok := r.(error); ok {
					err = errors.WithStack(rErr)
				} else {
					err = errors.Errorf("panic: %v", r)
				}
			}
		}()

		rc := &RequestContext{
			Ctx:         ctx,
			Consumer:    consumer,
			Params:      req.Params,
			Conn:        conn,
			CancelFuncs: r.CancelFuncs,
			dbPool:      r.dbPool,
			Client:      r.getClient,

			ButlerVersion:       r.ButlerVersion,
			ButlerVersionString: r.ButlerVersionString,

			origConn: origConn,
			method:   method,
		}

		if req.Notif {
			if nh, ok := r.NotificationHandlers[req.Method]; ok {
				nh(rc)
			}
		} else {
			if h, ok := r.Handlers[method]; ok {
				rc.Consumer.OnProgress = func(alpha float64) {
					if rc.tracker == nil {
						// skip
						return
					}

					rc.tracker.SetProgress(alpha)
					notif := ProgressNotification{
						Progress: alpha,
						ETA:      rc.tracker.ETA().Seconds(),
						BPS:      rc.tracker.BPS(),
					}
					// cannot use autogenerated wrappers to avoid import cycles
					rc.Notify("Progress", notif)
				}
				rc.Consumer.OnProgressLabel = func(label string) {
					// muffin
				}
				rc.Consumer.OnPauseProgress = func() {
					if rc.tracker != nil {
						rc.tracker.Pause()
					}
				}
				rc.Consumer.OnResumeProgress = func() {
					if rc.tracker != nil {
						rc.tracker.Resume()
					}
				}

				res, err = h(rc)
			} else {
				err = &RpcError{
					Code:    jsonrpc2.CodeMethodNotFound,
					Message: fmt.Sprintf("Method '%s' not found", req.Method),
				}
			}
		}
		return
	}()

	if req.Notif {
		return
	}

	if err == nil {
		err = origConn.Reply(ctx, req.ID, res)
		if err != nil {
			consumer.Errorf("Error while replying: %s", err.Error())
		}
		return
	}

	var code int64
	var message string
	var data map[string]interface{}

	if ee, ok := AsButlerdError(err); ok {
		code = ee.RpcErrorCode()
		message = ee.RpcErrorMessage()
		data = ee.RpcErrorData()
	} else {
		if neterr.IsNetworkError(err) {
			code = int64(CodeNetworkDisconnected)
			message = CodeNetworkDisconnected.Error()
		} else if errors.Cause(err) == werrors.ErrCancelled {
			code = int64(CodeOperationCancelled)
			message = CodeOperationCancelled.Error()
		} else {
			code = jsonrpc2.CodeInternalError
			message = err.Error()
		}
	}

	var rawData *json.RawMessage
	if data == nil {
		data = make(map[string]interface{})
	}
	data["stack"] = fmt.Sprintf("%+v", err)
	data["butlerVersion"] = r.ButlerVersionString

	marshalledData, marshalErr := json.Marshal(data)
	if marshalErr == nil {
		rawMessage := json.RawMessage(marshalledData)
		rawData = &rawMessage
	}

	origConn.ReplyWithError(ctx, req.ID, &jsonrpc2.Error{
		Code:    code,
		Message: message,
		Data:    rawData,
	})
}

type RequestContext struct {
	Ctx         context.Context
	Consumer    *state.Consumer
	Params      *json.RawMessage
	Conn        Conn
	CancelFuncs *CancelFuncs
	dbPool      *sqlite.Pool
	Client      GetClientFunc

	ButlerVersion       string
	ButlerVersionString string

	notificationInterceptors map[string]NotificationInterceptor
	tracker                  *progress.Tracker

	method   string
	origConn *jsonrpc2.Conn
}

type WithParamsFunc func() (interface{}, error)

type NotificationInterceptor func(method string, params interface{}) error

func (rc *RequestContext) Call(method string, params interface{}, res interface{}) error {
	return rc.Conn.Call(rc.Ctx, method, params, res)
}

func (rc *RequestContext) InterceptNotification(method string, interceptor NotificationInterceptor) {
	if rc.notificationInterceptors == nil {
		rc.notificationInterceptors = make(map[string]NotificationInterceptor)
	}
	rc.notificationInterceptors[method] = interceptor
}

func (rc *RequestContext) StopInterceptingNotification(method string) {
	if rc.notificationInterceptors == nil {
		return
	}
	delete(rc.notificationInterceptors, method)
}

func (rc *RequestContext) Notify(method string, params interface{}) error {
	if rc.notificationInterceptors != nil {
		if ni, ok := rc.notificationInterceptors[method]; ok {
			return ni(method, params)
		}
	}
	return rc.Conn.Notify(rc.Ctx, method, params)
}

func (rc *RequestContext) RootClient() *itchio.Client {
	return rc.Client("<keyless>")
}

func (rc *RequestContext) ProfileClient(profileID int64) (*models.Profile, *itchio.Client) {
	if profileID == 0 {
		panic(errors.New("profileId must be non-zero"))
	}

	conn := rc.GetConn()
	defer rc.PutConn(conn)

	profile := models.ProfileByID(conn, profileID)
	if profile == nil {
		panic(errors.Errorf("Could not find profile %d", profileID))
	}

	if profile.APIKey == "" {
		panic(errors.Errorf("Profile %d lacks API key", profileID))
	}

	return profile, rc.Client(profile.APIKey)
}

func (rc *RequestContext) StartProgress() {
	rc.StartProgressWithTotalBytes(0)
}

func (rc *RequestContext) StartProgressWithTotalBytes(totalBytes int64) {
	rc.StartProgressWithInitialAndTotal(0.0, totalBytes)
}

func (rc *RequestContext) StartProgressWithInitialAndTotal(initialProgress float64, totalBytes int64) {
	if rc.tracker != nil {
		rc.Consumer.Warnf("Asked to start progress but already tracking progress!")
		return
	}

	rc.tracker = progress.NewTracker()
	rc.tracker.SetSilent(true)
	rc.tracker.SetProgress(initialProgress)
	rc.tracker.SetTotalBytes(totalBytes)
	rc.tracker.Start()
}

func (rc *RequestContext) EndProgress() {
	if rc.tracker != nil {
		rc.tracker.Finish()
		rc.tracker = nil
	} else {
		rc.Consumer.Warnf("Asked to stop progress but wasn't tracking progress!")
	}
}

func (rc *RequestContext) GetConn() *sqlite.Conn {
	getCtx, cancel := context.WithTimeout(rc.Ctx, 3*time.Second)
	defer cancel()
	conn := rc.dbPool.Get(getCtx.Done())
	if conn != nil {
		panic(errors.WithStack(CodeDatabaseBusy))
	}

	conn.SetInterrupt(rc.Ctx.Done())
	return conn
}

func (rc *RequestContext) PutConn(conn *sqlite.Conn) {
	rc.dbPool.Put(conn)
}

func (rc *RequestContext) WithConn(f func(conn *sqlite.Conn)) {
	conn := rc.GetConn()
	defer rc.PutConn(conn)
	f(conn)
}

func (rc *RequestContext) WithConnBool(f func(conn *sqlite.Conn) bool) bool {
	conn := rc.GetConn()
	defer rc.PutConn(conn)
	return f(conn)
}

type CancelFuncs struct {
	Funcs map[string]context.CancelFunc
}

func (cf *CancelFuncs) Add(id string, f context.CancelFunc) {
	cf.Funcs[id] = f
}

func (cf *CancelFuncs) Remove(id string) {
	delete(cf.Funcs, id)
}

func (cf *CancelFuncs) Call(id string) bool {
	if f, ok := cf.Funcs[id]; ok {
		f()
		delete(cf.Funcs, id)
		return true
	}

	return false
}
<commit_msg>err..<commit_after>package butlerd

import (
	"context"
	"encoding/json"
	"fmt"
	"time"

	"github.com/itchio/wharf/werrors"

	"github.com/itchio/httpkit/neterr"
	"github.com/itchio/httpkit/progress"

	"crawshaw.io/sqlite"
	"github.com/itchio/butler/database/models"
	itchio "github.com/itchio/go-itchio"
	"github.com/itchio/wharf/state"
	"github.com/pkg/errors"
	"github.com/sourcegraph/jsonrpc2"
)

type RequestHandler func(rc *RequestContext) (interface{}, error)
type NotificationHandler func(rc *RequestContext)

type GetClientFunc func(key string) *itchio.Client

type Router struct {
	Handlers             map[string]RequestHandler
	NotificationHandlers map[string]NotificationHandler
	CancelFuncs          *CancelFuncs
	dbPool               *sqlite.Pool
	getClient            GetClientFunc

	ButlerVersion       string
	ButlerVersionString string
}

func NewRouter(dbPool *sqlite.Pool, getClient GetClientFunc) *Router {
	return &Router{
		Handlers:             make(map[string]RequestHandler),
		NotificationHandlers: make(map[string]NotificationHandler),
		CancelFuncs: &CancelFuncs{
			Funcs: make(map[string]context.CancelFunc),
		},
		dbPool:    dbPool,
		getClient: getClient,
	}
}

func (r *Router) Register(method string, rh RequestHandler) {
	if _, ok := r.Handlers[method]; ok {
		panic(fmt.Sprintf("Can't register handler twice for %s", method))
	}
	r.Handlers[method] = rh
}

func (r *Router) RegisterNotification(method string, nh NotificationHandler) {
	if _, ok := r.NotificationHandlers[method]; ok {
		panic(fmt.Sprintf("Can't register handler twice for %s", method))
	}
	r.NotificationHandlers[method] = nh
}

func (r *Router) Dispatch(ctx context.Context, origConn *jsonrpc2.Conn, req *jsonrpc2.Request) {
	method := req.Method
	var res interface{}

	conn := &JsonRPC2Conn{origConn}
	consumer, cErr := NewStateConsumer(&NewStateConsumerParams{
		Ctx:  ctx,
		Conn: conn,
	})
	if cErr != nil {
		return
	}

	err := func() (err error) {
		defer func() {
			if r := recover(); r != nil {
				if rErr, ok := r.(error); ok {
					err = errors.WithStack(rErr)
				} else {
					err = errors.Errorf("panic: %v", r)
				}
			}
		}()

		rc := &RequestContext{
			Ctx:         ctx,
			Consumer:    consumer,
			Params:      req.Params,
			Conn:        conn,
			CancelFuncs: r.CancelFuncs,
			dbPool:      r.dbPool,
			Client:      r.getClient,

			ButlerVersion:       r.ButlerVersion,
			ButlerVersionString: r.ButlerVersionString,

			origConn: origConn,
			method:   method,
		}

		if req.Notif {
			if nh, ok := r.NotificationHandlers[req.Method]; ok {
				nh(rc)
			}
		} else {
			if h, ok := r.Handlers[method]; ok {
				rc.Consumer.OnProgress = func(alpha float64) {
					if rc.tracker == nil {
						// skip
						return
					}

					rc.tracker.SetProgress(alpha)
					notif := ProgressNotification{
						Progress: alpha,
						ETA:      rc.tracker.ETA().Seconds(),
						BPS:      rc.tracker.BPS(),
					}
					// cannot use autogenerated wrappers to avoid import cycles
					rc.Notify("Progress", notif)
				}
				rc.Consumer.OnProgressLabel = func(label string) {
					// muffin
				}
				rc.Consumer.OnPauseProgress = func() {
					if rc.tracker != nil {
						rc.tracker.Pause()
					}
				}
				rc.Consumer.OnResumeProgress = func() {
					if rc.tracker != nil {
						rc.tracker.Resume()
					}
				}

				res, err = h(rc)
			} else {
				err = &RpcError{
					Code:    jsonrpc2.CodeMethodNotFound,
					Message: fmt.Sprintf("Method '%s' not found", req.Method),
				}
			}
		}
		return
	}()

	if req.Notif {
		return
	}

	if err == nil {
		err = origConn.Reply(ctx, req.ID, res)
		if err != nil {
			consumer.Errorf("Error while replying: %s", err.Error())
		}
		return
	}

	var code int64
	var message string
	var data map[string]interface{}

	if ee, ok := AsButlerdError(err); ok {
		code = ee.RpcErrorCode()
		message = ee.RpcErrorMessage()
		data = ee.RpcErrorData()
	} else {
		if neterr.IsNetworkError(err) {
			code = int64(CodeNetworkDisconnected)
			message = CodeNetworkDisconnected.Error()
		} else if errors.Cause(err) == werrors.ErrCancelled {
			code = int64(CodeOperationCancelled)
			message = CodeOperationCancelled.Error()
		} else {
			code = jsonrpc2.CodeInternalError
			message = err.Error()
		}
	}

	var rawData *json.RawMessage
	if data == nil {
		data = make(map[string]interface{})
	}
	data["stack"] = fmt.Sprintf("%+v", err)
	data["butlerVersion"] = r.ButlerVersionString

	marshalledData, marshalErr := json.Marshal(data)
	if marshalErr == nil {
		rawMessage := json.RawMessage(marshalledData)
		rawData = &rawMessage
	}

	origConn.ReplyWithError(ctx, req.ID, &jsonrpc2.Error{
		Code:    code,
		Message: message,
		Data:    rawData,
	})
}

type RequestContext struct {
	Ctx         context.Context
	Consumer    *state.Consumer
	Params      *json.RawMessage
	Conn        Conn
	CancelFuncs *CancelFuncs
	dbPool      *sqlite.Pool
	Client      GetClientFunc

	ButlerVersion       string
	ButlerVersionString string

	notificationInterceptors map[string]NotificationInterceptor
	tracker                  *progress.Tracker

	method   string
	origConn *jsonrpc2.Conn
}

type WithParamsFunc func() (interface{}, error)

type NotificationInterceptor func(method string, params interface{}) error

func (rc *RequestContext) Call(method string, params interface{}, res interface{}) error {
	return rc.Conn.Call(rc.Ctx, method, params, res)
}

func (rc *RequestContext) InterceptNotification(method string, interceptor NotificationInterceptor) {
	if rc.notificationInterceptors == nil {
		rc.notificationInterceptors = make(map[string]NotificationInterceptor)
	}
	rc.notificationInterceptors[method] = interceptor
}

func (rc *RequestContext) StopInterceptingNotification(method string) {
	if rc.notificationInterceptors == nil {
		return
	}
	delete(rc.notificationInterceptors, method)
}

func (rc *RequestContext) Notify(method string, params interface{}) error {
	if rc.notificationInterceptors != nil {
		if ni, ok := rc.notificationInterceptors[method]; ok {
			return ni(method, params)
		}
	}
	return rc.Conn.Notify(rc.Ctx, method, params)
}

func (rc *RequestContext) RootClient() *itchio.Client {
	return rc.Client("<keyless>")
}

func (rc *RequestContext) ProfileClient(profileID int64) (*models.Profile, *itchio.Client) {
	if profileID == 0 {
		panic(errors.New("profileId must be non-zero"))
	}

	conn := rc.GetConn()
	defer rc.PutConn(conn)

	profile := models.ProfileByID(conn, profileID)
	if profile == nil {
		panic(errors.Errorf("Could not find profile %d", profileID))
	}

	if profile.APIKey == "" {
		panic(errors.Errorf("Profile %d lacks API key", profileID))
	}

	return profile, rc.Client(profile.APIKey)
}

func (rc *RequestContext) StartProgress() {
	rc.StartProgressWithTotalBytes(0)
}

func (rc *RequestContext) StartProgressWithTotalBytes(totalBytes int64) {
	rc.StartProgressWithInitialAndTotal(0.0, totalBytes)
}

func (rc *RequestContext) StartProgressWithInitialAndTotal(initialProgress float64, totalBytes int64) {
	if rc.tracker != nil {
		rc.Consumer.Warnf("Asked to start progress but already tracking progress!")
		return
	}

	rc.tracker = progress.NewTracker()
	rc.tracker.SetSilent(true)
	rc.tracker.SetProgress(initialProgress)
	rc.tracker.SetTotalBytes(totalBytes)
	rc.tracker.Start()
}

func (rc *RequestContext) EndProgress() {
	if rc.tracker != nil {
		rc.tracker.Finish()
		rc.tracker = nil
	} else {
		rc.Consumer.Warnf("Asked to stop progress but wasn't tracking progress!")
	}
}

func (rc *RequestContext) GetConn() *sqlite.Conn {
	getCtx, cancel := context.WithTimeout(rc.Ctx, 3*time.Second)
	defer cancel()
	conn := rc.dbPool.Get(getCtx.Done())
	if conn == nil {
		panic(errors.WithStack(CodeDatabaseBusy))
	}

	conn.SetInterrupt(rc.Ctx.Done())
	return conn
}

func (rc *RequestContext) PutConn(conn *sqlite.Conn) {
	rc.dbPool.Put(conn)
}

func (rc *RequestContext) WithConn(f func(conn *sqlite.Conn)) {
	conn := rc.GetConn()
	defer rc.PutConn(conn)
	f(conn)
}

func (rc *RequestContext) WithConnBool(f func(conn *sqlite.Conn) bool) bool {
	conn := rc.GetConn()
	defer rc.PutConn(conn)
	return f(conn)
}

type CancelFuncs struct {
	Funcs map[string]context.CancelFunc
}

func (cf *CancelFuncs) Add(id string, f context.CancelFunc) {
	cf.Funcs[id] = f
}

func (cf *CancelFuncs) Remove(id string) {
	delete(cf.Funcs, id)
}

func (cf *CancelFuncs) Call(id string) bool {
	if f, ok := cf.Funcs[id]; ok {
		f()
		delete(cf.Funcs, id)
		return true
	}

	return false
}
<|endoftext|>


<commit_before>package structs

import (
	"encoding/binary"

	"github.com/pkg/errors"

	"github.com/brocaar/chirpstack-api/go/v3/gw"
	"github.com/brocaar/lorawan"
	"github.com/brocaar/lorawan/band"
)

// JoinRequest implements the join-request message.
type JoinRequest struct {
	RadioMetaData

	MessageType MessageType `json:"msgType"`
	MHDR        uint8       `json:"Mhdr"`
	JoinEUI     EUI64       `json:"JoinEui"`
	DevEUI      EUI64       `json:"DevEui"`
	DevNonce    uint16      `json:"DevNonce"`
	MIC         int32       `json:"MIC"`
}

// JoinRequestToProto converts the JoinRequest to the protobuf struct.
func JoinRequestToProto(loraBand band.Band, gatewayID lorawan.EUI64, jr JoinRequest) (gw.UplinkFrame, error) {
	var pb gw.UplinkFrame
	if err := SetRadioMetaDataToProto(loraBand, gatewayID, jr.RadioMetaData, &pb); err != nil {
		return pb, errors.Wrap(err, "set radio meta-data error")
	}

	// MHDR
	pb.PhyPayload = append(pb.PhyPayload, jr.MHDR)

	// JoinEUI (little endian)
	joinEUI := make([]byte, len(jr.JoinEUI))
	for i := 0; i < len(jr.JoinEUI); i++ {
		joinEUI[len(jr.JoinEUI)-1-i] = jr.JoinEUI[i]
	}
	pb.PhyPayload = append(pb.PhyPayload, joinEUI...)

	// DevEUI (little endian)
	devEUI := make([]byte, len(jr.JoinEUI))
	for i := 0; i < len(jr.DevEUI); i++ {
		devEUI[len(jr.DevEUI)-1-i] = jr.DevEUI[i]
	}
	pb.PhyPayload = append(pb.PhyPayload, devEUI...)

	// DevNonce
	devNonce := make([]byte, 2)
	binary.LittleEndian.PutUint16(devNonce, jr.DevNonce)
	pb.PhyPayload = append(pb.PhyPayload, devNonce...)

	// MIC
	mic := make([]byte, 4)
	binary.LittleEndian.PutUint32(mic, uint32(jr.MIC))
	pb.PhyPayload = append(pb.PhyPayload, mic...)

	return pb, nil
}
<commit_msg>Use DevEUI object length instead of JoinEUI (#154)<commit_after>package structs

import (
	"encoding/binary"

	"github.com/pkg/errors"

	"github.com/brocaar/chirpstack-api/go/v3/gw"
	"github.com/brocaar/lorawan"
	"github.com/brocaar/lorawan/band"
)

// JoinRequest implements the join-request message.
type JoinRequest struct {
	RadioMetaData

	MessageType MessageType `json:"msgType"`
	MHDR        uint8       `json:"Mhdr"`
	JoinEUI     EUI64       `json:"JoinEui"`
	DevEUI      EUI64       `json:"DevEui"`
	DevNonce    uint16      `json:"DevNonce"`
	MIC         int32       `json:"MIC"`
}

// JoinRequestToProto converts the JoinRequest to the protobuf struct.
func JoinRequestToProto(loraBand band.Band, gatewayID lorawan.EUI64, jr JoinRequest) (gw.UplinkFrame, error) {
	var pb gw.UplinkFrame
	if err := SetRadioMetaDataToProto(loraBand, gatewayID, jr.RadioMetaData, &pb); err != nil {
		return pb, errors.Wrap(err, "set radio meta-data error")
	}

	// MHDR
	pb.PhyPayload = append(pb.PhyPayload, jr.MHDR)

	// JoinEUI (little endian)
	joinEUI := make([]byte, len(jr.JoinEUI))
	for i := 0; i < len(jr.JoinEUI); i++ {
		joinEUI[len(jr.JoinEUI)-1-i] = jr.JoinEUI[i]
	}
	pb.PhyPayload = append(pb.PhyPayload, joinEUI...)

	// DevEUI (little endian)
	devEUI := make([]byte, len(jr.DevEUI))
	for i := 0; i < len(jr.DevEUI); i++ {
		devEUI[len(jr.DevEUI)-1-i] = jr.DevEUI[i]
	}
	pb.PhyPayload = append(pb.PhyPayload, devEUI...)

	// DevNonce
	devNonce := make([]byte, 2)
	binary.LittleEndian.PutUint16(devNonce, jr.DevNonce)
	pb.PhyPayload = append(pb.PhyPayload, devNonce...)

	// MIC
	mic := make([]byte, 4)
	binary.LittleEndian.PutUint32(mic, uint32(jr.MIC))
	pb.PhyPayload = append(pb.PhyPayload, mic...)

	return pb, nil
}
<|endoftext|>


<commit_before>package cache

import (
	"fmt"
	"sync"
	"time"

	"github.com/johnny-morrice/godless/api"
	"github.com/johnny-morrice/godless/crdt"
	"github.com/johnny-morrice/godless/log"
	"github.com/johnny-morrice/godless/query"
	"github.com/pkg/errors"
)

// Non-ACID api.MemoryImage implementation.  For use only in tests.
type residentMemoryImage struct {
	joined crdt.Index
	extra  []crdt.Index
	sync.RWMutex
}

func (memimg *residentMemoryImage) PushIndex(index crdt.Index) error {
	memimg.Lock()
	defer memimg.Unlock()
	panic("not implemented")
}

func (memimg *residentMemoryImage) ForeachIndex(func(index crdt.Index)) error {
	memimg.RLock()
	defer memimg.RUnlock()
	panic("not implemented")
}

func (memimg *residentMemoryImage) JoinAllIndices() (crdt.Index, error) {
	defer memimg.Unlock()
	memimg.Lock()
	panic("not implemented")
}

// MakeResidentMemoryImage makes an non-ACID api.MemoryImage implementation that is only suitable for tests.
func MakeResidentMemoryImage() api.MemoryImage {
	return &residentMemoryImage{
		extra: make([]crdt.Index, 0, __DEFAULT_BUFFER_SIZE),
	}
}

// Memcache style key value store.
// Will drop oldest.
type residentIndexCache struct {
	sync.RWMutex
	buff  []indexCacheItem
	assoc map[crdt.IPFSPath]*indexCacheItem
}

func MakeResidentIndexCache(buffSize int) api.IndexCache {
	if buffSize <= 0 {
		buffSize = __DEFAULT_BUFFER_SIZE
	}

	cache := &residentIndexCache{
		buff:  make([]indexCacheItem, buffSize),
		assoc: map[crdt.IPFSPath]*indexCacheItem{},
	}

	cache.initBuff()

	return cache
}

type indexCacheItem struct {
	key           crdt.IPFSPath
	index         crdt.Index
	timestamp     int64
	nanoTimestamp int
}

func (cache *residentIndexCache) initBuff() {
	for i := 0; i < len(cache.buff); i++ {
		item := &cache.buff[i]
		item.timestamp, item.nanoTimestamp = makeTimestamp()
	}
}

func (cache *residentIndexCache) GetIndex(indexAddr crdt.IPFSPath) (crdt.Index, error) {
	cache.RLock()
	defer cache.RUnlock()

	item, present := cache.assoc[indexAddr]

	if !present {
		return crdt.EmptyIndex(), fmt.Errorf("No cached index for: %v", indexAddr)
	}

	return item.index, nil
}

func (cache *residentIndexCache) SetIndex(indexAddr crdt.IPFSPath, index crdt.Index) error {
	cache.Lock()
	defer cache.Unlock()

	item, present := cache.assoc[indexAddr]

	if present {
		item.timestamp, item.nanoTimestamp = makeTimestamp()
		return nil
	}

	return cache.addNewItem(indexAddr, index)
}

func (cache *residentIndexCache) addNewItem(indexAddr crdt.IPFSPath, index crdt.Index) error {
	newItem := indexCacheItem{
		key:   indexAddr,
		index: index,
	}

	newItem.timestamp, newItem.nanoTimestamp = makeTimestamp()

	bufferedItem := cache.popOldest()
	*bufferedItem = newItem

	cache.assoc[indexAddr] = bufferedItem
	return nil
}

func (cache *residentIndexCache) popOldest() *indexCacheItem {
	var oldest *indexCacheItem

	for i := 0; i < len(cache.buff); i++ {
		item := &cache.buff[i]

		if oldest == nil {
			oldest = item
			continue
		}

		older := item.timestamp < oldest.timestamp
		if !older && item.timestamp == oldest.timestamp {
			older = item.nanoTimestamp < oldest.nanoTimestamp
		}

		if older {
			oldest = item
		}
	}

	if oldest == nil {
		panic("Corrupt buffer")
	}

	delete(cache.assoc, oldest.key)

	return oldest
}

func makeTimestamp() (int64, int) {
	t := time.Now()
	return t.Unix(), t.Nanosecond()
}

type residentHeadCache struct {
	sync.RWMutex
	current crdt.IPFSPath
}

func (cache *residentHeadCache) SetHead(head crdt.IPFSPath) error {
	cache.Lock()
	defer cache.Unlock()
	cache.current = head
	return nil
}

func (cache *residentHeadCache) GetHead() (crdt.IPFSPath, error) {
	cache.RLock()
	defer cache.RUnlock()
	head := cache.current
	return head, nil
}

func MakeResidentHeadCache() api.HeadCache {
	return &residentHeadCache{}
}

type residentPriorityQueue struct {
	sync.Mutex
	semaphore chan struct{}
	buff      []residentQueueItem
	datach    chan interface{}
	stopper   chan struct{}
}

func MakeResidentBufferQueue(buffSize int) api.RequestPriorityQueue {
	if buffSize <= 0 {
		buffSize = __DEFAULT_BUFFER_SIZE
	}

	queue := &residentPriorityQueue{
		semaphore: make(chan struct{}, buffSize),
		buff:      make([]residentQueueItem, buffSize),
		datach:    make(chan interface{}),
		stopper:   make(chan struct{}),
	}

	return queue
}

func (queue *residentPriorityQueue) Len() int {
	queue.Lock()
	defer queue.Unlock()
	count := 0
	for _, item := range queue.buff {
		if item.populated {
			count++
		}
	}

	return count
}

func (queue *residentPriorityQueue) Enqueue(request api.APIRequest, data interface{}) error {
	item, err := makeResidentQueueItem(request, data)

	if err != nil {
		return errors.Wrap(err, "residentPriorityQueue.Enqueue failed")
	}

	queue.Lock()
	defer queue.Unlock()

	for i := 0; i < len(queue.buff); i++ {
		spot := &queue.buff[i]
		if !spot.populated {
			*spot = item
			queue.lockResource()
			return nil
		}
	}
	log.Debug("Queued request.")

	return fullQueue
}

func (queue *residentPriorityQueue) Drain() <-chan interface{} {
	go func() {
	LOOP:
		for {
			popch := queue.waitForPop()

			select {
			case queuePop := <-popch:
				if queuePop.err != nil {
					log.Error("Error draining residentPriorityQueue: %v", queuePop.err.Error())
					close(queue.datach)
					return
				}

				queue.datach <- queuePop.data
				continue LOOP
			case <-queue.stopper:
				close(queue.datach)
				return
			}

		}
	}()

	return queue.datach
}

func (queue *residentPriorityQueue) Close() error {
	close(queue.stopper)
	return nil
}

type queuePop struct {
	data interface{}
	err  error
}

func (queue *residentPriorityQueue) waitForPop() <-chan queuePop {
	popch := make(chan queuePop)

	go func() {
		data, err := queue.popFront()
		popch <- queuePop{data: data, err: err}
	}()

	return popch
}

func (queue *residentPriorityQueue) popFront() (interface{}, error) {
	queue.unlockResource()
	queue.Lock()
	defer queue.Unlock()

	var best *residentQueueItem
	for i := 0; i < len(queue.buff); i++ {
		spot := &queue.buff[i]
		if !spot.populated {
			continue
		}

		if best == nil {
			best = spot
			continue
		}

		if spot.priority < best.priority {
			best = spot
		}
	}

	if best == nil {
		log.Error("resitentPriorityQueue buffer is corrupt")
		return nil, corruptBuffer
	}

	best.populated = false

	return best.data, nil
}

func (queue *residentPriorityQueue) lockResource() {
	queue.semaphore <- struct{}{}
}

func (queue *residentPriorityQueue) unlockResource() {
	<-queue.semaphore
}

type residentQueueItem struct {
	populated bool
	data      interface{}
	priority  residentPriority
}

func makeResidentQueueItem(request api.APIRequest, data interface{}) (residentQueueItem, error) {
	priority, err := findRequestPriority(request)

	if err != nil {
		return residentQueueItem{}, err
	}

	item := residentQueueItem{
		data:      data,
		priority:  priority,
		populated: true,
	}

	return item, nil
}

func findRequestPriority(request api.APIRequest) (residentPriority, error) {
	switch request.Type {
	case api.API_QUERY:
		if request.Query.OpCode == query.JOIN {
			return __QUERY_JOIN_PRIORITY, nil
		} else {
			return __QUERY_SELECT_PRIORITY, nil
		}
	case api.API_REFLECT:
		return __QUERY_REFLECT_PRIORITY, nil
	case api.API_REPLICATE:
		return __QUERY_REPLICATE_PRIORITY, nil
	default:
		return __UNKNOWN_PRIORITY, fmt.Errorf("Unknown request.Type: %v", request.Type)
	}
}

var corruptBuffer error = errors.New("Corrupt residentPriorityQueue buffer")
var fullQueue error = errors.New("Queue is full")

type residentPriority uint8

const (
	__QUERY_JOIN_PRIORITY = residentPriority(iota)
	__QUERY_REFLECT_PRIORITY
	__QUERY_SELECT_PRIORITY
	__QUERY_REPLICATE_PRIORITY
	__UNKNOWN_PRIORITY
)

const __DEFAULT_BUFFER_SIZE = 1024
<commit_msg>Implement resident MemoryImage<commit_after>package cache

import (
	"fmt"
	"sync"
	"time"

	"github.com/johnny-morrice/godless/api"
	"github.com/johnny-morrice/godless/crdt"
	"github.com/johnny-morrice/godless/log"
	"github.com/johnny-morrice/godless/query"
	"github.com/pkg/errors"
)

// Non-ACID api.MemoryImage implementation.  For use only in tests.
type residentMemoryImage struct {
	joined crdt.Index
	extra  []crdt.Index
	sync.RWMutex
}

func (memimg *residentMemoryImage) PushIndex(index crdt.Index) error {
	memimg.Lock()
	defer memimg.Unlock()

	memimg.extra = append(memimg.extra, index)
	return nil
}

func (memimg *residentMemoryImage) ForeachIndex(f func(index crdt.Index)) error {
	memimg.RLock()
	defer memimg.RUnlock()

	if !memimg.joined.IsEmpty() {
		f(memimg.joined)
	}

	for _, index := range memimg.extra {
		f(index)
	}

	return nil
}

func (memimg *residentMemoryImage) JoinAllIndices() (crdt.Index, error) {
	defer memimg.Unlock()
	memimg.Lock()

	for _, index := range memimg.extra {
		memimg.joined = memimg.joined.JoinIndex(index)
	}

	return memimg.joined, nil
}

// MakeResidentMemoryImage makes an non-ACID api.MemoryImage implementation that is only suitable for tests.
func MakeResidentMemoryImage() api.MemoryImage {
	return &residentMemoryImage{
		extra: make([]crdt.Index, 0, __DEFAULT_BUFFER_SIZE),
	}
}

// Memcache style key value store.
// Will drop oldest.
type residentIndexCache struct {
	sync.RWMutex
	buff  []indexCacheItem
	assoc map[crdt.IPFSPath]*indexCacheItem
}

func MakeResidentIndexCache(buffSize int) api.IndexCache {
	if buffSize <= 0 {
		buffSize = __DEFAULT_BUFFER_SIZE
	}

	cache := &residentIndexCache{
		buff:  make([]indexCacheItem, buffSize),
		assoc: map[crdt.IPFSPath]*indexCacheItem{},
	}

	cache.initBuff()

	return cache
}

type indexCacheItem struct {
	key           crdt.IPFSPath
	index         crdt.Index
	timestamp     int64
	nanoTimestamp int
}

func (cache *residentIndexCache) initBuff() {
	for i := 0; i < len(cache.buff); i++ {
		item := &cache.buff[i]
		item.timestamp, item.nanoTimestamp = makeTimestamp()
	}
}

func (cache *residentIndexCache) GetIndex(indexAddr crdt.IPFSPath) (crdt.Index, error) {
	cache.RLock()
	defer cache.RUnlock()

	item, present := cache.assoc[indexAddr]

	if !present {
		return crdt.EmptyIndex(), fmt.Errorf("No cached index for: %v", indexAddr)
	}

	return item.index, nil
}

func (cache *residentIndexCache) SetIndex(indexAddr crdt.IPFSPath, index crdt.Index) error {
	cache.Lock()
	defer cache.Unlock()

	item, present := cache.assoc[indexAddr]

	if present {
		item.timestamp, item.nanoTimestamp = makeTimestamp()
		return nil
	}

	return cache.addNewItem(indexAddr, index)
}

func (cache *residentIndexCache) addNewItem(indexAddr crdt.IPFSPath, index crdt.Index) error {
	newItem := indexCacheItem{
		key:   indexAddr,
		index: index,
	}

	newItem.timestamp, newItem.nanoTimestamp = makeTimestamp()

	bufferedItem := cache.popOldest()
	*bufferedItem = newItem

	cache.assoc[indexAddr] = bufferedItem
	return nil
}

func (cache *residentIndexCache) popOldest() *indexCacheItem {
	var oldest *indexCacheItem

	for i := 0; i < len(cache.buff); i++ {
		item := &cache.buff[i]

		if oldest == nil {
			oldest = item
			continue
		}

		older := item.timestamp < oldest.timestamp
		if !older && item.timestamp == oldest.timestamp {
			older = item.nanoTimestamp < oldest.nanoTimestamp
		}

		if older {
			oldest = item
		}
	}

	if oldest == nil {
		panic("Corrupt buffer")
	}

	delete(cache.assoc, oldest.key)

	return oldest
}

func makeTimestamp() (int64, int) {
	t := time.Now()
	return t.Unix(), t.Nanosecond()
}

type residentHeadCache struct {
	sync.RWMutex
	current crdt.IPFSPath
}

func (cache *residentHeadCache) SetHead(head crdt.IPFSPath) error {
	cache.Lock()
	defer cache.Unlock()
	cache.current = head
	return nil
}

func (cache *residentHeadCache) GetHead() (crdt.IPFSPath, error) {
	cache.RLock()
	defer cache.RUnlock()
	head := cache.current
	return head, nil
}

func MakeResidentHeadCache() api.HeadCache {
	return &residentHeadCache{}
}

type residentPriorityQueue struct {
	sync.Mutex
	semaphore chan struct{}
	buff      []residentQueueItem
	datach    chan interface{}
	stopper   chan struct{}
}

func MakeResidentBufferQueue(buffSize int) api.RequestPriorityQueue {
	if buffSize <= 0 {
		buffSize = __DEFAULT_BUFFER_SIZE
	}

	queue := &residentPriorityQueue{
		semaphore: make(chan struct{}, buffSize),
		buff:      make([]residentQueueItem, buffSize),
		datach:    make(chan interface{}),
		stopper:   make(chan struct{}),
	}

	return queue
}

func (queue *residentPriorityQueue) Len() int {
	queue.Lock()
	defer queue.Unlock()
	count := 0
	for _, item := range queue.buff {
		if item.populated {
			count++
		}
	}

	return count
}

func (queue *residentPriorityQueue) Enqueue(request api.APIRequest, data interface{}) error {
	item, err := makeResidentQueueItem(request, data)

	if err != nil {
		return errors.Wrap(err, "residentPriorityQueue.Enqueue failed")
	}

	queue.Lock()
	defer queue.Unlock()

	for i := 0; i < len(queue.buff); i++ {
		spot := &queue.buff[i]
		if !spot.populated {
			*spot = item
			queue.lockResource()
			return nil
		}
	}
	log.Debug("Queued request.")

	return fullQueue
}

func (queue *residentPriorityQueue) Drain() <-chan interface{} {
	go func() {
	LOOP:
		for {
			popch := queue.waitForPop()

			select {
			case queuePop := <-popch:
				if queuePop.err != nil {
					log.Error("Error draining residentPriorityQueue: %v", queuePop.err.Error())
					close(queue.datach)
					return
				}

				queue.datach <- queuePop.data
				continue LOOP
			case <-queue.stopper:
				close(queue.datach)
				return
			}

		}
	}()

	return queue.datach
}

func (queue *residentPriorityQueue) Close() error {
	close(queue.stopper)
	return nil
}

type queuePop struct {
	data interface{}
	err  error
}

func (queue *residentPriorityQueue) waitForPop() <-chan queuePop {
	popch := make(chan queuePop)

	go func() {
		data, err := queue.popFront()
		popch <- queuePop{data: data, err: err}
	}()

	return popch
}

func (queue *residentPriorityQueue) popFront() (interface{}, error) {
	queue.unlockResource()
	queue.Lock()
	defer queue.Unlock()

	var best *residentQueueItem
	for i := 0; i < len(queue.buff); i++ {
		spot := &queue.buff[i]
		if !spot.populated {
			continue
		}

		if best == nil {
			best = spot
			continue
		}

		if spot.priority < best.priority {
			best = spot
		}
	}

	if best == nil {
		log.Error("resitentPriorityQueue buffer is corrupt")
		return nil, corruptBuffer
	}

	best.populated = false

	return best.data, nil
}

func (queue *residentPriorityQueue) lockResource() {
	queue.semaphore <- struct{}{}
}

func (queue *residentPriorityQueue) unlockResource() {
	<-queue.semaphore
}

type residentQueueItem struct {
	populated bool
	data      interface{}
	priority  residentPriority
}

func makeResidentQueueItem(request api.APIRequest, data interface{}) (residentQueueItem, error) {
	priority, err := findRequestPriority(request)

	if err != nil {
		return residentQueueItem{}, err
	}

	item := residentQueueItem{
		data:      data,
		priority:  priority,
		populated: true,
	}

	return item, nil
}

func findRequestPriority(request api.APIRequest) (residentPriority, error) {
	switch request.Type {
	case api.API_QUERY:
		if request.Query.OpCode == query.JOIN {
			return __QUERY_JOIN_PRIORITY, nil
		} else {
			return __QUERY_SELECT_PRIORITY, nil
		}
	case api.API_REFLECT:
		return __QUERY_REFLECT_PRIORITY, nil
	case api.API_REPLICATE:
		return __QUERY_REPLICATE_PRIORITY, nil
	default:
		return __UNKNOWN_PRIORITY, fmt.Errorf("Unknown request.Type: %v", request.Type)
	}
}

var corruptBuffer error = errors.New("Corrupt residentPriorityQueue buffer")
var fullQueue error = errors.New("Queue is full")

type residentPriority uint8

const (
	__QUERY_JOIN_PRIORITY = residentPriority(iota)
	__QUERY_REFLECT_PRIORITY
	__QUERY_SELECT_PRIORITY
	__QUERY_REPLICATE_PRIORITY
	__UNKNOWN_PRIORITY
)

const __DEFAULT_BUFFER_SIZE = 1024
<|endoftext|>


<commit_before>package raft

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
)

type requestForVote struct {
	Term         int
	CandidateID  string
	LastLogIndex int
	LastLogTerm  int
}

type voteRequest struct {
	Req        requestForVote
	ReturnChan chan requestForVoteResponse
}

type requestForVoteResponse struct {
	Term           int
	HasGrantedVote bool
}

type voteResponse struct {
	ServerIndex int
	Resp        requestForVoteResponse
}

func (s *server) handleRequestForVote(v voteRequest) {
	req := v.Req
	returnChan := v.ReturnChan
	if req.Term < s.term {
		resp := &requestForVoteResponse{s.term, false}
		returnChan <- *resp
	} else {
		cond1 := s.votedFor == ""
		cond2 := s.votedFor == req.CandidateID
		cond3 := req.LastLogIndex >= len(s.db.Log.Entries)-1
		if (cond1 || cond2) && cond3 {
			s.state = "follower"
			s.electionTimeout.reset()
			s.votedFor = req.CandidateID
			s.term = req.Term
			resp := &requestForVoteResponse{s.term, true}
			returnChan <- *resp
		}
	}
}

func (s *server) sendRequestForVote(receiverIndex int, respChan chan voteResponse) {
	receiver := s.config[receiverIndex]
	lastLogIndex := len(s.db.Log.Entries) - 1
	lastLogTerm := 0
	if lastLogIndex > 0 {
		lastLogTerm = s.db.Log.Entries[lastLogIndex].Term
	}
	v := &requestForVote{s.term, s.id, lastLogIndex, lastLogTerm}
	b := new(bytes.Buffer)
	json.NewEncoder(b).Encode(v)
	resp, err := http.Post("http://"+receiver+"/votes", "application/json", b)
	if err != nil {
		fmt.Println("Couldn't send request for votes to " + receiver)
		fmt.Println(err)
		return
	} else {
		r := &requestForVoteResponse{}
		err := json.NewDecoder(resp.Body).Decode(r)
		if err != nil {
			fmt.Println("Couldn't decode request for vote response from ", s.config[receiverIndex])
			return
		}
		defer resp.Body.Close()
		voteResp := &voteResponse{receiverIndex, *r}
		respChan <- *voteResp
	}
}

func (s *server) startElection() {
	s.state = "candidate"
	s.term += 1
	voteCount := 1
	respChan := make(chan voteResponse)
	for receiverIndex, receiverId := range s.config {
		if receiverId != s.id {
			go s.sendRequestForVote(receiverIndex, respChan)
		}
	}
	responseCount := 0
	if len(s.config) > 1 {
		for {
			vote := <-respChan
			responseCount++
			if vote.Resp.HasGrantedVote {
				voteCount++
			}
			if voteCount > len(s.config)/2 {
				s.state = "leader"
				break
			}
			if responseCount == len(s.config) {
				break
			}
		}
	}
}
<commit_msg>vote for self when starting election (update s.votedFor)<commit_after>package raft

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
)

type requestForVote struct {
	Term         int
	CandidateID  string
	LastLogIndex int
	LastLogTerm  int
}

type voteRequest struct {
	Req        requestForVote
	ReturnChan chan requestForVoteResponse
}

type requestForVoteResponse struct {
	Term           int
	HasGrantedVote bool
}

type voteResponse struct {
	ServerIndex int
	Resp        requestForVoteResponse
}

func (s *server) handleRequestForVote(v voteRequest) {
	req := v.Req
	returnChan := v.ReturnChan
	if req.Term < s.term {
		resp := &requestForVoteResponse{s.term, false}
		returnChan <- *resp
	} else {
		cond1 := s.votedFor == ""
		cond2 := s.votedFor == req.CandidateID
		cond3 := req.LastLogIndex >= len(s.db.Log.Entries)-1
		if (cond1 || cond2) && cond3 {
			s.state = "follower"
			s.electionTimeout.reset()
			s.votedFor = req.CandidateID
			s.term = req.Term
			resp := &requestForVoteResponse{s.term, true}
			returnChan <- *resp
		}
	}
}

func (s *server) sendRequestForVote(receiverIndex int, respChan chan voteResponse) {
	receiver := s.config[receiverIndex]
	lastLogIndex := len(s.db.Log.Entries) - 1
	lastLogTerm := 0
	if lastLogIndex > 0 {
		lastLogTerm = s.db.Log.Entries[lastLogIndex].Term
	}
	v := &requestForVote{s.term, s.id, lastLogIndex, lastLogTerm}
	b := new(bytes.Buffer)
	json.NewEncoder(b).Encode(v)
	resp, err := http.Post("http://"+receiver+"/votes", "application/json", b)
	if err != nil {
		fmt.Println("Couldn't send request for votes to " + receiver)
		fmt.Println(err)
		return
	} else {
		r := &requestForVoteResponse{}
		err := json.NewDecoder(resp.Body).Decode(r)
		if err != nil {
			fmt.Println("Couldn't decode request for vote response from ", s.config[receiverIndex])
			return
		}
		defer resp.Body.Close()
		voteResp := &voteResponse{receiverIndex, *r}
		respChan <- *voteResp
	}
}

func (s *server) startElection() {
	s.state = "candidate"
	s.term += 1
	s.votedFor = s.id
	voteCount := 1
	respChan := make(chan voteResponse)
	for receiverIndex, receiverId := range s.config {
		if receiverId != s.id {
			go s.sendRequestForVote(receiverIndex, respChan)
		}
	}
	responseCount := 0
	if len(s.config) > 1 {
		for {
			vote := <-respChan
			responseCount++
			if vote.Resp.HasGrantedVote {
				voteCount++
			}
			if voteCount > len(s.config)/2 {
				s.state = "leader"
				break
			}
			if responseCount == len(s.config) {
				break
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"math/rand"
	"strings"
	"time"
)

var (
	separator string
	numberOfWords int
)

func init() {
	flag.IntVar(&numberOfWords, "n", 3, "the number of random words to join")
	flag.StringVar(&separator, "s", "-", "a separator to use when joining words")
}

// TODO: break the random word functionality into windows && unix helpers
func main() {
	if len(os.Args) > 1 {
		checkUsage()
	}

	words, err := readAvailableDictionary()
	if err != nil {
		println("Sorry, some unexpected happening reading your dictionary:")
		println(err.Error())
		os.Exit(2)
	}

	flag.Parse()
	rand.Seed(time.Now().Unix())

	pieces := []string{}
	for i := 0; i < numberOfWords; i++ {
		pieces = append(pieces, words[rand.Int() % len(words)])
	}

	println(strings.Join(pieces, separator))
	return
}

// this will fail horribly on windows
func readAvailableDictionary() (words []string, err error) {
	file, err := os.Open("/usr/share/dict/words")
	if err != nil {
		return
	}

	bytes, err := ioutil.ReadAll(file)
	if err != nil {
		return
	}

	words = strings.Split(string(bytes), "\n")
	return
}

func checkUsage() {
	if os.Args[1] == "help" || os.Args[1] == "-h" || os.Args[1] == "--help" {
		fmt.Printf(`
usage: random-word -s [separator] -n [number-of-words]
eg: random-word -s="-" -n=5 # holy-moly-guacamole-oily-strombole

The separator between words defaults to '-'
The number of words printed defaults to 3
`)
		os.Exit(1)
	}
}
<commit_msg>Go fmt<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"math/rand"
	"os"
	"strings"
	"time"
)

var (
	separator     string
	numberOfWords int
)

func init() {
	flag.IntVar(&numberOfWords, "n", 3, "the number of random words to join")
	flag.StringVar(&separator, "s", "-", "a separator to use when joining words")
}

// TODO: break the random word functionality into windows && unix helpers
func main() {
	if len(os.Args) > 1 {
		checkUsage()
	}

	words, err := readAvailableDictionary()
	if err != nil {
		println("Sorry, some unexpected happening reading your dictionary:")
		println(err.Error())
		os.Exit(2)
	}

	flag.Parse()
	rand.Seed(time.Now().Unix())

	pieces := []string{}
	for i := 0; i < numberOfWords; i++ {
		pieces = append(pieces, words[rand.Int()%len(words)])
	}

	println(strings.Join(pieces, separator))
	return
}

// this will fail horribly on windows
func readAvailableDictionary() (words []string, err error) {
	file, err := os.Open("/usr/share/dict/words")
	if err != nil {
		return
	}

	bytes, err := ioutil.ReadAll(file)
	if err != nil {
		return
	}

	words = strings.Split(string(bytes), "\n")
	return
}

func checkUsage() {
	if os.Args[1] == "help" || os.Args[1] == "-h" || os.Args[1] == "--help" {
		fmt.Printf(`
usage: random-word -s [separator] -n [number-of-words]
eg: random-word -s="-" -n=5 # holy-moly-guacamole-oily-strombole

The separator between words defaults to '-'
The number of words printed defaults to 3
`)
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/garyburd/redigo/redis"
	"net/http"
	"os"
	"testing"
)

func TestMain(m *testing.M) {

	retCode := m.Run()

	// your func
	teardown()

	// call with result of m.Run()
	os.Exit(retCode)
}

// TestRecordHeader tests whether request gets new header assigned
func TestRecordHeader(t *testing.T) {

	server, dbClient := testTools(200, `{'message': 'here'}`)
	defer server.Close()
	defer dbClient.cache.pool.Close()

	req, err := http.NewRequest("GET", "http://example.com", nil)
	expect(t, err, nil)

	response, err := dbClient.recordRequest(req)

	expect(t, response.Header.Get("Gen-proxy"), "Was-Here")
}

// TestRecordingToCache tests cache wrapper get/set/delete operations
func TestRecordingToCache(t *testing.T) {

	server, dbClient := testTools(200, `{'message': 'here'}`)
	defer server.Close()
	defer dbClient.cache.pool.Close()

	dbClient.cache.set("some_key", "value")

	value, err := redis.String(dbClient.cache.get("some_key"))

	expect(t, err, nil)

	expect(t, string(value), "value")

	err = dbClient.cache.delete("some_key")

	expect(t, err, nil)
}

// TestRequestFingerprint tests whether we get correct request ID
func TestRequestFingerprint(t *testing.T) {

	req, err := http.NewRequest("GET", "http://example.com", nil)
	expect(t, err, nil)

	fp := getRequestFingerprint(req)

	expect(t, fp, "92a65ed4ca2b7100037a4cba9afd15ea")

}

// TestGetAllRecords - tests recording and then getting responses
func TestGetAllRecords(t *testing.T) {

	server, dbClient := testTools(201, `{'message': 'here'}`)
	defer server.Close()
	defer dbClient.cache.pool.Close()

	// inserting some payloads
	for i := 0; i < 5; i++ {
		req, err := http.NewRequest("GET", fmt.Sprintf("http://example.com/q=%d", i), nil)
		expect(t, err, nil)
		dbClient.recordRequest(req)
	}

	// getting all keys
	keys, _ := dbClient.cache.getAllKeys()
	expect(t, len(keys) > 0, true)
	// getting requests
	payloads, err := dbClient.getAllRecords()
	expect(t, err, nil)

	for _, payload := range payloads {
		expect(t, payload.Request.Method, "GET")
		expect(t, payload.Response.Status, 201)
	}

}
<commit_msg>test for delete all records<commit_after>package main

import (
	"fmt"
	"github.com/garyburd/redigo/redis"
	"net/http"
	"os"
	"testing"
)

func TestMain(m *testing.M) {

	retCode := m.Run()

	// your func
	teardown()

	// call with result of m.Run()
	os.Exit(retCode)
}

// TestRecordHeader tests whether request gets new header assigned
func TestRecordHeader(t *testing.T) {

	server, dbClient := testTools(200, `{'message': 'here'}`)
	defer server.Close()
	defer dbClient.cache.pool.Close()

	req, err := http.NewRequest("GET", "http://example.com", nil)
	expect(t, err, nil)

	response, err := dbClient.recordRequest(req)

	expect(t, response.Header.Get("Gen-proxy"), "Was-Here")
}

// TestRecordingToCache tests cache wrapper get/set/delete operations
func TestRecordingToCache(t *testing.T) {

	server, dbClient := testTools(200, `{'message': 'here'}`)
	defer server.Close()
	defer dbClient.cache.pool.Close()

	dbClient.cache.set("some_key", "value")

	value, err := redis.String(dbClient.cache.get("some_key"))

	expect(t, err, nil)

	expect(t, string(value), "value")

	err = dbClient.cache.delete("some_key")

	expect(t, err, nil)
}

// TestRequestFingerprint tests whether we get correct request ID
func TestRequestFingerprint(t *testing.T) {

	req, err := http.NewRequest("GET", "http://example.com", nil)
	expect(t, err, nil)

	fp := getRequestFingerprint(req)

	expect(t, fp, "92a65ed4ca2b7100037a4cba9afd15ea")

}

// TestGetAllRecords - tests recording and then getting responses
func TestGetAllRecords(t *testing.T) {

	server, dbClient := testTools(201, `{'message': 'here'}`)
	defer server.Close()
	defer dbClient.cache.pool.Close()

	// inserting some payloads
	for i := 0; i < 5; i++ {
		req, err := http.NewRequest("GET", fmt.Sprintf("http://example.com/q=%d", i), nil)
		expect(t, err, nil)
		dbClient.recordRequest(req)
	}

	// getting all keys
	keys, _ := dbClient.cache.getAllKeys()
	expect(t, len(keys) > 0, true)
	// getting requests
	payloads, err := dbClient.getAllRecords()
	expect(t, err, nil)

	for _, payload := range payloads {
		expect(t, payload.Request.Method, "GET")
		expect(t, payload.Response.Status, 201)
	}

}

func TestDeleteAllRecords(t *testing.T) {

	server, dbClient := testTools(201, `{'message': 'here'}`)
	defer server.Close()
	defer dbClient.cache.pool.Close()

	// inserting some payloads
	for i := 0; i < 5; i++ {
		req, err := http.NewRequest("GET", fmt.Sprintf("http://example.com/q=%d", i), nil)
		expect(t, err, nil)
		dbClient.recordRequest(req)
	}
	// checking that keys are there
	keys, _ := dbClient.cache.getAllKeys()
	expect(t, len(keys) > 0, true)

	// deleting
	err := dbClient.deleteAllRecords()
	expect(t, err, nil)

	// checking whether all records were deleted
	keys, _ = dbClient.cache.getAllKeys()
	expect(t, len(keys), 0)
}
<|endoftext|>


<commit_before>package goldb

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestRecord_DecodeKey(t *testing.T) {
	rec := NewRecord(Key(123, "Зазеркалье", 0x4567, []byte("Alice")), &User{"Alice", 22})

	var (
		s   string
		num int
		bb  []byte
	)
	tableID := int(rec.Table())
	rec.DecodeKey(&s, &num, &bb)

	assert.Equal(t, tableID, 123)
	assert.Equal(t, "Зазеркалье", s)
	assert.Equal(t, 0x4567, num)
	assert.Equal(t, []byte("Alice"), bb)
	assert.Equal(t, []byte("Alice"), bb)
}

func TestRecord_Decode(t *testing.T) {
	rec := NewRecord(Key(123, 0x456), &User{"Alice", 22})

	var user User
	rowID := rec.RowID()
	rec.Decode(&user)

	assert.EqualValues(t, 0x456, rowID)
	assert.Equal(t, User{"Alice", 22}, user)
}
<commit_msg>refactor test<commit_after>package goldb

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestRecord_DecodeKey(t *testing.T) {
	rec := NewRecord(Key(123, "Зазеркалье", 0x4567, []byte("Alice")), &User{"Alice", 22})

	var (
		s   string
		num int
		bb  []byte
	)
	tableID := int(rec.Table())
	err := rec.DecodeKey(&s, &num, &bb)

	assert.NoError(t, err)
	assert.Equal(t, tableID, 123)
	assert.Equal(t, "Зазеркалье", s)
	assert.Equal(t, 0x4567, num)
	assert.Equal(t, []byte("Alice"), bb)
	assert.Equal(t, []byte("Alice"), bb)
}

func TestRecord_Decode(t *testing.T) {
	rec := NewRecord(Key(123, 0x456), &User{"Alice", 22})

	var user User
	rowID := rec.RowID()
	err := rec.Decode(&user)

	assert.NoError(t, err)
	assert.EqualValues(t, 0x456, rowID)
	assert.Equal(t, User{"Alice", 22}, user)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/robertkrimen/otto"
	"github.com/robertkrimen/otto/underscore"
	"io/ioutil"
	"os"
)

var underscoreFlag *bool = flag.Bool("underscore", true, "Load underscore into the runtime environment")

func main() {
	flag.Parse()
	var script []byte
	var err error
	filename := flag.Arg(0)
	if filename == "" || filename == "-" {
		script, err = ioutil.ReadAll(os.Stdin)
		if err != nil {
			fmt.Printf("Can't read stdin: %v\n", err)
			os.Exit(64)
		}
	} else {
		script, err = ioutil.ReadFile(filename)
		if err != nil {
			fmt.Printf("Can't open file \"%v\": %v\n", filename, err)
			os.Exit(64)
		}
	}
	if !*underscoreFlag {
		underscore.Disable()
	}
	Otto := otto.New()
	_, err = Otto.Run(string(script))
	if err != nil {
		fmt.Println(err)
		os.Exit(64)
	}
}
<commit_msg>Simplify the commandline client (otto)<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"

	"github.com/robertkrimen/otto"
	"github.com/robertkrimen/otto/underscore"
)

var flag_underscore *bool = flag.Bool("underscore", true, "Load underscore into the runtime environment")

func readSource(filename string) ([]byte, error) {
	if filename == "" || filename == "-" {
		return ioutil.ReadAll(os.Stdin)
	}
	return ioutil.ReadFile(filename)
}

func main() {
	flag.Parse()

	if !*flag_underscore {
		underscore.Disable()
	}

	err := func() error {
		src, err := readSource(flag.Arg(0))
		if err != nil {
			return err
		}

		vm := otto.New()
		_, err = vm.Run(src)
		return err
	}()
	if err != nil {
		fmt.Println(err)
		os.Exit(64)
	}
}
<|endoftext|>


<commit_before>package checkers

/*
Checker board class
For example:

  abcdefgh
 ..........
8| # # # #|8
7|# # # # |7
6| # # # #|6
5|# # # # |5
4| # # # #|4
3|# # # # |3
2| # # # #|2
1|# # # # |1
 ''''''''''
  abcdefgh

Here a1 has position (0,0) and h8 is on (7,7)
*/
type Board struct {
	cells [][]*Checker
}

func NewBoard(size int) *Board {
	if size < 0 {
		return nil
	}
	cells := make([][]*Checker, size)
	for i := range cells {
		cells[i] = make([]*Checker, size)
	}
	return &Board{cells: cells}
}

func (b Board) Size() int {
	return len(b.cells)
}

func (b *Board) placeChecker(x, y int, c *Checker) bool {
	if !b.ContainsPos(x, y) {
		return false
	}

	b.cells[y][x] = c
	if c != nil {
		c.setPosition(x, y)
	}
	return true
}

func (b *Board) takeChecker(x, y int) *Checker {
	c := b.cells[y][x]
	b.cells[y][x] = nil
	return c
}

func (b *Board) moveChecker(from, to Point) bool {
	if from == to {
		return false
	}
	if !b.ContainsPos(from.X, from.Y) || !b.ContainsPos(to.X, to.Y) {
		return false
	}
	if !b.IsEmpty(to.X, to.Y) {
		return false
	}
	c := b.takeChecker(from.X, from.Y)
	return b.placeChecker(to.X, to.Y, c)
}

func (b Board) GetChecker(x, y int) *Checker {
	return b.cells[y][x]
}

func (b Board) IsEmpty(x, y int) bool {
	return b.cells[y][x] == nil
}

func (b Board) IsBlackSquare(pos Point) bool {
	return pos.Manhattan()%2 == 0
}

func (b Board) IsWhiteSquare(pos Point) bool {
	return pos.Manhattan()%2 == 1
}

func (b Board) ContainsPos(x, y int) bool {
	fieldSize := b.Size()
	return x >= 0 && y >= 0 && x < fieldSize && y < fieldSize
}

func (b Board) LastRowIndex() int {
	return b.Size() - 1
}

func (b Board) LastColumnIndex() int {
	return b.Size() - 1
}
<commit_msg>Add clear method for Board<commit_after>package checkers

/*
Checker board class
For example:

  abcdefgh
 ..........
8| # # # #|8
7|# # # # |7
6| # # # #|6
5|# # # # |5
4| # # # #|4
3|# # # # |3
2| # # # #|2
1|# # # # |1
 ''''''''''
  abcdefgh

Here a1 has position (0,0) and h8 is on (7,7)
*/
type Board struct {
	cells [][]*Checker
}

func NewBoard(size int) *Board {
	if size < 0 {
		return nil
	}
	cells := make([][]*Checker, size)
	for i := range cells {
		cells[i] = make([]*Checker, size)
	}
	return &Board{cells: cells}
}

func (b Board) Size() int {
	return len(b.cells)
}

func (b *Board) clear() {
	for _, r := range b.cells {
		for c := range r {
			r[c] = nil
		}
	}
}

func (b *Board) placeChecker(x, y int, c *Checker) bool {
	if !b.ContainsPos(x, y) {
		return false
	}

	b.cells[y][x] = c
	if c != nil {
		c.setPosition(x, y)
	}
	return true
}

func (b *Board) takeChecker(x, y int) *Checker {
	c := b.cells[y][x]
	b.cells[y][x] = nil
	return c
}

func (b *Board) moveChecker(from, to Point) bool {
	if from == to {
		return false
	}
	if !b.ContainsPos(from.X, from.Y) || !b.ContainsPos(to.X, to.Y) {
		return false
	}
	if !b.IsEmpty(to.X, to.Y) {
		return false
	}
	c := b.takeChecker(from.X, from.Y)
	return b.placeChecker(to.X, to.Y, c)
}

func (b Board) GetChecker(x, y int) *Checker {
	return b.cells[y][x]
}

func (b Board) IsEmpty(x, y int) bool {
	return b.cells[y][x] == nil
}

func (b Board) IsBlackSquare(pos Point) bool {
	return pos.Manhattan()%2 == 0
}

func (b Board) IsWhiteSquare(pos Point) bool {
	return pos.Manhattan()%2 == 1
}

func (b Board) ContainsPos(x, y int) bool {
	fieldSize := b.Size()
	return x >= 0 && y >= 0 && x < fieldSize && y < fieldSize
}

func (b Board) LastRowIndex() int {
	return b.Size() - 1
}

func (b Board) LastColumnIndex() int {
	return b.Size() - 1
}
<|endoftext|>