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

// +build ignore

package main

import (
	"math"
	"testing"

	"gosl/chk"
	"gosl/io"
	"gosl/la"
	"gosl/mpi"
	"gosl/ode"
)

func main() {

	// start mpi
	mpi.Start()
	defer mpi.Stop()

	// check number of processors
	if mpi.WorldRank() == 0 {
		chk.Verbose = true
		chk.PrintTitle("Hairer-Wanner VII-p376 Transistor Amplifier")
	}
	if mpi.WorldSize() != 3 {
		if mpi.WorldRank() == 0 {
			io.Pf("ERROR: this test needs 3 processors (run with mpi -np 3)\n")
		}
		return
	}

	// communicator
	comm := mpi.NewCommunicator(nil)

	// constants
	ue, ub, uf, α, β := 0.1, 6.0, 0.026, 0.99, 1.0e-6
	r0, r1, r2, r3, r4, r5 := 1000.0, 9000.0, 9000.0, 9000.0, 9000.0, 9000.0
	r6, r7, r8, r9 := 9000.0, 9000.0, 9000.0, 9000.0
	w := 2.0 * 3.141592654 * 100.0
	xf := 0.05

	// initial values
	y := la.NewVectorSlice([]float64{0.0,
		ub,
		ub / (r6/r5 + 1.0),
		ub / (r6/r5 + 1.0),
		ub,
		ub / (r2/r1 + 1.0),
		ub / (r2/r1 + 1.0),
		0.0,
	})
	ndim := len(y)

	// right-hand side of the amplifier problem
	fcn := func(f la.Vector, dx, x float64, y la.Vector) {
		uet := ue * math.Sin(w*x)
		fac1 := β * (math.Exp((y[3]-y[2])/uf) - 1.0)
		fac2 := β * (math.Exp((y[6]-y[5])/uf) - 1.0)
		f[0] = y[0] / r9
		f[1] = (y[1]-ub)/r8 + α*fac1
		f[2] = y[2]/r7 - fac1
		f[3] = y[3]/r5 + (y[3]-ub)/r6 + (1.0-α)*fac1
		f[4] = (y[4]-ub)/r4 + α*fac2
		f[5] = y[5]/r3 - fac2
		f[6] = y[6]/r1 + (y[6]-ub)/r2 + (1.0-α)*fac2
		f[7] = (y[7] - uet) / r0
	}

	// Jacobian of the amplifier problem
	jac := func(dfdy *la.Triplet, dx, x float64, y la.Vector) {
		fac14 := β * math.Exp((y[3]-y[2])/uf) / uf
		fac27 := β * math.Exp((y[6]-y[5])/uf) / uf
		if dfdy.Max() == 0 {
			dfdy.Init(8, 8, 16)
		}
		nu := 2
		dfdy.Start()
		switch comm.Rank() {
		case 0:
			dfdy.Put(2+0-nu, 0, 1.0/r9)
			dfdy.Put(2+1-nu, 1, 1.0/r8)
			dfdy.Put(1+2-nu, 2, -α*fac14)
			dfdy.Put(0+3-nu, 3, α*fac14)
			dfdy.Put(2+2-nu, 2, 1.0/r7+fac14)
		case 1:
			dfdy.Put(1+3-nu, 3, -fac14)
			dfdy.Put(2+3-nu, 3, 1.0/r5+1.0/r6+(1.0-α)*fac14)
			dfdy.Put(3+2-nu, 2, -(1.0-α)*fac14)
			dfdy.Put(2+4-nu, 4, 1.0/r4)
			dfdy.Put(1+5-nu, 5, -α*fac27)
		case 2:
			dfdy.Put(0+6-nu, 6, α*fac27)
			dfdy.Put(2+5-nu, 5, 1.0/r3+fac27)
			dfdy.Put(1+6-nu, 6, -fac27)
			dfdy.Put(2+6-nu, 6, 1.0/r1+1.0/r2+(1.0-α)*fac27)
			dfdy.Put(3+5-nu, 5, -(1.0-α)*fac27)
			dfdy.Put(2+7-nu, 7, 1.0/r0)
		}
	}

	// "mass" matrix
	c1, c2, c3, c4, c5 := 1.0e-6, 2.0e-6, 3.0e-6, 4.0e-6, 5.0e-6
	M := new(la.Triplet)
	M.Init(8, 8, 14)
	M.Start()
	nu := 1
	switch comm.Rank() {
	case 0:
		M.Put(1+0-nu, 0, -c5)
		M.Put(0+1-nu, 1, c5)
		M.Put(2+0-nu, 0, c5)
		M.Put(1+1-nu, 1, -c5)
		M.Put(1+2-nu, 2, -c4)
		M.Put(1+3-nu, 3, -c3)
	case 1:
		M.Put(0+4-nu, 4, c3)
		M.Put(2+3-nu, 3, c3)
		M.Put(1+4-nu, 4, -c3)
	case 2:
		M.Put(1+5-nu, 5, -c2)
		M.Put(1+6-nu, 6, -c1)
		M.Put(0+7-nu, 7, c1)
		M.Put(2+6-nu, 6, c1)
		M.Put(1+7-nu, 7, -c1)
	}

	// configurations
	conf := ode.NewConfig("radau5", "mumps", comm)
	conf.SetStepOut(true, nil)
	conf.IniH = 1.0e-6 // initial step size

	// set tolerances
	atol, rtol := 1e-11, 1e-5
	conf.SetTols(atol, rtol)

	// ODE solver
	sol := ode.NewSolver(ndim, conf, fcn, jac, M)
	defer sol.Free()

	// run
	sol.Solve(y, 0.0, xf)

	// only root
	if mpi.WorldRank() == 0 {

		// check
		tst := new(testing.T)
		chk.Int(tst, "number of F evaluations ", sol.Stat.Nfeval, 2655)
		chk.Int(tst, "number of J evaluations ", sol.Stat.Njeval, 217)
		chk.Int(tst, "total number of steps   ", sol.Stat.Nsteps, 282)
		chk.Int(tst, "number of accepted steps", sol.Stat.Naccepted, 221)
		chk.Int(tst, "number of rejected steps", sol.Stat.Nrejected, 23)
		chk.Int(tst, "number of decompositions", sol.Stat.Ndecomp, 281)
		chk.Int(tst, "number of lin solutions ", sol.Stat.Nlinsol, 809)
		chk.Int(tst, "max number of iterations", sol.Stat.Nitmax, 6)
	}
}
<commit_msg>Update stats for ODE amplifier tests (they are better)<commit_after>// Copyright 2016 The Gosl Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build ignore

package main

import (
	"math"
	"testing"

	"gosl/chk"
	"gosl/io"
	"gosl/la"
	"gosl/mpi"
	"gosl/ode"
)

func main() {

	// start mpi
	mpi.Start()
	defer mpi.Stop()

	// check number of processors
	if mpi.WorldRank() == 0 {
		chk.Verbose = true
		chk.PrintTitle("Hairer-Wanner VII-p376 Transistor Amplifier")
	}
	if mpi.WorldSize() != 3 {
		if mpi.WorldRank() == 0 {
			io.Pf("ERROR: this test needs 3 processors (run with mpi -np 3)\n")
		}
		return
	}

	// communicator
	comm := mpi.NewCommunicator(nil)

	// constants
	ue, ub, uf, α, β := 0.1, 6.0, 0.026, 0.99, 1.0e-6
	r0, r1, r2, r3, r4, r5 := 1000.0, 9000.0, 9000.0, 9000.0, 9000.0, 9000.0
	r6, r7, r8, r9 := 9000.0, 9000.0, 9000.0, 9000.0
	w := 2.0 * 3.141592654 * 100.0
	xf := 0.05

	// initial values
	y := la.NewVectorSlice([]float64{0.0,
		ub,
		ub / (r6/r5 + 1.0),
		ub / (r6/r5 + 1.0),
		ub,
		ub / (r2/r1 + 1.0),
		ub / (r2/r1 + 1.0),
		0.0,
	})
	ndim := len(y)

	// right-hand side of the amplifier problem
	fcn := func(f la.Vector, dx, x float64, y la.Vector) {
		uet := ue * math.Sin(w*x)
		fac1 := β * (math.Exp((y[3]-y[2])/uf) - 1.0)
		fac2 := β * (math.Exp((y[6]-y[5])/uf) - 1.0)
		f[0] = y[0] / r9
		f[1] = (y[1]-ub)/r8 + α*fac1
		f[2] = y[2]/r7 - fac1
		f[3] = y[3]/r5 + (y[3]-ub)/r6 + (1.0-α)*fac1
		f[4] = (y[4]-ub)/r4 + α*fac2
		f[5] = y[5]/r3 - fac2
		f[6] = y[6]/r1 + (y[6]-ub)/r2 + (1.0-α)*fac2
		f[7] = (y[7] - uet) / r0
	}

	// Jacobian of the amplifier problem
	jac := func(dfdy *la.Triplet, dx, x float64, y la.Vector) {
		fac14 := β * math.Exp((y[3]-y[2])/uf) / uf
		fac27 := β * math.Exp((y[6]-y[5])/uf) / uf
		if dfdy.Max() == 0 {
			dfdy.Init(8, 8, 16)
		}
		nu := 2
		dfdy.Start()
		switch comm.Rank() {
		case 0:
			dfdy.Put(2+0-nu, 0, 1.0/r9)
			dfdy.Put(2+1-nu, 1, 1.0/r8)
			dfdy.Put(1+2-nu, 2, -α*fac14)
			dfdy.Put(0+3-nu, 3, α*fac14)
			dfdy.Put(2+2-nu, 2, 1.0/r7+fac14)
		case 1:
			dfdy.Put(1+3-nu, 3, -fac14)
			dfdy.Put(2+3-nu, 3, 1.0/r5+1.0/r6+(1.0-α)*fac14)
			dfdy.Put(3+2-nu, 2, -(1.0-α)*fac14)
			dfdy.Put(2+4-nu, 4, 1.0/r4)
			dfdy.Put(1+5-nu, 5, -α*fac27)
		case 2:
			dfdy.Put(0+6-nu, 6, α*fac27)
			dfdy.Put(2+5-nu, 5, 1.0/r3+fac27)
			dfdy.Put(1+6-nu, 6, -fac27)
			dfdy.Put(2+6-nu, 6, 1.0/r1+1.0/r2+(1.0-α)*fac27)
			dfdy.Put(3+5-nu, 5, -(1.0-α)*fac27)
			dfdy.Put(2+7-nu, 7, 1.0/r0)
		}
	}

	// "mass" matrix
	c1, c2, c3, c4, c5 := 1.0e-6, 2.0e-6, 3.0e-6, 4.0e-6, 5.0e-6
	M := new(la.Triplet)
	M.Init(8, 8, 14)
	M.Start()
	nu := 1
	switch comm.Rank() {
	case 0:
		M.Put(1+0-nu, 0, -c5)
		M.Put(0+1-nu, 1, c5)
		M.Put(2+0-nu, 0, c5)
		M.Put(1+1-nu, 1, -c5)
		M.Put(1+2-nu, 2, -c4)
		M.Put(1+3-nu, 3, -c3)
	case 1:
		M.Put(0+4-nu, 4, c3)
		M.Put(2+3-nu, 3, c3)
		M.Put(1+4-nu, 4, -c3)
	case 2:
		M.Put(1+5-nu, 5, -c2)
		M.Put(1+6-nu, 6, -c1)
		M.Put(0+7-nu, 7, c1)
		M.Put(2+6-nu, 6, c1)
		M.Put(1+7-nu, 7, -c1)
	}

	// configurations
	conf := ode.NewConfig("radau5", "mumps", comm)
	conf.SetStepOut(true, nil)
	conf.IniH = 1.0e-6 // initial step size

	// set tolerances
	atol, rtol := 1e-11, 1e-5
	conf.SetTols(atol, rtol)

	// ODE solver
	sol := ode.NewSolver(ndim, conf, fcn, jac, M)
	defer sol.Free()

	// run
	sol.Solve(y, 0.0, xf)

	// only root
	if mpi.WorldRank() == 0 {

		// check
		tst := new(testing.T)
		chk.Int(tst, "number of F evaluations ", sol.Stat.Nfeval, 2559)
		chk.Int(tst, "number of J evaluations ", sol.Stat.Njeval, 212)
		chk.Int(tst, "total number of steps   ", sol.Stat.Nsteps, 266)
		chk.Int(tst, "number of accepted steps", sol.Stat.Naccepted, 217)
		chk.Int(tst, "number of rejected steps", sol.Stat.Nrejected, 23)
		chk.Int(tst, "number of decompositions", sol.Stat.Ndecomp, 265)
		chk.Int(tst, "number of lin solutions ", sol.Stat.Nlinsol, 780)
		chk.Int(tst, "max number of iterations", sol.Stat.Nitmax, 6)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/kelseyhightower/envconfig"
	"log"
)

type Config struct {
	Port int `default:"3000"`
}

var config Config

func init() {
	err := envconfig.Process("slack_exact", &config)
	if err != nil {
		log.Fatal(err.Error())
	}
}
<commit_msg>Defined some more settings<commit_after>package main

import (
	"github.com/kelseyhightower/envconfig"
	"log"
)

type configSpecification struct {
	// Port
	Port int `default:"3000"`
	// URL of the Slack Webhook
	WebhookURL string `envconfig:"webhook_url"`
	// Token for incoming Slack requests
	IncomingToken string `envconfig:"incoming_token"`
	// Username for bot replies
	BotUsername string `envconfig:"bot_username" default:"Exact Online"`
	// Base URL of Slack Exact
	BaseURL string `envconfig:"base_url" default:"http://slackexact.greymug.io/"`
	// Exact app key
	AppKey string `envconfig:"app_key"`
	// Exact client ID
	ClientID string `envconfig:"client_id"`
	// Exact client secret
	ClientSecret string `envconfig:"client_secret"`
}

var config configSpecification

func init() {
	err := envconfig.Process("slack_exact", &config)
	if err != nil {
		log.Fatal(err.Error())
	}
}
<|endoftext|>


<commit_before>package dulbecco

import (
	"encoding/json"
	"errors"
	"github.com/BurntSushi/toml"
	"io/ioutil"
	"math/rand"
	"path/filepath"
	"strings"
)

var defaultReplies []string

type Configuration struct {
	Servers []ServerConfiguration
	Plugins []PluginConfiguration
	Replies []string
	Hipchat HipchatConfiguration
}

type ServerConfiguration struct {
	Name           string
	Address        string
	Ssl            bool
	SslInsecure    bool   `json:"ssl_insecure" toml:"ssl_insecure"`
	SslCertificate string `json:"ssl_certificate" toml:"ssl_certificate"`
	Channels       []string
	Nickname       string
	Altnicknames   []string
	Username       string
	Realname       string
	Password       string
	Nickserv       string
	Debug          bool
}

func (sc *ServerConfiguration) GetHostname() string {
	if colon := strings.Index(sc.Address, ":"); colon > 0 {
		return sc.Address[0:colon]
	}
	return sc.Address
}

type PluginConfiguration struct {
	Name    string
	Command string
	Trigger string
}

type HipchatConfiguration struct {
	Address string
}

func ReadConfig(filename string) (*Configuration, error) {
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}

	var config *Configuration
	if filepath.Ext(filename) == ".json" {
		config, err = readJsonConfig(data)
	} else {
		config, err = readTomlConfig(data)
	}
	if err != nil {
		return nil, err
	}

	if len(config.Servers) < 1 {
		return nil, errors.New("no servers defined")
	}

	defaultReplies = append(defaultReplies, config.Replies...)

	return config, nil
}

