<commit_before>// Copyright 2016,2017 Yaacov Zamir <kobi.zamir@gmail.com>
// and other contributors.
//
// 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 cli command line interface
package cli

import (
	"fmt"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"

	"github.com/MohawkTSDB/mohawk/api"
)

// AUTHOR the author name and Email
const AUTHOR = "Yaacov Zamir <kobi.zamir@gmail.com>"

// defaults
const defaultTLSKey = "server.key"
const defaultTLSCert = "server.pem"

// RootCmd Mohawk root cli Command
var RootCmd = &cobra.Command{
	Use: "mohawk",
	Long: fmt.Sprintf(`Mohawk is a metric data storage engine.

Mohawk is a metric data storage engine that uses a plugin architecture for data
storage and a simple REST API as the primary interface.

Version:
  %s

Author:
  %s`, api.VER, AUTHOR),
	Run: func(cmd *cobra.Command, args []string) {

		// Print version and quit
		if viper.GetBool("version") {
			fmt.Printf("Mohawk version: %s\n\n", api.VER)
			return
		}

		// Run the REST API server
		api.Serve()
	},
}

func init() {
	cobra.OnInitialize(initConfig)

	// Flag definition
	RootCmd.Flags().StringP("storage", "b", "memory", "the storage plugin to use")
	RootCmd.Flags().String("token", "", "authorization token")
	RootCmd.Flags().String("media", "./mohawk-webui", "path to media files (default is ./mohawk-webui)")
	RootCmd.Flags().String("key", defaultTLSKey, "path to TLS key file")
	RootCmd.Flags().String("cert", defaultTLSCert, "path to TLS cert file")
	RootCmd.Flags().String("options", "", "specific storage options [e.g. db-dirname, db-url]")
	RootCmd.Flags().IntP("port", "p", 8080, "server port")
	RootCmd.Flags().BoolP("tls", "t", false, "use TLS server")
	RootCmd.Flags().BoolP("gzip", "g", false, "use gzip encoding")
	RootCmd.Flags().BoolP("verbose", "V", false, "more debug output")
	RootCmd.Flags().BoolP("version", "v", false, "display mohawk version number")
	RootCmd.Flags().StringP("config", "c", "", "config file (default is None)")

	// Viper Binding
	viper.BindPFlag("storage", RootCmd.Flags().Lookup("storage"))
	viper.BindPFlag("token", RootCmd.Flags().Lookup("token"))
	viper.BindPFlag("media", RootCmd.Flags().Lookup("media"))
	viper.BindPFlag("key", RootCmd.Flags().Lookup("key"))
	viper.BindPFlag("cert", RootCmd.Flags().Lookup("cert"))
	viper.BindPFlag("options", RootCmd.Flags().Lookup("options"))
	viper.BindPFlag("port", RootCmd.Flags().Lookup("port"))
	viper.BindPFlag("tls", RootCmd.Flags().Lookup("tls"))
	viper.BindPFlag("gzip", RootCmd.Flags().Lookup("gzip"))
	viper.BindPFlag("verbose", RootCmd.Flags().Lookup("verbose"))
	viper.BindPFlag("version", RootCmd.Flags().Lookup("version"))
	viper.BindPFlag("config", RootCmd.Flags().Lookup("config"))
}

func initConfig() {
	if viper.GetString("config") != "" {
		viper.SetConfigFile(viper.GetString("config"))
		if err := viper.ReadInConfig(); err != nil {
			fmt.Println("Error reading config file:", err)
		}
	}
}
<commit_msg>fix-api-help<commit_after>// Copyright 2016,2017 Yaacov Zamir <kobi.zamir@gmail.com>
// and other contributors.
//
// 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 cli command line interface
package cli

import (
	"fmt"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"

	"github.com/MohawkTSDB/mohawk/api"
)

// AUTHOR the author name and Email
const AUTHOR = "Yaacov Zamir <kobi.zamir@gmail.com>"

// defaults
const defaultTLSKey = "server.key"
const defaultTLSCert = "server.pem"

// RootCmd Mohawk root cli Command
var RootCmd = &cobra.Command{
	Use: "mohawk",
	Long: fmt.Sprintf(`Mohawk is a metric data storage engine.

Mohawk is a metric data storage engine that uses a plugin architecture for data
storage and a simple REST API as the primary interface.

Version:
  %s

Author:
  %s`, api.VER, AUTHOR),
	Run: func(cmd *cobra.Command, args []string) {

		// Print version and quit
		if viper.GetBool("version") {
			fmt.Printf("Mohawk version: %s\n\n", api.VER)
			return
		}

		// Run the REST API server
		api.Serve()
	},
}

func init() {
	cobra.OnInitialize(initConfig)

	// Flag definition
	RootCmd.Flags().StringP("storage", "b", "memory", "the storage plugin to use")
	RootCmd.Flags().String("token", "", "authorization token")
	RootCmd.Flags().String("media", "./mohawk-webui", "path to media files")
	RootCmd.Flags().String("key", defaultTLSKey, "path to TLS key file")
	RootCmd.Flags().String("cert", defaultTLSCert, "path to TLS cert file")
	RootCmd.Flags().String("options", "", "specific storage options [e.g. db-dirname, db-url]")
	RootCmd.Flags().IntP("port", "p", 8080, "server port")
	RootCmd.Flags().BoolP("tls", "t", false, "use TLS server")
	RootCmd.Flags().BoolP("gzip", "g", false, "use gzip encoding")
	RootCmd.Flags().BoolP("verbose", "V", false, "more debug output")
	RootCmd.Flags().BoolP("version", "v", false, "display mohawk version number")
	RootCmd.Flags().StringP("config", "c", "", "config file")

	// Viper Binding
	viper.BindPFlag("storage", RootCmd.Flags().Lookup("storage"))
	viper.BindPFlag("token", RootCmd.Flags().Lookup("token"))
	viper.BindPFlag("media", RootCmd.Flags().Lookup("media"))
	viper.BindPFlag("key", RootCmd.Flags().Lookup("key"))
	viper.BindPFlag("cert", RootCmd.Flags().Lookup("cert"))
	viper.BindPFlag("options", RootCmd.Flags().Lookup("options"))
	viper.BindPFlag("port", RootCmd.Flags().Lookup("port"))
	viper.BindPFlag("tls", RootCmd.Flags().Lookup("tls"))
	viper.BindPFlag("gzip", RootCmd.Flags().Lookup("gzip"))
	viper.BindPFlag("verbose", RootCmd.Flags().Lookup("verbose"))
	viper.BindPFlag("version", RootCmd.Flags().Lookup("version"))
	viper.BindPFlag("config", RootCmd.Flags().Lookup("config"))
}

func initConfig() {
	if viper.GetString("config") != "" {
		viper.SetConfigFile(viper.GetString("config"))
		if err := viper.ReadInConfig(); err != nil {
			fmt.Println("Error reading config file:", err)
		}
	}
}
<|endoftext|>


<commit_before>package core

import (
	"log"

	"github.com/nikhan/go-fetch"
)

type Map struct {
	*Block
}

func NewMap(name string) Map {
	b := NewBlock(name)
	b.AddInput("in")
	b.AddInput("mapping")
	b.AddOutput("out")
	return Map{b}
}

func parseKeys(m map[string]interface{}) (interface{}, error) {
	t := make(map[string]interface{})

	for k, e := range m {
		switch r := e.(type) {
		case map[string]interface{}:
			//recurse
			j, err := parseKeys(r)
			if err != nil {
				return nil, err
			}
			t[k] = j
		case string:
			// this is a go-fetch directive
			q, err := fetch.Parse(r)
			if err != nil {
				return nil, err
			}
			t[k] = q
		}
	}

	return t, nil
}

func evalMap(msg interface{}, m map[string]interface{}) (interface{}, error) {
	return nil, nil
}

func (b Map) Serve() {

	in := b.GetInput("in")
	mapping := b.GetInput("mapping")
	var mI interface{}
	var p map[string]interface{}

	for {
		select {
		case msg := <-in.Connection:
			out, err := evalMap(msg, p)
			if err != nil {
				log.Fatal(err)
			}
			if ok := b.Broadcast(out, "out"); !ok {
				return
			}

		case mI = <-mapping.Connection:
			m, ok := mI.(map[string]interface{})
			if !ok {
				log.Fatal("could not assert mapping to map")
			}
			// iteratively parse and lex each key
			p, err := parseKeys(m)
			if err != nil {
				log.Fatal("could not parse keys")
			}
		case <-b.QuitChan:
			return
		}

	}
}
<commit_msg>pretty sure this is totally busted<commit_after>package core

import (
	"log"

	"github.com/nikhan/go-fetch"
)

type Map struct {
	*Block
}

func NewMap(name string) Map {
	b := NewBlock(name)
	b.AddInput("in")
	b.AddInput("mapping")
	b.AddOutput("out")
	return Map{b}
}

func parseKeys(m map[string]interface{}) (interface{}, error) {
	t := make(map[string]interface{})

	for k, e := range m {
		switch r := e.(type) {
		case map[string]interface{}:
			//recurse
			j, err := parseKeys(r)
			if err != nil {
				return nil, err
			}
			t[k] = j
		case string:
			// this is a go-fetch directive
			q, err := fetch.Parse(r)
			if err != nil {
				return nil, err
			}
			t[k] = q
		}
	}

	return t, nil
}

func evalMap(msg interface{}, m map[string]interface{}) (interface{}, error) {

	t := make(map[string]interface{})
	for k, e := range m {
		switch r := e.(type) {
		case map[string]interface{}:
			j, err := evalMap(msg, r)
			if err != nil {
				return nil, err
			}
			t[k] = j
		case *fetch.Query:
			value, err := fetch.Run(r, msg)
			if err != nil {
				return nil, err
			}
			t[k] = value
		}
	}
	return t, nil

}

func (b Map) Serve() {

	in := b.GetInput("in")
	mapping := b.GetInput("mapping")
	var mI interface{}
	var p map[string]interface{}

	for {
		select {
		case msg := <-in.Connection:
			out, err := evalMap(msg, p)
			if err != nil {
				log.Fatal(err)
			}
			if ok := b.Broadcast(out, "out"); !ok {
				return
			}

		case mI = <-mapping.Connection:
			m, ok := mI.(map[string]interface{})
			if !ok {
				log.Fatal("could not assert mapping to map")
			}
			p, err := parseKeys(m)
			if err != nil {
				log.Fatal("could not parse keys")
			}
		case <-b.QuitChan:
			return
		}

	}
}
<|endoftext|>


<commit_before>package main

import (
	"testing"
)

// Test that the version flag outputs the current version and retusn
func TestParse_versionFlag(t *testing.T) {
	// CLI.Parse([]string{"consul-template", "-version"})
}
<commit_msg>Add initial test coverage for the CLI<commit_after>package main

import (
	"bytes"
	"fmt"
	"reflect"
	"strings"
	"testing"
	"time"
)

//
func TestRun_printsErrors(t *testing.T) {
	outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
	cli := &CLI{outStream: outStream, errStream: errStream}
	args := strings.Split("consul-template -bacon delicious", " ")

	status := cli.Run(args)
	if status == ExitCodeOK {
		t.Fatal("expected not OK exit code")
	}

	expected := "flag provided but not defined: -bacon"
	if !strings.Contains(errStream.String(), expected) {
		t.Errorf("expected %q to eq %q", errStream.String(), expected)
	}
}

// Test that the version flag outputs the version and retuns an OK exit code
func TestParse_versionFlag(t *testing.T) {
	var cli CLI
	args := strings.Split("consul-template -version", " ")

	_, status, err := cli.Parse(args)
	if err == nil {
		t.Fatal("expected error, but nothing was returned")
	}

	expected := fmt.Sprintf("consul-template v%s", Version)
	if !strings.Contains(err.Error(), expected) {
		t.Errorf("expected %q to contain %q", err.Error(), expected)
	}

	if status != ExitCodeOK {
		t.Errorf("expected %s to eq %s", status, ExitCodeOK)
	}
}

// Test that parser errors are returned
func TestParse_parseError(t *testing.T) {
	outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
	cli := &CLI{outStream: outStream, errStream: errStream}
	args := strings.Split("consul-template -bacon delicious", " ")

	_, status, err := cli.Parse(args)
	if err == nil {
		t.Fatal("expected error, but nothing was returned")
	}

	expected := "flag provided but not defined: -bacon"
	if !strings.Contains(err.Error(), expected) {
		t.Fatalf("expected %q to contain %q", err.Error(), expected)
	}

	if status != ExitCodeParseFlagsError {
		t.Errorf("expected %s to eq %s", status, ExitCodeParseFlagsError)
	}
}

// Test wait flag is parsed
func TestParse_waitFlag(t *testing.T) {
	var cli CLI
	args := strings.Split("consul-template -wait=5s:10s", " ")

	config, status, err := cli.Parse(args)
	if err != nil {
		t.Fatal(err)
	}

	expected := &Wait{
		Min: time.Duration(5) * time.Second,
		Max: time.Duration(10) * time.Second,
	}

	if !reflect.DeepEqual(config.Wait, expected) {
		t.Errorf("expected %q to equal %q", config.Wait, expected)
	}

	if status != ExitCodeOK {
		t.Errorf("expected %s to eq %s", status, ExitCodeOK)
	}
}