func readJsonConfig(data []byte) (*Configuration, error) {
	var config Configuration
	if err := json.Unmarshal(data, &config); err != nil {
		return nil, err
	}
	return &config, nil
}

func readTomlConfig(data []byte) (*Configuration, error) {
	var config Configuration
	if _, err := toml.Decode(string(data), &config); err != nil {
		return nil, err
	}
	return &config, nil
}

func GetRandomReply() string {
	if len(defaultReplies) > 0 {
		return defaultReplies[rand.Intn(len(defaultReplies))]
	}
	return "DEMENZA MI COLSE"
}
<commit_msg>fix toml configuration<commit_after>package dulbecco

import (
	"encoding/json"
	"errors"
	"github.com/BurntSushi/toml"
	"io/ioutil"
	"math/rand"
	"path/filepath"
	"strings"
)

var defaultReplies []string

type Configuration struct {
	Servers []ServerConfiguration `toml:"server"`
	Plugins []PluginConfiguration
	Replies []string
	Hipchat HipchatConfiguration
}

type ServerConfiguration struct {
	Name           string
	Address        string
	Ssl            bool
	SslInsecure    bool   `json:"ssl_insecure" toml:"ssl_insecure"`
	SslCertificate string `json:"ssl_certificate" toml:"ssl_certificate"`
	Channels       []string
	Nickname       string
	Altnicknames   []string
	Username       string
	Realname       string
	Password       string
	Nickserv       string
	Debug          bool
}

func (sc *ServerConfiguration) GetHostname() string {
	if colon := strings.Index(sc.Address, ":"); colon > 0 {
		return sc.Address[0:colon]
	}
	return sc.Address
}

type PluginConfiguration struct {
	Name    string
	Command string
	Trigger string
}

type HipchatConfiguration struct {
	Address string
}

func ReadConfig(filename string) (*Configuration, error) {
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}

	var config *Configuration
	if filepath.Ext(filename) == ".json" {
		config, err = readJsonConfig(data)
	} else {
		config, err = readTomlConfig(data)
	}
	if err != nil {
		return nil, err
	}

	if len(config.Servers) < 1 {
		return nil, errors.New("no servers defined")
	}

	defaultReplies = append(defaultReplies, config.Replies...)

	return config, nil
}

func readJsonConfig(data []byte) (*Configuration, error) {
	var config Configuration
	if err := json.Unmarshal(data, &config); err != nil {
		return nil, err
	}
	return &config, nil
}

func readTomlConfig(data []byte) (*Configuration, error) {
	var config Configuration
	if _, err := toml.Decode(string(data), &config); err != nil {
		return nil, err
	}
	return &config, nil
}

func GetRandomReply() string {
	if len(defaultReplies) > 0 {
		return defaultReplies[rand.Intn(len(defaultReplies))]
	}
	return "DEMENZA MI COLSE"
}
<|endoftext|>


<commit_before>package config

import (
	"errors"
	"fmt"
	"os"
)

type Provider interface {
	SetRawString(raw string)
	SetRawBytes(raw []byte)
	Get(data interface{}) error
	Set(data interface{}) (int, error)
}

var (
	Prefix   string
	filepath string
	provider Provider
)

func New(file, format string) (provider Provider, err error) {

	// set config file full path
	filepath = Prefix + file
	fp, fperr := os.Open(filepath)
	if os.IsNotExist(fperr) {
		fperr = nil
		filepath = Prefix + "/etc/" + file
		fp, fperr = os.Open(filepath)
	}

	if fperr != nil {
		return nil, fperr
	}

	// read config file raw data.
	fstat, _ := fp.Stat()
	raw := make([]byte, fstat.Size())
	fp.Read(raw)

	switch format {
	case "json":
		provider = &JSON{}
		provider.SetRawBytes(raw)

	case "xml":
		provider = &XML{}
		provider.SetRawBytes(raw)

	default:
		return nil, errors.New("Not support this format config file.")
	}
	return
}

// init default provider
func defaultProvider() {
	var derr error
	Prefix = "./"
	provider, derr = New("main.json", "json")
	if derr != nil {
		fmt.Printf("[config package]get default config error,details: %v\n", derr)
		os.Exit(1)
	}
}

func Get(data interface{}) error {
	defaultProvider()
	return provider.Get(data)
}

func Set(data interface{}) (int, error) {
	defaultProvider()
	return provider.Set(data)
}
<commit_msg>if not exist create config file when create new provider.<commit_after>package config

import (
	"errors"
	"fmt"
	"os"
)

type Provider interface {
	SetRawString(raw string)
	SetRawBytes(raw []byte)
	Get(data interface{}) error
	Set(data interface{}) (int, error)
}

var (
	Prefix   string
	filepath string
	provider Provider
)

func New(file, format string) (provider Provider, err error) {

	// set config file full path
	filepath = Prefix + file
	fp, fperr := os.OpenFile(filepath, os.O_RDONLY|os.O_CREATE, os.ModePerm)
	if os.IsNotExist(fperr) {
		fperr = nil
		filepath = Prefix + "/etc/" + file
		fp, fperr = os.Open(filepath)
	}

	if fperr != nil {
		return nil, fperr
	}

	// read config file raw data.
	fstat, _ := fp.Stat()
	raw := make([]byte, fstat.Size())
	fp.Read(raw)

	switch format {
	case "json":
		provider = &JSON{}
		provider.SetRawBytes(raw)

	case "xml":
		provider = &XML{}
		provider.SetRawBytes(raw)

	default:
		return nil, errors.New("Not support this format config file.")
	}
	return
}

// init default provider
func defaultProvider() {
	var derr error
	Prefix = "./"
	provider, derr = New("main.json", "json")
	if derr != nil {
		fmt.Printf("[config package]get default config error,details: %v\n", derr)
		os.Exit(1)
	}
}

func Get(data interface{}) error {
	defaultProvider()
	return provider.Get(data)
}

func Set(data interface{}) (int, error) {
	defaultProvider()
	return provider.Set(data)
}
<|endoftext|>


<commit_before>package bitutils

import (
	"fmt"
	"math/rand"
	"os"
	"strconv"
	"strings"
	"testing"
	"time"
)

var r *rand.Rand
var w Word
var ws string

func reverse(s string) string {
	runes := []rune(s)
	for i, j := 0, len(runes)-1; i < len(runes)/2; i, j = i+1, j-1 {
		runes[i], runes[j] = runes[j], runes[i]
	}
	return string(runes)
}

func testCase() (w Word, ws string) {
	r = rand.New(rand.NewSource(time.Now().UnixNano()))
	w = Word(r.Uint32()) | Word(r.Uint32())<<32
	ws = fmt.Sprintf("%064b", w)
	return
}

func TestMain(m *testing.M) {
	w, ws = testCase()
	os.Exit(m.Run())
}

func TestCount1(t *testing.T) {
	got := w.Count1()
	want := strings.Count(ws, "1")
	if got != want {
		t.Errorf("got %d, want %d for %s", got, want, ws)
	}
}

func TestCount0(t *testing.T) {
	want := w.Count0()
	got := strings.Count(ws, "0")
	if got != want {
		t.Errorf("got %d, want %d for %s", got, want, ws)
	}
}

func TestCount(t *testing.T) {
	for i := 0; i < 2; i++ {
		want := w.Count(i)
		got := strings.Count(ws, strconv.Itoa(i))
		if got != want {
			t.Errorf("got %d, want %d for %s", got, want, ws)
		}
	}
}

func TestGet(t *testing.T) {
	for i := 0; i < W; i++ {
		j := W - i - 1 // corresponding index in ws.

		n, err := strconv.ParseUint(ws[j:j+1], 10, 0)
		if err != nil {
			t.Errorf("ParseUint failed")
		}

		got := w.Get(i)
		want := Word(n)
		if got != want {
			t.Errorf("got %d, want %d for %s", got, want, ws)
		}
	}
}

func TestSet1(t *testing.T) {
	for i := 0; i < W; i++ {
		v := w.Set1(i)
		for j := 0; j < W; j++ {
			got := v.Get(j)
			want := w.Get(j)
			if i == j {
				want = 1
			}
			if got != want {
				t.Errorf("got %d, want %d", got, want)
			}
		}
	}
}

func TestSet0(t *testing.T) {
	for i := 0; i < W; i++ {
		v := w.Set0(i)
		for j := 0; j < W; j++ {
			got := v.Get(j)
			want := w.Get(j)
			if i == j {
				want = 0
			}
			if got != want {
				t.Errorf("got %d, want %d", got, want)
			}
		}
	}
}

func TestFlip(t *testing.T) {
	for i := 0; i < W; i++ {
		v := w.Flip(i)
		for j := 0; j < W; j++ {
			got := v.Get(j)
			want := w.Get(j)
			if i == j {
				if want == 1 {
					want = 0
				} else {
					want = 1
				}
			}
			if got != want {
				t.Errorf("got %d, want %d", got, want)
			}
		}
	}
}

func TestLsb(t *testing.T) {
	got := w.Lsb()
	want := strings.Index(reverse(ws), "1")
	if got != want {
		t.Errorf("got %d, want %d for %s", got, want, ws)
	}
}

func TestRank1(t *testing.T) {
	for i := 0; i < W; i++ {
		got := w.Rank1(i)
		want := strings.Count(ws[len(ws)-i-1:len(ws)], "1")
		if got != want {
			t.Errorf("got %d, want %d", got, want)
		}
	}
}

func TestRank0(t *testing.T) {
	for i := 0; i < W; i++ {
		got := w.Rank0(i)
		want := strings.Count(ws[len(ws)-i-1:len(ws)], "0")
		if got != want {
			t.Errorf("got %d, want %d", got, want)
		}
	}
}

func BenchmarkCount1(b *testing.B) {
	for i := 0; i < b.N; i++ {
		w := Word(i)
		_ = w.Count1()
	}
}

func BenchmarkCount0(b *testing.B) {
	for i := 0; i < b.N; i++ {
		w := Word(i)
		_ = w.Count0()
	}
}

func BenchmarkCount(b *testing.B) {
	for i := 0; i < b.N; i++ {
		w := Word(i)
		_ = w.Count(1)
	}
}

func BenchmarkGet(b *testing.B) {
	for i := 0; i < b.N; i++ {
		w := Word(i)
		_ = w.Get(i % W)
	}
}

func BenchmarkSet1(b *testing.B) {
	for i := 0; i < b.N; i++ {
		w := Word(i)
		_ = w.Set1(i % W)
	}
}

func BenchmarkSet0(b *testing.B) {
	for i := 0; i < b.N; i++ {
		w := Word(i)
		_ = w.Set0(i % W)
	}
}

func BenchmarkFlip(b *testing.B) {
	for i := 0; i < b.N; i++ {
		w := Word(i)
		_ = w.Flip(i % W)
	}
}

func BenchmarkLsb(b *testing.B) {
	for i := 0; i < b.N; i++ {
		w := Word(i)
		_ = w.Lsb()
	}
}

func BenchmarkRank1(b *testing.B) {
	for i := 0; i < b.N; i++ {
		w := Word(i)
		_ = w.Rank1(i % W)
	}
}

func BenchmarkRank0(b *testing.B) {
	for i := 0; i < b.N; i++ {
		w := Word(i)
		_ = w.Rank0(i % W)
	}
}
<commit_msg>Refactor test code<commit_after>package bitutils

import (
	"fmt"
	"math/rand"
	"os"
	"strconv"
	"strings"
	"testing"
	"time"
)

var r *rand.Rand
var w Word
var ws, wsR string

func reverse(s string) string {
	runes := []rune(s)
	for i, j := 0, len(runes)-1; i < len(runes)/2; i, j = i+1, j-1 {
		runes[i], runes[j] = runes[j], runes[i]
	}
	return string(runes)
}

func testCase() (w Word, ws string) {
	r = rand.New(rand.NewSource(time.Now().UnixNano()))
	w = Word(r.Uint32()) | Word(r.Uint32())<<32
	ws = fmt.Sprintf("%064b", w)
	wsR = reverse(ws)
	return
}

func TestMain(m *testing.M) {
	w, ws = testCase()
	os.Exit(m.Run())
}

func TestCount1(t *testing.T) {
	got, want := w.Count1(), strings.Count(ws, "1")
	if got != want {
		t.Errorf("got %d, want %d", got, want)
	}
}

func TestCount0(t *testing.T) {
	got, want := w.Count0(), strings.Count(ws, "0")
	if got != want {
		t.Errorf("got %d, want %d", got, want)
	}
}

func TestCount(t *testing.T) {
	for i := 0; i < 2; i++ {
		got, want := w.Count(i), strings.Count(ws, strconv.Itoa(i))
		if got != want {
			t.Errorf("got %d, want %d", got, want)
		}
	}
}

func TestGet(t *testing.T) {
	for i := 0; i < W; i++ {
		n, err := strconv.ParseUint(wsR[i:i+1], 10, 0)
		if err != nil {
			t.Errorf("ParseUint failed")
		}
		got, want := w.Get(i), Word(n)
		if got != want {
			t.Errorf("got %d, want %d", got, want)
		}
	}
}

func TestSet1(t *testing.T) {
	for i := 0; i < W; i++ {
		v := w.Set1(i)
		for j := 0; j < W; j++ {
			got, want := v.Get(j), w.Get(j)
			if i == j {
				want = 1
			}
			if got != want {
				t.Errorf("got %d, want %d", got, want)
			}
		}
	}
}

func TestSet0(t *testing.T) {
	for i := 0; i < W; i++ {
		v := w.Set0(i)
		for j := 0; j < W; j++ {
			got, want := v.Get(j), w.Get(j)
			if i == j {
				want = 0
			}
			if got != want {
				t.Errorf("got %d, want %d", got, want)
			}
		}
	}
}

func TestFlip(t *testing.T) {
	for i := 0; i < W; i++ {
		v := w.Flip(i)
		for j := 0; j < W; j++ {
			got, want := v.Get(j), w.Get(j)
			if i == j {
				if want == 1 {
					want = 0
				} else {
					want = 1
				}
			}
			if got != want {
				t.Errorf("got %d, want %d", got, want)
			}
		}
	}
}

func TestLsb(t *testing.T) {
	got, want := w.Lsb(), strings.Index(wsR, "1")
	if got != want {
		t.Errorf("got %d, want %d", got, want)
	}
}

func TestRank1(t *testing.T) {
	for i := 0; i < W; i++ {
		got, want := w.Rank1(i), strings.Count(wsR[0:i+1], "1")
		if got != want {
			t.Errorf("got %d, want %d", got, want)
		}
	}
}

func TestRank0(t *testing.T) {
	for i := 0; i < W; i++ {
		got, want := w.Rank0(i), strings.Count(wsR[0:i+1], "0")
		if got != want {
			t.Errorf("got %d, want %d", got, want)
		}
	}
}

func BenchmarkCount1(b *testing.B) {
	for i := 0; i < b.N; i++ {
		w := Word(i)
		_ = w.Count1()
	}
}

func BenchmarkCount0(b *testing.B) {
	for i := 0; i < b.N; i++ {
		w := Word(i)
		_ = w.Count0()
	}
}

func BenchmarkCount(b *testing.B) {
	for i := 0; i < b.N; i++ {
		w := Word(i)
		_ = w.Count(1)
	}
}

func BenchmarkGet(b *testing.B) {
	for i := 0; i < b.N; i++ {
		w := Word(i)
		_ = w.Get(i % W)
	}
}

func BenchmarkSet1(b *testing.B) {
	for i := 0; i < b.N; i++ {
		w := Word(i)
		_ = w.Set1(i % W)
	}
}

func BenchmarkSet0(b *testing.B) {
	for i := 0; i < b.N; i++ {
		w := Word(i)
		_ = w.Set0(i % W)
	}
}

func BenchmarkFlip(b *testing.B) {
	for i := 0; i < b.N; i++ {
		w := Word(i)
		_ = w.Flip(i % W)
	}
}

func BenchmarkLsb(b *testing.B) {
	for i := 0; i < b.N; i++ {
		w := Word(i)
		_ = w.Lsb()
	}
}

func BenchmarkRank1(b *testing.B) {
	for i := 0; i < b.N; i++ {
		w := Word(i)
		_ = w.Rank1(i % W)
	}
}

func BenchmarkRank0(b *testing.B) {
	for i := 0; i < b.N; i++ {
		w := Word(i)
		_ = w.Rank0(i % W)
	}
}
<|endoftext|>


<commit_before>// Package config version v1.0.0
package config

import (
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"os/user"
	"path/filepath"
	"reflect"
	"strings"

	"gopkg.in/yaml.v2"
)

// Namespace holds the pieces joined together to form the
// directory namespacing for config.
type Namespace struct {
	Organization string // optional additional namespace for orgs.
	System       string // Name of the system associated with this config.
}

// The Config interface implements config.
type Config interface {
	Load(src string, dst interface{}) error
}

// UserBase and SystemBase are the prefixes for the user and system config
// paths, respectively.
const (
	UserBase   string = "~/.config/"
	SystemBase string = "/etc/"
)

// Load expands the provided src path using config.ExpandUser, then reads
// the file and unmarshals into dst using go-yaml.
func Load(src string, dst interface{}) (err error) {
	dstv := reflect.ValueOf(dst)

	if dstv.Kind() != reflect.Ptr {
		err = errors.New("config: not a pointer")
	}
	if err != nil {
		return
	}

	path := ExpandUser(src)

	data, err := ioutil.ReadFile(path)
	if err != nil {
		return
	}

	err = yaml.Unmarshal(data, dst)
	return
}

// ExpandUser acts kind of like os.path.expanduser in Python, except only
// supports expanding "~/" or "$HOME"
func ExpandUser(path string) (exPath string) {
	usr, _ := user.Current()

	dir := fmt.Sprintf("%s/", usr.HomeDir)

	exPath = path
	if len(path) > 2 && path[:2] == "~/" {
		exPath = strings.Replace(exPath, "~/", dir, 1)
	} else if len(path) > 5 && path[:5] == "$HOME" {
		exPath = strings.Replace(exPath, "$HOME", dir, 1)
	}

	exPath, _ = filepath.Abs(filepath.Clean(exPath))
	return
}

// Path returns path to config, chosen by hierarchy and checked for
// existence:
//
// 1. User config (~/.config/podhub/canary/config.yaml)
//
// 2. System config (/etc/podhub/canary/config.yaml)
func (c Namespace) Path() (path string) {
	systemPath, _ := c.systemPath()
	if _, err := os.Stat(systemPath); err == nil {
		path, _ = c.systemPath()
	}

	userPath, _ := c.userPath()
	if _, err := os.Stat(userPath); err == nil {
		path, _ = c.userPath()
	}
	return
}

func (c Namespace) systemPath() (path string, err error) {
	path = filepath.Join(SystemBase, c.Organization, c.System, "config.yaml")
	return
}

func (c Namespace) userPath() (path string, err error) {
	userBase := ExpandUser(UserBase)

	path = filepath.Join(userBase, c.Organization, c.System, "config.yaml")
	return
}

// EnvVar returns the name of the environment variable containing the URI
// of the config.
// Example: PODHUB_UUIDD_CONFIG_URI
func (c Namespace) EnvVar() (envvar string) {
	s := []string{c.Organization, c.System, "CONFIG", "URI"}
	envvar = strings.ToUpper(strings.Join(s, "_"))
	return
}

// Load is a convenience function registered to config.Namespace to
// implement Config.Load().
func (c Namespace) Load(dst interface{}) (err error) {
	cfgPath := c.Path()

	err = Load(cfgPath, dst)
	return
}
<commit_msg>add basic support for uri<commit_after>// Package config version v1.0.0
package config

import (
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"os/user"
	"path/filepath"
	"reflect"
	"strings"

	"gopkg.in/yaml.v2"
)

// Namespace holds the pieces joined together to form the
// directory namespacing for config.
type Namespace struct {
	Organization string // optional additional namespace for orgs.
	System       string // Name of the system associated with this config.
}

// The Config interface implements config.
type Config interface {
	Load(src string, dst interface{}) error
}

// UserBase and SystemBase are the prefixes for the user and system config
// paths, respectively.
const (
	UserBase   string = "~/.config/"
	SystemBase string = "/etc/"
)

// Load reads the contents of the src URI and unmarshals into dst using
// go-yaml.
func Load(src string, dst interface{}) (err error) {
	var data []byte
	dstv := reflect.ValueOf(dst)

	if dstv.Kind() != reflect.Ptr {
		err = errors.New("config: not a pointer")
		return
	}

	uri, err := url.Parse(src)
	if err != nil {
		return err
	}

	switch {
	case uri.Scheme == "file":
		path := ExpandUser(uri.Path)
		data, err = ioutil.ReadFile(path)
		if err != nil {
			return err
		}
	case uri.Scheme == "http" || uri.Scheme == "https":
		resp, err := http.Get(uri.String())
		if err != nil {
			return err
		}

		data, err = ioutil.ReadAll(resp.Body)

		resp.Body.Close()
		if err != nil {
			return err
		}
	}

	err = yaml.Unmarshal(data, dst)
	return
}

// ExpandUser acts kind of like os.path.expanduser in Python, except only
// supports expanding "~/" or "$HOME"
func ExpandUser(path string) (exPath string) {
	usr, _ := user.Current()

	dir := fmt.Sprintf("%s/", usr.HomeDir)

	exPath = path
	if len(path) > 2 && path[:2] == "~/" {
		exPath = strings.Replace(exPath, "~/", dir, 1)
	} else if len(path) > 5 && path[:5] == "$HOME" {
		exPath = strings.Replace(exPath, "$HOME", dir, 1)
	}

	exPath, _ = filepath.Abs(filepath.Clean(exPath))
	return
}

// Path returns path to config, chosen by hierarchy and checked for
// existence:
//
// 1. User config (~/.config/podhub/canary/config.yaml)
//
// 2. System config (/etc/podhub/canary/config.yaml)
func (c Namespace) Path() (path string) {
	systemPath, _ := c.systemPath()
	if _, err := os.Stat(systemPath); err == nil {
		path, _ = c.systemPath()
	}

	userPath, _ := c.userPath()
	if _, err := os.Stat(userPath); err == nil {
		path, _ = c.userPath()
	}
	return
}

func (c Namespace) systemPath() (path string, err error) {
	path = filepath.Join(SystemBase, c.Organization, c.System, "config.yaml")
	return
}

func (c Namespace) userPath() (path string, err error) {
	userBase := ExpandUser(UserBase)

	path = filepath.Join(userBase, c.Organization, c.System, "config.yaml")
	return
}

// EnvVar returns the name of the environment variable containing the URI
// of the config.
// Example: PODHUB_UUIDD_CONFIG_URI
func (c Namespace) EnvVar() (envvar string) {
	s := []string{c.Organization, c.System, "CONFIG", "URI"}
	envvar = strings.ToUpper(strings.Join(s, "_"))
	return
}

// Load is a convenience function registered to config.Namespace to
// implement Config.Load().
func (c Namespace) Load(dst interface{}) (err error) {
	cfgPath := c.Path()

	err = Load(cfgPath, dst)
	return
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"io/ioutil"
	"math"
	"math/rand"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strconv"
	"time"

	"github.com/BurntSushi/toml"
)

type SLHConfig struct {
	SerialPort SerialPortConfig `toml:"serialport"`
	Bluetooth  BluetoothConfig  `toml:"bluetooth"`
	Twitter    TwitterConfig    `toml:"twitter"`
}
type SerialPortConfig struct {
	Serial string `toml:"serial"`
}
type BluetoothConfig struct {
	Uuid  string `toml:"uuid"`
	Major string `toml:"major"`
	Minor string `toml:"minor"`
}
type TwitterConfig struct {
	ConsumerKey       string `toml:"consumer_key"`
	ConsumerSecret    string `toml:"consumer_secret"`
	AccessToken       string `toml:"access_token"`
	AccessTokenSecret string `toml:"access_token_secret"`
}

func uuid() string {
	uuidgen, err := exec.Command("uuidgen").Output()
	if err != nil {
		panic(err)
	}
	return string(uuidgen[:len(uuidgen)-1])
}

func randomNum(i int64) string {
	// 0 - 65535
	rand.Seed(time.Now().Unix() * i)
	return strconv.Itoa(rand.Intn(math.MaxUint16))
}

func scan() string {
	sc := bufio.NewScanner(os.Stdin)
	sc.Scan()
	input := sc.Text()
	return input
}

// get config file path
func getConfigPath() (string, error) {
	// check the home directory
	homeDir := ""
	switch runtime.GOOS {
	case "darwin", "linux":
		homeDir = os.Getenv("HOME")
	default:
		return "", errors.New("don't support this platform")
	}

	// create the config directory
	// $HOME/.config/surelock-homes
	configDir := filepath.Join(homeDir, ".config", "surelock-homes")
	if _, err := os.Stat(configDir); err != nil {
		if err := os.MkdirAll(configDir, 0755); err != nil {
			return "", err
		}
	}

	// create the config filepath
	file := filepath.Join(configDir, "config.tml")
	return file, nil
}