// Test wait flag error is propagated
func TestParse_waitFlagError(t *testing.T) {
	var cli CLI
	args := strings.Split("consul-template -wait=watermelon:bacon", " ")

	_, status, err := cli.Parse(args)
	if err == nil {
		t.Fatal("expected error, but nothing was returned")
	}

	expected := "time: invalid duration watermelon"
	if !strings.Contains(err.Error(), expected) {
		t.Fatalf("expected %q to contain %q", err.Error(), expected)
	}

	if status != ExitCodeParseWaitError {
		t.Errorf("expected %s to eq %s", status, ExitCodeParseWaitError)
	}
}

// Test that the -config flag is parsed properly
func TestParse_configFlag(t *testing.T) {
	var cli CLI

	configOnDisk := createTempfile([]byte(`
    consul = "nyc1.demo.consul.io"
    wait = "5s:10s"
  `), t)
	defer deleteTempfile(configOnDisk, t)

	cmd := fmt.Sprintf("consul-template -config %s -wait=30s:1m", configOnDisk.Name())
	args := strings.Split(cmd, " ")

	config, status, err := cli.Parse(args)
	if err != nil {
		t.Fatal(err)
	}

	// Test that the config is parsed
	expectedConsul := "nyc1.demo.consul.io"
	if config.Consul != expectedConsul {
		t.Fatalf("expected %q to equal %q", config.Consul, expectedConsul)
	}

	// Test that command line options take precedence over config file options
	expectedWait := &Wait{
		Min: time.Duration(30) * time.Second,
		Max: time.Duration(1) * time.Minute,
	}

	if !reflect.DeepEqual(config.Wait, expectedWait) {
		t.Fatalf("expected %q to equal %q", config.Wait, expectedWait)
	}

	if status != ExitCodeOK {
		t.Errorf("expected %s to eq %s", status, ExitCodeOK)
	}
}
<|endoftext|>


<commit_before>package physical

import (
	"context"
	"sync/atomic"

	log "github.com/hashicorp/go-hclog"
	"github.com/hashicorp/golang-lru"
	"github.com/hashicorp/vault/helper/locksutil"
	"github.com/hashicorp/vault/helper/pathmanager"
)

const (
	// DefaultCacheSize is used if no cache size is specified for NewCache
	DefaultCacheSize = 128 * 1024
)

// These paths don't need to be cached by the LRU cache. This should
// particularly help memory pressure when unsealing.
var cacheExceptionsPaths = []string{
	"wal/logs/",
	"index/pages/",
	"index-dr/pages/",
	"sys/expire/",
}

// Cache is used to wrap an underlying physical backend
// and provide an LRU cache layer on top. Most of the reads done by
// Vault are for policy objects so there is a large read reduction
// by using a simple write-through cache.
type Cache struct {
	backend         Backend
	lru             *lru.TwoQueueCache
	locks           []*locksutil.LockEntry
	logger          log.Logger
	enabled         *uint32
	cacheExceptions *pathmanager.PathManager
}

// TransactionalCache is a Cache that wraps the physical that is transactional
type TransactionalCache struct {
	*Cache
	Transactional
}

// Verify Cache satisfies the correct interfaces
var _ ToggleablePurgemonster = (*Cache)(nil)
var _ ToggleablePurgemonster = (*TransactionalCache)(nil)
var _ Backend = (*Cache)(nil)
var _ Transactional = (*TransactionalCache)(nil)

// NewCache returns a physical cache of the given size.
// If no size is provided, the default size is used.
func NewCache(b Backend, size int, logger log.Logger) *Cache {
	if logger.IsDebug() {
		logger.Debug("creating LRU cache", "size", size)
	}
	if size <= 0 {
		size = DefaultCacheSize
	}

	pm := pathmanager.New()
	pm.AddPaths(cacheExceptionsPaths)

	cache, _ := lru.New2Q(size)
	c := &Cache{
		backend: b,
		lru:     cache,
		locks:   locksutil.CreateLocks(),
		logger:  logger,
		// This fails safe.
		enabled:         new(uint32),
		cacheExceptions: pm,
	}
	return c
}

func NewTransactionalCache(b Backend, size int, logger log.Logger) *TransactionalCache {
	c := &TransactionalCache{
		Cache:         NewCache(b, size, logger),
		Transactional: b.(Transactional),
	}
	return c
}

func (c *Cache) shouldCache(key string) bool {
	if atomic.LoadUint32(c.enabled) == 0 {
		return false
	}

	return !c.cacheExceptions.HasPath(key)
}

// SetEnabled is used to toggle whether the cache is on or off. It must be
// called with true to actually activate the cache after creation.
func (c *Cache) SetEnabled(enabled bool) {
	if enabled {
		atomic.StoreUint32(c.enabled, 1)
		return
	}
	atomic.StoreUint32(c.enabled, 0)
}

// Purge is used to clear the cache
func (c *Cache) Purge(ctx context.Context) {
	// Lock the world
	for _, lock := range c.locks {
		lock.Lock()
		defer lock.Unlock()
	}

	c.lru.Purge()
}

func (c *Cache) Put(ctx context.Context, entry *Entry) error {
	if entry != nil && !c.shouldCache(entry.Key) {
		return c.backend.Put(ctx, entry)
	}

	lock := locksutil.LockForKey(c.locks, entry.Key)
	lock.Lock()
	defer lock.Unlock()

	err := c.backend.Put(ctx, entry)
	if err == nil {
		c.lru.Add(entry.Key, entry)
	}
	return err
}

func (c *Cache) Get(ctx context.Context, key string) (*Entry, error) {
	if !c.shouldCache(key) {
		return c.backend.Get(ctx, key)
	}

	lock := locksutil.LockForKey(c.locks, key)
	lock.RLock()
	defer lock.RUnlock()

	// Check the LRU first
	if raw, ok := c.lru.Get(key); ok {
		if raw == nil {
			return nil, nil
		}
		return raw.(*Entry), nil
	}

	// Read from the underlying backend
	ent, err := c.backend.Get(ctx, key)
	if err != nil {
		return nil, err
	}

	// Cache the result
	if ent != nil {
		c.lru.Add(key, ent)
	}

	return ent, nil
}

func (c *Cache) Delete(ctx context.Context, key string) error {
	if !c.shouldCache(key) {
		return c.backend.Delete(ctx, key)
	}

	lock := locksutil.LockForKey(c.locks, key)
	lock.Lock()
	defer lock.Unlock()

	err := c.backend.Delete(ctx, key)
	if err == nil {
		c.lru.Remove(key)
	}
	return err
}

func (c *Cache) List(ctx context.Context, prefix string) ([]string, error) {
	// Always pass-through as this would be difficult to cache. For the same
	// reason we don't lock as we can't reasonably know which locks to readlock
	// ahead of time.
	return c.backend.List(ctx, prefix)
}