// set config data
func setConfig() error {
	var config SLHConfig

	var serialportConfig SerialPortConfig
	fmt.Printf("Input the serial port: ")
	serialportConfig.Serial = scan()

	var bluetoothConfig BluetoothConfig
	bluetoothConfig.Uuid = uuid()
	bluetoothConfig.Major = randomNum(1)
	bluetoothConfig.Minor = randomNum(2)

	var twitterConfig TwitterConfig
	fmt.Printf("Input the twitter consumer-key: ")
	twitterConfig.ConsumerKey = scan()
	fmt.Printf("Input the twitter consumer-secret: ")
	twitterConfig.ConsumerSecret = scan()
	fmt.Printf("Input the twitter access-token: ")
	twitterConfig.AccessToken = scan()
	fmt.Printf("Input the twitter access-token-secret: ")
	twitterConfig.AccessTokenSecret = scan()

	config.SerialPort = serialportConfig
	config.Bluetooth = bluetoothConfig
	config.Twitter = twitterConfig

	var buffer bytes.Buffer
	encoder := toml.NewEncoder(&buffer)
	if err := encoder.Encode(config); err != nil {
		return err
	}

	// create the config file
	if file, err := getConfigPath(); err != nil {
		return err
	} else {
		ioutil.WriteFile(file, []byte(buffer.String()), 0755)
		fmt.Printf("Created: \"" + file + "\"\n\n")
		fmt.Println(buffer.String())
	}

	return nil
}

// get config data
func getConfig() (SLHConfig, error) {
	var config SLHConfig

	if file, err := getConfigPath(); err != nil {
		return config, err
	} else {
		if _, err := toml.DecodeFile(file, &config); err != nil {
			return config, err
		} else {
			return config, nil
		}
	}
}
<commit_msg>add: twitter account<commit_after>package main

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"io/ioutil"
	"math"
	"math/rand"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strconv"
	"time"

	"github.com/BurntSushi/toml"
)

type SLHConfig struct {
	SerialPort SerialPortConfig `toml:"serialport"`
	Bluetooth  BluetoothConfig  `toml:"bluetooth"`
	Twitter    TwitterConfig    `toml:"twitter"`
}
type SerialPortConfig struct {
	Serial string `toml:"serial"`
}
type BluetoothConfig struct {
	Uuid  string `toml:"uuid"`
	Major string `toml:"major"`
	Minor string `toml:"minor"`
}
type TwitterConfig struct {
	Account           string `toml:"account"`
	ConsumerKey       string `toml:"consumer_key"`
	ConsumerSecret    string `toml:"consumer_secret"`
	AccessToken       string `toml:"access_token"`
	AccessTokenSecret string `toml:"access_token_secret"`
}

func uuid() string {
	uuidgen, err := exec.Command("uuidgen").Output()
	if err != nil {
		panic(err)
	}
	return string(uuidgen[:len(uuidgen)-1])
}

func randomNum(i int64) string {
	// 0 - 65535
	rand.Seed(time.Now().Unix() * i)
	return strconv.Itoa(rand.Intn(math.MaxUint16))
}

func scan() string {
	sc := bufio.NewScanner(os.Stdin)
	sc.Scan()
	input := sc.Text()
	return input
}

// get config file path
func getConfigPath() (string, error) {
	// check the home directory
	homeDir := ""
	switch runtime.GOOS {
	case "darwin", "linux":
		homeDir = os.Getenv("HOME")
	default:
		return "", errors.New("don't support this platform")
	}

	// create the config directory
	// $HOME/.config/surelock-homes
	configDir := filepath.Join(homeDir, ".config", "surelock-homes")
	if _, err := os.Stat(configDir); err != nil {
		if err := os.MkdirAll(configDir, 0755); err != nil {
			return "", err
		}
	}

	// create the config filepath
	file := filepath.Join(configDir, "config.tml")
	return file, nil
}

// set config data
func setConfig() error {
	var config SLHConfig

	var serialportConfig SerialPortConfig
	fmt.Printf("Input the serial port: ")
	serialportConfig.Serial = scan()

	var bluetoothConfig BluetoothConfig
	bluetoothConfig.Uuid = uuid()
	bluetoothConfig.Major = randomNum(1)
	bluetoothConfig.Minor = randomNum(2)

	var twitterConfig TwitterConfig
	fmt.Printf("Input the twitter account: ")
	twitterConfig.Account = scan()
	fmt.Printf("Input the twitter consumer-key: ")
	twitterConfig.ConsumerKey = scan()
	fmt.Printf("Input the twitter consumer-secret: ")
	twitterConfig.ConsumerSecret = scan()
	fmt.Printf("Input the twitter access-token: ")
	twitterConfig.AccessToken = scan()
	fmt.Printf("Input the twitter access-token-secret: ")
	twitterConfig.AccessTokenSecret = scan()

	config.SerialPort = serialportConfig
	config.Bluetooth = bluetoothConfig
	config.Twitter = twitterConfig

	var buffer bytes.Buffer
	encoder := toml.NewEncoder(&buffer)
	if err := encoder.Encode(config); err != nil {
		return err
	}

	// create the config file
	if file, err := getConfigPath(); err != nil {
		return err
	} else {
		ioutil.WriteFile(file, []byte(buffer.String()), 0755)
		fmt.Printf("Created: \"" + file + "\"\n\n")
		fmt.Println(buffer.String())
	}

	return nil
}

// get config data
func getConfig() (SLHConfig, error) {
	var config SLHConfig

	if file, err := getConfigPath(); err != nil {
		return config, err
	} else {
		if _, err := toml.DecodeFile(file, &config); err != nil {
			return config, err
		} else {
			return config, nil
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/x509"
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"reflect"
	"regexp"
	"strconv"
	"strings"
	"time"

	"github.com/mitchellh/mapstructure"
	"github.com/papertrail/remote_syslog2/syslog"
	"github.com/papertrail/remote_syslog2/utils"
	"github.com/spf13/pflag"
	"github.com/spf13/viper"
)

var (
	config *viper.Viper
	flags  *pflag.FlagSet

	Version string

	ErrUsage = errors.New("usage")
)

const (
	envPrefix         = "remote_syslog"
	defaultConfigFile = "/etc/log_files.yml"
)

// The global Config object for remote_syslog2 server. "mapstructure" tags
// signify the config file key names.
type Config struct {
	ConnectTimeout       time.Duration    `mapstructure:"connect_timeout"`
	WriteTimeout         time.Duration    `mapstructure:"write_timeout"`
	NewFileCheckInterval time.Duration    `mapstructure:"new_file_check_interval"`
	ExcludeFiles         []*regexp.Regexp `mapstructure:"exclude_files"`
	ExcludePatterns      []*regexp.Regexp `mapstructure:"exclude_patterns"`
	LogLevels            string           `mapstructure:"log_levels"`
	DebugLogFile         string           `mapstructure:"debug_log_file"`
	PidFile              string           `mapstructure:"pid_file"`
	TcpMaxLineLength     int              `mapstructure:"tcp_max_line_length"`
	NoDetach             bool             `mapstructure:"no_detach"`
	TCP                  bool             `mapstructure:"tcp"`
	TLS                  bool             `mapstructure:"tls"`
	Files                []LogFile
	Hostname             string
	Severity             syslog.Priority
	Facility             syslog.Priority
	Poll                 bool
	Destination          struct {
		Host     string
		Port     int
		Protocol string
		Token    string
	}
	RootCAs *x509.CertPool
}

type LogFile struct {
	Path string
	Tag  string
}

func init() {
	initConfigAndFlags()
}

func initConfigAndFlags() {
	flags = pflag.NewFlagSet(envPrefix, pflag.ExitOnError)

	config = viper.New()
	config.SetEnvPrefix(envPrefix)

	// set defaults for configuration values that aren't provided by flags here:
	config.SetDefault("destination.protocol", "udp")
	config.SetDefault("tcp_max_line_length", 99990)
	config.SetDefault("debug_log_file", "/dev/null")
	config.SetDefault("connect_timeout", 30*time.Second)
	config.SetDefault("write_timeout", 30*time.Second)

	// flag-only "configuration" values (help and version)
	flags.BoolP("help", "h", false, "Display this help message")
	flags.BoolP("version", "V", false, "Display version and exit")

	// set available commandline flags here:
	flags.StringP("configfile", "c", defaultConfigFile, "Path to config")
	config.BindPFlag("config_file", flags.Lookup("configfile"))

	flags.StringP("dest-host", "d", "", "Destination syslog hostname or IP")
	config.BindPFlag("destination.host", flags.Lookup("dest-host"))

	flags.IntP("dest-port", "p", 514, "Destination syslog port")
	config.BindPFlag("destination.port", flags.Lookup("dest-port"))

	flags.StringP("dest-token", "t", "", "Destination ingestion token")
	config.BindPFlag("destination.token", flags.Lookup("dest-token"))

	flags.StringP("facility", "f", "user", "Facility")
	config.BindPFlag("facility", flags.Lookup("facility"))

	hostname, _ := os.Hostname()
	flags.String("hostname", hostname, "Local hostname to send from")
	config.BindPFlag("hostname", flags.Lookup("hostname"))

	flags.String("pid-file", "", "Location of the PID file")
	config.BindPFlag("pid_file", flags.Lookup("pid-file"))

	flags.StringP("severity", "s", "notice", "Severity")
	config.BindPFlag("severity", flags.Lookup("severity"))

	flags.Bool("tcp", false, "Connect via TCP (no TLS)")
	config.BindPFlag("tcp", flags.Lookup("tcp"))

	flags.Bool("tls", false, "Connect via TCP with TLS")
	config.BindPFlag("tls", flags.Lookup("tls"))

	flags.Bool("poll", false, "Detect changes by polling instead of inotify")
	config.BindPFlag("poll", flags.Lookup("poll"))

	flags.Int("new-file-check-interval", 10, "How often to check for new files (seconds)")
	config.BindPFlag("new_file_check_interval", flags.Lookup("new-file-check-interval"))

	flags.String("debug-log-cfg", "", "The debug log file; overridden by -D/--no-detach")
	config.BindPFlag("debug_log_file", flags.Lookup("debug-log-cfg"))

	flags.String("log", "<root>=INFO", "Set loggo config, like: --log=\"<root>=DEBUG\"")
	config.BindPFlag("log_levels", flags.Lookup("log"))

	// only present this flag to systems that can daemonize
	if utils.CanDaemonize {
		flags.BoolP("no-detach", "D", false, "Don't daemonize and detach from the terminal; overrides --debug-log-cfg")
		config.BindPFlag("no_detach", flags.Lookup("no-detach"))
	}

	// deprecated flags
	flags.Bool("no-eventmachine-tail", false, "No action, provided for backwards compatibility")
	flags.Bool("eventmachine-tail", false, "No action, provided for backwards compatibility")

	// bind env vars to config automatically
	config.AutomaticEnv()
}

// Read in configuration from environment, flags, and specified or default config file.
func NewConfigFromEnv() (*Config, error) {
	if err := flags.Parse(os.Args[1:]); err != nil {
		return nil, err
	}

	if h, _ := flags.GetBool("help"); h {
		usage()
		return nil, ErrUsage
	}

	if v, _ := flags.GetBool("version"); v {
		version()
		return nil, ErrUsage
	}

	c := &Config{}

	// read in config file if it's there
	configFile := config.GetString("config_file")
	config.SetConfigFile(configFile)
	if err := config.ReadInConfig(); err != nil && configFile != defaultConfigFile {
		return nil, err
	}

	// override daemonize setting for platforms that don't support it
	if !utils.CanDaemonize {
		config.Set("no_daemonize", true)
	}

	// unmarshal environment config into our Config object here
	decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
		Result:           c,
		WeaklyTypedInput: true,
		DecodeHook:       decodeHook,
	})
	if err != nil {
		return nil, err
	}

	if err = decoder.Decode(config.AllSettings()); err != nil {
		return nil, err
	}

	// explicitly set destination fields since they are nested
	c.Destination.Host = config.GetString("destination.host")
	c.Destination.Port = config.GetInt("destination.port")
	c.Destination.Protocol = config.GetString("destination.protocol")
	c.Destination.Token = config.GetString("destination.token")

	// explicitly set destination protocol if we've asked for tcp or tls
	if c.TLS {
		c.Destination.Protocol = "tls"
	}
	if c.TCP {
		c.Destination.Protocol = "tcp"
	}

	// figure out where to create a pidfile if none was configured
	if c.PidFile == "" {
		c.PidFile = getPidFile()
	}

	// collect any extra args passed on the command line and add them to our file list
	for _, file := range flags.Args() {
		files, err := decodeLogFiles([]interface{}{file})
		if err != nil {
			return nil, err
		}

		c.Files = append(c.Files, files...)
	}

	return c, nil
}

func (c *Config) Validate() error {
	if c.Destination.Host == "" {
		return fmt.Errorf("No destination hostname specified")
	}

	if c.NewFileCheckInterval < 1*time.Second {
		return fmt.Errorf("new_file_check_interval is too small, try setting >= 1")
	}

	return nil
}

func decodeDuration(f interface{}) (time.Duration, error) {
	var (
		i   int
		err error
	)

	switch val := f.(type) {
	case string:
		i, err = strconv.Atoi(val)
		if err != nil {
			return 0, err
		}

	case int:
		i = val

	case time.Duration:
		return val, nil

	default:
		return 0, fmt.Errorf("Invalid duration: %#v", val)
	}

	return time.Duration(i) * time.Second, nil
}

func decodeRegexps(f interface{}) ([]*regexp.Regexp, error) {
	rs, ok := f.([]interface{})
	if !ok {
		return nil, fmt.Errorf("Invalid input type for regular expression %#v", f)
	}

	exps := make([]*regexp.Regexp, len(rs))
	for i, r := range rs {
		str, ok := r.(string)
		if !ok {
			return nil, fmt.Errorf("Invalid input type for regular expression %#v", r)
		}

		exp, err := regexp.Compile(str)
		if err != nil {
			return nil, err
		}

		exps[i] = exp
	}

	return exps, nil
}

func decodeLogFiles(f interface{}) ([]LogFile, error) {
	var (
		files []LogFile
	)

	vals, ok := f.([]interface{})
	if !ok {
		return files, fmt.Errorf("Invalid input type for files: %#v", f)
	}

	for _, v := range vals {
		switch val := v.(type) {
		case string:
			lf := strings.Split(val, "=")
			switch len(lf) {
			case 2:
				files = append(files, LogFile{Tag: lf[0], Path: lf[1]})
			case 1:
				files = append(files, LogFile{Path: val})
			default:
				return files, fmt.Errorf("Invalid log file name %s", val)
			}

		case map[interface{}]interface{}:
			var (
				tag  string
				path string
			)

			tag, _ = val["tag"].(string)
			path, _ = val["path"].(string)

			if path == "" {
				return files, fmt.Errorf("Invalid log file %#v", val)
			}

			files = append(files, LogFile{Tag: tag, Path: path})

		default:
			panic(vals)
		}
	}

	return files, nil
}

func decodePriority(p interface{}) (interface{}, error) {
	ps, ok := p.(string)
	if !ok {
		return nil, fmt.Errorf("Invalid priority: %#v", p)
	}

	pri, err := syslog.Severity(ps)
	if err == nil {
		return pri, nil
	}

	// if it's not a severity, try facility
	pri, err = syslog.Facility(ps)
	if err == nil {
		return pri, nil
	}

	return nil, fmt.Errorf("%s: %s", err.Error(), ps)
}

func decodeHook(from reflect.Type, to reflect.Type, data interface{}) (interface{}, error) {
	switch to {
	case reflect.TypeOf([]LogFile{}):
		return decodeLogFiles(data)
	case reflect.TypeOf([]*regexp.Regexp{}):
		return decodeRegexps(data)
	case reflect.TypeOf(syslog.Priority(0)):
		return decodePriority(data)
	case reflect.TypeOf(time.Duration(0)):
		return decodeDuration(data)
	}

	return data, nil
}

func getPidFile() string {
	pidFiles := []string{
		"/var/run/remote_syslog.pid",
		os.Getenv("HOME") + "/run/remote_syslog.pid",
		os.Getenv("HOME") + "/tmp/remote_syslog.pid",
		os.Getenv("HOME") + "/remote_syslog.pid",
		os.TempDir() + "/remote_syslog.pid",
		os.Getenv("TMPDIR") + "/remote_syslog.pid",
	}

	for _, f := range pidFiles {
		dir := filepath.Dir(f)
		dirStat, err := os.Stat(dir)
		if err != nil || dirStat == nil || !dirStat.IsDir() {
			continue
		}

		fd, err := os.OpenFile(f, os.O_WRONLY|os.O_CREATE, 0644)
		if err != nil {
			continue
		}
		fd.Close()

		return f
	}

	return "/tmp/remote_syslog.pid"
}

func usage() {
	fmt.Fprintf(os.Stderr, "Usage of %s %s:\n", envPrefix, Version)
	flags.PrintDefaults()
}

func version() {
	fmt.Fprintf(os.Stderr, "%s %s\n", envPrefix, Version)
}
<commit_msg>Fix panic: cannot daemonize on windows<commit_after>package main

import (
	"crypto/x509"
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"reflect"
	"regexp"
	"strconv"
	"strings"
	"time"

	"github.com/mitchellh/mapstructure"
	"github.com/papertrail/remote_syslog2/syslog"
	"github.com/papertrail/remote_syslog2/utils"
	"github.com/spf13/pflag"
	"github.com/spf13/viper"
)

var (
	config *viper.Viper
	flags  *pflag.FlagSet

	Version string

	ErrUsage = errors.New("usage")
)

const (
	envPrefix         = "remote_syslog"
	defaultConfigFile = "/etc/log_files.yml"
)

// The global Config object for remote_syslog2 server. "mapstructure" tags
// signify the config file key names.
type Config struct {
	ConnectTimeout       time.Duration    `mapstructure:"connect_timeout"`
	WriteTimeout         time.Duration    `mapstructure:"write_timeout"`
	NewFileCheckInterval time.Duration    `mapstructure:"new_file_check_interval"`
	ExcludeFiles         []*regexp.Regexp `mapstructure:"exclude_files"`
	ExcludePatterns      []*regexp.Regexp `mapstructure:"exclude_patterns"`
	LogLevels            string           `mapstructure:"log_levels"`
	DebugLogFile         string           `mapstructure:"debug_log_file"`
	PidFile              string           `mapstructure:"pid_file"`
	TcpMaxLineLength     int              `mapstructure:"tcp_max_line_length"`
	NoDetach             bool             `mapstructure:"no_detach"`
	TCP                  bool             `mapstructure:"tcp"`
	TLS                  bool             `mapstructure:"tls"`
	Files                []LogFile
	Hostname             string
	Severity             syslog.Priority
	Facility             syslog.Priority
	Poll                 bool
	Destination          struct {
		Host     string
		Port     int
		Protocol string
		Token    string
	}
	RootCAs *x509.CertPool
}

type LogFile struct {
	Path string
	Tag  string
}

func init() {
	initConfigAndFlags()
}

func initConfigAndFlags() {
	flags = pflag.NewFlagSet(envPrefix, pflag.ExitOnError)

	config = viper.New()
	config.SetEnvPrefix(envPrefix)

	// set defaults for configuration values that aren't provided by flags here:
	config.SetDefault("destination.protocol", "udp")
	config.SetDefault("tcp_max_line_length", 99990)
	config.SetDefault("debug_log_file", "/dev/null")
	config.SetDefault("connect_timeout", 30*time.Second)
	config.SetDefault("write_timeout", 30*time.Second)

	// flag-only "configuration" values (help and version)
	flags.BoolP("help", "h", false, "Display this help message")
	flags.BoolP("version", "V", false, "Display version and exit")

	// set available commandline flags here:
	flags.StringP("configfile", "c", defaultConfigFile, "Path to config")
	config.BindPFlag("config_file", flags.Lookup("configfile"))

	flags.StringP("dest-host", "d", "", "Destination syslog hostname or IP")
	config.BindPFlag("destination.host", flags.Lookup("dest-host"))

	flags.IntP("dest-port", "p", 514, "Destination syslog port")
	config.BindPFlag("destination.port", flags.Lookup("dest-port"))

	flags.StringP("dest-token", "t", "", "Destination ingestion token")
	config.BindPFlag("destination.token", flags.Lookup("dest-token"))

	flags.StringP("facility", "f", "user", "Facility")
	config.BindPFlag("facility", flags.Lookup("facility"))

	hostname, _ := os.Hostname()
	flags.String("hostname", hostname, "Local hostname to send from")
	config.BindPFlag("hostname", flags.Lookup("hostname"))

	flags.String("pid-file", "", "Location of the PID file")
	config.BindPFlag("pid_file", flags.Lookup("pid-file"))

	flags.StringP("severity", "s", "notice", "Severity")
	config.BindPFlag("severity", flags.Lookup("severity"))

	flags.Bool("tcp", false, "Connect via TCP (no TLS)")
	config.BindPFlag("tcp", flags.Lookup("tcp"))

	flags.Bool("tls", false, "Connect via TCP with TLS")
	config.BindPFlag("tls", flags.Lookup("tls"))

	flags.Bool("poll", false, "Detect changes by polling instead of inotify")
	config.BindPFlag("poll", flags.Lookup("poll"))

	flags.Int("new-file-check-interval", 10, "How often to check for new files (seconds)")
	config.BindPFlag("new_file_check_interval", flags.Lookup("new-file-check-interval"))

	flags.String("debug-log-cfg", "", "The debug log file; overridden by -D/--no-detach")
	config.BindPFlag("debug_log_file", flags.Lookup("debug-log-cfg"))

	flags.String("log", "<root>=INFO", "Set loggo config, like: --log=\"<root>=DEBUG\"")
	config.BindPFlag("log_levels", flags.Lookup("log"))

	// only present this flag to systems that can daemonize
	if utils.CanDaemonize {
		flags.BoolP("no-detach", "D", false, "Don't daemonize and detach from the terminal; overrides --debug-log-cfg")
		config.BindPFlag("no_detach", flags.Lookup("no-detach"))
	}

	// deprecated flags
	flags.Bool("no-eventmachine-tail", false, "No action, provided for backwards compatibility")
	flags.Bool("eventmachine-tail", false, "No action, provided for backwards compatibility")

	// bind env vars to config automatically
	config.AutomaticEnv()
}

// Read in configuration from environment, flags, and specified or default config file.
func NewConfigFromEnv() (*Config, error) {
	if err := flags.Parse(os.Args[1:]); err != nil {
		return nil, err
	}

	if h, _ := flags.GetBool("help"); h {
		usage()
		return nil, ErrUsage
	}

	if v, _ := flags.GetBool("version"); v {
		version()
		return nil, ErrUsage
	}

	c := &Config{}

	// read in config file if it's there
	configFile := config.GetString("config_file")
	config.SetConfigFile(configFile)
	if err := config.ReadInConfig(); err != nil && configFile != defaultConfigFile {
		return nil, err
	}

	// override daemonize setting for platforms that don't support it
	if !utils.CanDaemonize {
		config.Set("no_detach", true)
	}

	// unmarshal environment config into our Config object here
	decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
		Result:           c,
		WeaklyTypedInput: true,
		DecodeHook:       decodeHook,
	})
	if err != nil {
		return nil, err
	}

	if err = decoder.Decode(config.AllSettings()); err != nil {
		return nil, err
	}

	// explicitly set destination fields since they are nested
	c.Destination.Host = config.GetString("destination.host")
	c.Destination.Port = config.GetInt("destination.port")
	c.Destination.Protocol = config.GetString("destination.protocol")
	c.Destination.Token = config.GetString("destination.token")

	// explicitly set destination protocol if we've asked for tcp or tls
	if c.TLS {
		c.Destination.Protocol = "tls"
	}
	if c.TCP {
		c.Destination.Protocol = "tcp"
	}

	// figure out where to create a pidfile if none was configured
	if c.PidFile == "" {
		c.PidFile = getPidFile()
	}

	// collect any extra args passed on the command line and add them to our file list
	for _, file := range flags.Args() {
		files, err := decodeLogFiles([]interface{}{file})
		if err != nil {
			return nil, err
		}

		c.Files = append(c.Files, files...)
	}

	return c, nil
}

func (c *Config) Validate() error {
	if c.Destination.Host == "" {
		return fmt.Errorf("No destination hostname specified")
	}

	if c.NewFileCheckInterval < 1*time.Second {
		return fmt.Errorf("new_file_check_interval is too small, try setting >= 1")
	}

	return nil
}

func decodeDuration(f interface{}) (time.Duration, error) {
	var (
		i   int
		err error
	)

	switch val := f.(type) {
	case string:
		i, err = strconv.Atoi(val)
		if err != nil {
			return 0, err
		}

	case int:
		i = val

	case time.Duration:
		return val, nil

	default:
		return 0, fmt.Errorf("Invalid duration: %#v", val)
	}

	return time.Duration(i) * time.Second, nil
}

func decodeRegexps(f interface{}) ([]*regexp.Regexp, error) {
	rs, ok := f.([]interface{})
	if !ok {
		return nil, fmt.Errorf("Invalid input type for regular expression %#v", f)
	}

	exps := make([]*regexp.Regexp, len(rs))
	for i, r := range rs {
		str, ok := r.(string)
		if !ok {
			return nil, fmt.Errorf("Invalid input type for regular expression %#v", r)
		}

		exp, err := regexp.Compile(str)
		if err != nil {
			return nil, err
		}

		exps[i] = exp
	}

	return exps, nil
}

func decodeLogFiles(f interface{}) ([]LogFile, error) {
	var (
		files []LogFile
	)

	vals, ok := f.([]interface{})
	if !ok {
		return files, fmt.Errorf("Invalid input type for files: %#v", f)
	}

	for _, v := range vals {
		switch val := v.(type) {
		case string:
			lf := strings.Split(val, "=")
			switch len(lf) {
			case 2:
				files = append(files, LogFile{Tag: lf[0], Path: lf[1]})
			case 1:
				files = append(files, LogFile{Path: val})
			default:
				return files, fmt.Errorf("Invalid log file name %s", val)
			}

		case map[interface{}]interface{}:
			var (
				tag  string
				path string
			)

			tag, _ = val["tag"].(string)
			path, _ = val["path"].(string)

			if path == "" {
				return files, fmt.Errorf("Invalid log file %#v", val)
			}

			files = append(files, LogFile{Tag: tag, Path: path})

		default:
			panic(vals)
		}
	}

	return files, nil
}

func decodePriority(p interface{}) (interface{}, error) {
	ps, ok := p.(string)
	if !ok {
		return nil, fmt.Errorf("Invalid priority: %#v", p)
	}

	pri, err := syslog.Severity(ps)
	if err == nil {
		return pri, nil
	}

	// if it's not a severity, try facility
	pri, err = syslog.Facility(ps)
	if err == nil {
		return pri, nil
	}

	return nil, fmt.Errorf("%s: %s", err.Error(), ps)
}

func decodeHook(from reflect.Type, to reflect.Type, data interface{}) (interface{}, error) {
	switch to {
	case reflect.TypeOf([]LogFile{}):
		return decodeLogFiles(data)
	case reflect.TypeOf([]*regexp.Regexp{}):
		return decodeRegexps(data)
	case reflect.TypeOf(syslog.Priority(0)):
		return decodePriority(data)
	case reflect.TypeOf(time.Duration(0)):
		return decodeDuration(data)
	}

	return data, nil
}

func getPidFile() string {
	pidFiles := []string{
		"/var/run/remote_syslog.pid",
		os.Getenv("HOME") + "/run/remote_syslog.pid",
		os.Getenv("HOME") + "/tmp/remote_syslog.pid",
		os.Getenv("HOME") + "/remote_syslog.pid",
		os.TempDir() + "/remote_syslog.pid",
		os.Getenv("TMPDIR") + "/remote_syslog.pid",
	}

	for _, f := range pidFiles {
		dir := filepath.Dir(f)
		dirStat, err := os.Stat(dir)
		if err != nil || dirStat == nil || !dirStat.IsDir() {
			continue
		}

		fd, err := os.OpenFile(f, os.O_WRONLY|os.O_CREATE, 0644)
		if err != nil {
			continue
		}
		fd.Close()

		return f
	}

	return "/tmp/remote_syslog.pid"
}