func (c *TransactionalCache) Transaction(ctx context.Context, txns []*TxnEntry) error {
	// Bypass the locking below
	if atomic.LoadUint32(c.enabled) == 0 {
		return c.Transactional.Transaction(ctx, txns)
	}

	// Collect keys that need to be locked
	var keys []string
	for _, curr := range txns {
		keys = append(keys, curr.Entry.Key)
	}
	// Lock the keys
	for _, l := range locksutil.LocksForKeys(c.locks, keys) {
		l.Lock()
		defer l.Unlock()
	}

	if err := c.Transactional.Transaction(ctx, txns); err != nil {
		return err
	}

	for _, txn := range txns {
		if !c.shouldCache(txn.Entry.Key) {
			continue
		}

		switch txn.Operation {
		case PutOperation:
			c.lru.Add(txn.Entry.Key, txn.Entry)
		case DeleteOperation:
			c.lru.Remove(txn.Entry.Key)
		}
	}

	return nil
}
<commit_msg>Cache negative results in physical cache (#5303)<commit_after>package physical

import (
	"context"
	"sync/atomic"

	log "github.com/hashicorp/go-hclog"
	"github.com/hashicorp/golang-lru"
	"github.com/hashicorp/vault/helper/locksutil"
	"github.com/hashicorp/vault/helper/pathmanager"
)

const (
	// DefaultCacheSize is used if no cache size is specified for NewCache
	DefaultCacheSize = 128 * 1024
)

// These paths don't need to be cached by the LRU cache. This should
// particularly help memory pressure when unsealing.
var cacheExceptionsPaths = []string{
	"wal/logs/",
	"index/pages/",
	"index-dr/pages/",
	"sys/expire/",
}

// Cache is used to wrap an underlying physical backend
// and provide an LRU cache layer on top. Most of the reads done by
// Vault are for policy objects so there is a large read reduction
// by using a simple write-through cache.
type Cache struct {
	backend         Backend
	lru             *lru.TwoQueueCache
	locks           []*locksutil.LockEntry
	logger          log.Logger
	enabled         *uint32
	cacheExceptions *pathmanager.PathManager
}

// TransactionalCache is a Cache that wraps the physical that is transactional
type TransactionalCache struct {
	*Cache
	Transactional
}

// Verify Cache satisfies the correct interfaces
var _ ToggleablePurgemonster = (*Cache)(nil)
var _ ToggleablePurgemonster = (*TransactionalCache)(nil)
var _ Backend = (*Cache)(nil)
var _ Transactional = (*TransactionalCache)(nil)

// NewCache returns a physical cache of the given size.
// If no size is provided, the default size is used.
func NewCache(b Backend, size int, logger log.Logger) *Cache {
	if logger.IsDebug() {
		logger.Debug("creating LRU cache", "size", size)
	}
	if size <= 0 {
		size = DefaultCacheSize
	}

	pm := pathmanager.New()
	pm.AddPaths(cacheExceptionsPaths)

	cache, _ := lru.New2Q(size)
	c := &Cache{
		backend: b,
		lru:     cache,
		locks:   locksutil.CreateLocks(),
		logger:  logger,
		// This fails safe.
		enabled:         new(uint32),
		cacheExceptions: pm,
	}
	return c
}

func NewTransactionalCache(b Backend, size int, logger log.Logger) *TransactionalCache {
	c := &TransactionalCache{
		Cache:         NewCache(b, size, logger),
		Transactional: b.(Transactional),
	}
	return c
}

func (c *Cache) shouldCache(key string) bool {
	if atomic.LoadUint32(c.enabled) == 0 {
		return false
	}

	return !c.cacheExceptions.HasPath(key)
}

// SetEnabled is used to toggle whether the cache is on or off. It must be
// called with true to actually activate the cache after creation.
func (c *Cache) SetEnabled(enabled bool) {
	if enabled {
		atomic.StoreUint32(c.enabled, 1)
		return
	}
	atomic.StoreUint32(c.enabled, 0)
}

// Purge is used to clear the cache
func (c *Cache) Purge(ctx context.Context) {
	// Lock the world
	for _, lock := range c.locks {
		lock.Lock()
		defer lock.Unlock()
	}

	c.lru.Purge()
}

func (c *Cache) Put(ctx context.Context, entry *Entry) error {
	if entry != nil && !c.shouldCache(entry.Key) {
		return c.backend.Put(ctx, entry)
	}

	lock := locksutil.LockForKey(c.locks, entry.Key)
	lock.Lock()
	defer lock.Unlock()

	err := c.backend.Put(ctx, entry)
	if err == nil {
		c.lru.Add(entry.Key, entry)
	}
	return err
}

func (c *Cache) Get(ctx context.Context, key string) (*Entry, error) {
	if !c.shouldCache(key) {
		return c.backend.Get(ctx, key)
	}

	lock := locksutil.LockForKey(c.locks, key)
	lock.RLock()
	defer lock.RUnlock()

	// Check the LRU first
	if raw, ok := c.lru.Get(key); ok {
		if raw == nil {
			return nil, nil
		}
		return raw.(*Entry), nil
	}

	// Read from the underlying backend
	ent, err := c.backend.Get(ctx, key)
	if err != nil {
		return nil, err
	}

	// Cache the result
	c.lru.Add(key, ent)

	return ent, nil
}

func (c *Cache) Delete(ctx context.Context, key string) error {
	if !c.shouldCache(key) {
		return c.backend.Delete(ctx, key)
	}

	lock := locksutil.LockForKey(c.locks, key)
	lock.Lock()
	defer lock.Unlock()

	err := c.backend.Delete(ctx, key)
	if err == nil {
		c.lru.Remove(key)
	}
	return err
}

func (c *Cache) List(ctx context.Context, prefix string) ([]string, error) {
	// Always pass-through as this would be difficult to cache. For the same
	// reason we don't lock as we can't reasonably know which locks to readlock
	// ahead of time.
	return c.backend.List(ctx, prefix)
}

func (c *TransactionalCache) Transaction(ctx context.Context, txns []*TxnEntry) error {
	// Bypass the locking below
	if atomic.LoadUint32(c.enabled) == 0 {
		return c.Transactional.Transaction(ctx, txns)
	}

	// Collect keys that need to be locked
	var keys []string
	for _, curr := range txns {
		keys = append(keys, curr.Entry.Key)
	}
	// Lock the keys
	for _, l := range locksutil.LocksForKeys(c.locks, keys) {
		l.Lock()
		defer l.Unlock()
	}

	if err := c.Transactional.Transaction(ctx, txns); err != nil {
		return err
	}

	for _, txn := range txns {
		if !c.shouldCache(txn.Entry.Key) {
			continue
		}

		switch txn.Operation {
		case PutOperation:
			c.lru.Add(txn.Entry.Key, txn.Entry)
		case DeleteOperation:
			c.lru.Remove(txn.Entry.Key)
		}
	}

	return nil
}
<|endoftext|>


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

package backend

import (
	"context"
	"errors"
	"net/http"
	"net/url"
	"sync"

	"github.com/gorilla/websocket"
)

// ContextHandler handles ServeHTTP with context.
type ContextHandler interface {
	ServeHTTPContext(context.Context, http.ResponseWriter, *http.Request) error
}

// ContextHandlerFunc defines HandlerFunc function signature to wrap context.
type ContextHandlerFunc func(context.Context, http.ResponseWriter, *http.Request) error

// ServeHTTPContext serve HTTP requests with context.
func (f ContextHandlerFunc) ServeHTTPContext(ctx context.Context, w http.ResponseWriter, req *http.Request) error {
	return f(ctx, w, req)
}

// ContextAdapter wraps context handler.
type ContextAdapter struct {
	ctx     context.Context
	handler ContextHandler
}

func (ca *ContextAdapter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	if err := ca.handler.ServeHTTPContext(ca.ctx, w, req); err != nil {
		plog.Errorf("ServeHTTP (%v) [method: %q | path: %q]", err, req.Method, req.URL.Path)
	}
}

type key int

const userKey key = 0

type userData struct {
	upgrader *websocket.Upgrader
}

var (
	globalCacheLock sync.Mutex
	globalCache     = make(map[string]*userData)
)

func checkSameOrigin(req *http.Request) bool {
	origin := req.Header["Origin"]
	if len(origin) == 0 {
		return true
	}
	u, err := url.Parse(origin[0])
	if err != nil {
		return false
	}
	return u.Host == "localhost:4200" // sync with Angular app
}

var (
	errUserLeft = errors.New("websocket: close 1001 (going away)")
)

func withCache(h ContextHandler) ContextHandler {
	return ContextHandlerFunc(func(ctx context.Context, w http.ResponseWriter, req *http.Request) error {
		userID := getUserID(req)
		ctx = context.WithValue(ctx, userKey, &userID)

		globalCacheLock.Lock()
		if _, ok := globalCache[userID]; !ok { // if user visits first time, create user cache
			plog.Infof("just created user %q", userID)

			globalCache[userID] = &userData{
				upgrader: &websocket.Upgrader{CheckOrigin: checkSameOrigin},
			}
		}
		globalCacheLock.Unlock()

		err := h.ServeHTTPContext(ctx, w, req)
		if err != nil && err.Error() == errUserLeft.Error() {
			plog.Infof("user %q just left the browser", userID)

			globalCacheLock.Lock()
			delete(globalCache, userID)
			globalCacheLock.Unlock()
			err = nil
		}
		return err
	})
}
<commit_msg>backend: add error log<commit_after>// Copyright 2016 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package backend

import (
	"context"
	"errors"
	"net/http"
	"net/url"
	"sync"

	"github.com/gorilla/websocket"
)

// ContextHandler handles ServeHTTP with context.
type ContextHandler interface {
	ServeHTTPContext(context.Context, http.ResponseWriter, *http.Request) error
}

// ContextHandlerFunc defines HandlerFunc function signature to wrap context.
type ContextHandlerFunc func(context.Context, http.ResponseWriter, *http.Request) error

// ServeHTTPContext serve HTTP requests with context.
func (f ContextHandlerFunc) ServeHTTPContext(ctx context.Context, w http.ResponseWriter, req *http.Request) error {
	return f(ctx, w, req)
}

// ContextAdapter wraps context handler.
type ContextAdapter struct {
	ctx     context.Context
	handler ContextHandler
}

func (ca *ContextAdapter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	if err := ca.handler.ServeHTTPContext(ca.ctx, w, req); err != nil {
		plog.Errorf("ServeHTTP (%v) [method: %q | path: %q]", err, req.Method, req.URL.Path)
	}
}

type key int

const userKey key = 0

type userData struct {
	upgrader *websocket.Upgrader
}

var (
	globalCacheLock sync.Mutex
	globalCache     = make(map[string]*userData)
)

func checkSameOrigin(req *http.Request) bool {
	origin := req.Header["Origin"]
	if len(origin) == 0 {
		return true
	}
	u, err := url.Parse(origin[0])
	if err != nil {
		return false
	}

	if u.Host == "localhost:4200" { // sync with Angular app
		return true
	}

	plog.Warningf("can verify the origin %q (expected %q)", req.Host, u.Host)
	return false
}

var (
	errUserLeft = errors.New("websocket: close 1001 (going away)")
)

func withCache(h ContextHandler) ContextHandler {
	return ContextHandlerFunc(func(ctx context.Context, w http.ResponseWriter, req *http.Request) error {
		userID := getUserID(req)
		ctx = context.WithValue(ctx, userKey, &userID)

		globalCacheLock.Lock()
		if _, ok := globalCache[userID]; !ok { // if user visits first time, create user cache
			plog.Infof("just created user %q", userID)

			globalCache[userID] = &userData{
				upgrader: &websocket.Upgrader{CheckOrigin: checkSameOrigin},
			}
		}
		globalCacheLock.Unlock()

		err := h.ServeHTTPContext(ctx, w, req)
		if err != nil && err.Error() == errUserLeft.Error() {
			plog.Infof("user %q just left the browser", userID)

			globalCacheLock.Lock()
			delete(globalCache, userID)
			globalCacheLock.Unlock()
			err = nil
		}
		return err
	})
}
<|endoftext|>


<commit_before>package pocketcleaner_test

import (
	"github.com/mrtazz/pocketcleaner"
	"io/ioutil"
	"testing"
)

func TestParsePacketResponse(t *testing.T) {
	input, _ := ioutil.ReadFile("fixtures/pocket_response.json")
	ret, err := pocketcleaner.ParsePocketResponse(string(input))
	if err != nil {
		t.Errorf("ParsePocketResponse: parse failed: %s", err.Error())
	}
	if ret.Since != 1448244422 {
		t.Errorf("ParsePocketResponse: expected %d, actual %d", 1448244422, ret.Since)
	}
	if len(ret.List) != 16 {
		t.Errorf("ParsePocketResponse: expected %d, actual %d", 16, len(ret.List))
	}
	item := ret.List["839271306"]
	if item.GivenTitle != "That's What Xu Said : Stop Blowhard Syndrome" {
		t.Errorf("ParsePocketResponse: expected %s, actual %s", "That's What Xu Said : Stop Blowhard Syndrome", item.GivenTitle)
	}
}

func TestFilterOutNewestItems(t *testing.T) {
	input, _ := ioutil.ReadFile("fixtures/pocket_response.json")
	items, err := pocketcleaner.ParsePocketResponse(string(input))
	if err != nil {
		t.Errorf("ParsePocketResponse: parse failed: %s", err.Error())
	}
	arr := make(pocketcleaner.PocketItemArray, 0)

	for _, v := range items.List {
		arr = append(arr, v)
	}

	ret := pocketcleaner.FilterOutNewestItems(arr, 5)

	if len(ret) != 11 {
		t.Errorf("FilterOutNewestItems: expected: %d, actual: %d", 11, len(ret))
	}

	// TODO: test that the right ones got filtered
	var flagtests = []struct {
		id          int
		timestamp   string
		given_title string
	}{
		{0, "1385319303", "Silicon Allee » Bootstrapping Business: Grow Your Company Without VC Fundin"},
		{1, "1394546312", "Your Marriage Will Fail, by Alicia Liu | Model View Culture"},
		{2, "1400039331", ""},
		{3, "1404071597", "http://www.vox.com/2014/6/26/5837638/the-ipo-is-dying-marc-andreessen-expla"},
		{4, "1410813125", "published a fascinating writeup"},
		{5, "1414509648", "Project Managing Your Health — Medium"},
		{6, "1415733610", "What It's Like To Burn Out - Career Burnout - Elle"},
		{7, "1421113507", "Towards Better Interviews – Venkata Mahalingam"},
		{8, "1421515685", "Why Remote Engineering Is So Difficult blog.learningbyshipping.com/2014/12/"},
		{9, "1422935881", ""},
		{10, "1426045670", "Meeting with purpose derrickbradley.github.io/2015/02/20/mee…"},
	}

	for _, tt := range flagtests {
		if ret[tt.id].GivenTitle != tt.given_title {
			t.Errorf("FilterOutNewestItems Title: expected: %s, actual: %s, at index: %d", tt.given_title, ret[tt.id].GivenTitle, tt.id)
			t.Errorf("FilterOutNewestItems Timestamp: expected: %s, actual: %d, at index: %d", tt.timestamp, ret[tt.id].TimeAdded, tt.id)
		}
	}

}
<commit_msg>DRY up tests<commit_after>package pocketcleaner_test

import (
	"github.com/mrtazz/pocketcleaner"
	"io/ioutil"
	"reflect"
	"testing"
)

func expect(t *testing.T, a interface{}, b interface{}) {
	if a != b {
		t.Errorf("Expected %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
	}
}

func TestParsePacketResponse(t *testing.T) {
	input, _ := ioutil.ReadFile("fixtures/pocket_response.json")
	ret, err := pocketcleaner.ParsePocketResponse(string(input))

	expect(t, err, nil)
	expect(t, ret.Since, uint(1448244422))
	expect(t, len(ret.List), 16)
	item := ret.List["839271306"]
	expect(t, item.GivenTitle, "That's What Xu Said : Stop Blowhard Syndrome")
}

func TestFilterOutNewestItems(t *testing.T) {
	input, _ := ioutil.ReadFile("fixtures/pocket_response.json")
	items, err := pocketcleaner.ParsePocketResponse(string(input))
	expect(t, err, nil)
	arr := make(pocketcleaner.PocketItemArray, 0)

	for _, v := range items.List {
		arr = append(arr, v)
	}

	ret := pocketcleaner.FilterOutNewestItems(arr, 5)

	expect(t, len(ret), 11)

	var flagtests = []struct {
		id          int
		timestamp   uint64
		given_title string
	}{
		{0, 1385319303, "Silicon Allee » Bootstrapping Business: Grow Your Company Without VC Fundin"},
		{1, 1394546312, "Your Marriage Will Fail, by Alicia Liu | Model View Culture"},
		{2, 1400039331, ""},
		{3, 1404071597, "http://www.vox.com/2014/6/26/5837638/the-ipo-is-dying-marc-andreessen-expla"},
		{4, 1410813125, "published a fascinating writeup"},
		{5, 1414509648, "Project Managing Your Health — Medium"},
		{6, 1415733610, "What It's Like To Burn Out - Career Burnout - Elle"},
		{7, 1421113507, "Towards Better Interviews – Venkata Mahalingam"},
		{8, 1421515685, "Why Remote Engineering Is So Difficult blog.learningbyshipping.com/2014/12/"},
		{9, 1422935881, ""},
		{10, 1426045670, "Meeting with purpose derrickbradley.github.io/2015/02/20/mee…"},
	}

	for _, tt := range flagtests {
		expect(t, ret[tt.id].GivenTitle, tt.given_title)
		expect(t, ret[tt.id].TimeAdded, tt.timestamp)
	}

}
<|endoftext|>


<commit_before>package proxy

import (
	"bytes"
	. "launchpad.net/gocheck"
	"net/http"
	"net/url"
	"regexp"
	"time"
	"github.com/cloudfoundry/gorouter/route"
	"runtime"
)

type AccessLoggerSuite struct{}

var _ = Suite(&AccessLoggerSuite{})

func (s *AccessLoggerSuite) CreateAccessLogRecord() *AccessLogRecord {
	u, err := url.Parse("http://foo.bar:1234/quz?wat")
	if err != nil {
		panic(err)
	}

	req := &http.Request{
		Method:     "GET",
		URL:        u,
		Proto:      "HTTP/1.1",
		Header:     make(http.Header),
		Host:       "foo.bar",
		RemoteAddr: "1.2.3.4:5678",
	}

	req.Header.Set("Referer", "referer")
	req.Header.Set("User-Agent", "user-agent")

	res := &http.Response{
		StatusCode: http.StatusOK,
	}

	b := &route.Endpoint{
		ApplicationId: "my_awesome_id",
		Host:          "127.0.0.1",
		Port:          4567,
	}

	r := AccessLogRecord{
		Request:       req,
		Response:      res,
		RouteEndpoint: b,
		StartedAt:     time.Unix(10, 100000000),
		FirstByteAt:   time.Unix(10, 200000000),
		FinishedAt:    time.Unix(10, 300000000),
		BodyBytesSent: 42,
	}

	return &r
}

func (s *AccessLoggerSuite) TestAccessLogRecordEncode(c *C) {
	r := s.CreateAccessLogRecord()

	p := `` +
		regexp.QuoteMeta(`foo.bar `) +
		regexp.QuoteMeta(`- `) +
		`\[\d{2}/\d{2}/\d{4}:\d{2}:\d{2}:\d{2} [+-]\d{4}\] ` +
		regexp.QuoteMeta(`"GET /quz?wat HTTP/1.1" `) +
		regexp.QuoteMeta(`200 `) +
		regexp.QuoteMeta(`42 `) +
		regexp.QuoteMeta(`"referer" `) +
		regexp.QuoteMeta(`"user-agent" `) +
		regexp.QuoteMeta(`1.2.3.4:5678 `) +
		regexp.QuoteMeta(`response_time:0.200000000 `) +
		regexp.QuoteMeta(`app_id:my_awesome_id`)

	b := &bytes.Buffer{}
	_, err := r.WriteTo(b)
	c.Assert(err, IsNil)

	c.Check(b.String(), Matches, "^"+p+"\n")
}

type fakeFile struct {
	payload []byte
}

func (f *fakeFile) Write(data []byte) (int, error) {
	f.payload = data
	return 12, nil
}

type mockEmitter struct{
	emitted bool
	appId string
	message string
}

func (m *mockEmitter) Emit(appid, message string) {
	m.emitted = true
	m.appId = appid
	m.message = message
}

func (s *AccessLoggerSuite) TestEmittingOfLogRecords(c *C) {
	accessLogger := NewAccessLogger(nil, "localhost:9843")
	testEmitter := &mockEmitter{emitted: false}
	accessLogger.e = testEmitter

	accessLogger.Log(*s.CreateAccessLogRecord())
	go accessLogger.Run()
	runtime.Gosched()

	c.Check(testEmitter.emitted, Equals, true)
	c.Check(testEmitter.appId, Equals, "my_awesome_id")
	c.Check(testEmitter.message, Equals, "foo.bar - [31/12/1969:17:00:10 -0700] \"GET /quz?wat HTTP/1.1\" 200 42 \"referer\" \"user-agent\" 1.2.3.4:5678 response_time:0.200000000 app_id:my_awesome_id\n")
	accessLogger.Stop()
}

func (s *AccessLoggerSuite) TestWritingOfLogRecordsToTheFile(c *C) {
	var fakeFile = new(fakeFile)

	accessLogger := NewAccessLogger(fakeFile, "localhost:9843")

	accessLogger.Log(*s.CreateAccessLogRecord())
	go accessLogger.Run()
	runtime.Gosched()

	c.Check(string(fakeFile.payload), Equals, "foo.bar - [31/12/1969:17:00:10 -0700] \"GET /quz?wat HTTP/1.1\" 200 42 \"referer\" \"user-agent\" 1.2.3.4:5678 response_time:0.200000000 app_id:my_awesome_id\n")
	accessLogger.Stop()
}

func (s *AccessLoggerSuite) TestNotCreatingEmitterWhenNoValidUrlIsGiven(c *C) {
	accessLogger := NewAccessLogger(nil, "this_is_not_a_url")
	c.Assert(accessLogger.e, IsNil)
	accessLogger.Stop()

	accessLogger = NewAccessLogger(nil, "localhost")
	c.Assert(accessLogger.e, IsNil)
	accessLogger.Stop()

	accessLogger = NewAccessLogger(nil, "10.10.16.14")
	c.Assert(accessLogger.e, IsNil)
	accessLogger.Stop()

	accessLogger = NewAccessLogger(nil, "")
	c.Assert(accessLogger.e, IsNil)
	accessLogger.Stop()
}

func (s *AccessLoggerSuite) TestCreatingEmitterWithIPAddressAndPort(c *C) {
	accessLogger := NewAccessLogger(nil, "10.10.16.14:5432")

	c.Assert(accessLogger.e, NotNil)
	accessLogger.Stop()
}

func (s *AccessLoggerSuite) TestCreatingEmitterWithLocalhostt(c *C) {
	accessLogger := NewAccessLogger(nil, "localhost:123")

	c.Assert(accessLogger.e, NotNil)
	accessLogger.Stop()
}

type nullWriter struct{}

func (n nullWriter) Write(b []byte) (int, error) {
	return len(b), nil
}

func (s *AccessLoggerSuite) BenchmarkAccessLogRecordWriteTo(c *C) {
	r := s.CreateAccessLogRecord()
	w := nullWriter{}

	for i := 0; i < c.N; i++ {
		r.WriteTo(w)
	}
}
<commit_msg>Fixing a timezone related test failure<commit_after>package proxy

import (
	"bytes"
	. "launchpad.net/gocheck"
	"net/http"
	"net/url"
	"regexp"
	"time"
	"github.com/cloudfoundry/gorouter/route"
	"runtime"
)

type AccessLoggerSuite struct{}

var _ = Suite(&AccessLoggerSuite{})

var logMessageRegex = `` +
	regexp.QuoteMeta(`foo.bar `) +
	regexp.QuoteMeta(`- `) +
	`\[\d{2}/\d{2}/\d{4}:\d{2}:\d{2}:\d{2} [+-]\d{4}\] ` +
	regexp.QuoteMeta(`"GET /quz?wat HTTP/1.1" `) +
	regexp.QuoteMeta(`200 `) +
	regexp.QuoteMeta(`42 `) +
	regexp.QuoteMeta(`"referer" `) +
	regexp.QuoteMeta(`"user-agent" `) +
	regexp.QuoteMeta(`1.2.3.4:5678 `) +
	regexp.QuoteMeta(`response_time:0.200000000 `) +
	regexp.QuoteMeta(`app_id:my_awesome_id`)

func (s *AccessLoggerSuite) CreateAccessLogRecord() *AccessLogRecord {
	u, err := url.Parse("http://foo.bar:1234/quz?wat")
	if err != nil {
		panic(err)
	}

	req := &http.Request{
		Method:     "GET",
		URL:        u,
		Proto:      "HTTP/1.1",
		Header:     make(http.Header),
		Host:       "foo.bar",
		RemoteAddr: "1.2.3.4:5678",
	}

	req.Header.Set("Referer", "referer")
	req.Header.Set("User-Agent", "user-agent")

	res := &http.Response{
		StatusCode: http.StatusOK,
	}

	b := &route.Endpoint{
		ApplicationId: "my_awesome_id",
		Host:          "127.0.0.1",
		Port:          4567,
	}

	r := AccessLogRecord{
		Request:       req,
		Response:      res,
		RouteEndpoint: b,
		StartedAt:     time.Unix(10, 100000000),
		FirstByteAt:   time.Unix(10, 200000000),
		FinishedAt:    time.Unix(10, 300000000),
		BodyBytesSent: 42,
	}

	return &r
}

func (s *AccessLoggerSuite) TestAccessLogRecordEncode(c *C) {
	r := s.CreateAccessLogRecord()

	b := &bytes.Buffer{}
	_, err := r.WriteTo(b)
	c.Assert(err, IsNil)

	c.Check(b.String(), Matches, "^"+logMessageRegex+"\n")
}

type fakeFile struct {
	payload []byte
}

func (f *fakeFile) Write(data []byte) (int, error) {
	f.payload = data
	return 12, nil
}

type mockEmitter struct{
	emitted bool
	appId string
	message string
}

func (m *mockEmitter) Emit(appid, message string) {
	m.emitted = true
	m.appId = appid
	m.message = message
}

func (s *AccessLoggerSuite) TestEmittingOfLogRecords(c *C) {
	accessLogger := NewAccessLogger(nil, "localhost:9843")
	testEmitter := &mockEmitter{emitted: false}
	accessLogger.e = testEmitter

	accessLogger.Log(*s.CreateAccessLogRecord())
	go accessLogger.Run()
	runtime.Gosched()

	c.Check(testEmitter.emitted, Equals, true)
	c.Check(testEmitter.appId, Equals, "my_awesome_id")
	c.Check(testEmitter.message, Matches, "^"+logMessageRegex+"\n")
	accessLogger.Stop()
}

func (s *AccessLoggerSuite) TestWritingOfLogRecordsToTheFile(c *C) {
	var fakeFile = new(fakeFile)

	accessLogger := NewAccessLogger(fakeFile, "localhost:9843")

	accessLogger.Log(*s.CreateAccessLogRecord())
	go accessLogger.Run()
	runtime.Gosched()

	c.Check(string(fakeFile.payload), Matches, "^"+logMessageRegex+"\n")
	accessLogger.Stop()
}

func (s *AccessLoggerSuite) TestNotCreatingEmitterWhenNoValidUrlIsGiven(c *C) {
	accessLogger := NewAccessLogger(nil, "this_is_not_a_url")
	c.Assert(accessLogger.e, IsNil)
	accessLogger.Stop()

	accessLogger = NewAccessLogger(nil, "localhost")
	c.Assert(accessLogger.e, IsNil)
	accessLogger.Stop()

	accessLogger = NewAccessLogger(nil, "10.10.16.14")
	c.Assert(accessLogger.e, IsNil)
	accessLogger.Stop()

	accessLogger = NewAccessLogger(nil, "")
	c.Assert(accessLogger.e, IsNil)
	accessLogger.Stop()
}

func (s *AccessLoggerSuite) TestCreatingEmitterWithIPAddressAndPort(c *C) {
	accessLogger := NewAccessLogger(nil, "10.10.16.14:5432")

	c.Assert(accessLogger.e, NotNil)
	accessLogger.Stop()
}

func (s *AccessLoggerSuite) TestCreatingEmitterWithLocalhostt(c *C) {
	accessLogger := NewAccessLogger(nil, "localhost:123")

	c.Assert(accessLogger.e, NotNil)
	accessLogger.Stop()
}

type nullWriter struct{}

func (n nullWriter) Write(b []byte) (int, error) {
	return len(b), nil
}

func (s *AccessLoggerSuite) BenchmarkAccessLogRecordWriteTo(c *C) {
	r := s.CreateAccessLogRecord()
	w := nullWriter{}

	for i := 0; i < c.N; i++ {
		r.WriteTo(w)
	}
}
<|endoftext|>


<commit_before>package commands

import (
	"encoding/json"
	"fmt"

	"github.com/spf13/cobra"

	"github.com/nanobox-io/nanobox/commands/steps"
	"github.com/nanobox-io/nanobox/models"
	"github.com/nanobox-io/nanobox/processors"
	"github.com/nanobox-io/nanobox/util/display"
)

var (

	// ConfigureCmd ...
	ConfigureCmd = &cobra.Command{
		Use:   "configure",
		Short: "Configure Nanobox.",
		Long: `
Walks through a series of question prompts that modify your local
Nanobox configuration (~/.nanobox/config.yml).
		`,
		Run: configureFn,
		Aliases: []string{"config"},
	}

	ConfigureSetCmd = &cobra.Command{
		Use:   "set",
		Short: "Set a configuration key",
		Long: `
Set a key in the configuration
		`,
		Run: configureSetFn,
	}

	ConfigureGetCmd = &cobra.Command{
		Use:   "get",
		Short: "Get a value form the configuration",
		Long: `
Get a key from the configuration
		`,
		Run: configureGetFn,
	}

	ConfigureListCmd = &cobra.Command{
		Use:   "show",
		Short: "Show the full configuration",
		Long: `
List the full configuration.
		`,
		Run: configureListFn,
		Aliases: []string{"list"},
	}
)

func init() {
	steps.Build("configure", configureComplete, configureFn)

	ConfigureCmd.AddCommand(ConfigureSetCmd)
	ConfigureCmd.AddCommand(ConfigureGetCmd)
	ConfigureCmd.AddCommand(ConfigureListCmd)

}

// configureFn ...
func configureFn(ccmd *cobra.Command, args []string) {

	display.CommandErr(processors.Configure())
}

func configureSetFn(ccmd *cobra.Command, args []string) {
	if len(args) != 2 {
		fmt.Println("setting a key requires <key> <value>")
		return
	}
	display.CommandErr(processors.ConfigureSet(args[0], args[1]))
}

func configureGetFn(ccmd *cobra.Command, args []string) {
	if len(args) != 1 {
		fmt.Println("what is the key you would like to see")
		return
	}
	config, _ := models.LoadConfig()
	jsonData, _ := json.Marshal(config)
	configMap := map[string]interface{}{}
	json.Unmarshal(jsonData, &configMap)
	fmt.Println(configMap[args[0]])
	return

}

func configureListFn(ccmd *cobra.Command, args []string) {
	config, _ := models.LoadConfig()
	prettyJson, _ := json.MarshalIndent(config, "", "  ")
	fmt.Printf("%s\n", prettyJson)
	return
}

func configureComplete() bool {
	_, err := models.LoadConfig()
	return err == nil
}
<commit_msg>more aliases<commit_after>package commands

import (
	"encoding/json"
	"fmt"

	"github.com/spf13/cobra"

	"github.com/nanobox-io/nanobox/commands/steps"
	"github.com/nanobox-io/nanobox/models"
	"github.com/nanobox-io/nanobox/processors"
	"github.com/nanobox-io/nanobox/util/display"
)

var (

	// ConfigureCmd ...
	ConfigureCmd = &cobra.Command{
		Use:   "configure",
		Short: "Configure Nanobox.",
		Long: `
Walks through a series of question prompts that modify your local
Nanobox configuration (~/.nanobox/config.yml).
		`,
		Run: configureFn,
		Aliases: []string{"config"},
	}

	ConfigureSetCmd = &cobra.Command{
		Use:   "set",
		Short: "Set a configuration key",
		Long: `
Set a key in the configuration
		`,
		Run: configureSetFn,
	}

	ConfigureGetCmd = &cobra.Command{
		Use:   "get",
		Short: "Get a value form the configuration",
		Long: `
Get a key from the configuration
		`,
		Run: configureGetFn,
	}

	ConfigureListCmd = &cobra.Command{
		Use:   "show",
		Short: "Show the full configuration",
		Long: `
List the full configuration.
		`,
		Run: configureListFn,
		Aliases: []string{"list", "ls"},
	}
)

func init() {
	steps.Build("configure", configureComplete, configureFn)

	ConfigureCmd.AddCommand(ConfigureSetCmd)
	ConfigureCmd.AddCommand(ConfigureGetCmd)
	ConfigureCmd.AddCommand(ConfigureListCmd)

}

// configureFn ...
func configureFn(ccmd *cobra.Command, args []string) {

	display.CommandErr(processors.Configure())
}

func configureSetFn(ccmd *cobra.Command, args []string) {
	if len(args) != 2 {
		fmt.Println("setting a key requires <key> <value>")
		return
	}
	display.CommandErr(processors.ConfigureSet(args[0], args[1]))
}

func configureGetFn(ccmd *cobra.Command, args []string) {
	if len(args) != 1 {
		fmt.Println("what is the key you would like to see")
		return
	}
	config, _ := models.LoadConfig()
	jsonData, _ := json.Marshal(config)
	configMap := map[string]interface{}{}
	json.Unmarshal(jsonData, &configMap)
	fmt.Println(configMap[args[0]])
	return

}

func configureListFn(ccmd *cobra.Command, args []string) {
	config, _ := models.LoadConfig()
	prettyJson, _ := json.MarshalIndent(config, "", "  ")
	fmt.Printf("%s\n", prettyJson)
	return
}

func configureComplete() bool {
	_, err := models.LoadConfig()
	return err == nil
}
<|endoftext|>


<commit_before>package hdrhistogram_test

import (
	"reflect"
	"testing"

	"github.com/codahale/hdrhistogram"
)

func TestHighSigFig(t *testing.T) {
	input := []int64{
		459876, 669187, 711612, 816326, 931423, 1033197, 1131895, 2477317,
		3964974, 12718782,
	}

	hist := hdrhistogram.New(459876, 12718782, 5)
	for _, sample := range input {
		hist.RecordValue(sample)
	}

	if v, want := hist.ValueAtQuantile(50), int64(1048575); v != want {
		t.Errorf("Median was %v, but expected %v", v, want)
	}
}

func TestValueAtQuantile(t *testing.T) {
	h := hdrhistogram.New(1, 10000000, 3)

	for i := 0; i < 1000000; i++ {
		if err := h.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	data := []struct {
		q float64
		v int64
	}{
		{q: 50, v: 500223},
		{q: 75, v: 750079},
		{q: 90, v: 900095},
		{q: 95, v: 950271},
		{q: 99, v: 990207},
		{q: 99.9, v: 999423},
		{q: 99.99, v: 999935},
	}

	for _, d := range data {
		if v := h.ValueAtQuantile(d.q); v != d.v {
			t.Errorf("P%v was %v, but expected %v", d.q, v, d.v)
		}
	}
}

func TestMean(t *testing.T) {
	h := hdrhistogram.New(1, 10000000, 3)

	for i := 0; i < 1000000; i++ {
		if err := h.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	if v, want := h.Mean(), 500000.013312; v != want {
		t.Errorf("Mean was %v, but expected %v", v, want)
	}
}

func TestStdDev(t *testing.T) {
	h := hdrhistogram.New(1, 10000000, 3)

	for i := 0; i < 1000000; i++ {
		if err := h.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	if v, want := h.StdDev(), 288675.1403682715; v != want {
		t.Errorf("StdDev was %v, but expected %v", v, want)
	}
}

func TestMax(t *testing.T) {
	h := hdrhistogram.New(1, 10000000, 3)

	for i := 0; i < 1000000; i++ {
		if err := h.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	if v, want := h.Max(), int64(1000447); v != want {
		t.Errorf("Max was %v, but expected %v", v, want)
	}
}

func TestReset(t *testing.T) {
	h := hdrhistogram.New(1, 10000000, 3)

	for i := 0; i < 1000000; i++ {
		if err := h.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	h.Reset()

	if v, want := h.Max(), int64(0); v != want {
		t.Errorf("Max was %v, but expected %v", v, want)
	}
}

func TestMerge(t *testing.T) {
	h1 := hdrhistogram.New(1, 1000, 3)
	h2 := hdrhistogram.New(1, 1000, 3)

	for i := 0; i < 100; i++ {
		if err := h1.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	for i := 100; i < 200; i++ {
		if err := h2.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	h1.Merge(h2)

	if v, want := h1.ValueAtQuantile(50), int64(99); v != want {
		t.Errorf("Median was %v, but expected %v", v, want)
	}
}

func TestMin(t *testing.T) {
	h := hdrhistogram.New(1, 10000000, 3)

	for i := 0; i < 1000000; i++ {
		if err := h.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	if v, want := h.Min(), int64(0); v != want {
		t.Errorf("Min was %v, but expected %v", v, want)
	}
}

func TestByteSize(t *testing.T) {
	h := hdrhistogram.New(1, 100000, 3)

	if v, want := h.ByteSize(), 65604; v != want {
		t.Errorf("ByteSize was %v, but expected %d", v, want)
	}
}

func TestRecordCorrectedValue(t *testing.T) {
	h := hdrhistogram.New(1, 100000, 3)

	if err := h.RecordCorrectedValue(10, 100); err != nil {
		t.Fatal(err)
	}

	if v, want := h.ValueAtQuantile(75), int64(10); v != want {
		t.Errorf("Corrected value was %v, but expected %v", v, want)
	}
}

func TestRecordCorrectedValueStall(t *testing.T) {
	h := hdrhistogram.New(1, 100000, 3)

	if err := h.RecordCorrectedValue(1000, 100); err != nil {
		t.Fatal(err)
	}

	if v, want := h.ValueAtQuantile(75), int64(800); v != want {
		t.Errorf("Corrected value was %v, but expected %v", v, want)
	}
}

func TestCumulativeDistribution(t *testing.T) {
	h := hdrhistogram.New(1, 100000000, 3)

	for i := 0; i < 1000000; i++ {
		if err := h.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	actual := h.CumulativeDistribution()
	expected := []hdrhistogram.Bracket{
		hdrhistogram.Bracket{Quantile: 0, Count: 1, ValueAt: 0},
		hdrhistogram.Bracket{Quantile: 50, Count: 500224, ValueAt: 500223},
		hdrhistogram.Bracket{Quantile: 75, Count: 750080, ValueAt: 750079},
		hdrhistogram.Bracket{Quantile: 87.5, Count: 875008, ValueAt: 875007},
		hdrhistogram.Bracket{Quantile: 93.75, Count: 937984, ValueAt: 937983},
		hdrhistogram.Bracket{Quantile: 96.875, Count: 969216, ValueAt: 969215},
		hdrhistogram.Bracket{Quantile: 98.4375, Count: 984576, ValueAt: 984575},
		hdrhistogram.Bracket{Quantile: 99.21875, Count: 992256, ValueAt: 992255},
		hdrhistogram.Bracket{Quantile: 99.609375, Count: 996352, ValueAt: 996351},
		hdrhistogram.Bracket{Quantile: 99.8046875, Count: 998400, ValueAt: 998399},
		hdrhistogram.Bracket{Quantile: 99.90234375, Count: 999424, ValueAt: 999423},
		hdrhistogram.Bracket{Quantile: 99.951171875, Count: 999936, ValueAt: 999935},
		hdrhistogram.Bracket{Quantile: 99.9755859375, Count: 999936, ValueAt: 999935},
		hdrhistogram.Bracket{Quantile: 99.98779296875, Count: 999936, ValueAt: 999935},
		hdrhistogram.Bracket{Quantile: 99.993896484375, Count: 1000000, ValueAt: 1000447}, hdrhistogram.Bracket{Quantile: 100, Count: 1000000, ValueAt: 1000447},
	}

	if !reflect.DeepEqual(actual, expected) {
		t.Errorf("CF was %#v, but expected %#v", actual, expected)
	}
}

func TestDistribution(t *testing.T) {
	h := hdrhistogram.New(8, 1024, 3)

	for i := 0; i < 1024; i++ {
		if err := h.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	actual := h.Distribution()
	if len(actual) != 128 {
		t.Errorf("Number of bars seen was %v, expected was 128", len(actual))
	}
	for _, b := range actual {
		if b.Count != 8 {
			t.Errorf("Count per bar seen was %v, expected was 8", b.Count)
		}
	}
}

func BenchmarkHistogramRecordValue(b *testing.B) {
	h := hdrhistogram.New(1, 10000000, 3)
	for i := 0; i < 1000000; i++ {
		if err := h.RecordValue(int64(i)); err != nil {
			b.Fatal(err)
		}
	}
	b.ResetTimer()
	b.ReportAllocs()

	for i := 0; i < b.N; i++ {
		h.RecordValue(100)
	}
}

func BenchmarkNew(b *testing.B) {
	b.ReportAllocs()

	for i := 0; i < b.N; i++ {
		hdrhistogram.New(1, 120000, 3) // this could track 1ms-2min
	}
}

func TestUnitMagnitudeOverflow(t *testing.T) {
	h := hdrhistogram.New(0, 200, 4)
	if err := h.RecordValue(11); err != nil {
		t.Fatal(err)
	}
}

func TestSubBucketMaskOverflow(t *testing.T) {
	hist := hdrhistogram.New(2e7, 1e8, 5)
	for _, sample := range [...]int64{1e8, 2e7, 3e7} {
		hist.RecordValue(sample)
	}

	for q, want := range map[float64]int64{
		50:    33554431,
		83.33: 33554431,
		83.34: 100663295,
		99:    100663295,
	} {
		if got := hist.ValueAtQuantile(q); got != want {
			t.Errorf("got %d for %fth percentile. want: %d", got, q, want)
		}
	}
}

func TestExportImport(t *testing.T) {
	min := int64(1)
	max := int64(10000000)
	sigfigs := 3
	h := hdrhistogram.New(min, max, sigfigs)
	for i := 0; i < 1000000; i++ {
		if err := h.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	s := h.Export()

	if v := s.LowestTrackableValue; v != min {
		t.Errorf("LowestTrackableValue was %v, but expected %v", v, min)
	}

	if v := s.HighestTrackableValue; v != max {
		t.Errorf("HighestTrackableValue was %v, but expected %v", v, max)
	}

	if v := int(s.SignificantFigures); v != sigfigs {
		t.Errorf("SignificantFigures was %v, but expected %v", v, sigfigs)
	}

	if imported := hdrhistogram.Import(s); !imported.Equals(h) {
		t.Error("Expected Histograms to be equivalent")
	}

}

func TestEquals(t *testing.T) {
	h1 := hdrhistogram.New(1, 10000000, 3)
	for i := 0; i < 1000000; i++ {
		if err := h1.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	h2 := hdrhistogram.New(1, 10000000, 3)
	for i := 0; i < 10000; i++ {
		if err := h1.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	if h1.Equals(h2) {
		t.Error("Expected Histograms to not be equivalent")
	}

	h1.Reset()
	h2.Reset()

	if !h1.Equals(h2) {
		t.Error("Expected Histograms to be equivalent")
	}
}
<commit_msg>Fixed line wrap<commit_after>package hdrhistogram_test

import (
	"reflect"
	"testing"

	"github.com/codahale/hdrhistogram"
)

func TestHighSigFig(t *testing.T) {
	input := []int64{
		459876, 669187, 711612, 816326, 931423, 1033197, 1131895, 2477317,
		3964974, 12718782,
	}

	hist := hdrhistogram.New(459876, 12718782, 5)
	for _, sample := range input {
		hist.RecordValue(sample)
	}

	if v, want := hist.ValueAtQuantile(50), int64(1048575); v != want {
		t.Errorf("Median was %v, but expected %v", v, want)
	}
}

func TestValueAtQuantile(t *testing.T) {
	h := hdrhistogram.New(1, 10000000, 3)

	for i := 0; i < 1000000; i++ {
		if err := h.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	data := []struct {
		q float64
		v int64
	}{
		{q: 50, v: 500223},
		{q: 75, v: 750079},
		{q: 90, v: 900095},
		{q: 95, v: 950271},
		{q: 99, v: 990207},
		{q: 99.9, v: 999423},
		{q: 99.99, v: 999935},
	}

	for _, d := range data {
		if v := h.ValueAtQuantile(d.q); v != d.v {
			t.Errorf("P%v was %v, but expected %v", d.q, v, d.v)
		}
	}
}

func TestMean(t *testing.T) {
	h := hdrhistogram.New(1, 10000000, 3)

	for i := 0; i < 1000000; i++ {
		if err := h.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	if v, want := h.Mean(), 500000.013312; v != want {
		t.Errorf("Mean was %v, but expected %v", v, want)
	}
}

func TestStdDev(t *testing.T) {
	h := hdrhistogram.New(1, 10000000, 3)

	for i := 0; i < 1000000; i++ {
		if err := h.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	if v, want := h.StdDev(), 288675.1403682715; v != want {
		t.Errorf("StdDev was %v, but expected %v", v, want)
	}
}

func TestMax(t *testing.T) {
	h := hdrhistogram.New(1, 10000000, 3)

	for i := 0; i < 1000000; i++ {
		if err := h.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	if v, want := h.Max(), int64(1000447); v != want {
		t.Errorf("Max was %v, but expected %v", v, want)
	}
}

func TestReset(t *testing.T) {
	h := hdrhistogram.New(1, 10000000, 3)

	for i := 0; i < 1000000; i++ {
		if err := h.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	h.Reset()

	if v, want := h.Max(), int64(0); v != want {
		t.Errorf("Max was %v, but expected %v", v, want)
	}
}

func TestMerge(t *testing.T) {
	h1 := hdrhistogram.New(1, 1000, 3)
	h2 := hdrhistogram.New(1, 1000, 3)

	for i := 0; i < 100; i++ {
		if err := h1.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	for i := 100; i < 200; i++ {
		if err := h2.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	h1.Merge(h2)

	if v, want := h1.ValueAtQuantile(50), int64(99); v != want {
		t.Errorf("Median was %v, but expected %v", v, want)
	}
}

func TestMin(t *testing.T) {
	h := hdrhistogram.New(1, 10000000, 3)

	for i := 0; i < 1000000; i++ {
		if err := h.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	if v, want := h.Min(), int64(0); v != want {
		t.Errorf("Min was %v, but expected %v", v, want)
	}
}

func TestByteSize(t *testing.T) {
	h := hdrhistogram.New(1, 100000, 3)

	if v, want := h.ByteSize(), 65604; v != want {
		t.Errorf("ByteSize was %v, but expected %d", v, want)
	}
}

func TestRecordCorrectedValue(t *testing.T) {
	h := hdrhistogram.New(1, 100000, 3)

	if err := h.RecordCorrectedValue(10, 100); err != nil {
		t.Fatal(err)
	}

	if v, want := h.ValueAtQuantile(75), int64(10); v != want {
		t.Errorf("Corrected value was %v, but expected %v", v, want)
	}
}

func TestRecordCorrectedValueStall(t *testing.T) {
	h := hdrhistogram.New(1, 100000, 3)

	if err := h.RecordCorrectedValue(1000, 100); err != nil {
		t.Fatal(err)
	}

	if v, want := h.ValueAtQuantile(75), int64(800); v != want {
		t.Errorf("Corrected value was %v, but expected %v", v, want)
	}
}

func TestCumulativeDistribution(t *testing.T) {
	h := hdrhistogram.New(1, 100000000, 3)

	for i := 0; i < 1000000; i++ {
		if err := h.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	actual := h.CumulativeDistribution()
	expected := []hdrhistogram.Bracket{
		hdrhistogram.Bracket{Quantile: 0, Count: 1, ValueAt: 0},
		hdrhistogram.Bracket{Quantile: 50, Count: 500224, ValueAt: 500223},
		hdrhistogram.Bracket{Quantile: 75, Count: 750080, ValueAt: 750079},
		hdrhistogram.Bracket{Quantile: 87.5, Count: 875008, ValueAt: 875007},
		hdrhistogram.Bracket{Quantile: 93.75, Count: 937984, ValueAt: 937983},
		hdrhistogram.Bracket{Quantile: 96.875, Count: 969216, ValueAt: 969215},
		hdrhistogram.Bracket{Quantile: 98.4375, Count: 984576, ValueAt: 984575},
		hdrhistogram.Bracket{Quantile: 99.21875, Count: 992256, ValueAt: 992255},
		hdrhistogram.Bracket{Quantile: 99.609375, Count: 996352, ValueAt: 996351},
		hdrhistogram.Bracket{Quantile: 99.8046875, Count: 998400, ValueAt: 998399},
		hdrhistogram.Bracket{Quantile: 99.90234375, Count: 999424, ValueAt: 999423},
		hdrhistogram.Bracket{Quantile: 99.951171875, Count: 999936, ValueAt: 999935},
		hdrhistogram.Bracket{Quantile: 99.9755859375, Count: 999936, ValueAt: 999935},
		hdrhistogram.Bracket{Quantile: 99.98779296875, Count: 999936, ValueAt: 999935},
		hdrhistogram.Bracket{Quantile: 99.993896484375, Count: 1000000, ValueAt: 1000447},
		hdrhistogram.Bracket{Quantile: 100, Count: 1000000, ValueAt: 1000447},
	}

	if !reflect.DeepEqual(actual, expected) {
		t.Errorf("CF was %#v, but expected %#v", actual, expected)
	}
}

func TestDistribution(t *testing.T) {
	h := hdrhistogram.New(8, 1024, 3)

	for i := 0; i < 1024; i++ {
		if err := h.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	actual := h.Distribution()
	if len(actual) != 128 {
		t.Errorf("Number of bars seen was %v, expected was 128", len(actual))
	}
	for _, b := range actual {
		if b.Count != 8 {
			t.Errorf("Count per bar seen was %v, expected was 8", b.Count)
		}
	}
}

func BenchmarkHistogramRecordValue(b *testing.B) {
	h := hdrhistogram.New(1, 10000000, 3)
	for i := 0; i < 1000000; i++ {
		if err := h.RecordValue(int64(i)); err != nil {
			b.Fatal(err)
		}
	}
	b.ResetTimer()
	b.ReportAllocs()

	for i := 0; i < b.N; i++ {
		h.RecordValue(100)
	}
}

func BenchmarkNew(b *testing.B) {
	b.ReportAllocs()

	for i := 0; i < b.N; i++ {
		hdrhistogram.New(1, 120000, 3) // this could track 1ms-2min
	}
}

func TestUnitMagnitudeOverflow(t *testing.T) {
	h := hdrhistogram.New(0, 200, 4)
	if err := h.RecordValue(11); err != nil {
		t.Fatal(err)
	}
}

func TestSubBucketMaskOverflow(t *testing.T) {
	hist := hdrhistogram.New(2e7, 1e8, 5)
	for _, sample := range [...]int64{1e8, 2e7, 3e7} {
		hist.RecordValue(sample)
	}

	for q, want := range map[float64]int64{
		50:    33554431,
		83.33: 33554431,
		83.34: 100663295,
		99:    100663295,
	} {
		if got := hist.ValueAtQuantile(q); got != want {
			t.Errorf("got %d for %fth percentile. want: %d", got, q, want)
		}
	}
}

func TestExportImport(t *testing.T) {
	min := int64(1)
	max := int64(10000000)
	sigfigs := 3
	h := hdrhistogram.New(min, max, sigfigs)
	for i := 0; i < 1000000; i++ {
		if err := h.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	s := h.Export()

	if v := s.LowestTrackableValue; v != min {
		t.Errorf("LowestTrackableValue was %v, but expected %v", v, min)
	}

	if v := s.HighestTrackableValue; v != max {
		t.Errorf("HighestTrackableValue was %v, but expected %v", v, max)
	}

	if v := int(s.SignificantFigures); v != sigfigs {
		t.Errorf("SignificantFigures was %v, but expected %v", v, sigfigs)
	}

	if imported := hdrhistogram.Import(s); !imported.Equals(h) {
		t.Error("Expected Histograms to be equivalent")
	}

}

func TestEquals(t *testing.T) {
	h1 := hdrhistogram.New(1, 10000000, 3)
	for i := 0; i < 1000000; i++ {
		if err := h1.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	h2 := hdrhistogram.New(1, 10000000, 3)
	for i := 0; i < 10000; i++ {
		if err := h1.RecordValue(int64(i)); err != nil {
			t.Fatal(err)
		}
	}

	if h1.Equals(h2) {
		t.Error("Expected Histograms to not be equivalent")
	}

	h1.Reset()
	h2.Reset()

	if !h1.Equals(h2) {
		t.Error("Expected Histograms to be equivalent")
	}
}
<|endoftext|>


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

package main

import (
	"fmt"
	"strconv"

	"github.com/couchbase/gomemcached/client"
	log "github.com/couchbaselabs/clog"
	"github.com/couchbaselabs/go-couchbase"
)

type TAPFeed struct {
	name       string
	url        string
	poolName   string
	bucketName string
	bucketUUID string
	pf         StreamPartitionFunc
	streams    map[string]Stream
	closeCh    chan bool
	doneCh     chan bool
	doneErr    error
	doneMsg    string
}

func NewTAPFeed(name, url, poolName, bucketName, bucketUUID string,
	pf StreamPartitionFunc, streams map[string]Stream) (*TAPFeed, error) {
	return &TAPFeed{
		name:       name,
		url:        url,
		poolName:   poolName,
		bucketName: bucketName,
		bucketUUID: bucketUUID,
		pf:         pf,
		streams:    streams,
		closeCh:    make(chan bool),
		doneCh:     make(chan bool),
		doneErr:    nil,
		doneMsg:    "",
	}, nil
}

func (t *TAPFeed) Name() string {
	return t.name
}

func (t *TAPFeed) Start() error {
	log.Printf("TAPFeed.Start, name: %s", t.Name())

	go ExponentialBackoffLoop(t.Name(),
		func() int {
			progress, err := t.feed()
			if err != nil {
				log.Printf("TAPFeed name: %s, progress: %d, err: %v",
					t.Name(), progress, err)
			}
			return progress
		},
		FEED_SLEEP_INIT_MS,  // Milliseconds.
		FEED_BACKOFF_FACTOR, // Backoff.
		FEED_SLEEP_MAX_MS)

	return nil
}

func (t *TAPFeed) feed() (int, error) {
	select {
	case <-t.closeCh:
		t.doneErr = nil
		t.doneMsg = "closeCh closed"
		close(t.doneCh)
		return -1, nil
	default:
	}

	bucket, err := couchbase.GetBucket(t.url, t.poolName, t.bucketName)
	if err != nil {
		return 0, err
	}
	defer bucket.Close()

	if t.bucketUUID != "" && t.bucketUUID != bucket.UUID {
		bucket.Close()
		return -1, fmt.Errorf("error: mismatched bucket uuid,"+
			"bucketName: %s, bucketUUID: %s, bucket.UUID: %s",
			t.bucketName, t.bucketUUID, bucket.UUID)
	}

	args := memcached.TapArguments{}

	vbuckets, err := ParsePartitionsToVBucketIds(t.streams)
	if err != nil {
		return -1, err
	}
	if len(vbuckets) > 0 {
		args.VBuckets = vbuckets
	}

	feed, err := bucket.StartTapFeed(&args)
	if err != nil {
		return 0, err
	}
	defer feed.Close()

	// TODO: maybe TAPFeed should do a rollback to zero if it finds it
	// needs to do a full backfill.
	// TODO: this TAPFeed implementation currently only works against
	// a couchbase cluster that has just a single node.

	log.Printf("TapFeed: running, url: %s,"+
		" poolName: %s, bucketName: %s, vbuckets: %#v",
		t.url, t.poolName, t.bucketName, vbuckets)

loop:
	for {
		select {
		case <-t.closeCh:
			t.doneErr = nil
			t.doneMsg = "closeCh closed"
			close(t.doneCh)
			return -1, nil

		case req, alive := <-feed.C:
			if !alive {
				break loop
			}

			log.Printf("TapFeed: received from url: %s,"+
				" poolName: %s, bucketName: %s, opcode: %s, req: %#v",
				t.url, t.poolName, t.bucketName, req.Opcode, req)

			partition := fmt.Sprintf("%d", req.VBucket)
			stream, err := t.pf(req.Key, partition, t.streams)
			if err != nil {
				return 1, fmt.Errorf("error: TAPFeed:"+
					" partition func error from url: %s,"+
					" poolName: %s, bucketName: %s, req: %#v, streams: %#v, err: %v",
					t.url, t.poolName, t.bucketName, req, t.streams, err)
			}

			if req.Opcode == memcached.TapMutation {
				stream <- &StreamRequest{
					Op:  STREAM_OP_UPDATE,
					Key: req.Key,
					Val: req.Value,
				}
			} else if req.Opcode == memcached.TapDeletion {
				stream <- &StreamRequest{
					Op:  STREAM_OP_DELETE,
					Key: req.Key,
				}
			}
		}
	}

	return 1, nil
}

func (t *TAPFeed) Close() error {
	select {
	case <-t.doneCh:
		return t.doneErr
	default:
	}

	close(t.closeCh)
	<-t.doneCh
	return t.doneErr
}

func (t *TAPFeed) Streams() map[string]Stream {
	return t.streams
}

func ParsePartitionsToVBucketIds(streams map[string]Stream) ([]uint16, error) {
	vbuckets := make([]uint16, 0, len(streams))
	for partition, _ := range streams {
		if partition != "" {
			vbId, err := strconv.Atoi(partition)
			if err != nil {
				return nil, fmt.Errorf("error: could not parse partition: %s, err: %v",
					partition, err)
			}
			vbuckets = append(vbuckets, uint16(vbId))
		}
	}
	return vbuckets, nil
}
<commit_msg>VBucketIdToPartitionStream()<commit_after>//  Copyright (c) 2014 Couchbase, Inc.
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the
//  License. You may obtain a copy of the License at
//    http://www.apache.org/licenses/LICENSE-2.0
//  Unless required by applicable law or agreed to in writing,
//  software distributed under the License is distributed on an "AS
//  IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
//  express or implied. See the License for the specific language
//  governing permissions and limitations under the License.

package main

import (
	"fmt"
	"strconv"

	"github.com/couchbase/gomemcached/client"
	log "github.com/couchbaselabs/clog"
	"github.com/couchbaselabs/go-couchbase"
)

type TAPFeed struct {
	name       string
	url        string
	poolName   string
	bucketName string
	bucketUUID string
	pf         StreamPartitionFunc
	streams    map[string]Stream
	closeCh    chan bool
	doneCh     chan bool
	doneErr    error
	doneMsg    string
}

func NewTAPFeed(name, url, poolName, bucketName, bucketUUID string,
	pf StreamPartitionFunc, streams map[string]Stream) (*TAPFeed, error) {
	return &TAPFeed{
		name:       name,
		url:        url,
		poolName:   poolName,
		bucketName: bucketName,
		bucketUUID: bucketUUID,
		pf:         pf,
		streams:    streams,
		closeCh:    make(chan bool),
		doneCh:     make(chan bool),
		doneErr:    nil,
		doneMsg:    "",
	}, nil
}

func (t *TAPFeed) Name() string {
	return t.name
}

func (t *TAPFeed) Start() error {
	log.Printf("TAPFeed.Start, name: %s", t.Name())

	go ExponentialBackoffLoop(t.Name(),
		func() int {
			progress, err := t.feed()
			if err != nil {
				log.Printf("TAPFeed name: %s, progress: %d, err: %v",
					t.Name(), progress, err)
			}
			return progress
		},
		FEED_SLEEP_INIT_MS,  // Milliseconds.
		FEED_BACKOFF_FACTOR, // Backoff.
		FEED_SLEEP_MAX_MS)

	return nil
}

func (t *TAPFeed) feed() (int, error) {
	select {
	case <-t.closeCh:
		t.doneErr = nil
		t.doneMsg = "closeCh closed"
		close(t.doneCh)
		return -1, nil
	default:
	}

	bucket, err := couchbase.GetBucket(t.url, t.poolName, t.bucketName)
	if err != nil {
		return 0, err
	}
	defer bucket.Close()

	if t.bucketUUID != "" && t.bucketUUID != bucket.UUID {
		bucket.Close()
		return -1, fmt.Errorf("error: mismatched bucket uuid,"+
			"bucketName: %s, bucketUUID: %s, bucket.UUID: %s",
			t.bucketName, t.bucketUUID, bucket.UUID)
	}

	args := memcached.TapArguments{}

	vbuckets, err := ParsePartitionsToVBucketIds(t.streams)
	if err != nil {
		return -1, err
	}
	if len(vbuckets) > 0 {
		args.VBuckets = vbuckets
	}

	feed, err := bucket.StartTapFeed(&args)
	if err != nil {
		return 0, err
	}
	defer feed.Close()

	// TODO: maybe TAPFeed should do a rollback to zero if it finds it
	// needs to do a full backfill.
	// TODO: this TAPFeed implementation currently only works against
	// a couchbase cluster that has just a single node.

	log.Printf("TapFeed: running, url: %s,"+
		" poolName: %s, bucketName: %s, vbuckets: %#v",
		t.url, t.poolName, t.bucketName, vbuckets)

loop:
	for {
		select {
		case <-t.closeCh:
			t.doneErr = nil
			t.doneMsg = "closeCh closed"
			close(t.doneCh)
			return -1, nil

		case req, alive := <-feed.C:
			if !alive {
				break loop
			}

			log.Printf("TapFeed: received from url: %s,"+
				" poolName: %s, bucketName: %s, opcode: %s, req: %#v",
				t.url, t.poolName, t.bucketName, req.Opcode, req)

			partition, stream, err :=
				VBucketIdToPartitionStream(t.pf, t.streams, req.VBucket, req.Key)
			if err != nil {
				return 1, err
			}

			if req.Opcode == memcached.TapMutation {
				stream <- &StreamRequest{
					Op:        STREAM_OP_UPDATE,
					Partition: partition,
					Key:       req.Key,
					Val:       req.Value,
				}
			} else if req.Opcode == memcached.TapDeletion {
				stream <- &StreamRequest{
					Op:        STREAM_OP_DELETE,
					Partition: partition,
					Key:       req.Key,
				}
			}
		}
	}

	return 1, nil
}

func (t *TAPFeed) Close() error {
	select {
	case <-t.doneCh:
		return t.doneErr
	default:
	}

	close(t.closeCh)
	<-t.doneCh
	return t.doneErr
}

func (t *TAPFeed) Streams() map[string]Stream {
	return t.streams
}

func ParsePartitionsToVBucketIds(streams map[string]Stream) ([]uint16, error) {
	vbuckets := make([]uint16, 0, len(streams))
	for partition, _ := range streams {
		if partition != "" {
			vbId, err := strconv.Atoi(partition)
			if err != nil {
				return nil, fmt.Errorf("error: could not parse partition: %s, err: %v",
					partition, err)
			}
			vbuckets = append(vbuckets, uint16(vbId))
		}
	}
	return vbuckets, nil
}

func VBucketIdToPartitionStream(pf StreamPartitionFunc,
	streams map[string]Stream, vbucketId uint16, key []byte) (
	partition string, stream Stream, err error) {
	partition = fmt.Sprintf("%d", vbucketId)
	stream, err = pf(key, partition, streams)
	if err != nil {
		return "", nil, fmt.Errorf("error: VBucketIdToPartitionStream,"+
			" partition func, vbucketId: %d, err: %v", vbucketId, err)
	}
	return partition, stream, err
}
<|endoftext|>


<commit_before>package hdwallet

import (
    "bytes"
    "crypto/hmac"
    "crypto/sha512"
    "crypto/rand"
    "encoding/hex"
    "errors"
    "github.com/conformal/btcutil"
    )

var (
    //MainNet
    Public []byte
    Private []byte
    )

func init() {
    Public,_ = hex.DecodeString("0488B21E")
    Private,_ = hex.DecodeString("0488ADE4")
}

// HDWallet defines the components of a hierarchical deterministic wallet
type HDWallet struct {
    Vbytes []byte //4 bytes
    Depth uint16 //1 byte
    Fingerprint []byte //4 bytes
    I []byte //4 bytes
    Chaincode []byte //32 bytes
    Key []byte //33 bytes
}

// Child returns the ith child of wallet w. Values of i >= 2^31
// signify private key derivation. Attempting private key derivation
// with a public key will throw an error.
func (w *HDWallet) Child(i uint32) (*HDWallet,error) {
    var fingerprint, I , newkey []byte
    switch {
    case bytes.Compare(w.Vbytes, Private) == 0:
        pub := privToPub(w.Key)
        mac := hmac.New(sha512.New, w.Chaincode)
        if i >= uint32(0x80000000) {
            mac.Write(append(w.Key,uint32ToByte(i)...))
        } else {
            mac.Write(append(pub,uint32ToByte(i)...))
        }
        I = mac.Sum(nil)
        newkey = addPrivKeys(I[:32], w.Key)
        fingerprint = hash160(privToPub(w.Key))[:4]

    case bytes.Compare(w.Vbytes, Public) == 0:
        mac := hmac.New(sha512.New, w.Chaincode)
        if i >= uint32(0x80000000) {
            return &HDWallet{}, errors.New("Can't do Private derivation on Public key!")
        }
        mac.Write(append(w.Key,uint32ToByte(i)...))
        I = mac.Sum(nil)
        newkey = addPubKeys(privToPub(I[:32]), w.Key)
        fingerprint = hash160(w.Key)[:4]
    }
    return &HDWallet{w.Vbytes, w.Depth + 1, fingerprint, uint32ToByte(i), I[32:], newkey}, nil
}

// Serialize returns the serialized form of the wallet.
func (w *HDWallet) Serialize() []byte  {
    depth := uint16ToByte(uint16(w.Depth % 256))
    //bindata = vbytes||depth||fingerprint||i||chaincode||key
    bindata := append(w.Vbytes,append(depth,append(w.Fingerprint,append(w.I,append(w.Chaincode,w.Key...)...)...)...)...)
    chksum := dblSha256(bindata)[:4]
    return append(bindata,chksum...)
}

// String returns the base58-encoded string form of the wallet.
func (w *HDWallet) String() string  {
    return btcutil.Base58Encode(w.Serialize())
}

// StringWallet returns a wallet given a base58-encoded extended key
func StringWallet(data string) (*HDWallet,error) {
    dbin := btcutil.Base58Decode(data)
    if err := ByteCheck(dbin); err != nil {
        return &HDWallet{}, err
    }
    if bytes.Compare(dblSha256(dbin[:(len(dbin)-4)])[:4], dbin[(len(dbin)-4):]) != 0 {
        return &HDWallet{}, errors.New("Invalid checksum")
    }
    vbytes := dbin[0:4]
    depth := byteToUint16(dbin[4:5])
    fingerprint := dbin[5:9]
    i := dbin[9:13]
    chaincode := dbin[13:45]
    key := dbin[45:78]
    return &HDWallet{vbytes, depth, fingerprint, i, chaincode, key}, nil
}

// Pub returns a new wallet which is the public key version of w.
// If w is a public key, Pub returns a copy of w
func (w *HDWallet) Pub() *HDWallet {
    if bytes.Compare(w.Vbytes,Public) == 0 {
        return &HDWallet{w.Vbytes, w.Depth, w.Fingerprint, w.I, w.Chaincode, w.Key}
    } else {
        return &HDWallet{Public, w.Depth, w.Fingerprint, w.I, w.Chaincode, privToPub(w.Key)}
    }
}

// StringChild returns the ith base58-encoded extended key of a base58-encoded extended key.
func StringChild(data string ,i uint32) (string, error) {
    w, err := StringWallet(data)
    if err != nil {
        return "", err
    } else {
        w, err = w.Child(i)
        if err != nil {
            return "", err
        } else {
            return w.String(), nil
        }
    }
}

//StringToAddress returns the Bitcoin address of a base58-encoded extended key.
func StringAddress(data string) (string, error) {
    w, err := StringWallet(data)
    if err != nil {
        return "", err
    } else {
        return w.Address(), nil
    }
}

// Address returns bitcoin address represented by wallet w.
func (w *HDWallet) Address() string {
    x, y := expand(w.Key)
    four,_ := hex.DecodeString("04")
    padded_key := append(four,append(x.Bytes(),y.Bytes()...)...)
    zero,_ := hex.DecodeString("00")
    addr_1 := append(zero,hash160(padded_key)...)
    chksum := dblSha256(addr_1)
    return btcutil.Base58Encode(append(addr_1,chksum[:4]...))
}

// GenSeed returns a random seed with a length measured in bytes.
// The length must be at least 128.
func GenSeed(length int) ([]byte, error) {
    b := make([]byte, length)
    if length < 128 {
        return b, errors.New("length must be at least 128 bits")
    }
    _, err := rand.Read(b)
    return b, err
}

// MasterKey returns a new wallet given a random seed.
func MasterKey(seed []byte) *HDWallet {
    key := []byte("Bitcoin seed")
    mac := hmac.New(sha512.New, key)
    mac.Write(seed)
    I := mac.Sum(nil)
    secret := I[:len(I)/2]
    chain_code := I[len(I)/2:]
    depth := 0
    i := make([]byte, 4)
    fingerprint := make([]byte, 4)
    zero := make([]byte,1)
    return &HDWallet{Private,uint16(depth),fingerprint,i,chain_code,append(zero,secret...)}
}

// StringCheck is a validation check of a base58-encoded extended key.
func StringCheck(key string) error {
    return ByteCheck(btcutil.Base58Decode(key))
}

func ByteCheck(dbin []byte) error{
    // check proper length
    if len(dbin) != 82 {
        return errors.New("invalid string")
    }
    // check for correct Public or Private vbytes
    if bytes.Compare(dbin[:4],Public) != 0 && bytes.Compare(dbin[:4],Private) != 0 {
        return errors.New("invalid string")
    }
    // if Public, check x coord is on curve
    x, y := expand(dbin[45:78])
    if bytes.Compare(dbin[:4],Public) == 0 {
        if !onCurve(x,y) {
            return errors.New("invalid string")
        }
    }
    return nil
}
<commit_msg>added testnet support<commit_after>package hdwallet

import (
    "bytes"
    "crypto/hmac"
    "crypto/sha512"
    "crypto/rand"
    "encoding/hex"
    "errors"
    "github.com/conformal/btcutil"
    )

var (
    //MainNet
    Public []byte
    Private []byte
    //TestNet
    TestPublic []byte
    TestPrivate []byte
    )

func init() {
    Public,_ = hex.DecodeString("0488B21E")
    Private,_ = hex.DecodeString("0488ADE4")
    TestPublic,_ = hex.DecodeString("043587CF")
    TestPrivate,_ = hex.DecodeString("04358394")
}

// HDWallet defines the components of a hierarchical deterministic wallet
type HDWallet struct {
    Vbytes []byte //4 bytes
    Depth uint16 //1 byte
    Fingerprint []byte //4 bytes
    I []byte //4 bytes
    Chaincode []byte //32 bytes
    Key []byte //33 bytes
}

// Child returns the ith child of wallet w. Values of i >= 2^31
// signify private key derivation. Attempting private key derivation
// with a public key will throw an error.
func (w *HDWallet) Child(i uint32) (*HDWallet,error) {
    var fingerprint, I , newkey []byte
    switch {
    case bytes.Compare(w.Vbytes, Private) == 0, bytes.Compare(w.Vbytes, TestPrivate) == 0:
        pub := privToPub(w.Key)
        mac := hmac.New(sha512.New, w.Chaincode)
        if i >= uint32(0x80000000) {
            mac.Write(append(w.Key,uint32ToByte(i)...))
        } else {
            mac.Write(append(pub,uint32ToByte(i)...))
        }
        I = mac.Sum(nil)
        newkey = addPrivKeys(I[:32], w.Key)
        fingerprint = hash160(privToPub(w.Key))[:4]

    case bytes.Compare(w.Vbytes, Public) == 0, bytes.Compare(w.Vbytes, TestPrivate) == 0:
        mac := hmac.New(sha512.New, w.Chaincode)
        if i >= uint32(0x80000000) {
            return &HDWallet{}, errors.New("Can't do Private derivation on Public key!")
        }
        mac.Write(append(w.Key,uint32ToByte(i)...))
        I = mac.Sum(nil)
        newkey = addPubKeys(privToPub(I[:32]), w.Key)
        fingerprint = hash160(w.Key)[:4]
    }
    return &HDWallet{w.Vbytes, w.Depth + 1, fingerprint, uint32ToByte(i), I[32:], newkey}, nil
}

// Serialize returns the serialized form of the wallet.
func (w *HDWallet) Serialize() []byte  {
    depth := uint16ToByte(uint16(w.Depth % 256))
    //bindata = vbytes||depth||fingerprint||i||chaincode||key
    bindata := append(w.Vbytes,append(depth,append(w.Fingerprint,append(w.I,append(w.Chaincode,w.Key...)...)...)...)...)
    chksum := dblSha256(bindata)[:4]
    return append(bindata,chksum...)
}

// String returns the base58-encoded string form of the wallet.
func (w *HDWallet) String() string  {
    return btcutil.Base58Encode(w.Serialize())
}

// StringWallet returns a wallet given a base58-encoded extended key
func StringWallet(data string) (*HDWallet,error) {
    dbin := btcutil.Base58Decode(data)
    if err := ByteCheck(dbin); err != nil {
        return &HDWallet{}, err
    }
    if bytes.Compare(dblSha256(dbin[:(len(dbin)-4)])[:4], dbin[(len(dbin)-4):]) != 0 {
        return &HDWallet{}, errors.New("Invalid checksum")
    }
    vbytes := dbin[0:4]
    depth := byteToUint16(dbin[4:5])
    fingerprint := dbin[5:9]
    i := dbin[9:13]
    chaincode := dbin[13:45]
    key := dbin[45:78]
    return &HDWallet{vbytes, depth, fingerprint, i, chaincode, key}, nil
}

// Pub returns a new wallet which is the public key version of w.
// If w is a public key, Pub returns a copy of w
func (w *HDWallet) Pub() *HDWallet {
    if bytes.Compare(w.Vbytes,Public) == 0 {
        return &HDWallet{w.Vbytes, w.Depth, w.Fingerprint, w.I, w.Chaincode, w.Key}
    } else {
        return &HDWallet{Public, w.Depth, w.Fingerprint, w.I, w.Chaincode, privToPub(w.Key)}
    }
}

// StringChild returns the ith base58-encoded extended key of a base58-encoded extended key.
func StringChild(data string ,i uint32) (string, error) {
    w, err := StringWallet(data)
    if err != nil {
        return "", err
    } else {
        w, err = w.Child(i)
        if err != nil {
            return "", err
        } else {
            return w.String(), nil
        }
    }
}

//StringToAddress returns the Bitcoin address of a base58-encoded extended key.
func StringAddress(data string) (string, error) {
    w, err := StringWallet(data)
    if err != nil {
        return "", err
    } else {
        return w.Address(), nil
    }
}

// Address returns bitcoin address represented by wallet w.
func (w *HDWallet) Address() string {
    x, y := expand(w.Key)
    four,_ := hex.DecodeString("04")
    padded_key := append(four,append(x.Bytes(),y.Bytes()...)...)
    var prefix []byte
    if bytes.Compare(w.Vbytes,TestPublic) == 0 || bytes.Compare(w.Vbytes,TestPrivate) == 0 {
        prefix,_ = hex.DecodeString("6F")
    } else {
        prefix,_ = hex.DecodeString("00")
    }
    addr_1 := append(prefix,hash160(padded_key)...)
    chksum := dblSha256(addr_1)
    return btcutil.Base58Encode(append(addr_1,chksum[:4]...))
}

// GenSeed returns a random seed with a length measured in bytes.
// The length must be at least 128.
func GenSeed(length int) ([]byte, error) {
    b := make([]byte, length)
    if length < 128 {
        return b, errors.New("length must be at least 128 bits")
    }
    _, err := rand.Read(b)
    return b, err
}

// MasterKey returns a new wallet given a random seed.
func MasterKey(seed []byte) *HDWallet {
    key := []byte("Bitcoin seed")
    mac := hmac.New(sha512.New, key)
    mac.Write(seed)
    I := mac.Sum(nil)
    secret := I[:len(I)/2]
    chain_code := I[len(I)/2:]
    depth := 0
    i := make([]byte, 4)
    fingerprint := make([]byte, 4)
    zero := make([]byte,1)
    return &HDWallet{Private,uint16(depth),fingerprint,i,chain_code,append(zero,secret...)}
}

// StringCheck is a validation check of a base58-encoded extended key.
func StringCheck(key string) error {
    return ByteCheck(btcutil.Base58Decode(key))
}

func ByteCheck(dbin []byte) error{
    // check proper length
    if len(dbin) != 82 {
        return errors.New("invalid string")
    }
    // check for correct Public or Private vbytes
    if bytes.Compare(dbin[:4],Public) != 0 && bytes.Compare(dbin[:4],Private) != 0 && bytes.Compare(dbin[:4],TestPublic) != 0 && bytes.Compare(dbin[:4],TestPrivate) != 0 {
        return errors.New("invalid string")
    }
    // if Public, check x coord is on curve
    x, y := expand(dbin[45:78])
    if bytes.Compare(dbin[:4],Public) == 0 || bytes.Compare(dbin[:4],TestPublic) == 0 {
        if !onCurve(x,y) {
            return errors.New("invalid string")
        }
    }
    return nil
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/go-kit/kit/log"
	"github.com/go-kit/kit/log/level"
	"github.com/grpc-ecosystem/go-grpc-middleware"
	"github.com/grpc-ecosystem/go-grpc-middleware/recovery"
	"github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
	"github.com/grpc-ecosystem/go-grpc-prometheus"
	"google.golang.org/grpc"
	"google.golang.org/grpc/grpclog"
)

func createGrpcServer(appCtx *application) *grpc.Server {
	// TODO: separate log levels
	grpclog.SetLoggerV2(grpclog.NewLoggerV2(
		log.NewStdlibAdapter(level.Info(appCtx.logger)),
		log.NewStdlibAdapter(level.Warn(appCtx.logger)),
		log.NewStdlibAdapter(level.Error(appCtx.logger)),
	))

	server := grpc.NewServer(
		grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(
			grpc_opentracing.StreamServerInterceptor(grpc_opentracing.WithTracer(appCtx.tracer)),
			grpc_prometheus.StreamServerInterceptor,
			grpc_recovery.StreamServerInterceptor(),
		)),
		grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
			grpc_opentracing.UnaryServerInterceptor(grpc_opentracing.WithTracer(appCtx.tracer)),
			grpc_prometheus.UnaryServerInterceptor,
			grpc_recovery.UnaryServerInterceptor(),
		)),
	)

	return server
}
<commit_msg>Rename appCtx to app<commit_after>package main

import (
	"github.com/go-kit/kit/log"
	"github.com/go-kit/kit/log/level"
	"github.com/grpc-ecosystem/go-grpc-middleware"
	"github.com/grpc-ecosystem/go-grpc-middleware/recovery"
	"github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
	"github.com/grpc-ecosystem/go-grpc-prometheus"
	"google.golang.org/grpc"
	"google.golang.org/grpc/grpclog"
)

func createGrpcServer(app *application) *grpc.Server {
	// TODO: separate log levels
	grpclog.SetLoggerV2(grpclog.NewLoggerV2(
		log.NewStdlibAdapter(level.Info(app.logger)),
		log.NewStdlibAdapter(level.Warn(app.logger)),
		log.NewStdlibAdapter(level.Error(app.logger)),
	))

	server := grpc.NewServer(
		grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(
			grpc_opentracing.StreamServerInterceptor(grpc_opentracing.WithTracer(app.tracer)),
			grpc_prometheus.StreamServerInterceptor,
			grpc_recovery.StreamServerInterceptor(),
		)),
		grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
			grpc_opentracing.UnaryServerInterceptor(grpc_opentracing.WithTracer(app.tracer)),
			grpc_prometheus.UnaryServerInterceptor,
			grpc_recovery.UnaryServerInterceptor(),
		)),
	)

	return server
}
<|endoftext|>


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

package cmd

import (
	"fmt"

	"github.com/spf13/cobra"
)

// initCmd represents the init command
var initCmd = &cobra.Command{
	Use:   "init",
	Short: "A brief description of your command",
	Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
	Run: func(cmd *cobra.Command, args []string) {
		// TODO: Work your own magic here
		fmt.Println("init called")
	},
}

func init() {
	RootCmd.AddCommand(initCmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// initCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// initCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")

}
<commit_msg>Adds description to the init command<commit_after>// Copyright © 2016 Jip J. Dekker <jip@dekker.li>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
	"fmt"

	"github.com/spf13/cobra"
)

// initCmd represents the init command
var initCmd = &cobra.Command{
	Use:   "init [name]",
	Short: "Initialize a Ponder Library",
	Long: `Initialize (ponder init) will create a new library, with a ponder
	settings file and corresponding git ignore file.

  * If a name is provided, it will be created in the current directory;
  * If no name is provided, the current directory will be assumed;
Init will not use an existing directory with contents.`,
	Run: func(cmd *cobra.Command, args []string) {
		// TODO: Work your own magic here
		fmt.Println("init called")
	},
}

func init() {
	RootCmd.AddCommand(initCmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// initCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// initCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")

}
<|endoftext|>


<commit_before>package cmd

import (
	"fmt"
	"os"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var cfgFile string

// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
	Use:   "minima",
	Short: "A brief description of your application",
	Long: `A longer description that spans multiple lines and likely contains
examples and usage of using your application. For example:

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
// Uncomment the following line if your bare application
// has an action associated with it:
//	Run: func(cmd *cobra.Command, args []string) { },
}

// Execute adds all child commands to the root command sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
	if err := RootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}

func init() {
	cobra.OnInitialize(initConfig)

	// Here you will define your flags and configuration settings.
	// Cobra supports Persistent Flags, which, if defined here,
	// will be global for your application.

	RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.minima.yaml)")
	// Cobra also supports local flags, which will only run
	// when this action is called directly.
	RootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

// initConfig reads in config file and ENV variables if set.
func initConfig() {
	if cfgFile != "" { // enable ability to specify config file via flag
		viper.SetConfigFile(cfgFile)
	}

	viper.SetConfigName(".minima") // name of config file (without extension)
	viper.AddConfigPath("$HOME")  // adding home directory as first search path
	viper.AutomaticEnv()          // read in environment variables that match

	// If a config file is found, read it in.
	if err := viper.ReadInConfig(); err == nil {
		fmt.Println("Using config file:", viper.ConfigFileUsed())
	}
}
<commit_msg>Add proper descriptions<commit_after>package cmd

import (
	"fmt"
	"os"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var cfgFile string

// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
	Use:   "minima",
	Short: "A Simple Linux Repository Manager",
	Long: "minima is an application to mirror and manage Linux package repos.",
}

// Execute adds all child commands to the root command sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
	if err := RootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}

func init() {
	cobra.OnInitialize(initConfig)

	// Here you will define your flags and configuration settings.
	// Cobra supports Persistent Flags, which, if defined here,
	// will be global for your application.

	RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.minima.yaml)")
	// Cobra also supports local flags, which will only run
	// when this action is called directly.
	RootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

// initConfig reads in config file and ENV variables if set.
func initConfig() {
	if cfgFile != "" { // enable ability to specify config file via flag
		viper.SetConfigFile(cfgFile)
	}

	viper.SetConfigName(".minima") // name of config file (without extension)
	viper.AddConfigPath("$HOME")  // adding home directory as first search path
	viper.AutomaticEnv()          // read in environment variables that match

	// If a config file is found, read it in.
	if err := viper.ReadInConfig(); err == nil {
		fmt.Println("Using config file:", viper.ConfigFileUsed())
	}
}
<|endoftext|>


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

package goversion

// Version is the current Go 1.x version. During development cycles on
// the master branch it changes to be the version of the next Go 1.x
// release.
//
// When incrementing this, also add to the list at src/go/build/doc.go
// (search for "onward").
const Version = 15
<commit_msg>internal/goversion: update Version to 1.16<commit_after>// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package goversion

// Version is the Go 1.x version which is currently
// in development and will eventually get released.
//
// It should be updated at the start of each development cycle to be
// the version of the next Go 1.x release. See golang.org/issue/40705.
const Version = 16
<|endoftext|>