func usage() {
	fmt.Fprintf(os.Stderr, "Usage of %s %s:\n", envPrefix, Version)
	flags.PrintDefaults()
}

func version() {
	fmt.Fprintf(os.Stderr, "%s %s\n", envPrefix, Version)
}
<|endoftext|>


<commit_before>package config

import (
	"encoding/json"
	"strings"
	"strconv"
	"os"
	"io"
	"context"
)

type Config map[string]interface{}

// GetString return string config value
func (conf Config) GetString(path string) string {

	result := conf.Get(path)
	if result == nil {
		return ""
	}

	// Если строка, то это результат
	switch val := result.(type) {
	case string: return val

	default:
		return ""
	}
}

// GetArray return array config value
func (conf Config) GetArray(path string) []interface{} {

	result := conf.Get(path)
	if result == nil {
		return []interface{}{}
	}

	switch val := result.(type) {
	case []interface{}: return val

	default:
		return []interface{}{}
	}
}

// GetBool return bool config value
func (conf Config) GetBool(path string) bool {

	result := conf.Get(path)
	if result == nil {
		return false
	}

	switch val := result.(type) {
	case bool: return val

	default:
		return false
	}
}

// GetInt return int64 config value. It may be in hex & oct variants
func (conf Config) GetInt(path string) int64 {

	result := conf.Get(path)
	if result == nil {
		return 0
	}

	switch val := result.(type) {
	case int: return int64(val)
	case int64: return val
	case json.Number:
		if res, err := strconv.ParseInt(string(val), 0, 64); err != nil {
			return 0
		} else {
			return res
		}

	default:
		return 0
	}
}

// GetFloat64 return float64 config value
func (conf Config) GetFloat64(path string) float64 {

	result := conf.Get(path)
	if result == nil {
		return 0
	}

	switch val := result.(type) {
	case float64: return val
	case int: return float64(val)
	case int64: return float64(val)
	case json.Number:
		if res, err := strconv.ParseFloat(string(val), 64); err != nil {
			return 0
		} else {
			return res
		}

	default:
		return 0
	}
}

// Get return config value by dotted path in json tree. Path should be like this "root.option.item"
func (conf Config) Get(path string) interface{} {
	items := strings.Split(path, ".")

	idx := 0
	value := map[string]interface{}(conf)

	// Перебор до предпоследнего элемента
	for idx < len(items) - 1 {
		tmp, ok := value[items[idx]]
		if !ok {
			return ""
		}

		value = tmp.(map[string]interface{})
		idx++
	}

	// Последний элемент
	return value[items[idx]]
}

// New create config from file
func New(filename string) Config {
	file, err := os.Open(filename)
	if err != nil {
		panic(err)
	}

	return NewFromIO(file)
}

// NewFromIO create config from io.Reader
func NewFromIO(input io.Reader) Config {
	decoder := json.NewDecoder(input)
	decoder.UseNumber()

	res := make(Config)
	if err := decoder.Decode(&res); err != nil {
		panic(err)
	}

	return res
}

type key int

const keyConfig key = iota

// NewContext create new context with config
func NewContext(ctx context.Context, filename string) context.Context {
	return context.WithValue(ctx, keyConfig, New(filename))
}

// FromContext return config from context
func FromContext(ctx context.Context) (Config, bool) {
	value, ok := ctx.Value(keyConfig).(Config)
	return value, ok
}<commit_msg>New returns error<commit_after>package config

import (
	"encoding/json"
	"strings"
	"strconv"
	"os"
	"io"
	"context"
)

type Config map[string]interface{}

// GetString return string config value
func (conf Config) GetString(path string) string {

	result := conf.Get(path)
	if result == nil {
		return ""
	}

	// Если строка, то это результат
	switch val := result.(type) {
	case string: return val

	default:
		return ""
	}
}

// GetArray return array config value
func (conf Config) GetArray(path string) []interface{} {

	result := conf.Get(path)
	if result == nil {
		return []interface{}{}
	}

	switch val := result.(type) {
	case []interface{}: return val

	default:
		return []interface{}{}
	}
}

// GetBool return bool config value
func (conf Config) GetBool(path string) bool {

	result := conf.Get(path)
	if result == nil {
		return false
	}

	switch val := result.(type) {
	case bool: return val

	default:
		return false
	}
}

// GetInt return int64 config value. It may be in hex & oct variants
func (conf Config) GetInt(path string) int64 {

	result := conf.Get(path)
	if result == nil {
		return 0
	}

	switch val := result.(type) {
	case int: return int64(val)
	case int64: return val
	case json.Number:
		if res, err := strconv.ParseInt(string(val), 0, 64); err != nil {
			return 0
		} else {
			return res
		}

	default:
		return 0
	}
}

// GetFloat64 return float64 config value
func (conf Config) GetFloat64(path string) float64 {

	result := conf.Get(path)
	if result == nil {
		return 0
	}

	switch val := result.(type) {
	case float64: return val
	case int: return float64(val)
	case int64: return float64(val)
	case json.Number:
		if res, err := strconv.ParseFloat(string(val), 64); err != nil {
			return 0
		} else {
			return res
		}

	default:
		return 0
	}
}

// Get return config value by dotted path in json tree. Path should be like this "root.option.item"
func (conf Config) Get(path string) interface{} {
	items := strings.Split(path, ".")

	idx := 0
	value := map[string]interface{}(conf)

	// Перебор до предпоследнего элемента
	for idx < len(items) - 1 {
		tmp, ok := value[items[idx]]
		if !ok {
			return ""
		}

		value = tmp.(map[string]interface{})
		idx++
	}

	// Последний элемент
	return value[items[idx]]
}

// New create config from file
func New(filename string) (*Config, error) {
	file, err := os.Open(filename)
	if err != nil {
		return nil, err
	}

	return NewFromIO(file), nil
}

// NewFromIO create config from io.Reader
func NewFromIO(input io.Reader) *Config {
	decoder := json.NewDecoder(input)
	decoder.UseNumber()

	res := new(Config)
	if err := decoder.Decode(res); err != nil {
		panic(err)
	}

	return res
}

type key int

const keyConfig key = iota

// NewContext create new context with config
func NewContext(ctx context.Context, filename string) (context.Context, error) {
	if conf, err := New(filename); err != nil {
		return ctx, err
	} else {
		return context.WithValue(ctx, keyConfig, conf), nil
	}
}

// FromContext return config from context
func FromContext(ctx context.Context) (*Config, bool) {
	value, ok := ctx.Value(keyConfig).(*Config)
	return value, ok
}<|endoftext|>


<commit_before>// Copyright (c) 2017 Tigera, Inc. All rights reserved.

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

package resourcemgr

import (
	"context"

	api "github.com/projectcalico/libcalico-go/lib/apis/v2"
	client "github.com/projectcalico/libcalico-go/lib/clientv2"
	"github.com/projectcalico/libcalico-go/lib/options"
)

func init() {
	registerResource(
		api.NewBGPConfiguration(),
		api.NewBGPConfigurationList(),
		false,
		[]string{"bgpconfiguration", "bgpconfigurations", "bgpconfig", "bgpconfigs"},
		[]string{"NAME", "LOGSEVERITY", "MESHENABLED", "DEFAULTASN"},
		[]string{"NAME", "LOGSEVERITY", "MESHENABLED", "DEFAULTASN"},
		map[string]string{
			"NAME":        "{{.ObjectMeta.Name}}",
			"LOGSEVERITY": "{{.Spec.LogSeverityScreen}}",
			"MESHENABLED": "{{if .Spec.NodeToNodeMeshEnabled}}{{.Spec.NodeToNodeMeshEnabled}}{{ else }}-{{ end }}",
			"DEFAULTASN":  "{{if .Spec.DefaultNodeASNumber}}{{.Spec.DefaultNodeASNumber}}{{ else }}-{{ end }}",
		},
		func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) {
			r := resource.(*api.BGPConfiguration)
			return client.BGPConfigurations().Create(ctx, r, options.SetOptions{})
		},
		func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) {
			r := resource.(*api.BGPConfiguration)
			return client.BGPConfigurations().Update(ctx, r, options.SetOptions{})
		},
		func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) {
			r := resource.(*api.BGPConfiguration)
			return client.BGPConfigurations().Delete(ctx, r.Name, options.DeleteOptions{ResourceVersion: r.ResourceVersion})
		},
		func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) {
			r := resource.(*api.BGPConfiguration)
			return client.BGPConfigurations().Get(ctx, r.Name, options.GetOptions{ResourceVersion: r.ResourceVersion})
		},
		func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceListObject, error) {
			r := resource.(*api.BGPConfiguration)
			return client.BGPConfigurations().List(ctx, options.ListOptions{ResourceVersion: r.ResourceVersion, Name: r.Name})
		},
	)
}
<commit_msg>bugfix: calicoctl get bgpconfig command panics<commit_after>// Copyright (c) 2017 Tigera, Inc. All rights reserved.

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

package resourcemgr

import (
	"context"

	api "github.com/projectcalico/libcalico-go/lib/apis/v2"
	client "github.com/projectcalico/libcalico-go/lib/clientv2"
	"github.com/projectcalico/libcalico-go/lib/options"
)

func init() {
	registerResource(
		api.NewBGPConfiguration(),
		api.NewBGPConfigurationList(),
		false,
		[]string{"bgpconfiguration", "bgpconfigurations", "bgpconfig", "bgpconfigs"},
		[]string{"NAME", "LOGSEVERITY", "MESHENABLED", "ASNUMBER"},
		[]string{"NAME", "LOGSEVERITY", "MESHENABLED", "ASNUMBER"},
		map[string]string{
			"NAME":        "{{.ObjectMeta.Name}}",
			"LOGSEVERITY": "{{.Spec.LogSeverityScreen}}",
			"MESHENABLED": "{{if .Spec.NodeToNodeMeshEnabled}}{{.Spec.NodeToNodeMeshEnabled}}{{ else }}-{{ end }}",
			"ASNUMBER":  "{{if .Spec.ASNumber}}{{.Spec.ASNumber}}{{ else }}-{{ end }}",
		},
		func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) {
			r := resource.(*api.BGPConfiguration)
			return client.BGPConfigurations().Create(ctx, r, options.SetOptions{})
		},
		func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) {
			r := resource.(*api.BGPConfiguration)
			return client.BGPConfigurations().Update(ctx, r, options.SetOptions{})
		},
		func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) {
			r := resource.(*api.BGPConfiguration)
			return client.BGPConfigurations().Delete(ctx, r.Name, options.DeleteOptions{ResourceVersion: r.ResourceVersion})
		},
		func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) {
			r := resource.(*api.BGPConfiguration)
			return client.BGPConfigurations().Get(ctx, r.Name, options.GetOptions{ResourceVersion: r.ResourceVersion})
		},
		func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceListObject, error) {
			r := resource.(*api.BGPConfiguration)
			return client.BGPConfigurations().List(ctx, options.ListOptions{ResourceVersion: r.ResourceVersion, Name: r.Name})
		},
	)
}
<|endoftext|>


<commit_before>package storagenode

import (
	"encoding/json"
	"io/ioutil"
	"net/http"

	"github.com/jacksontj/dataman/src/query"
	"github.com/jacksontj/dataman/src/metadata"
	"github.com/julienschmidt/httprouter"
)

type HTTPApi struct {
	storageNode *StorageNode
}

func NewHTTPApi(storageNode *StorageNode) *HTTPApi {
	api := &HTTPApi{
		storageNode: storageNode,
	}

	return api
}

// Register any endpoints to the router
func (h *HTTPApi) Start(router *httprouter.Router) {
	router.POST("/v1/data/raw", h.rawQueryHandler)
}

// TODO: streaming parser
func (h *HTTPApi) rawQueryHandler(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	defer r.Body.Close()
	bytes, _ := ioutil.ReadAll(r.Body)

	var queries []map[query.QueryType]query.QueryArgs

	if err := json.Unmarshal(bytes, &queries); err != nil {
		// TODO: correct status code, 4xx for invalid request
		w.WriteHeader(http.StatusInternalServerError)
		return
	} else {
		// At this point we have a list of queries that we need to do, so lets do it
		// TODO: we should actually do these in parallel (potentially with some
		// config of *how* parallel)
		results := make([]*query.Result, len(queries))

		// We specifically want to load this once for the batch so we don't have mixed
		// schema information across this batch of queries
		meta := h.storageNode.Meta.Load().(*metadata.Meta)

		for i, queryMap := range queries {
			// We only allow a single method to be defined per item
			if len(queryMap) == 1 {
				for queryType, queryArgs := range queryMap {
					// Verify that the table is within our domain
					if _, err := meta.GetTable(queryArgs["db"].(string), queryArgs["table"].(string)); err != nil {
						results[i] = &query.Result{
							Error: err.Error(),
						}
						continue
					}

					// TODO: have a map or some other switch from query -> interface?
					// This will need to get more complex as we support multiple
					// storage interfaces
					switch queryType {
					case query.Get:
						results[i] = h.storageNode.Store.Get(queryArgs)
					case query.Set:
						results[i] = h.storageNode.Store.Set(queryArgs)
					case query.Filter:
						results[i] = h.storageNode.Store.Filter(queryArgs)
					default:
						results[i] = &query.Result{
							Error: "Unsupported query type " + string(queryType),
						}
					}
				}

			} else {
				results[i] = &query.Result{
					Error: "Only one QueryType supported per query",
				}
			}

		}

		// Now we need to return the results
		if bytes, err := json.Marshal(results); err != nil {
			// TODO: log this better?
			w.WriteHeader(http.StatusInternalServerError)
			return
		} else {
			w.Header().Set("Content-Type", "application/json")
			w.Write(bytes)
		}
	}
}
<commit_msg>Notes to self<commit_after>package storagenode

import (
	"encoding/json"
	"io/ioutil"
	"net/http"

	"github.com/jacksontj/dataman/src/query"
	"github.com/jacksontj/dataman/src/metadata"
	"github.com/julienschmidt/httprouter"
)

type HTTPApi struct {
	storageNode *StorageNode
}

func NewHTTPApi(storageNode *StorageNode) *HTTPApi {
	api := &HTTPApi{
		storageNode: storageNode,
	}

	return api
}

// REST API methods:
// 	 GET - READ/list
//	 PUT - UPDATE
//   POST - CREATE
//   DELETE - DELETE
// Register any endpoints to the router
func (h *HTTPApi) Start(router *httprouter.Router) {
	router.POST("/v1/data/raw", h.rawQueryHandler)
}

// TODO: streaming parser
func (h *HTTPApi) rawQueryHandler(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	defer r.Body.Close()
	bytes, _ := ioutil.ReadAll(r.Body)

	var queries []map[query.QueryType]query.QueryArgs

	if err := json.Unmarshal(bytes, &queries); err != nil {
		// TODO: correct status code, 4xx for invalid request
		w.WriteHeader(http.StatusInternalServerError)
		return
	} else {
		// At this point we have a list of queries that we need to do, so lets do it
		// TODO: we should actually do these in parallel (potentially with some
		// config of *how* parallel)
		results := make([]*query.Result, len(queries))

		// We specifically want to load this once for the batch so we don't have mixed
		// schema information across this batch of queries
		meta := h.storageNode.Meta.Load().(*metadata.Meta)

		for i, queryMap := range queries {
			// We only allow a single method to be defined per item
			if len(queryMap) == 1 {
				for queryType, queryArgs := range queryMap {
					// Verify that the table is within our domain
					if _, err := meta.GetTable(queryArgs["db"].(string), queryArgs["table"].(string)); err != nil {
						results[i] = &query.Result{
							Error: err.Error(),
						}
						continue
					}

					// TODO: have a map or some other switch from query -> interface?
					// This will need to get more complex as we support multiple
					// storage interfaces
					switch queryType {
					case query.Get:
						results[i] = h.storageNode.Store.Get(queryArgs)
					case query.Set:
						results[i] = h.storageNode.Store.Set(queryArgs)
					case query.Filter:
						results[i] = h.storageNode.Store.Filter(queryArgs)
					default:
						results[i] = &query.Result{
							Error: "Unsupported query type " + string(queryType),
						}
					}
				}

			} else {
				results[i] = &query.Result{
					Error: "Only one QueryType supported per query",
				}
			}

		}

		// Now we need to return the results
		if bytes, err := json.Marshal(results); err != nil {
			// TODO: log this better?
			w.WriteHeader(http.StatusInternalServerError)
			return
		} else {
			w.Header().Set("Content-Type", "application/json")
			w.Write(bytes)
		}
	}
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/kinesis"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsKinesisStream() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsKinesisStreamCreate,
		Read:   resourceAwsKinesisStreamRead,
		Update: resourceAwsKinesisStreamUpdate,
		Delete: resourceAwsKinesisStreamDelete,

		Schema: map[string]*schema.Schema{
			"name": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"shard_count": &schema.Schema{
				Type:     schema.TypeInt,
				Required: true,
				ForceNew: true,
			},

			"arn": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},
			"tags": tagsSchema(),
		},
	}
}

func resourceAwsKinesisStreamCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).kinesisconn
	sn := d.Get("name").(string)
	createOpts := &kinesis.CreateStreamInput{
		ShardCount: aws.Int64(int64(d.Get("shard_count").(int))),
		StreamName: aws.String(sn),
	}

	_, err := conn.CreateStream(createOpts)
	if err != nil {
		if awsErr, ok := err.(awserr.Error); ok {
			return fmt.Errorf("[WARN] Error creating Kinesis Stream: \"%s\", code: \"%s\"", awsErr.Message(), awsErr.Code())
		}
		return err
	}

	stateConf := &resource.StateChangeConf{
		Pending:    []string{"CREATING"},
		Target:     "ACTIVE",
		Refresh:    streamStateRefreshFunc(conn, sn),
		Timeout:    5 * time.Minute,
		Delay:      10 * time.Second,
		MinTimeout: 3 * time.Second,
	}

	streamRaw, err := stateConf.WaitForState()
	if err != nil {
		return fmt.Errorf(
			"Error waiting for Kinesis Stream (%s) to become active: %s",
			sn, err)
	}

	s := streamRaw.(*kinesis.StreamDescription)
	d.SetId(*s.StreamARN)
	d.Set("arn", s.StreamARN)

	return resourceAwsKinesisStreamUpdate(d, meta)
}

func resourceAwsKinesisStreamUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).kinesisconn

	d.Partial(true)
	if err := setTagsKinesis(conn, d); err != nil {
		return err
	}

	d.SetPartial("tags")
	d.Partial(false)

	return resourceAwsKinesisStreamRead(d, meta)
}

func resourceAwsKinesisStreamRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).kinesisconn
	sn := d.Get("name").(string)
	describeOpts := &kinesis.DescribeStreamInput{
		StreamName: aws.String(sn),
	}
	resp, err := conn.DescribeStream(describeOpts)
	if err != nil {
		if awsErr, ok := err.(awserr.Error); ok {
			if awsErr.Code() == "ResourceNotFoundException" {
				d.SetId("")
				return nil
			}
			return fmt.Errorf("[WARN] Error reading Kinesis Stream: \"%s\", code: \"%s\"", awsErr.Message(), awsErr.Code())
		}
		return err
	}

	s := resp.StreamDescription
	d.Set("arn", *s.StreamARN)
	d.Set("shard_count", len(s.Shards))

	// set tags
	describeTagsOpts := &kinesis.ListTagsForStreamInput{
		StreamName: aws.String(sn),
	}
	tagsResp, err := conn.ListTagsForStream(describeTagsOpts)
	if err != nil {
		log.Printf("[DEBUG] Error retrieving tags for Stream: %s. %s", sn, err)
	} else {
		d.Set("tags", tagsToMapKinesis(tagsResp.Tags))
	}

	return nil
}

func resourceAwsKinesisStreamDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).kinesisconn
	sn := d.Get("name").(string)
	_, err := conn.DeleteStream(&kinesis.DeleteStreamInput{
		StreamName: aws.String(sn),
	})

	if err != nil {
		return err
	}

	stateConf := &resource.StateChangeConf{
		Pending:    []string{"DELETING"},
		Target:     "DESTROYED",
		Refresh:    streamStateRefreshFunc(conn, sn),
		Timeout:    5 * time.Minute,
		Delay:      10 * time.Second,
		MinTimeout: 3 * time.Second,
	}

	_, err = stateConf.WaitForState()
	if err != nil {
		return fmt.Errorf(
			"Error waiting for Stream (%s) to be destroyed: %s",
			sn, err)
	}

	d.SetId("")
	return nil
}

func streamStateRefreshFunc(conn *kinesis.Kinesis, sn string) resource.StateRefreshFunc {
	return func() (interface{}, string, error) {
		describeOpts := &kinesis.DescribeStreamInput{
			StreamName: aws.String(sn),
		}
		resp, err := conn.DescribeStream(describeOpts)
		if err != nil {
			if awsErr, ok := err.(awserr.Error); ok {
				if awsErr.Code() == "ResourceNotFoundException" {
					return 42, "DESTROYED", nil
				}
				return nil, awsErr.Code(), err
			}
			return nil, "failed", err
		}

		return resp.StreamDescription, *resp.StreamDescription.StreamStatus, nil
	}
}
<commit_msg>provider/aws: Kinesis DescribeStream pagination<commit_after>package aws

import (
	"fmt"
	"log"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/kinesis"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsKinesisStream() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsKinesisStreamCreate,
		Read:   resourceAwsKinesisStreamRead,
		Update: resourceAwsKinesisStreamUpdate,
		Delete: resourceAwsKinesisStreamDelete,

		Schema: map[string]*schema.Schema{
			"name": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"shard_count": &schema.Schema{
				Type:     schema.TypeInt,
				Required: true,
				ForceNew: true,
			},

			"arn": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},
			"tags": tagsSchema(),
		},
	}
}

func resourceAwsKinesisStreamCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).kinesisconn
	sn := d.Get("name").(string)
	createOpts := &kinesis.CreateStreamInput{
		ShardCount: aws.Int64(int64(d.Get("shard_count").(int))),
		StreamName: aws.String(sn),
	}

	_, err := conn.CreateStream(createOpts)
	if err != nil {
		if awsErr, ok := err.(awserr.Error); ok {
			return fmt.Errorf("[WARN] Error creating Kinesis Stream: \"%s\", code: \"%s\"", awsErr.Message(), awsErr.Code())
		}
		return err
	}

	stateConf := &resource.StateChangeConf{
		Pending:    []string{"CREATING"},
		Target:     "ACTIVE",
		Refresh:    streamStateRefreshFunc(conn, sn),
		Timeout:    5 * time.Minute,
		Delay:      10 * time.Second,
		MinTimeout: 3 * time.Second,
	}

	streamRaw, err := stateConf.WaitForState()
	if err != nil {
		return fmt.Errorf(
			"Error waiting for Kinesis Stream (%s) to become active: %s",
			sn, err)
	}

	s := streamRaw.(kinesisStreamState)
	d.SetId(s.arn)
	d.Set("arn", s.arn)
	d.Set("shard_count", s.shardCount)

	return resourceAwsKinesisStreamUpdate(d, meta)
}

func resourceAwsKinesisStreamUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).kinesisconn

	d.Partial(true)
	if err := setTagsKinesis(conn, d); err != nil {
		return err
	}

	d.SetPartial("tags")
	d.Partial(false)

	return resourceAwsKinesisStreamRead(d, meta)
}

func resourceAwsKinesisStreamRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).kinesisconn
	sn := d.Get("name").(string)

	state, err := readKinesisStreamState(conn, sn)
	if err != nil {
		if awsErr, ok := err.(awserr.Error); ok {
			if awsErr.Code() == "ResourceNotFoundException" {
				d.SetId("")
				return nil
			}
			return fmt.Errorf("[WARN] Error reading Kinesis Stream: \"%s\", code: \"%s\"", awsErr.Message(), awsErr.Code())
		}
		return err

	}
	d.Set("arn", state.arn)
	d.Set("shard_count", state.shardCount)

	// set tags
	describeTagsOpts := &kinesis.ListTagsForStreamInput{
		StreamName: aws.String(sn),
	}
	tagsResp, err := conn.ListTagsForStream(describeTagsOpts)
	if err != nil {
		log.Printf("[DEBUG] Error retrieving tags for Stream: %s. %s", sn, err)
	} else {
		d.Set("tags", tagsToMapKinesis(tagsResp.Tags))
	}

	return nil
}

func resourceAwsKinesisStreamDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).kinesisconn
	sn := d.Get("name").(string)
	_, err := conn.DeleteStream(&kinesis.DeleteStreamInput{
		StreamName: aws.String(sn),
	})

	if err != nil {
		return err
	}

	stateConf := &resource.StateChangeConf{
		Pending:    []string{"DELETING"},
		Target:     "DESTROYED",
		Refresh:    streamStateRefreshFunc(conn, sn),
		Timeout:    5 * time.Minute,
		Delay:      10 * time.Second,
		MinTimeout: 3 * time.Second,
	}

	_, err = stateConf.WaitForState()
	if err != nil {
		return fmt.Errorf(
			"Error waiting for Stream (%s) to be destroyed: %s",
			sn, err)
	}

	d.SetId("")
	return nil
}

type kinesisStreamState struct {
	arn        string
	status     string
	shardCount int
}

func readKinesisStreamState(conn *kinesis.Kinesis, sn string) (kinesisStreamState, error) {
	describeOpts := &kinesis.DescribeStreamInput{
		StreamName: aws.String(sn),
	}

	var state kinesisStreamState
	err := conn.DescribeStreamPages(describeOpts, func(page *kinesis.DescribeStreamOutput, last bool) (shouldContinue bool) {
		state.arn = aws.StringValue(page.StreamDescription.StreamARN)
		state.status = aws.StringValue(page.StreamDescription.StreamStatus)
		state.shardCount += len(page.StreamDescription.Shards)
		return !last
	})
	return state, err
}

func streamStateRefreshFunc(conn *kinesis.Kinesis, sn string) resource.StateRefreshFunc {
	return func() (interface{}, string, error) {
		state, err := readKinesisStreamState(conn, sn)
		if err != nil {
			if awsErr, ok := err.(awserr.Error); ok {
				if awsErr.Code() == "ResourceNotFoundException" {
					return 42, "DESTROYED", nil
				}
				return nil, awsErr.Code(), err
			}
			return nil, "failed", err
		}

		return state, state.status, nil
	}
}
<|endoftext|>


<commit_before>package redis

import (
	"context"
	"io"
	"net"
	"strings"

	"github.com/go-redis/redis/v8/internal/pool"
	"github.com/go-redis/redis/v8/internal/proto"
)

// ErrClosed performs any operation on the closed client will return this error.
var ErrClosed = pool.ErrClosed

type Error interface {
	error

	// RedisError is a no-op function but
	// serves to distinguish types that are Redis
	// errors from ordinary errors: a type is a
	// Redis error if it has a RedisError method.
	RedisError()
}

var _ Error = proto.RedisError("")

func shouldRetry(err error, retryTimeout bool) bool {
	switch err {
	case io.EOF, io.ErrUnexpectedEOF:
		return true
	case nil, context.Canceled, context.DeadlineExceeded:
		return false
	}

	if v, ok := err.(timeoutError); ok {
		if v.Timeout() {
			return retryTimeout
		}
		return true
	}

	s := err.Error()
	if s == "ERR max number of clients reached" {
		return true
	}
	if strings.HasPrefix(s, "LOADING ") {
		return true
	}
	if strings.HasPrefix(s, "READONLY ") {
		return true
	}
	if strings.HasPrefix(s, "CLUSTERDOWN ") {
		return true
	}
	if strings.HasPrefix(s, "TRYAGAIN ") {
		return true
	}

	return false
}

func isRedisError(err error) bool {
	_, ok := err.(proto.RedisError)
	return ok
}

func isBadConn(err error, allowTimeout bool, addr string) bool {
	switch err {
	case nil:
		return false
	case context.Canceled, context.DeadlineExceeded:
		return true
	}

	if isRedisError(err) {
		switch {
		case isReadOnlyError(err):
			// Close connections in read only state in case domain addr is used
			// and domain resolves to a different Redis Server. See #790.
			return true
		case isMovedSameConnAddr(err, addr):
			// Close connections when we are asked to move to the same addr
			// of the connection. Force a DNS resolution when all connections
			// of the pool are recycled
			return true
		default:
			return false
		}
	}

	if allowTimeout {
		if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
			return !netErr.Temporary()
		}
	}

	return true
}

func isMovedError(err error) (moved bool, ask bool, addr string) {
	if !isRedisError(err) {
		return
	}

	s := err.Error()
	switch {
	case strings.HasPrefix(s, "MOVED "):
		moved = true
	case strings.HasPrefix(s, "ASK "):
		ask = true
	default:
		return
	}

	ind := strings.LastIndex(s, " ")
	if ind == -1 {
		return false, false, ""
	}
	addr = s[ind+1:]
	return
}

func isLoadingError(err error) bool {
	return strings.HasPrefix(err.Error(), "LOADING ")
}

func isReadOnlyError(err error) bool {
	return strings.HasPrefix(err.Error(), "READONLY ")
}

func isMovedSameConnAddr(err error, addr string) bool {
	redisError := err.Error()
	if !strings.HasPrefix(redisError, "MOVED ") {
		return false
	}
	return strings.HasSuffix(redisError, " "+addr)
}

//------------------------------------------------------------------------------

type timeoutError interface {
	Timeout() bool
}
<commit_msg>chore: fix golangci-lint<commit_after>package redis

import (
	"context"
	"io"
	"net"
	"strings"

	"github.com/go-redis/redis/v8/internal/pool"
	"github.com/go-redis/redis/v8/internal/proto"
)

// ErrClosed performs any operation on the closed client will return this error.
var ErrClosed = pool.ErrClosed

type Error interface {
	error

	// RedisError is a no-op function but
	// serves to distinguish types that are Redis
	// errors from ordinary errors: a type is a
	// Redis error if it has a RedisError method.
	RedisError()
}

var _ Error = proto.RedisError("")

func shouldRetry(err error, retryTimeout bool) bool {
	switch err {
	case io.EOF, io.ErrUnexpectedEOF:
		return true
	case nil, context.Canceled, context.DeadlineExceeded:
		return false
	}

	if v, ok := err.(timeoutError); ok {
		if v.Timeout() {
			return retryTimeout
		}
		return true
	}

	s := err.Error()
	if s == "ERR max number of clients reached" {
		return true
	}
	if strings.HasPrefix(s, "LOADING ") {
		return true
	}
	if strings.HasPrefix(s, "READONLY ") {
		return true
	}
	if strings.HasPrefix(s, "CLUSTERDOWN ") {
		return true
	}
	if strings.HasPrefix(s, "TRYAGAIN ") {
		return true
	}

	return false
}

func isRedisError(err error) bool {
	_, ok := err.(proto.RedisError)
	return ok
}

func isBadConn(err error, allowTimeout bool, addr string) bool {
	switch err {
	case nil:
		return false
	case context.Canceled, context.DeadlineExceeded:
		return true
	}

	if isRedisError(err) {
		switch {
		case isReadOnlyError(err):
			// Close connections in read only state in case domain addr is used
			// and domain resolves to a different Redis Server. See #790.
			return true
		case isMovedSameConnAddr(err, addr):
			// Close connections when we are asked to move to the same addr
			// of the connection. Force a DNS resolution when all connections
			// of the pool are recycled
			return true
		default:
			return false
		}
	}

	if allowTimeout {
		if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
			return false
		}
	}

	return true
}

func isMovedError(err error) (moved bool, ask bool, addr string) {
	if !isRedisError(err) {
		return
	}

	s := err.Error()
	switch {
	case strings.HasPrefix(s, "MOVED "):
		moved = true
	case strings.HasPrefix(s, "ASK "):
		ask = true
	default:
		return
	}

	ind := strings.LastIndex(s, " ")
	if ind == -1 {
		return false, false, ""
	}
	addr = s[ind+1:]
	return
}

func isLoadingError(err error) bool {
	return strings.HasPrefix(err.Error(), "LOADING ")
}

func isReadOnlyError(err error) bool {
	return strings.HasPrefix(err.Error(), "READONLY ")
}

func isMovedSameConnAddr(err error, addr string) bool {
	redisError := err.Error()
	if !strings.HasPrefix(redisError, "MOVED ") {
		return false
	}
	return strings.HasSuffix(redisError, " "+addr)
}

//------------------------------------------------------------------------------

type timeoutError interface {
	Timeout() bool
}
<|endoftext|>


<commit_before>package calendar

// locale: en_US

// NOTE: Work in progress!

// Anything that's specific to the US, with the exception of some movable dates which are in movable.go
// This calendar has a corresponding locale code in the NewCalendar function in calendar.go

import (
	"time"
)

type USCalendar struct{}

// Create a new US calendar
func NewUSCalendar() USCalendar {
	return USCalendar{}
}

// Finds the US name for a day of the week.
// Note that time.Weekday starts at 0 with Sunday, not Monday.
func (nc USCalendar) DayName(day time.Weekday) string {
	return day.String()
}

// Finds the US name for a given month
func (nc USCalendar) MonthName(month time.Month) string {
	return month.String()
}

// Checks if a given date is a "red day" (public holiday) in the US calendar.
// Returns true/false, a description and true/false for if it's a flag day.
// The dates will never overlap.
func (nc USCalendar) RedDay(date time.Time) (bool, string, bool) {

	// Source: http://en.wikipedia.org/wiki/Public_holidays_in_the_United_States
	// Source: http://timpanogos.wordpress.com/flag-fly-dates/

	var (
		desc string
		flag bool
	)

	// Sundays
	if date.Weekday() == time.Sunday {
		desc = "Sunday"
	}

	// Election Day
	if atElectionDay(date) {
		desc = "Election Day"
		flag = false
	}

	// New Year's Day
	if atMD(date, 1, 1) {
		desc = "New Year's Day"
		flag = true
	}

	// Birthday of Dr. Martin Luther King, Jr.
	if atNthWeekdayOfMonth(date, 3, time.Monday, time.January) {
		desc = "Martin Luther King Day"
		flag = true
	}

	// Inauguration Day
	if atInaugurationDay(date) {
		desc = "Inauguration Day"
		flag = true
	}

	// Lincoln's birthday
	if atMD(date, 2, 12) {
		desc = "Lincoln's birthday"
		flag = true
	}

	// Washington's Birthday / Presidents' Day
	if atNthWeekdayOfMonth(date, 3, time.Monday, time.February) {
		desc = "Presidents' Day"
		flag = true
	}

	// Armed Forces Day
	if atNthWeekdayOfMonth(date, 3, time.Saturday, time.May) {
		desc = "Armed Forces Day"
		flag = true
	}

	// Memorial Day
	if atLastWeekday(date, time.Monday, time.May) {
		desc = "Memorial Day"
		flag = true
	}

	// 4th of July
	if atMD(date, 7, 4) {
		desc = "Independence Day"
		flag = true
	}

	// Labor Day
	if atNthWeekdayOfMonth(date, 1, time.Monday, time.September) {
		desc = "Labor Day"
		flag = true
	}

	// Columbus Day
	if atNthWeekdayOfMonth(date, 2, time.Monday, time.October) {
		desc = "Columbus Day"
		flag = true
	}

	// Veterans Day
	if atMD(date, 11, 11) {
		desc = "Veterans Day"
		flag = true
	}

	// Thanksgiving Day
	if atNthWeekdayOfMonth(date, 4, time.Thursday, time.November) {
		desc = "Thanksgiving Day"
		flag = true
	}

	// Christmas
	if atMD(date, 12, 25) {
		desc = "Christmas Day"
		flag = true
	}

	// Red days
	if desc != "" {
		// Then return
		return true, desc, flag
	}

	// Normal days
	return false, desc, false
}

// Some days are not red, but special in one way or another.
// Checks if a given date is notable. Returns true/false if the
// given date is notable, a comma separated description (in case there are more
// than one notable event that day) and true/false depending on if it's a flag
// flying day or not.
func (nc USCalendar) NotableDay(date time.Time) (bool, string, bool) {

	var (
	//descriptions []string
	//flag         bool
	)

	// Since days may overlap, "flaggdager" must come first for the flag
	// flying days to be correct.

	// --- Flag days ---

	// --- Non-flag days ---

	// No notable events
	return false, "", false
}

// Checks if a given date is in a notable time range (summer holidays, for instance)
func (nc USCalendar) NotablePeriod(date time.Time) (bool, string) {
	// TODO:
	// christmas time
	// summer/winter/spring/autumn time
	// etc
	return false, ""
}

// An ordinary day
func (nc USCalendar) NormalDay() string {
	return "Ordinary"
}
<commit_msg>Better comments<commit_after>package calendar

// locale: en_US

// NOTE: Work in progress!

// Anything that's specific to the US, with the exception of some movable dates which are in movable.go
// This calendar has a corresponding locale code in the NewCalendar function in calendar.go

import (
	"time"
)

type USCalendar struct{}

// Create a new US calendar
func NewUSCalendar() USCalendar {
	return USCalendar{}
}

// Finds the US name for a day of the week.
// Note that time.Weekday starts at 0 with Sunday, not Monday.
func (nc USCalendar) DayName(day time.Weekday) string {
	return day.String()
}

// Finds the US name for a given month
func (nc USCalendar) MonthName(month time.Month) string {
	return month.String()
}

// Checks if a given date is a "red day" (public holiday) in the US calendar.
// Returns true/false, a description and true/false for if it's a flag day.
// The dates will never overlap.
func (nc USCalendar) RedDay(date time.Time) (bool, string, bool) {

	// Source: http://en.wikipedia.org/wiki/Public_holidays_in_the_United_States
	// Source: http://timpanogos.wordpress.com/flag-fly-dates/

	var (
		desc string
		flag bool
	)

	// Sundays
	if date.Weekday() == time.Sunday {
		desc = "Sunday"
	}

	// Election Day
	if atElectionDay(date) {
		desc = "Election Day"
		flag = false
	}

	// New Year's Day
	if atMD(date, 1, 1) {
		desc = "New Year's Day"
		flag = true
	}

	// Birthday of Dr. Martin Luther King, Jr.
	if atNthWeekdayOfMonth(date, 3, time.Monday, time.January) {
		desc = "Martin Luther King Day"
		flag = true
	}

	// Inauguration Day
	if atInaugurationDay(date) {
		desc = "Inauguration Day"
		flag = true
	}

	// Lincoln's birthday
	if atMD(date, 2, 12) {
		desc = "Lincoln's birthday"
		flag = true
	}

	// Washington's Birthday / Presidents' Day
	if atNthWeekdayOfMonth(date, 3, time.Monday, time.February) {
		desc = "Presidents' Day"
		flag = true
	}

	// Armed Forces Day
	if atNthWeekdayOfMonth(date, 3, time.Saturday, time.May) {
		desc = "Armed Forces Day"
		flag = true
	}

	// Memorial Day
	if atLastWeekday(date, time.Monday, time.May) {
		desc = "Memorial Day"
		flag = true
	}

	// 4th of July
	if atMD(date, 7, 4) {
		desc = "Independence Day"
		flag = true
	}

	// Labor Day
	if atNthWeekdayOfMonth(date, 1, time.Monday, time.September) {
		desc = "Labor Day"
		flag = true
	}

	// Columbus Day
	if atNthWeekdayOfMonth(date, 2, time.Monday, time.October) {
		desc = "Columbus Day"
		flag = true
	}

	// Veterans Day
	if atMD(date, 11, 11) {
		desc = "Veterans Day"
		flag = true
	}

	// Thanksgiving Day
	if atNthWeekdayOfMonth(date, 4, time.Thursday, time.November) {
		desc = "Thanksgiving Day"
		flag = true
	}

	// Christmas
	if atMD(date, 12, 25) {
		desc = "Christmas Day"
		flag = true
	}

	// Red days
	if desc != "" {
		// Then return
		return true, desc, flag
	}

	// Normal days
	return false, desc, false
}

// Some days are not red, but special in one way or another.
// Checks if a given date is notable. Returns true/false if the
// given date is notable, a comma separated description (in case there are more
// than one notable event that day) and true/false depending on if it's a flag
// flying day or not.
func (nc USCalendar) NotableDay(date time.Time) (bool, string, bool) {

	var (
	//descriptions []string
	//flag         bool
	)

	// Since days may overlap, flag flying days must come first.

	// --- Flag flying days ---

	// --- Other days ---

	// No notable events
	return false, "", false
}

// Checks if a given date is in a notable time range (summer holidays, for instance)
func (nc USCalendar) NotablePeriod(date time.Time) (bool, string) {
	// TODO:
	// Christmas time
	// summer/winter/spring/autumn time
	// etc
	return false, ""
}

// An ordinary day
func (nc USCalendar) NormalDay() string {
	return "Ordinary"
}
<|endoftext|>