<commit_before>package main

import (
	"bufio"
	"encoding/json"
	"flag"
	"fmt"
	"os"
	"os/exec"
	"time"

	"github.com/kouhin/envflag"
)

var (
	previousRead     int
	previousReadTime time.Time
)

type MeterRead struct {
	Time    *time.Time
	Offset  int
	Length  int
	Message *MeterMessage
}

type MeterMessage struct {
	ID          int
	Type        int
	TamperPhy   int
	TamperEnc   int
	Consumption int
	ChecksumVal int
}

func main() {
	var (
		meterId = flag.String("meter-id", "REQUIRED", "ID of the meter to read from")
	)
	if err := envflag.Parse(); err != nil {
		panic(err)
	}

	if *meterId == "REQUIRED" {
		fmt.Println("meter-id is a required field")
		os.Exit(1)
	}

	cmdName := "rtlamr"
	cmdArgs := []string{"-format=json", "-filterid=" + *meterId}

	cmd := exec.Command(cmdName, cmdArgs...)
	cmdReader, err := cmd.StdoutPipe()
	if err != nil {
		panic(err)
	}

	scanner := bufio.NewScanner(cmdReader)
	go func() {
		for scanner.Scan() {
			text := scanner.Text()
			line := &MeterRead{}
			if err := json.Unmarshal([]byte(text), &line); err != nil {
				fmt.Fprintln(os.Stderr, fmt.Sprintf("Error unmarshaling line (%s):| %s", err, text))
				continue
			}
			fmt.Printf("line | %q\n", line)
		}
	}()

	err = cmd.Start()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error starting Cmd", err)
		os.Exit(1)
	}

	err = cmd.Wait()
	if err != nil {
		time.Sleep(2000) // let the scanner finish. there's gotta be a better way
		fmt.Fprintln(os.Stderr, "Command exited", err)
		os.Exit(1)
	}
}

func processLine(read *MeterRead) {
	if previousRead == 0 {
		// we have no baseline, set and wait for more
		previousRead = read.Message.Consumption
		previousReadTime = *read.Time
		return
	}

	timeBetweenReads := read.Time.Sub(previousReadTime)
	if timeBetweenReads.Hours() < 1.0 {
		// not long enough, bail out
		return
	}

	// it's been more than an hour, so we can report data. Compare the two readings, then factor in
	// that the time might have been more than an hour to get a cf/hr measurement.
	consumed := float64(read.Message.Consumption - previousRead)
	minsBetweenReads := timeBetweenReads.Minutes()
	consumedPerMin := consumed / minsBetweenReads
	consumedPerHour := consumedPerMin * 60
	reportMetric(consumedPerHour)
}

func reportMetric(cfHr float64) {
	fmt.Printf("At %s, consumption rate is %f cf/hr", time.Now().Format("2006-01-02T15:04:05.999999-07:00"), cfHr)
}
<commit_msg>works better if process is called<commit_after>package main

import (
	"bufio"
	"encoding/json"
	"flag"
	"fmt"
	"os"
	"os/exec"
	"time"

	"github.com/kouhin/envflag"
)

var (
	previousRead     int
	previousReadTime time.Time
)

type MeterRead struct {
	Time    *time.Time
	Offset  int
	Length  int
	Message *MeterMessage
}

type MeterMessage struct {
	ID          int
	Type        int
	TamperPhy   int
	TamperEnc   int
	Consumption int
	ChecksumVal int
}

func main() {
	var (
		meterId = flag.String("meter-id", "REQUIRED", "ID of the meter to read from")
	)
	if err := envflag.Parse(); err != nil {
		panic(err)
	}

	if *meterId == "REQUIRED" {
		fmt.Println("meter-id is a required field")
		os.Exit(1)
	}

	cmdName := "rtlamr"
	cmdArgs := []string{"-format=json", "-filterid=" + *meterId}

	cmd := exec.Command(cmdName, cmdArgs...)
	cmdReader, err := cmd.StdoutPipe()
	if err != nil {
		panic(err)
	}

	scanner := bufio.NewScanner(cmdReader)
	go func() {
		for scanner.Scan() {
			text := scanner.Text()
			line := &MeterRead{}
			if err := json.Unmarshal([]byte(text), &line); err != nil {
				fmt.Fprintln(os.Stderr, fmt.Sprintf("Error unmarshaling line (%s):| %s", err, text))
				continue
			}
			fmt.Printf("received | %#v\n", line)
			processLine(line)
		}
	}()

	err = cmd.Start()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error starting Cmd", err)
		os.Exit(1)
	}

	err = cmd.Wait()
	if err != nil {
		time.Sleep(2000) // let the scanner finish. there's gotta be a better way
		fmt.Fprintln(os.Stderr, "Command exited", err)
		os.Exit(1)
	}
}

func processLine(read *MeterRead) {
	if previousRead == 0 {
		// we have no baseline, set and wait for more
		previousRead = read.Message.Consumption
		previousReadTime = *read.Time
		return
	}

	timeBetweenReads := read.Time.Sub(previousReadTime)
	if timeBetweenReads.Hours() < 1.0 {
		// not long enough, bail out
		return
	}

	// it's been more than an hour, so we can report data. Compare the two readings, then factor in
	// that the time might have been more than an hour to get a cf/hr measurement.
	consumed := float64(read.Message.Consumption - previousRead)
	minsBetweenReads := timeBetweenReads.Minutes()
	consumedPerMin := consumed / minsBetweenReads
	consumedPerHour := consumedPerMin * 60
	reportMetric(consumedPerHour)
}

func reportMetric(cfHr float64) {
	fmt.Printf("At %s, consumption rate is %f cf/hr", time.Now().Format("2006-01-02T15:04:05.999999-07:00"), cfHr)
}
<|endoftext|>


<commit_before>package pgx

import (
	// DRIVER: pgx
	_ "github.com/jackc/pgx/stdlib"

	"github.com/jackc/pgx"

	"github.com/knq/usql/drivers"
)

const (
	pgxMaxConnections = 3
)

func init() {
	drivers.Register("pgx", drivers.Driver{
		AD: true, AMC: true,
		V: func(db drivers.DB) (string, error) {
			var ver string
			err := db.QueryRow(`show server_version`).Scan(&ver)
			if err != nil {
				return "", err
			}
			return "PostgreSQL " + ver, nil
		},
		ChPw: func(db drivers.DB, user, new, _ string) error {
			_, err := db.Exec(`alter user ` + user + ` password '` + new + `'`)
			return err
		},
		E: func(err error) (string, string) {
			if e, ok := err.(pgx.PgError); ok {
				return e.Code, e.Message
			}
			return "", err.Error()
		},
		PwErr: func(err error) bool {
			if e, ok := err.(pgx.PgError); ok {
				return e.Code == "28P01"
			}
			return false
		},
	})
}
<commit_msg>Removing dead code in pgx driver<commit_after>package pgx

import (
	// DRIVER: pgx
	_ "github.com/jackc/pgx/stdlib"

	"github.com/jackc/pgx"

	"github.com/knq/usql/drivers"
)

func init() {
	drivers.Register("pgx", drivers.Driver{
		AD: true, AMC: true,
		V: func(db drivers.DB) (string, error) {
			var ver string
			err := db.QueryRow(`show server_version`).Scan(&ver)
			if err != nil {
				return "", err
			}
			return "PostgreSQL " + ver, nil
		},
		ChPw: func(db drivers.DB, user, new, _ string) error {
			_, err := db.Exec(`alter user ` + user + ` password '` + new + `'`)
			return err
		},
		E: func(err error) (string, string) {
			if e, ok := err.(pgx.PgError); ok {
				return e.Code, e.Message
			}
			return "", err.Error()
		},
		PwErr: func(err error) bool {
			if e, ok := err.(pgx.PgError); ok {
				return e.Code == "28P01"
			}
			return false
		},
	})
}
<|endoftext|>


<commit_before>package router

import (
	"io/ioutil"
	"net/http/httputil"
	"testing"

	"github.com/tpbowden/swarm-ingress-router/service"
)

var certificate, certErr = ioutil.ReadFile("../fixtures/cert.crt")
var key, keyErr = ioutil.ReadFile("../fixtures/key.key")

type RouterTest struct {
	description string
	services    []service.Service
	host        string
	secure      bool
	success     bool
	redirect    bool
	proxy       bool
}

var routerTests = []RouterTest{
	{
		description: "A valid service returns an HTTP proxy",
		host:        "example.local",
		success:     true,
		proxy:       true,
		services: []service.Service{
			{
				URL:      "http://my-service:3000",
				DNSName:  "example.local",
				Secure:   false,
				ForceTLS: false,
			},
		},
	},
	{
		description: "A secure connection to an insecure service is not successful",
		host:        "example.local",
		success:     false,
		secure:      true,
		services: []service.Service{
			{
				URL:     "http://my-service:3000",
				DNSName: "example.local",
				Secure:  false,
			},
		},
	},
	{
		description: "A missing service does not return successfully",
		host:        "example.local",
		services:    []service.Service{},
	},
	{
		description: "A service with an invalid URL does not return successfully",
		host:        "example.local",
		services: []service.Service{
			{
				URL:     "http://[::1]a:3000",
				DNSName: "example.local",
			},
		},
	},
	{
		description: "An insecure connection with forceTLS returns a redirect",
		host:        "example.local",
		success:     true,
		redirect:    true,
		services: []service.Service{
			{
				URL:      "http://my-service:3000",
				DNSName:  "example.local",
				ForceTLS: true,
			},
		},
	},
}

func TestRouting(t *testing.T) {
	for _, test := range routerTests {
		subject := NewRouter()
		subject.UpdateTable(test.services)

		result, ok := subject.RouteToService(test.host, test.secure)

		if ok != test.success {
			t.Errorf("Test failed: service fetching did not match: %s", test.description)
		}

		if test.redirect {
			_, assertOk := result.(*RedirectHandler)
			if !assertOk {
				t.Errorf("Test failed: expected a redirect: %s", test.description)
			}
		}

		if test.proxy {
			_, assertOk := result.(*httputil.ReverseProxy)
			if !assertOk {
				t.Errorf("Test failed: expected a reverse proxy: %s", test.description)
			}
		}
	}
}

type CertificateTest struct {
	description string
	services    []service.Service
	host        string
	success     bool
}

var certificateTests = []CertificateTest{
	{
		description: "Missing services do not return successfully",
		services: []service.Service{
			{
				URL:     "http://my-service:3000",
				DNSName: "example.local",
				Secure:  false,
			},
		},
		host:    "foo.local",
		success: false,
	},
	{
		description: "Valid certificates return successfully",
		services: []service.Service{
			{
				URL:         "http://my-service:3000",
				DNSName:     "example.local",
				Secure:      true,
				EncodedCert: string(certificate),
				EncodedKey:  string(key),
			},
		},
		host:    "example.local",
		success: true,
	},
}

func TestCertificates(t *testing.T) {

	if certErr != nil {
		t.Error("Failed to read certificate fixture: ", certErr)
	}

	if keyErr != nil {
		t.Error("Failed to read key fixture: ", keyErr)
	}

	for _, test := range certificateTests {
		subject := NewRouter()
		subject.UpdateTable(test.services)

		_, ok := subject.CertificateForService(test.host)

		if ok != test.success {
			t.Errorf("Test failed: certificate fetching did not match: %s", test.description)
		}

	}
}
<commit_msg>Remove broken tests<commit_after>package router

import (
	"io/ioutil"
	"testing"

	"github.com/tpbowden/swarm-ingress-router/service"
)

var certificate, certErr = ioutil.ReadFile("../fixtures/cert.crt")
var key, keyErr = ioutil.ReadFile("../fixtures/key.key")

type RouterTest struct {
	description string
	services    []service.Service
	host        string
	secure      bool
	success     bool
	redirect    bool
	proxy       bool
}

var routerTests = []RouterTest{
	{
		description: "A valid service returns an HTTP proxy",
		host:        "example.local",
		success:     true,
		proxy:       true,
		services: []service.Service{
			{
				URL:      "http://my-service:3000",
				DNSName:  "example.local",
				Secure:   false,
				ForceTLS: false,
			},
		},
	},
	{
		description: "A secure connection to an insecure service is not successful",
		host:        "example.local",
		success:     false,
		secure:      true,
		services: []service.Service{
			{
				URL:     "http://my-service:3000",
				DNSName: "example.local",
				Secure:  false,
			},
		},
	},
	{
		description: "A missing service does not return successfully",
		host:        "example.local",
		services:    []service.Service{},
	},
	{
		description: "An insecure connection with forceTLS returns a redirect",
		host:        "example.local",
		success:     true,
		redirect:    true,
		services: []service.Service{
			{
				URL:      "http://my-service:3000",
				DNSName:  "example.local",
				ForceTLS: true,
			},
		},
	},
}

func TestRouting(t *testing.T) {
	for _, test := range routerTests {
		subject := NewRouter()
		subject.UpdateTable(test.services)

		_, ok := subject.RouteToService(test.host, test.secure)

		if ok != test.success {
			t.Errorf("Test failed: service fetching did not match: %s", test.description)
		}
	}
}

type CertificateTest struct {
	description string
	services    []service.Service
	host        string
	success     bool
}

var certificateTests = []CertificateTest{
	{
		description: "Missing services do not return successfully",
		services: []service.Service{
			{
				URL:     "http://my-service:3000",
				DNSName: "example.local",
				Secure:  false,
			},
		},
		host:    "foo.local",
		success: false,
	},
	{
		description: "Valid certificates return successfully",
		services: []service.Service{
			{
				URL:         "http://my-service:3000",
				DNSName:     "example.local",
				Secure:      true,
				EncodedCert: string(certificate),
				EncodedKey:  string(key),
			},
		},
		host:    "example.local",
		success: true,
	},
}

func TestCertificates(t *testing.T) {

	if certErr != nil {
		t.Error("Failed to read certificate fixture: ", certErr)
	}

	if keyErr != nil {
		t.Error("Failed to read key fixture: ", keyErr)
	}

	for _, test := range certificateTests {
		subject := NewRouter()
		subject.UpdateTable(test.services)

		_, ok := subject.CertificateForService(test.host)

		if ok != test.success {
			t.Errorf("Test failed: certificate fetching did not match: %s", test.description)
		}

	}
}
<|endoftext|>


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

package main

import (
	"bytes"
	"flag"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"runtime"
	"strconv"
	"text/template"
)

var (
	httpListen = flag.String("http", "127.0.0.1:3999", "host:port to listen on")
	htmlOutput = flag.Bool("html", false, "render program output as HTML")
)

var (
	// a source of numbers, for naming temporary files
	uniq = make(chan int)
)

func main() {
	flag.Parse()

	// source of unique numbers
	go func() {
		for i := 0; ; i++ {
			uniq <- i
		}
	}()

	http.HandleFunc("/", FrontPage)
	http.HandleFunc("/compile", Compile)
	log.Fatal(http.ListenAndServe(*httpListen, nil))
}

// FrontPage is an HTTP handler that renders the goplay interface.
// If a filename is supplied in the path component of the URI,
// its contents will be put in the interface's text area.
// Otherwise, the default "hello, world" program is displayed.
func FrontPage(w http.ResponseWriter, req *http.Request) {
	data, err := ioutil.ReadFile(req.URL.Path[1:])
	if err != nil {
		data = helloWorld
	}
	frontPage.Execute(w, data)
}

// Compile is an HTTP handler that reads Go source code from the request,
// runs the program (returning any errors),
// and sends the program's output as the HTTP response.
func Compile(w http.ResponseWriter, req *http.Request) {
	out, err := compile(req)
	if err != nil {
		error_(w, out, err)
		return
	}

	// write the output of x as the http response
	if *htmlOutput {
		w.Write(out)
	} else {
		output.Execute(w, out)
	}
}

var (
	commentRe = regexp.MustCompile(`(?m)^#.*\n`)
	tmpdir    string
)

func init() {
	// find real temporary directory (for rewriting filename in output)
	var err error
	tmpdir, err = filepath.EvalSymlinks(os.TempDir())
	if err != nil {
		log.Fatal(err)
	}
}

func compile(req *http.Request) (out []byte, err error) {
	// x is the base name for .go, .6, executable files
	x := filepath.Join(tmpdir, "compile"+strconv.Itoa(<-uniq))
	src := x + ".go"
	bin := x
	if runtime.GOOS == "windows" {
		bin += ".exe"
	}

	// rewrite filename in error output
	defer func() {
		if err != nil {
			// drop messages from the go tool like '# _/compile0'
			out = commentRe.ReplaceAll(out, nil)
		}
		out = bytes.Replace(out, []byte(src+":"), []byte("main.go:"), -1)
	}()

	// write body to x.go
	body := new(bytes.Buffer)
	if _, err = body.ReadFrom(req.Body); err != nil {
		return
	}
	defer os.Remove(src)
	if err = ioutil.WriteFile(src, body.Bytes(), 0666); err != nil {
		return
	}

	// build x.go, creating x
	dir, file := filepath.Split(src)
	out, err = run(dir, "go", "build", "-o", bin, file)
	defer os.Remove(bin)
	if err != nil {
		return
	}

	// run x
	return run("", bin)
}

// error writes compile, link, or runtime errors to the HTTP connection.
// The JavaScript interface uses the 404 status code to identify the error.
func error_(w http.ResponseWriter, out []byte, err error) {
	w.WriteHeader(404)
	if out != nil {
		output.Execute(w, out)
	} else {
		output.Execute(w, err.Error())
	}
}

// run executes the specified command and returns its output and an error.
func run(dir string, args ...string) ([]byte, error) {
	var buf bytes.Buffer
	cmd := exec.Command(args[0], args[1:]...)
	cmd.Dir = dir
	cmd.Stdout = &buf
	cmd.Stderr = cmd.Stdout
	err := cmd.Run()
	return buf.Bytes(), err
}

var frontPage = template.Must(template.New("frontPage").Parse(frontPageText)) // HTML template
var output = template.Must(template.New("output").Parse(outputText))          // HTML template

var outputText = `<pre>{{printf "%s" . |html}}</pre>`

var frontPageText = `<!doctype html>

<textarea autofocus="true" id="edit" spellcheck="false" onkeydown="keyHandler(event);" onkeyup="autocompile();">{{printf "%s" . |html}}</textarea>

(Shift-Enter to compile and run.)
<input type="checkbox" id="autocompile" value="checked" /> Compile and run after each keystroke

`

var helloWorld = []byte(`package main

import "fmt"

func main() {
	fmt.Println("hello, world")
}
`)
<commit_msg>misc/goplay: use `go run x.go` instead of `go build x.go`<commit_after>// Copyright 2010 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"flag"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strconv"
	"text/template"
)

var (
	httpListen = flag.String("http", "127.0.0.1:3999", "host:port to listen on")
	htmlOutput = flag.Bool("html", false, "render program output as HTML")
)

var (
	// a source of numbers, for naming temporary files
	uniq = make(chan int)
)

func main() {
	flag.Parse()

	// source of unique numbers
	go func() {
		for i := 0; ; i++ {
			uniq <- i
		}
	}()

	http.HandleFunc("/", FrontPage)
	http.HandleFunc("/compile", Compile)
	log.Fatal(http.ListenAndServe(*httpListen, nil))
}

// FrontPage is an HTTP handler that renders the goplay interface.
// If a filename is supplied in the path component of the URI,
// its contents will be put in the interface's text area.
// Otherwise, the default "hello, world" program is displayed.
func FrontPage(w http.ResponseWriter, req *http.Request) {
	data, err := ioutil.ReadFile(req.URL.Path[1:])
	if err != nil {
		data = helloWorld
	}
	frontPage.Execute(w, data)
}

// Compile is an HTTP handler that reads Go source code from the request,
// runs the program (returning any errors),
// and sends the program's output as the HTTP response.
func Compile(w http.ResponseWriter, req *http.Request) {
	out, err := compile(req)
	if err != nil {
		error_(w, out, err)
		return
	}

	// write the output of x as the http response
	if *htmlOutput {
		w.Write(out)
	} else {
		output.Execute(w, out)
	}
}

var (
	commentRe = regexp.MustCompile(`(?m)^#.*\n`)
	tmpdir    string
)

func init() {
	// find real temporary directory (for rewriting filename in output)
	var err error
	tmpdir, err = filepath.EvalSymlinks(os.TempDir())
	if err != nil {
		log.Fatal(err)
	}
}

func compile(req *http.Request) (out []byte, err error) {
	// x is the base name for .go, .6, executable files
	x := filepath.Join(tmpdir, "compile"+strconv.Itoa(<-uniq))
	src := x + ".go"

	// rewrite filename in error output
	defer func() {
		if err != nil {
			// drop messages from the go tool like '# _/compile0'
			out = commentRe.ReplaceAll(out, nil)
		}
		out = bytes.Replace(out, []byte(src+":"), []byte("main.go:"), -1)
	}()

	// write body to x.go
	body := new(bytes.Buffer)
	if _, err = body.ReadFrom(req.Body); err != nil {
		return
	}
	defer os.Remove(src)
	if err = ioutil.WriteFile(src, body.Bytes(), 0666); err != nil {
		return
	}

	// go run x.go
	dir, file := filepath.Split(src)
	out, err = run(dir, "go", "run", file)
	if err != nil {
		return
	}
	return out, nil
}

// error writes compile, link, or runtime errors to the HTTP connection.
// The JavaScript interface uses the 404 status code to identify the error.
func error_(w http.ResponseWriter, out []byte, err error) {
	w.WriteHeader(404)
	if out != nil {
		output.Execute(w, out)
	} else {
		output.Execute(w, err.Error())
	}
}

// run executes the specified command and returns its output and an error.
func run(dir string, args ...string) ([]byte, error) {
	var buf bytes.Buffer
	cmd := exec.Command(args[0], args[1:]...)
	cmd.Dir = dir
	cmd.Stdout = &buf
	cmd.Stderr = cmd.Stdout
	err := cmd.Run()
	return buf.Bytes(), err
}

var frontPage = template.Must(template.New("frontPage").Parse(frontPageText)) // HTML template
var output = template.Must(template.New("output").Parse(outputText))          // HTML template

var outputText = `<pre>{{printf "%s" . |html}}</pre>`

var frontPageText = `<!doctype html>

<textarea autofocus="true" id="edit" spellcheck="false" onkeydown="keyHandler(event);" onkeyup="autocompile();">{{printf "%s" . |html}}</textarea>

(Shift-Enter to compile and run.)
<input type="checkbox" id="autocompile" value="checked" /> Compile and run after each keystroke

`

var helloWorld = []byte(`package main

import "fmt"

func main() {
	fmt.Println("hello, world")
}
`)
<|endoftext|>


<commit_before>package prj

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"runtime"
	"strings"
)

var project *Project
var Debug bool

type Project struct {
	rootFolder string
	// Global  GOPATH
	ggopath string
}

func GetProject() (*Project, error) {
	if project == nil {
		project = &Project{}
		gdir, gerr := Git("rev-parse --git-dir")
		gdir = strings.TrimSpace(gdir)
		// fmt.Printf("ko '%s' '%s'", gdir, gerr)
		if gerr != nil {
			return nil, gerr
		}
		if gdir != ".git" {
			project.rootFolder = gdir[:len(gdir)-5]
		} else {
			// fmt.Printf("ok")
			project.rootFolder = wd
		}
		project.ggopath = os.Getenv("GOPATH")
	}
	// fmt.Printf("prf '%s'", project.rootFolder)
	// fmt.Printf("prf '%s'", project.ggopath)
	name := project.name()
	// fmt.Printf("name '%s'\n", name)
	depsPrjroot := project.rootFolder + "/deps/src/" + name
	// fmt.Printf("prf '%s'\n", depsPrjroot)
	var err error
	if depsPrjroot, err = filepath.Abs(depsPrjroot); err != nil {
		return nil, err
	}
	depsPrjdir := filepath.Dir(depsPrjroot)
	if fi, _ := os.Stat(depsPrjdir); fi == nil {
		if err := os.MkdirAll(depsPrjdir, os.ModeDir); err != nil {
			return nil, err
		}
	}
	// fmt.Println(depsPrjdir, depsPrjroot)
	if fi, _ := os.Stat(depsPrjroot); fi == nil {
		if _, err = execcmd("mklink", fmt.Sprintf("/J %s %s", depsPrjroot, project.rootFolder)); err != nil {
			return nil, err
		}
	}
	return project, nil
}

// either base or remote -v origin
func (p *Project) name() string {
	// git remote show -n origin
	// (?m)^(?:http(?:s)://)?(([^@]+)@)?(.*?)(?:.git)?$
	origin := p.origin()
	if origin != "" {
		return origin
	}
	return filepath.Base(p.RootFolder())

}

// git config --local --get remote.origin.url
// (?m)^\s+Fetch URL: (.*?)$
func (p *Project) origin() string {
	gorg, gerr := Git("config --local --get remote.origin.url")
	// fmt.Printf("gorg='%s', gerr='%+v'", gorg, gerr)
	if gorg == "" || gerr != nil {
		return ""
	}
	r := regexp.MustCompile(`(?m)^(?:http(?:s)://)?(([^@]+)@)?(.*?)(?:.git)?$`)
	sm := r.FindAllStringSubmatch(gorg, 1)
	// fmt.Printf("sm: %+v: %d %d\n", sm, len(sm), len(sm[0]))
	if len(sm) == 1 && len(sm[0]) == 4 {
		return sm[0][3]
	}
	return ""
}

func (p *Project) RootFolder() string {
	return p.rootFolder
}

// Inspired by https://github.com/ghthor/journal/blob/0bd4968a4f9841befdd0dde96b2096e6c930e74c/git/git.go

var gitPath string
var goPath string
var wd string

func init() {
	gitPath = getPathForExe("git")
	goPath = getPathForExe("go")
	var err error
	wd, err = os.Getwd()
	if err != nil {
		log.Fatal("Working directory not accessible")
	}
}

func getPathForExe(exe string) string {
	var err error
	var path = ""
	if path, err = exec.LookPath(exe); err != nil {
		aliases := ""
		if runtime.GOOS == "windows" {
			aliases, err = execcmd("doskey", "/macros")
		} else {
			aliases, err = execcmd("alias", "")
		}
		r := regexp.MustCompile(`(?m)^` + exe + `=(.*)\s+[\$%@\*].*$`)
		sm := r.FindAllStringSubmatch(aliases, 1)
		if len(sm) != 1 || len(sm[0]) != 2 {
			log.Fatalf("Unable to find '%s' path in aliases '%s'", exe)
		}
		return sm[0][1]
	}
	if runtime.GOOS == "windows" {
		if strings.HasSuffix(path, ".bat") {
			bat, err := ioutil.ReadFile(path)
			if err != nil {
				log.Fatalf("Unable to read '%s' for '%s'", path, exe)
			}
			bats := string(bat)
			r := regexp.MustCompile(`(?m)^\s*?(.*)\s+[\$%@\*].*$`)
			sm := r.FindAllStringSubmatch(bats, 1)
			if len(sm) != 1 || len(sm[0]) != 2 {
				log.Fatalf("Unable to find '%s' path in file '%s'", exe, path)
			}
			return sm[0][1]
		}
	}
	if path == "" {
		log.Fatalf("Unable to get path for '%s'", exe)
	}
	return path
}

// Construct an *exec.Cmd for `git {args}` with a workingDirectory
func Git(cmd string) (string, error) {
	return execcmd(gitPath, cmd)
}
func Golang(cmd string) (string, error) {
	os.Setenv("GOPATH", project.rootFolder+`/deps`)
	os.Setenv("GOBIN", project.rootFolder+`/bin`)
	return execcmd(goPath, cmd)
}

func execcmd(exe, cmd string) (string, error) {
	if Debug {
		fmt.Printf("%s %s\n", exe, cmd)
	}
	args := strings.Split(cmd, " ")
	args = append([]string{"/c", exe}, args...)
	c := exec.Command("cmd", args...)
	c.Dir = project.rootFolder
	var bout bytes.Buffer
	c.Stdout = &bout
	var berr bytes.Buffer
	c.Stderr = &berr
	err := c.Run()
	if err != nil {
		return bout.String(), fmt.Errorf("Unable to run '%s %s' in '%s': err '%s'\n'%s'", exe, cmd, wd, err.Error(), berr.String())
	} else if berr.String() != "" {
		return bout.String(), fmt.Errorf("Warning on run '%s %s' in '%s': '%s'", exe, cmd, wd, berr.String())
	}
	return bout.String(), nil
}

func (p *Project) updateGGopath(path string) error {
	dir := filepath.Dir(path)
	name := filepath.Base(path)
	gsrcpdir := p.ggopath + string(filepath.Separator) + "src" + string(filepath.Separator) + dir
	var err error
	if gsrcpdir, err = filepath.Abs(gsrcpdir); err != nil {
		return fmt.Errorf("Unable to get absolute path from '%s'", p.ggopath+string(filepath.Separator)+dir)
	}
	fmt.Println(gsrcpdir)
	if fi, _ := os.Stat(gsrcpdir); fi == nil {
		if err := os.MkdirAll(gsrcpdir, os.ModeDir); err != nil {
			return err
		}
	}
	gsrc := p.ggopath + string(filepath.Separator) + "src" + string(filepath.Separator) + path
	if gsrc, err = filepath.Abs(gsrc); err != nil {
		return fmt.Errorf("Unable to get absolute path from '%s'", p.ggopath+string(os.PathSeparator)+path)
	}
	var fi os.FileInfo
	if fi, _ = os.Stat(gsrc); fi == nil {
		if _, err := execcmd("mklink", fmt.Sprintf("/J %s %s", gsrc, project.rootFolder)); err != nil {
			return err
		}
	} else {
		var l string
		if l, err = execcmd("dir", gsrcpdir); err != nil {
			return fmt.Errorf("Unable to list %s in '%s'", name, gsrcpdir)
		}
		fmt.Println(l)
		r := regexp.MustCompile(fmt.Sprintf(`(?m)<JUNCTION>\s+%s\s+\[([^\]]+)\]\s*$`, name))
		n := r.FindAllStringSubmatch(l, -1)
		fmt.Printf("n='%+v'\n", n)
		if len(n) == 1 {
			pp := n[0][1]
			fmt.Printf("pp='%+v' vs. '%s'\n", pp, p.RootFolder())
			if strings.HasPrefix(pp, p.RootFolder()) {
				return nil
			}
			return fmt.Errorf("'%s' should point to '%s' but points instead to '%s'", gsrc, p.RootFolder(), pp)
		}
		r = regexp.MustCompile(fmt.Sprintf(`(?m)<DIR>\s+%s\s*$`, name))
		n = r.FindAllStringSubmatch(l, -1)
		fmt.Printf("n='%+v'\n", n)
		if len(n) == 1 {
			// move dir
			if err = os.Rename(gsrc, gsrc+".1"); err != nil {
				return fmt.Errorf("Unable to rename '%s'", gsrc)
			}
			// Let's try again, now that the dir has been renamed
			return p.updateGGopath(path)
		} else {
			return fmt.Errorf("Unable to access '%s'", gsrc)
		}
	}
	os.Exit(0)
	return nil
}
<commit_msg>project.go: GetProject() calls updateGGopath()<commit_after>package prj

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"runtime"
	"strings"
)

var project *Project
var Debug bool

type Project struct {
	rootFolder string
	// Global  GOPATH
	ggopath string
}

func GetProject() (*Project, error) {
	if project == nil {
		project = &Project{}
		gdir, gerr := Git("rev-parse --git-dir")
		gdir = strings.TrimSpace(gdir)
		// fmt.Printf("ko '%s' '%s'", gdir, gerr)
		if gerr != nil {
			return nil, gerr
		}
		if gdir != ".git" {
			project.rootFolder = gdir[:len(gdir)-5]
		} else {
			// fmt.Printf("ok")
			project.rootFolder = wd
		}
		project.ggopath = os.Getenv("GOPATH")
	}
	// fmt.Printf("prf '%s'", project.rootFolder)
	// fmt.Printf("prf '%s'", project.ggopath)
	name := project.name()
	fmt.Printf("name '%s'\n", name)
	depsPrjroot := project.rootFolder + "/deps/src/" + name
	// fmt.Printf("prf '%s'\n", depsPrjroot)
	var err error
	if depsPrjroot, err = filepath.Abs(depsPrjroot); err != nil {
		return nil, err
	}
	depsPrjdir := filepath.Dir(depsPrjroot)
	if fi, _ := os.Stat(depsPrjdir); fi == nil {
		if err := os.MkdirAll(depsPrjdir, os.ModeDir); err != nil {
			return nil, err
		}
	}
	// fmt.Println(depsPrjdir, depsPrjroot)
	if fi, _ := os.Stat(depsPrjroot); fi == nil {
		if _, err = execcmd("mklink", fmt.Sprintf("/J %s %s", depsPrjroot, project.rootFolder)); err != nil {
			return nil, err
		}
	}
	if err = project.updateGGopath(name); err != nil {
		return nil, err
	}
	return project, nil
}

// either base or remote -v origin
func (p *Project) name() string {
	// git remote show -n origin
	// (?m)^(?:http(?:s)://)?(([^@]+)@)?(.*?)(?:.git)?$
	origin := p.origin()
	if origin != "" {
		return origin
	}
	return filepath.Base(p.RootFolder())

}

// git config --local --get remote.origin.url
// (?m)^\s+Fetch URL: (.*?)$
func (p *Project) origin() string {
	gorg, gerr := Git("config --local --get remote.origin.url")
	// fmt.Printf("gorg='%s', gerr='%+v'", gorg, gerr)
	if gorg == "" || gerr != nil {
		return ""
	}
	r := regexp.MustCompile(`(?m)^(?:http(?:s)://)?(([^@]+)@)?(.*?)(?:.git)?$`)
	sm := r.FindAllStringSubmatch(gorg, 1)
	// fmt.Printf("sm: %+v: %d %d\n", sm, len(sm), len(sm[0]))
	if len(sm) == 1 && len(sm[0]) == 4 {
		return sm[0][3]
	}
	return ""
}

func (p *Project) RootFolder() string {
	return p.rootFolder
}

// Inspired by https://github.com/ghthor/journal/blob/0bd4968a4f9841befdd0dde96b2096e6c930e74c/git/git.go

var gitPath string
var goPath string
var wd string

func init() {
	gitPath = getPathForExe("git")
	goPath = getPathForExe("go")
	var err error
	wd, err = os.Getwd()
	if err != nil {
		log.Fatal("Working directory not accessible")
	}
}

func getPathForExe(exe string) string {
	var err error
	var path = ""
	if path, err = exec.LookPath(exe); err != nil {
		aliases := ""
		if runtime.GOOS == "windows" {
			aliases, err = execcmd("doskey", "/macros")
		} else {
			aliases, err = execcmd("alias", "")
		}
		r := regexp.MustCompile(`(?m)^` + exe + `=(.*)\s+[\$%@\*].*$`)
		sm := r.FindAllStringSubmatch(aliases, 1)
		if len(sm) != 1 || len(sm[0]) != 2 {
			log.Fatalf("Unable to find '%s' path in aliases '%s'", exe)
		}
		return sm[0][1]
	}
	if runtime.GOOS == "windows" {
		if strings.HasSuffix(path, ".bat") {
			bat, err := ioutil.ReadFile(path)
			if err != nil {
				log.Fatalf("Unable to read '%s' for '%s'", path, exe)
			}
			bats := string(bat)
			r := regexp.MustCompile(`(?m)^\s*?(.*)\s+[\$%@\*].*$`)
			sm := r.FindAllStringSubmatch(bats, 1)
			if len(sm) != 1 || len(sm[0]) != 2 {
				log.Fatalf("Unable to find '%s' path in file '%s'", exe, path)
			}
			return sm[0][1]
		}
	}
	if path == "" {
		log.Fatalf("Unable to get path for '%s'", exe)
	}
	return path
}

// Construct an *exec.Cmd for `git {args}` with a workingDirectory
func Git(cmd string) (string, error) {
	return execcmd(gitPath, cmd)
}
func Golang(cmd string) (string, error) {
	os.Setenv("GOPATH", project.rootFolder+`/deps`)
	os.Setenv("GOBIN", project.rootFolder+`/bin`)
	return execcmd(goPath, cmd)
}

func execcmd(exe, cmd string) (string, error) {
	if Debug {
		fmt.Printf("%s %s\n", exe, cmd)
	}
	args := strings.Split(cmd, " ")
	args = append([]string{"/c", exe}, args...)
	c := exec.Command("cmd", args...)
	c.Dir = project.rootFolder
	var bout bytes.Buffer
	c.Stdout = &bout
	var berr bytes.Buffer
	c.Stderr = &berr
	err := c.Run()
	if err != nil {
		return bout.String(), fmt.Errorf("Unable to run '%s %s' in '%s': err '%s'\n'%s'", exe, cmd, wd, err.Error(), berr.String())
	} else if berr.String() != "" {
		return bout.String(), fmt.Errorf("Warning on run '%s %s' in '%s': '%s'", exe, cmd, wd, berr.String())
	}
	return bout.String(), nil
}

func (p *Project) updateGGopath(path string) error {
	dir := filepath.Dir(path)
	name := filepath.Base(path)
	gsrcpdir := p.ggopath + string(filepath.Separator) + "src" + string(filepath.Separator) + dir
	var err error
	if gsrcpdir, err = filepath.Abs(gsrcpdir); err != nil {
		return fmt.Errorf("Unable to get absolute path from '%s'", p.ggopath+string(filepath.Separator)+dir)
	}
	fmt.Println(gsrcpdir)
	if fi, _ := os.Stat(gsrcpdir); fi == nil {
		if err := os.MkdirAll(gsrcpdir, os.ModeDir); err != nil {
			return err
		}
	}
	gsrc := p.ggopath + string(filepath.Separator) + "src" + string(filepath.Separator) + path
	if gsrc, err = filepath.Abs(gsrc); err != nil {
		return fmt.Errorf("Unable to get absolute path from '%s'", p.ggopath+string(os.PathSeparator)+path)
	}
	var fi os.FileInfo
	if fi, _ = os.Stat(gsrc); fi == nil {
		if _, err := execcmd("mklink", fmt.Sprintf("/J %s %s", gsrc, project.rootFolder)); err != nil {
			return err
		}
	} else {
		var l string
		if l, err = execcmd("dir", gsrcpdir); err != nil {
			return fmt.Errorf("Unable to list %s in '%s'", name, gsrcpdir)
		}
		fmt.Println(l)
		r := regexp.MustCompile(fmt.Sprintf(`(?m)<JUNCTION>\s+%s\s+\[([^\]]+)\]\s*$`, name))
		n := r.FindAllStringSubmatch(l, -1)
		fmt.Printf("n='%+v'\n", n)
		if len(n) == 1 {
			pp := n[0][1]
			fmt.Printf("pp='%+v' vs. '%s'\n", pp, p.RootFolder())
			if strings.HasPrefix(pp, p.RootFolder()) {
				return nil
			}
			return fmt.Errorf("'%s' should point to '%s' but points instead to '%s'", gsrc, p.RootFolder(), pp)
		}
		r = regexp.MustCompile(fmt.Sprintf(`(?m)<DIR>\s+%s\s*$`, name))
		n = r.FindAllStringSubmatch(l, -1)
		fmt.Printf("n='%+v'\n", n)
		if len(n) == 1 {
			// move dir
			if err = os.Rename(gsrc, gsrc+".1"); err != nil {
				return fmt.Errorf("Unable to rename '%s'", gsrc)
			}
			// Let's try again, now that the dir has been renamed
			return p.updateGGopath(path)
		} else {
			return fmt.Errorf("Unable to access '%s'", gsrc)
		}
	}
	os.Exit(0)
	return nil
}
<|endoftext|>


<commit_before>package adyen

import "testing"

func TestTestEnvironment(t *testing.T) {
	act := TestEnvironment()
	equals(t, Testing.apiURL, act.apiURL)
	equals(t, Testing.clientURL, act.clientURL)
	equals(t, Testing.hppURL, act.hppURL)
}

func TestBaseURLEnvironmentTesting(t *testing.T) {
	env := TestEnvironment()
	act := env.BaseURL("service", "version")
	exp := "https://pal-test.adyen.com/pal/servlet/service/version"

	equals(t, exp, act)
}

func TestClientURLEnvironmentTesting(t *testing.T) {
	env := TestEnvironment()
	act := env.ClientURL("clientID")
	exp := "https://test.adyen.com/hpp/cse/js/clientID.shtml"

	equals(t, exp, act)
}

func TestHppURLEnvironmentTest(t *testing.T) {
	env := TestEnvironment()
	act := env.HppURL("request")
	exp := "https://test.adyen.com/hpp/request.shtml"

	equals(t, exp, act)
}

func TestCheckoutURLEnvironmentTesting(t *testing.T) {
	env := TestEnvironment()
	act := env.CheckoutURL("service", "version")
	exp := "https://checkout-test.adyen.com/services/PaymentSetupAndVerification/version/service"

	equals(t, exp, act)
}

func TestEnvironmentProductionValidation(t *testing.T) {
	cases := []struct {
		name        string
		random      string
		companyName string
	}{
		{
			name:        "missing random",
			random:      "",
			companyName: "AcmeAccount123",
		},
		{
			name:        "missing company name",
			random:      "5409c4fd1cc98a4e",
			companyName: "",
		},
		{
			name:        "missing random and company name",
			random:      "",
			companyName: "",
		},
	}

	for _, c := range cases {
		t.Run(c.name, func(t *testing.T) {
			_, err := ProductionEnvironment(c.random, c.companyName)
			equals(t, errProdEnvValidation, err)
		})
	}
}

func TestBaseURLEnvironmentProduction(t *testing.T) {
	env, err := ProductionEnvironment("5409c4fd1cc98a4e", "AcmeAccount123")
	if err != nil {
		t.Fatalf("error creating production environment: %v", err)
	}

	act := env.BaseURL("service", "version")
	exp := "https://5409c4fd1cc98a4e-AcmeAccount123-pal-live.adyen.com/pal/servlet/service/version"

	equals(t, exp, act)
}

func TestClientURLEnvironmentProduction(t *testing.T) {
	env, err := ProductionEnvironment("5409c4fd1cc98a4e", "AcmeAccount123")
	if err != nil {
		t.Fatalf("error creating production environment: %v", err)
	}

	act := env.ClientURL("clientID")
	exp := "https://live.adyen.com/hpp/cse/js/clientID.shtml"

	equals(t, exp, act)
}

func TestHppURLEnvironmentProduction(t *testing.T) {
	env, err := ProductionEnvironment("5409c4fd1cc98a4e", "AcmeAccount123")
	if err != nil {
		t.Fatalf("error creating production environment: %v", err)
	}

	act := env.HppURL("request")
	exp := "https://live.adyen.com/hpp/request.shtml"

	equals(t, exp, act)
}

func TestCheckoutURLEnvironmentProduction(t *testing.T) {
	env, err := ProductionEnvironment("5409c4fd1cc98a4e", "AcmeAccount123")
	if err != nil {
		t.Fatalf("error creating production environment: %v", err)
	}

	act := env.CheckoutURL("service", "version")
	exp := "https://5409c4fd1cc98a4e-AcmeAccount123-checkout-live.adyen.com/services/PaymentSetupAndVerification/version/service"

	equals(t, exp, act)
}<commit_msg>Update environment_test.go<commit_after>package adyen

import "testing"

func TestTestEnvironment(t *testing.T) {
	act := TestEnvironment()
	equals(t, Testing.apiURL, act.apiURL)
	equals(t, Testing.clientURL, act.clientURL)
	equals(t, Testing.hppURL, act.hppURL)
}

func TestBaseURLEnvironmentTesting(t *testing.T) {
	env := TestEnvironment()
	act := env.BaseURL("service", "version")
	exp := "https://pal-test.adyen.com/pal/servlet/service/version"

	equals(t, exp, act)
}

func TestClientURLEnvironmentTesting(t *testing.T) {
	env := TestEnvironment()
	act := env.ClientURL("clientID")
	exp := "https://test.adyen.com/hpp/cse/js/clientID.shtml"

	equals(t, exp, act)
}

func TestHppURLEnvironmentTest(t *testing.T) {
	env := TestEnvironment()
	act := env.HppURL("request")
	exp := "https://test.adyen.com/hpp/request.shtml"

	equals(t, exp, act)
}

func TestCheckoutURLEnvironmentTesting(t *testing.T) {
	env := TestEnvironment()
	act := env.CheckoutURL("service", "version")
	exp := "https://checkout-test.adyen.com/services/PaymentSetupAndVerification/version/service"

	equals(t, exp, act)
}

func TestEnvironmentProductionValidation(t *testing.T) {
	cases := []struct {
		name        string
		random      string
		companyName string
	}{
		{
			name:        "missing random",
			random:      "",
			companyName: "AcmeAccount123",
		},
		{
			name:        "missing company name",
			random:      "5409c4fd1cc98a4e",
			companyName: "",
		},
		{
			name:        "missing random and company name",
			random:      "",
			companyName: "",
		},
	}

	for _, c := range cases {
		t.Run(c.name, func(t *testing.T) {
			_, err := ProductionEnvironment(c.random, c.companyName)
			equals(t, errProdEnvValidation, err)
		})
	}
}

func TestBaseURLEnvironmentProduction(t *testing.T) {
	env, err := ProductionEnvironment("5409c4fd1cc98a4e", "AcmeAccount123")
	if err != nil {
		t.Fatalf("error creating production environment: %v", err)
	}

	act := env.BaseURL("service", "version")
	exp := "https://5409c4fd1cc98a4e-AcmeAccount123-pal-live.adyenpayments.com/pal/servlet/service/version"

	equals(t, exp, act)
}

func TestClientURLEnvironmentProduction(t *testing.T) {
	env, err := ProductionEnvironment("5409c4fd1cc98a4e", "AcmeAccount123")
	if err != nil {
		t.Fatalf("error creating production environment: %v", err)
	}

	act := env.ClientURL("clientID")
	exp := "https://live.adyen.com/hpp/cse/js/clientID.shtml"

	equals(t, exp, act)
}

func TestHppURLEnvironmentProduction(t *testing.T) {
	env, err := ProductionEnvironment("5409c4fd1cc98a4e", "AcmeAccount123")
	if err != nil {
		t.Fatalf("error creating production environment: %v", err)
	}

	act := env.HppURL("request")
	exp := "https://live.adyen.com/hpp/request.shtml"

	equals(t, exp, act)
}

func TestCheckoutURLEnvironmentProduction(t *testing.T) {
	env, err := ProductionEnvironment("5409c4fd1cc98a4e", "AcmeAccount123")
	if err != nil {
		t.Fatalf("error creating production environment: %v", err)
	}

	act := env.CheckoutURL("service", "version")
	exp := "https://5409c4fd1cc98a4e-AcmeAccount123-checkout-live.adyen.com/services/PaymentSetupAndVerification/version/service"

	equals(t, exp, act)
}
<|endoftext|>


<commit_before>package client

import (
	"time"

	"github.com/pkg/errors"
	cmn "github.com/tendermint/go-common"
	events "github.com/tendermint/go-events"
	"github.com/tendermint/tendermint/types"
)

// Waiter is informed of current height, decided whether to quit early
type Waiter func(delta int) (abort error)

// DefaultWaitStrategy is the standard backoff algorithm,
// but you can plug in another one
func DefaultWaitStrategy(delta int) (abort error) {
	if delta > 10 {
		return errors.Errorf("Waiting for %d blocks... aborting", delta)
	} else if delta > 0 {
		// estimate of wait time....
		// wait half a second for the next block (in progress)
		// plus one second for every full block
		delay := time.Duration(delta-1)*time.Second + 500*time.Millisecond
		time.Sleep(delay)
	}
	return nil
}

// Wait for height will poll status at reasonable intervals until
// the block at the given height is available.
//
// If waiter is nil, we use DefaultWaitStrategy, but you can also
// provide your own implementation
func WaitForHeight(c StatusClient, h int, waiter Waiter) error {
	if waiter == nil {
		waiter = DefaultWaitStrategy
	}
	delta := 1
	for delta > 0 {
		s, err := c.Status()
		if err != nil {
			return err
		}
		delta = h - s.LatestBlockHeight
		// wait for the time, or abort early
		if err := waiter(delta); err != nil {
			return err
		}
	}
	return nil
}

// WaitForOneEvent subscribes to a websocket event for the given
// event time and returns upon receiving it one time, or
// when the timeout duration has expired.
//
// This handles subscribing and unsubscribing under the hood
func WaitForOneEvent(evsw types.EventSwitch,
	evtTyp string, timeout time.Duration) (types.TMEventData, error) {
	listener := cmn.RandStr(12)

	evts, quit := make(chan events.EventData, 10), make(chan bool, 1)
	// start timeout count-down
	go func() {
		time.Sleep(1 * time.Second)
		quit <- true
	}()

	// register for the next event of this type
	evsw.AddListenerForEvent(listener, evtTyp, func(data events.EventData) {
		evts <- data
	})
	// make sure to unregister after the test is over
	// TODO: why doesn't the other call work???
	// defer evsw.RemoveListenerForEvent(listener, evtTyp)
	defer evsw.RemoveListener(listener)

	select {
	case <-quit:
		return nil, errors.New("timed out waiting for event")
	case evt := <-evts:
		tmevt, ok := evt.(types.TMEventData)
		if ok {
			return tmevt, nil
		}
		return nil, errors.Errorf("Got unexpected event type: %#v", evt)
	}
}
<commit_msg>fix typo<commit_after>package client

import (
	"time"

	"github.com/pkg/errors"
	cmn "github.com/tendermint/go-common"
	events "github.com/tendermint/go-events"
	"github.com/tendermint/tendermint/types"
)

// Waiter is informed of current height, decided whether to quit early
type Waiter func(delta int) (abort error)

// DefaultWaitStrategy is the standard backoff algorithm,
// but you can plug in another one
func DefaultWaitStrategy(delta int) (abort error) {
	if delta > 10 {
		return errors.Errorf("Waiting for %d blocks... aborting", delta)
	} else if delta > 0 {
		// estimate of wait time....
		// wait half a second for the next block (in progress)
		// plus one second for every full block
		delay := time.Duration(delta-1)*time.Second + 500*time.Millisecond
		time.Sleep(delay)
	}
	return nil
}

// Wait for height will poll status at reasonable intervals until
// the block at the given height is available.
//
// If waiter is nil, we use DefaultWaitStrategy, but you can also
// provide your own implementation
func WaitForHeight(c StatusClient, h int, waiter Waiter) error {
	if waiter == nil {
		waiter = DefaultWaitStrategy
	}
	delta := 1
	for delta > 0 {
		s, err := c.Status()
		if err != nil {
			return err
		}
		delta = h - s.LatestBlockHeight
		// wait for the time, or abort early
		if err := waiter(delta); err != nil {
			return err
		}
	}
	return nil
}

// WaitForOneEvent subscribes to a websocket event for the given
// event time and returns upon receiving it one time, or
// when the timeout duration has expired.
//
// This handles subscribing and unsubscribing under the hood
func WaitForOneEvent(evsw types.EventSwitch,
	evtTyp string, timeout time.Duration) (types.TMEventData, error) {
	listener := cmn.RandStr(12)

	evts, quit := make(chan events.EventData, 10), make(chan bool, 1)
	// start timeout count-down
	go func() {
		time.Sleep(timeout)
		quit <- true
	}()

	// register for the next event of this type
	evsw.AddListenerForEvent(listener, evtTyp, func(data events.EventData) {
		evts <- data
	})
	// make sure to unregister after the test is over
	// TODO: why doesn't the other call work???
	// defer evsw.RemoveListenerForEvent(listener, evtTyp)
	defer evsw.RemoveListener(listener)

	select {
	case <-quit:
		return nil, errors.New("timed out waiting for event")
	case evt := <-evts:
		tmevt, ok := evt.(types.TMEventData)
		if ok {
			return tmevt, nil
		}
		return nil, errors.Errorf("Got unexpected event type: %#v", evt)
	}
}
<|endoftext|>


<commit_before>package rrs

import (
	"fmt"
	"runtime"
	"testing"
	"time"

	"github.com/facebookgo/ensure"
	"github.com/teh-cmc/seq"
)

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

// NOTE: run these tests with `go test -race -cpu 1,8,32`

func TestRRSeq_New_BufSize(t *testing.T) {
	var rrseq *RRSeq
	var err error

	name := fmt.Sprintf("TestRRSeq_New_BufSize(gomaxprocs:%d)", runtime.GOMAXPROCS(0))

	rrseq, err = NewRRSeq(name, -42, testingRRServerAddrs...)
	if err != nil {
		t.Fatal(err)
	}
	ensure.DeepEqual(t, cap(rrseq.ids), 0)

	rrseq, err = NewRRSeq(name, 0, testingRRServerAddrs...)
	if err != nil {
		t.Fatal(err)
	}
	ensure.DeepEqual(t, cap(rrseq.ids), 0)

	rrseq, err = NewRRSeq(name, 1, testingRRServerAddrs...)
	if err != nil {
		t.Fatal(err)
	}
	ensure.DeepEqual(t, cap(rrseq.ids), 1)

	rrseq, err = NewRRSeq(name, 1e6, testingRRServerAddrs...)
	if err != nil {
		t.Fatal(err)
	}
	ensure.DeepEqual(t, cap(rrseq.ids), int(1e6))
}

func TestRRSeq_FirstID(t *testing.T) {
	name := fmt.Sprintf("TestRRSeq_FirstID(gomaxprocs:%d)", runtime.GOMAXPROCS(0))
	rrseq, err := NewRRSeq(name, 1e2, testingRRServerAddrs...)
	if err != nil {
		t.Fatal(err)
	}
	ensure.DeepEqual(t, <-rrseq.GetStream(), seq.ID(1))
}

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

func testRRSeq_SingleClient(bufSize int, t *testing.T) {
	name := fmt.Sprintf(
		"testRRSeq_SingleClient(bufsz:%d)(gomaxprocs:%d)", bufSize, runtime.GOMAXPROCS(0),
	)
	s, err := NewRRSeq(name, bufSize, testingRRServerAddrs...)
	if err != nil {
		t.Fatal(err)
	}
	lastID := seq.ID(0)

	go func() {
		<-time.After(time.Millisecond * 500)
		_ = s.Close()
	}()

	for id := range s.GetStream() {
		ensure.DeepEqual(t, id, lastID+1)
		lastID = id
	}
}

func TestRRSeq_BufSize0_SingleClient(t *testing.T) {
	testRRSeq_SingleClient(0, t)
}

func TestRRSeq_BufSize1_SingleClient(t *testing.T) {
	testRRSeq_SingleClient(1, t)
}

func TestRRSeq_BufSize1024_SingleClient(t *testing.T) {
	testRRSeq_SingleClient(1024, t)
}

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

func testRRSeq_MultiClient(bufSize int, t *testing.T) {
	name := fmt.Sprintf(
		"testRRSeq_MultiClient(bufsz:%d)(gomaxprocs:%d)", bufSize, runtime.GOMAXPROCS(0),
	)
	s, err := NewRRSeq(name, bufSize, testingRRServerAddrs...)
	if err != nil {
		t.Fatal(err)
	}
	lastID := seq.ID(0)

	go func() {
		<-time.After(time.Millisecond * 500)
		_ = s.Close()
	}()

	s1, s2, s3 := s.GetStream(), s.GetStream(), s.GetStream()
	for {
		id1 := s1.Next()
		if id1 == 0 {
			break
		}
		ensure.DeepEqual(t, id1, lastID+1)
		lastID++
		id2 := s2.Next()
		if id2 == 0 {
			break
		}
		ensure.DeepEqual(t, id2, id1+1)
		lastID++
		id3 := s3.Next()
		if id3 == 0 {
			break
		}
		ensure.DeepEqual(t, id3, id2+1)
		lastID++
	}
}

func TestRRSeq_BufSize0_MultiClient(t *testing.T) {
	testRRSeq_MultiClient(0, t)
}

func TestRRSeq_BufSize1_MultiClient(t *testing.T) {
	testRRSeq_MultiClient(1, t)
}

func TestRRSeq_BufSize1024_MultiClient(t *testing.T) {
	testRRSeq_MultiClient(1024, t)
}
<commit_msg>added testRRSeq_ConcurrentClients256_Local{0,1,1024}<commit_after>package rrs

import (
	"fmt"
	"runtime"
	"sync"
	"testing"
	"time"

	"github.com/facebookgo/ensure"
	"github.com/teh-cmc/seq"
)

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

// NOTE: run these tests with `go test -race -cpu 1,8,32`

func TestRRSeq_New_BufSize(t *testing.T) {
	var rrseq *RRSeq
	var err error

	name := fmt.Sprintf("TestRRSeq_New_BufSize(gomaxprocs:%d)", runtime.GOMAXPROCS(0))

	rrseq, err = NewRRSeq(name, -42, testingRRServerAddrs...)
	if err != nil {
		t.Fatal(err)
	}
	ensure.DeepEqual(t, cap(rrseq.ids), 0)

	rrseq, err = NewRRSeq(name, 0, testingRRServerAddrs...)
	if err != nil {
		t.Fatal(err)
	}
	ensure.DeepEqual(t, cap(rrseq.ids), 0)

	rrseq, err = NewRRSeq(name, 1, testingRRServerAddrs...)
	if err != nil {
		t.Fatal(err)
	}
	ensure.DeepEqual(t, cap(rrseq.ids), 1)

	rrseq, err = NewRRSeq(name, 1e6, testingRRServerAddrs...)
	if err != nil {
		t.Fatal(err)
	}
	ensure.DeepEqual(t, cap(rrseq.ids), int(1e6))
}

func TestRRSeq_FirstID(t *testing.T) {
	name := fmt.Sprintf("TestRRSeq_FirstID(gomaxprocs:%d)", runtime.GOMAXPROCS(0))
	rrseq, err := NewRRSeq(name, 1e2, testingRRServerAddrs...)
	if err != nil {
		t.Fatal(err)
	}
	ensure.DeepEqual(t, <-rrseq.GetStream(), seq.ID(1))
}

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

func testRRSeq_SingleClient(bufSize int, t *testing.T) {
	name := fmt.Sprintf(
		"testRRSeq_SingleClient(bufsz:%d)(gomaxprocs:%d)", bufSize, runtime.GOMAXPROCS(0),
	)
	s, err := NewRRSeq(name, bufSize, testingRRServerAddrs...)
	if err != nil {
		t.Fatal(err)
	}
	lastID := seq.ID(0)

	go func() {
		<-time.After(time.Millisecond * 500)
		_ = s.Close()
	}()

	for id := range s.GetStream() {
		ensure.DeepEqual(t, id, lastID+1)
		lastID = id
	}
}

func TestRRSeq_BufSize0_SingleClient(t *testing.T) {
	testRRSeq_SingleClient(0, t)
}

func TestRRSeq_BufSize1_SingleClient(t *testing.T) {
	testRRSeq_SingleClient(1, t)
}

func TestRRSeq_BufSize1024_SingleClient(t *testing.T) {
	testRRSeq_SingleClient(1024, t)
}

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

func testRRSeq_MultiClient_Local(bufSize int, t *testing.T) {
	name := fmt.Sprintf(
		"testRRSeq_MultiClient_Local(bufsz:%d)(gomaxprocs:%d)", bufSize, runtime.GOMAXPROCS(0),
	)
	s, err := NewRRSeq(name, bufSize, testingRRServerAddrs...)
	if err != nil {
		t.Fatal(err)
	}
	lastID := seq.ID(0)

	go func() {
		<-time.After(time.Millisecond * 500)
		_ = s.Close()
	}()

	s1, s2, s3 := s.GetStream(), s.GetStream(), s.GetStream()
	for {
		id1 := s1.Next()
		if id1 == 0 {
			break
		}
		ensure.DeepEqual(t, id1, lastID+1)
		lastID++
		id2 := s2.Next()
		if id2 == 0 {
			break
		}
		ensure.DeepEqual(t, id2, id1+1)
		lastID++
		id3 := s3.Next()
		if id3 == 0 {
			break
		}
		ensure.DeepEqual(t, id3, id2+1)
		lastID++
	}
}

func TestRRSeq_BufSize0_MultiClient_Local(t *testing.T) {
	testRRSeq_MultiClient_Local(0, t)
}

func TestRRSeq_BufSize1_MultiClient_Local(t *testing.T) {
	testRRSeq_MultiClient_Local(1, t)
}

func TestRRSeq_BufSize1024_MultiClient_Local(t *testing.T) {
	testRRSeq_MultiClient_Local(1024, t)
}

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

func testRRSeq_ConcurrentClients256_Local(bufSize int, t *testing.T) {
	name := fmt.Sprintf(
		"testRRSeq_ConcurrentClients256_Local(bufsz:%d)(gomaxprocs:%d)", bufSize, runtime.GOMAXPROCS(0),
	)
	s, err := NewRRSeq(name, bufSize, testingRRServerAddrs...)
	if err != nil {
		t.Fatal(err)
	}

	go func() {
		<-time.After(time.Millisecond * 500)
		_ = s.Close()
	}()

	wg := &sync.WaitGroup{}
	for i := 0; i < 256; i++ {
		wg.Add(1)
		go func() {
			for id := range s.GetStream() {
				_ = id
			}
			wg.Done()
		}()
	}
	wg.Wait()
}

func TestRRSeq_BufSize0_ConcurrentClients256_Local(t *testing.T) {
	testRRSeq_ConcurrentClients256_Local(0, t)
}

func TestRRSeq_BufSize1_ConcurrentClients256_Local(t *testing.T) {
	testRRSeq_ConcurrentClients256_Local(1, t)
}

func TestRRSeq_BufSize1024_ConcurrentClients256_Local(t *testing.T) {
	testRRSeq_ConcurrentClients256_Local(1024, t)
}
<|endoftext|>


<commit_before>package model_test

import (
	"encoding/json"
	"github.com/crezam/actions-on-google-golang/internal/test"
	"github.com/crezam/actions-on-google-golang/model"
	"os"
	"testing"
	"time"
)

func TestRequestParsing(t *testing.T) {

	var req model.ApiAiRequest

	file, _ := os.Open("./data/sample_request1.json")
	dec := json.NewDecoder(file)

	err := dec.Decode(&req)

	// test if any issues decoding file
	test.Ok(t, err)

	// assert correct parsing
	test.Equals(t, "209eefa7-adb5-4d03-a8b9-9f7ae68a0c11", req.Id)

	expectedTimestamp, _ := time.Parse(time.RFC3339Nano, "2016-10-10T07:41:40.098Z")
	test.Equals(t, expectedTimestamp, req.Timestamp)

	test.Equals(t, "Hi, my name is Sam!", req.Result.ResolvedQuery)
}
<commit_msg>Add tests for parameters (verified broken), fix next commit<commit_after>package model_test

import (
	"encoding/json"
	"github.com/crezam/actions-on-google-golang/internal/test"
	"github.com/crezam/actions-on-google-golang/model"
	"os"
	"testing"
	"time"
)

func TestRequestParsing(t *testing.T) {

	var req model.ApiAiRequest

	file, _ := os.Open("./data/sample_request1.json")
	dec := json.NewDecoder(file)

	err := dec.Decode(&req)

	// test if any issues decoding file
	test.Ok(t, err)

	// assert correct parsing
	test.Equals(t, "209eefa7-adb5-4d03-a8b9-9f7ae68a0c11", req.Id)

	expectedTimestamp, _ := time.Parse(time.RFC3339Nano, "2016-10-10T07:41:40.098Z")
	test.Equals(t, expectedTimestamp, req.Timestamp)

	test.Equals(t, "Hi, my name is Sam!", req.Result.ResolvedQuery)
	test.Equals(t, "agent", req.Result.Source)
	test.Equals(t, "greetings", req.Result.Action)
	test.Equals(t, false, req.Result.ActionIncomplete)
	test.Equals(t, "Sam", req.Result.Parameters.Parameters["user_name"])

}
<|endoftext|>


<commit_before>package edit

import (
	"io/ioutil"
	"path"
	"strings"

	"github.com/elves/elvish/eval"
	"github.com/elves/elvish/parse"
)

// A completer takes the current node
type completer func(parse.Node, *Editor) []*candidate

var completers = []struct {
	name string
	completer
}{
	{"variable", complVariable},
	{"command name", complEmptyChunk},
	{"command name", makeCompoundCompleter(complFormHead)},
	{"argument", makeCompoundCompleter(complArg)},
}

func complVariable(n parse.Node, ed *Editor) []*candidate {
	primary, ok := n.(*parse.Primary)
	if !ok || primary.Type != parse.Variable {
		return nil
	}

	head := primary.Value[1:]
	cands := []*candidate{}
	for variable := range ed.evaler.Global() {
		if strings.HasPrefix(variable, head) {
			cands = append(cands, &candidate{
				source: styled{variable[len(head):], attrForType[Variable]},
				menu:   styled{"$" + variable, attrForType[Variable]}})
		}
	}
	return cands
}

func complEmptyChunk(n parse.Node, ed *Editor) []*candidate {
	if _, ok := n.(*parse.Chunk); ok {
		return complFormHeadInner("", ed)
	}
	return nil
}

func makeCompoundCompleter(
	f func(*parse.Compound, string, *Editor) []*candidate) completer {
	return func(n parse.Node, ed *Editor) []*candidate {
		pn, ok := n.(*parse.Primary)
		if !ok {
			return nil
		}
		cn, head := simpleCompound(pn)
		if cn == nil {
			return nil
		}
		return f(cn, head, ed)
	}
}

func complFormHead(cn *parse.Compound, head string, ed *Editor) []*candidate {
	if isFormHead(cn) {
		return complFormHeadInner(head, ed)
	}
	return nil
}

func complFormHeadInner(head string, ed *Editor) []*candidate {
	cands := []*candidate{}
	foundCommand := func(s string) {
		if strings.HasPrefix(s, head) {
			cands = append(cands, &candidate{
				source: styled{s[len(head):], styleForGoodCommand},
				menu:   styled{s, ""},
			})
		}
	}
	for special := range isBuiltinSpecial {
		foundCommand(special)
	}
	for variable := range ed.evaler.Global() {
		if strings.HasPrefix(variable, eval.FnPrefix) {
			foundCommand(variable[3:])
		}
	}
	for command := range ed.isExternal {
		foundCommand(command)
	}
	return cands
}

func complArg(cn *parse.Compound, head string, ed *Editor) []*candidate {
	// Assume that the argument is an incomplete filename
	dir, file := path.Split(head)
	var all []string
	if dir == "" {
		// XXX ignore error
		all, _ = fileNames(".")
	} else {
		all, _ = fileNames(dir)
	}

	cands := []*candidate{}
	// Make candidates out of elements that match the file component.
	for _, s := range all {
		if strings.HasPrefix(s, file) {
			cands = append(cands, &candidate{
				source: styled{s[len(file):], ""},
				menu:   styled{s, defaultLsColor.determineAttr(s)},
			})
		}
	}

	return cands
}

func fileNames(dir string) (names []string, err error) {
	infos, e := ioutil.ReadDir(dir)
	if e != nil {
		err = e
		return
	}
	for _, info := range infos {
		names = append(names, info.Name())
	}
	return
}
<commit_msg>edit: complete new form and new arg<commit_after>package edit

import (
	"io/ioutil"
	"path"
	"strings"

	"github.com/elves/elvish/eval"
	"github.com/elves/elvish/parse"
)

// A completer takes the current node
type completer func(parse.Node, *Editor) []*candidate

var completers = []struct {
	name string
	completer
}{
	{"variable", complVariable},
	{"command name", complNewForm},
	{"command name", makeCompoundCompleter(complFormHead)},
	{"argument", complNewArg},
	{"argument", makeCompoundCompleter(complArg)},
}

func complVariable(n parse.Node, ed *Editor) []*candidate {
	primary, ok := n.(*parse.Primary)
	if !ok || primary.Type != parse.Variable {
		return nil
	}

	head := primary.Value[1:]
	cands := []*candidate{}
	for variable := range ed.evaler.Global() {
		if strings.HasPrefix(variable, head) {
			cands = append(cands, &candidate{
				source: styled{variable[len(head):], attrForType[Variable]},
				menu:   styled{"$" + variable, attrForType[Variable]}})
		}
	}
	return cands
}

func complNewForm(n parse.Node, ed *Editor) []*candidate {
	if _, ok := n.(*parse.Chunk); ok {
		return complFormHeadInner("", ed)
	}
	if _, ok := n.Parent().(*parse.Chunk); ok {
		return complFormHeadInner("", ed)
	}
	return nil
}

func makeCompoundCompleter(
	f func(*parse.Compound, string, *Editor) []*candidate) completer {
	return func(n parse.Node, ed *Editor) []*candidate {
		pn, ok := n.(*parse.Primary)
		if !ok {
			return nil
		}
		cn, head := simpleCompound(pn)
		if cn == nil {
			return nil
		}
		return f(cn, head, ed)
	}
}

func complFormHead(cn *parse.Compound, head string, ed *Editor) []*candidate {
	if isFormHead(cn) {
		return complFormHeadInner(head, ed)
	}
	return nil
}

func complFormHeadInner(head string, ed *Editor) []*candidate {
	cands := []*candidate{}
	foundCommand := func(s string) {
		if strings.HasPrefix(s, head) {
			cands = append(cands, &candidate{
				source: styled{s[len(head):], styleForGoodCommand},
				menu:   styled{s, ""},
			})
		}
	}
	for special := range isBuiltinSpecial {
		foundCommand(special)
	}
	for variable := range ed.evaler.Global() {
		if strings.HasPrefix(variable, eval.FnPrefix) {
			foundCommand(variable[3:])
		}
	}
	for command := range ed.isExternal {
		foundCommand(command)
	}
	return cands
}

func complNewArg(n parse.Node, ed *Editor) []*candidate {
	sn, ok := n.(*parse.Sep)
	if !ok {
		return nil
	}
	if _, ok := sn.Parent().(*parse.Form); !ok {
		return nil
	}
	return complArgInner("")
}

func complArg(cn *parse.Compound, head string, ed *Editor) []*candidate {
	return complArgInner(head)
}

func complArgInner(head string) []*candidate {
	// Assume that the argument is an incomplete filename
	dir, file := path.Split(head)
	var all []string
	if dir == "" {
		// XXX ignore error
		all, _ = fileNames(".")
	} else {
		all, _ = fileNames(dir)
	}

	cands := []*candidate{}
	// Make candidates out of elements that match the file component.
	for _, s := range all {
		if strings.HasPrefix(s, file) {
			cands = append(cands, &candidate{
				source: styled{s[len(file):], ""},
				menu:   styled{s, defaultLsColor.determineAttr(s)},
			})
		}
	}

	return cands
}

func fileNames(dir string) (names []string, err error) {
	infos, e := ioutil.ReadDir(dir)
	if e != nil {
		err = e
		return
	}
	for _, info := range infos {
		names = append(names, info.Name())
	}
	return
}
<|endoftext|>


<commit_before>package server

import (
	"fmt"
	"github.com/centurylinkcloud/clc-go-cli/base"
	"github.com/centurylinkcloud/clc-go-cli/models"
	"github.com/centurylinkcloud/clc-go-cli/models/group"
	"time"
)

var (
	ListTimeout = 200
)

func Load(cn base.Connection, dataCenter string) ([]GetRes, error) {
	groups, err := group.Load(cn, dataCenter)
	if err != nil {
		return nil, err
	}

	links := []models.LinkEntity{}
	for _, g := range groups {
		err := extractServers(g, &links)
		if err != nil {
			return nil, err
		}
	}

	servers := make([]GetRes, len(links))
	if links == nil {
		return servers, nil
	}
	done := make(chan error)
	for i, link := range links {
		go loadServer(link, servers, i, done, cn)
	}

	serversLoaded := 0
	for {
		select {
		case err := <-done:
			if err != nil {
				return nil, err
			}
			serversLoaded += 1
			if serversLoaded == len(servers) {
				return servers, nil
			}
		case <-time.After(time.Second * time.Duration(ListTimeout)):
			return nil, fmt.Errorf("Request timeout error")
		}
	}
}

func IDByName(cn base.Connection, name string) (string, error) {
	servers, err := Load(cn, "all")
	if err != nil {
		return "", err
	}

	matched := []string{}
	for _, s := range servers {
		if s.Name == name {
			matched = append(matched, s.Id)
		}
	}

	switch len(matched) {
	case 0:
		return "", fmt.Errorf("There are no servers with name %s.", name)
	case 1:
		return matched[0], nil
	default:
		return "", fmt.Errorf("There is more than one server with name %s. Please, specify an ID.", name)
	}
}

func GetNames(cn base.Connection, dataCenter string) ([]string, error) {
	servers, err := Load(cn, "all")
	if err != nil {
		return nil, err
	}

	names := []string{}
	for _, s := range servers {
		names = append(names, s.Name)
	}
	return names, nil
}

func extractServers(g group.Entity, servers *[]models.LinkEntity) error {
	if g.ServersCount == 0 {
		return nil
	}

	for _, link := range g.Links {
		if link.Rel == "server" {
			*servers = append(*servers, link)
		}
	}
	if len(g.Groups) != 0 {
		for _, gnested := range g.Groups {
			err := extractServers(gnested, servers)
			if err != nil {
				return err
			}
		}
	}
	return nil
}

func loadServer(link models.LinkEntity, servers []GetRes, index int, done chan<- error, cn base.Connection) {
	href, err := models.GetLink([]models.LinkEntity{link}, "server")
	if err != nil {
		done <- err
		return
	}

	serverURL := fmt.Sprintf("%s%s", base.URL, href)
	d := GetRes{}
	err = cn.ExecuteRequest("GET", serverURL, nil, &d)
	if err != nil {
		done <- err
		return
	}

	servers[index] = d
	done <- nil
}
<commit_msg>Check if servers exist at all before collecting them<commit_after>package server

import (
	"fmt"
	"github.com/centurylinkcloud/clc-go-cli/base"
	"github.com/centurylinkcloud/clc-go-cli/models"
	"github.com/centurylinkcloud/clc-go-cli/models/group"
	"time"
)

var (
	ListTimeout = 200
)

func Load(cn base.Connection, dataCenter string) ([]GetRes, error) {
	groups, err := group.Load(cn, dataCenter)
	if err != nil {
		return nil, err
	}

	links := []models.LinkEntity{}
	for _, g := range groups {
		err := extractServers(g, &links)
		if err != nil {
			return nil, err
		}
	}

	servers := make([]GetRes, len(links))
	if len(links) == 0 {
		return servers, nil
	}
	done := make(chan error)
	for i, link := range links {
		go loadServer(link, servers, i, done, cn)
	}

	serversLoaded := 0
	for {
		select {
		case err := <-done:
			if err != nil {
				return nil, err
			}
			serversLoaded += 1
			if serversLoaded == len(servers) {
				return servers, nil
			}
		case <-time.After(time.Second * time.Duration(ListTimeout)):
			return nil, fmt.Errorf("Request timeout error")
		}
	}
}

func IDByName(cn base.Connection, name string) (string, error) {
	servers, err := Load(cn, "all")
	if err != nil {
		return "", err
	}

	matched := []string{}
	for _, s := range servers {
		if s.Name == name {
			matched = append(matched, s.Id)
		}
	}

	switch len(matched) {
	case 0:
		return "", fmt.Errorf("There are no servers with name %s.", name)
	case 1:
		return matched[0], nil
	default:
		return "", fmt.Errorf("There is more than one server with name %s. Please, specify an ID.", name)
	}
}

func GetNames(cn base.Connection, dataCenter string) ([]string, error) {
	servers, err := Load(cn, "all")
	if err != nil {
		return nil, err
	}

	names := []string{}
	for _, s := range servers {
		names = append(names, s.Name)
	}
	return names, nil
}

func extractServers(g group.Entity, servers *[]models.LinkEntity) error {
	if g.ServersCount == 0 {
		return nil
	}

	for _, link := range g.Links {
		if link.Rel == "server" {
			*servers = append(*servers, link)
		}
	}
	if len(g.Groups) != 0 {
		for _, gnested := range g.Groups {
			err := extractServers(gnested, servers)
			if err != nil {
				return err
			}
		}
	}
	return nil
}

func loadServer(link models.LinkEntity, servers []GetRes, index int, done chan<- error, cn base.Connection) {
	href, err := models.GetLink([]models.LinkEntity{link}, "server")
	if err != nil {
		done <- err
		return
	}

	serverURL := fmt.Sprintf("%s%s", base.URL, href)
	d := GetRes{}
	err = cn.ExecuteRequest("GET", serverURL, nil, &d)
	if err != nil {
		done <- err
		return
	}

	servers[index] = d
	done <- nil
}
<|endoftext|>


<commit_before>/*
Package chacha20 provides a pure Go implementation of ChaCha20, a fast, secure
stream cipher.

From DJB's paper:

	ChaCha8 is a 256-bit stream cipher based on the 8-round cipher Salsa20/8.
	The changes from Salsa20/8 to ChaCha8 are designed to improve diffusion per
	round, conjecturally increasing resistance to cryptanalysis, while
	preserving—and often improving—time per round. ChaCha12 and ChaCha20 are
	analogous modiﬁcations of the 12-round and 20-round ciphers Salsa20/12 and
	Salsa20/20. This paper presents the ChaCha family and explains the
	differences between Salsa20 and ChaCha.

(from http://cr.yp.to/chacha/chacha-20080128.pdf)

For more information, see http://cr.yp.to/chacha.html
*/
package chacha20

import (
	"encoding/binary"
	"errors"
	"unsafe"
)

const (
	// KeySize is the length of ChaCha20 keys, in bytes.
	KeySize = 32

	// NonceSize is the length of ChaCha20 nonces, in bytes.
	NonceSize = 8

	stateSize = 16            // the size of ChaCha20's state, in words
	blockSize = stateSize * 4 // the size of ChaCha20's block, in bytes
)

var (
	// ErrInvalidKey is returned when the provided key is not 256 bits long.
	ErrInvalidKey = errors.New("chacha20: Invalid key length (must be 256 bits)")
	// ErrInvalidNonce is returned when the provided nonce is not 64 bits long.
	ErrInvalidNonce = errors.New("chacha20: Invalid nonce length (must be 64 bits)")
)

// A Cipher is an instance of ChaCha20 using a particular key and nonce.
type Cipher struct {
	state  [stateSize]uint32 // the state as an array of 16 32-bit words
	block  [blockSize]byte   // the keystream as an array of 64 bytes
	offset int               // the offset of used bytes in block
}

// NewCipher creates and returns a new Cipher.  The key argument must be 256
// bits long, and the nonce argument must be 64 bits long. The nonce must be
// randomly generated or used only once. This Cipher instance must not be used
// to encrypt more than 2^70 bytes (~1 zettabyte).
func NewCipher(key []byte, nonce []byte) (*Cipher, error) {
	if len(key) != KeySize {
		return nil, ErrInvalidKey
	}

	if len(nonce) != NonceSize {
		return nil, ErrInvalidNonce
	}

	c := new(Cipher)

	// the magic constants for 256-bit keys
	c.state[0] = 0x61707865
	c.state[1] = 0x3320646e
	c.state[2] = 0x79622d32
	c.state[3] = 0x6b206574

	c.state[4] = binary.LittleEndian.Uint32(key[0:])
	c.state[5] = binary.LittleEndian.Uint32(key[4:])
	c.state[6] = binary.LittleEndian.Uint32(key[8:])
	c.state[7] = binary.LittleEndian.Uint32(key[12:])
	c.state[8] = binary.LittleEndian.Uint32(key[16:])
	c.state[9] = binary.LittleEndian.Uint32(key[20:])
	c.state[10] = binary.LittleEndian.Uint32(key[24:])
	c.state[11] = binary.LittleEndian.Uint32(key[28:])

	c.state[12] = 0
	c.state[13] = 0
	c.state[14] = binary.LittleEndian.Uint32(nonce[0:])
	c.state[15] = binary.LittleEndian.Uint32(nonce[4:])

	c.advance()

	return c, nil
}

// XORKeyStream sets dst to the result of XORing src with the key stream.
// Dst and src may be the same slice but otherwise should not overlap. You
// should not encrypt more than 2^70 bytes (~1 zettabyte) without re-keying and
// using a new nonce.
func (c *Cipher) XORKeyStream(dst, src []byte) {
	// Stride over the input in 64-byte blocks, minus the amount of keystream
	// previously used. This will produce best results when processing blocks
	// of a size evenly divisible by 64.
	i := 0
	max := len(src)
	for i < max {
		gap := blockSize - c.offset

		limit := i + gap
		if limit > max {
			limit = max
		}

		o := c.offset
		for j := i; j < limit; j++ {
			dst[j] = src[j] ^ c.block[o]
			o++
		}

		i += gap
		c.offset = o

		if o == blockSize {
			c.advance()
		}
	}
}

// Reset zeros the key data so that it will no longer appear in the process's
// memory.
func (c *Cipher) Reset() {
	for i := range c.state {
		c.state[i] = 0
	}
	for i := range c.block {
		c.block[i] = 0
	}
	c.offset = 0
}

// advances the keystream
func (c *Cipher) advance() {
	core(&c.state, (*[stateSize]uint32)(unsafe.Pointer(&c.block)))
	c.offset = 0
	i := c.state[12] + 1
	c.state[12] = i
	if i == 0 {
		c.state[13]++
	}
}
<commit_msg>First attempt at a fix for big-endian archs.<commit_after>/*
Package chacha20 provides a pure Go implementation of ChaCha20, a fast, secure
stream cipher.

From DJB's paper:

	ChaCha8 is a 256-bit stream cipher based on the 8-round cipher Salsa20/8.
	The changes from Salsa20/8 to ChaCha8 are designed to improve diffusion per
	round, conjecturally increasing resistance to cryptanalysis, while
	preserving—and often improving—time per round. ChaCha12 and ChaCha20 are
	analogous modiﬁcations of the 12-round and 20-round ciphers Salsa20/12 and
	Salsa20/20. This paper presents the ChaCha family and explains the
	differences between Salsa20 and ChaCha.

(from http://cr.yp.to/chacha/chacha-20080128.pdf)

For more information, see http://cr.yp.to/chacha.html
*/
package chacha20

import (
	"encoding/binary"
	"errors"
	"unsafe"
)

const (
	// KeySize is the length of ChaCha20 keys, in bytes.
	KeySize = 32

	// NonceSize is the length of ChaCha20 nonces, in bytes.
	NonceSize = 8

	stateSize = 16            // the size of ChaCha20's state, in words
	blockSize = stateSize * 4 // the size of ChaCha20's block, in bytes
)

var (
	// ErrInvalidKey is returned when the provided key is not 256 bits long.
	ErrInvalidKey = errors.New("chacha20: Invalid key length (must be 256 bits)")
	// ErrInvalidNonce is returned when the provided nonce is not 64 bits long.
	ErrInvalidNonce = errors.New("chacha20: Invalid nonce length (must be 64 bits)")

	bigEndian bool // we're running on a bigEndian CPU
)

// Do some up-front bookkeeping on what sort of CPU we're using. ChaCha20 treats
// its state as a little-endian byte array when it comes to generating the
// keystream, which allows for a zero-copy approach to the core transform. On
// big-endian architectures, we have to take a hit to reverse the bytes.
func init() {
	x := uint32(0x04030201)
	y := [4]byte{0x1, 0x2, 0x3, 0x4}
	bigEndian = *(*[4]byte)(unsafe.Pointer(&x)) != y
}

// A Cipher is an instance of ChaCha20 using a particular key and nonce.
type Cipher struct {
	state  [stateSize]uint32 // the state as an array of 16 32-bit words
	block  [blockSize]byte   // the keystream as an array of 64 bytes
	offset int               // the offset of used bytes in block
}

// NewCipher creates and returns a new Cipher.  The key argument must be 256
// bits long, and the nonce argument must be 64 bits long. The nonce must be
// randomly generated or used only once. This Cipher instance must not be used
// to encrypt more than 2^70 bytes (~1 zettabyte).
func NewCipher(key []byte, nonce []byte) (*Cipher, error) {
	if len(key) != KeySize {
		return nil, ErrInvalidKey
	}

	if len(nonce) != NonceSize {
		return nil, ErrInvalidNonce
	}

	c := new(Cipher)

	// the magic constants for 256-bit keys
	c.state[0] = 0x61707865
	c.state[1] = 0x3320646e
	c.state[2] = 0x79622d32
	c.state[3] = 0x6b206574

	c.state[4] = binary.LittleEndian.Uint32(key[0:])
	c.state[5] = binary.LittleEndian.Uint32(key[4:])
	c.state[6] = binary.LittleEndian.Uint32(key[8:])
	c.state[7] = binary.LittleEndian.Uint32(key[12:])
	c.state[8] = binary.LittleEndian.Uint32(key[16:])
	c.state[9] = binary.LittleEndian.Uint32(key[20:])
	c.state[10] = binary.LittleEndian.Uint32(key[24:])
	c.state[11] = binary.LittleEndian.Uint32(key[28:])

	c.state[12] = 0
	c.state[13] = 0
	c.state[14] = binary.LittleEndian.Uint32(nonce[0:])
	c.state[15] = binary.LittleEndian.Uint32(nonce[4:])

	c.advance()

	return c, nil
}

// XORKeyStream sets dst to the result of XORing src with the key stream.
// Dst and src may be the same slice but otherwise should not overlap. You
// should not encrypt more than 2^70 bytes (~1 zettabyte) without re-keying and
// using a new nonce.
func (c *Cipher) XORKeyStream(dst, src []byte) {
	// Stride over the input in 64-byte blocks, minus the amount of keystream
	// previously used. This will produce best results when processing blocks
	// of a size evenly divisible by 64.
	i := 0
	max := len(src)
	for i < max {
		gap := blockSize - c.offset

		limit := i + gap
		if limit > max {
			limit = max
		}

		o := c.offset
		for j := i; j < limit; j++ {
			dst[j] = src[j] ^ c.block[o]
			o++
		}

		i += gap
		c.offset = o

		if o == blockSize {
			c.advance()
		}
	}
}

// Reset zeros the key data so that it will no longer appear in the process's
// memory.
func (c *Cipher) Reset() {
	for i := range c.state {
		c.state[i] = 0
	}
	for i := range c.block {
		c.block[i] = 0
	}
	c.offset = 0
}

// BUG(codahale): Totally untested on big-endian CPUs. Would very much
// appreciate someone with an ARM device giving this a swing.

// advances the keystream
func (c *Cipher) advance() {
	core(&c.state, (*[stateSize]uint32)(unsafe.Pointer(&c.block)))

	if bigEndian {
		j := blockSize - 1
		for i := 0; i < blockSize/2; i++ {
			c.block[j], c.block[i] = c.block[i], c.block[j]
			j--
		}
	}

	c.offset = 0
	i := c.state[12] + 1
	c.state[12] = i
	if i == 0 {
		c.state[13]++
	}
}
<|endoftext|>


<commit_before>// Copyright 2015 Marc-Antoine Ruel. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.

// Package circular implements an efficient thread-safe circular byte buffer to
// keep in-memory logs. It implements both io.Writer and io.WriterTo.
package circular

import (
	"io"
	"net/http"
	"sync"
)

// Buffer is designed to keep recent logs in-memory efficiently and in a
// thread-safe manner. It implements both io.Writer and io.WriterTo. It must be
// instantiated with MakeBuffer().
//
// No allocation while writing to it. Independent readers each have their read
// position and are synchronized with the writer to not have any data loss.
type Buffer struct {
	wgReaders        sync.WaitGroup // number of readers active.
	wgReadersWaiting sync.WaitGroup // number of readers waiting for new data.
	wgWriterDone     sync.WaitGroup // safe for readers to get back asleep.
	lock             sync.RWMutex   //
	newData          *sync.Cond     // used to unblock readers all at once.
	buf              []byte         //
	closed           bool           // set to true by Close().
	bytesWritten     int            // total bytes written.
}

// MakeBuffer returns an initialized Buffer.
func MakeBuffer(size int) *Buffer {
	if size <= 0 {
		return nil
	}
	b := &Buffer{
		buf: make([]byte, size),
	}
	b.newData = sync.NewCond(b.lock.RLocker())
	return b
}

// Write implements io.Writer.
//
// If p is longer or equal to the internal buffer, this call will block until
// all readers have kept up with the data. To not get into this condition and
// keep Write() performant, ensure the internal buffer is significantly larger
// than the largest writes.
func (b *Buffer) Write(p []byte) (int, error) {
	s := len(b.buf)
	if s == 0 {
		// Wasn't instantiated with MakeBuffer().
		return 0, io.ErrClosedPipe
	}

	b.lock.Lock()
	defer b.lock.Unlock()
	if b.closed {
		return 0, io.ErrClosedPipe
	}
	originalbytesWritten := b.bytesWritten
	for chunkSize := len(p); chunkSize != 0; chunkSize = len(p) {
		writeOffset := b.bytesWritten % s
		if chunkSize > s-writeOffset {
			chunkSize = s - writeOffset
		}
		copy(b.buf[writeOffset:], p[:chunkSize])
		b.bytesWritten += chunkSize
		p = p[chunkSize:]

		b.wakeAllReaders()

		if b.closed {
			return b.bytesWritten - originalbytesWritten, io.ErrClosedPipe
		}
	}
	return b.bytesWritten - originalbytesWritten, nil
}

// Close implements io.Closer. It closes all WriteTo() streamers synchronously.
func (b *Buffer) Close() error {
	inner := func() error {
		b.lock.Lock()
		defer b.lock.Unlock()
		if b.closed {
			return io.ErrClosedPipe
		}
		// There could be a Write() function underway. Make sure it's properly
		// awaken.
		b.closed = true

		b.wakeAllReaders()

		return nil
	}

	err := inner()
	// Wait for all readers to be done.
	b.wgReaders.Wait()
	return err
}

func (b *Buffer) wakeAllReaders() {
	// Carefully tuned locking sequence to ensure all readers caught up.
	b.wgWriterDone.Add(1)
	b.lock.Unlock()
	b.newData.Broadcast()
	b.wgReadersWaiting.Wait()
	b.wgWriterDone.Done()
	b.lock.Lock()
}

// WriteTo implements io.WriterTo. It streams a Buffer to a io.Writer until
// the Buffer is clsoed. It forcibly flushes the output if w supports
// http.Flusher so it is sent to the underlying TCP connection as data is
// appended.
func (b *Buffer) WriteTo(w io.Writer) (int, error) {
	b.wgReaders.Add(1)
	defer b.wgReaders.Done()

	f, _ := w.(http.Flusher)
	s := len(b.buf)
	var err error
	readOffset := 0

	b.lock.RLock()

	if b.bytesWritten > s {
		// Had rolled over already, initial data is lost.
		readOffset = b.bytesWritten - s
	}
	originalReadOffset := readOffset

	// One of the important property is that when the Buffer is quickly written
	// to then closed, the remaining data is still sent to all readers.
	var wgFlushing sync.WaitGroup
	for (!b.closed || readOffset != b.bytesWritten) && err == nil {
		wrote := false
		for readOffset < b.bytesWritten && err == nil {
			off := readOffset % s
			end := (b.bytesWritten % s)
			if end <= off {
				end = s
			}
			// Never call .Write() and .Flush() concurrently.
			wgFlushing.Wait()
			var n int
			n, err = w.Write(b.buf[off:end])
			readOffset += n
			wrote = n != 0
			if n == 0 {
				break
			}
		}
		if f != nil && wrote {
			wgFlushing.Add(1)
			go func() {
				defer wgFlushing.Done()
				// Flush concurrently to the writer.
				f.Flush()
			}()
		}
		if err != nil {
			break
		}
		b.wgWriterDone.Wait()
		b.wgReadersWaiting.Add(1)
		b.newData.Wait()
		b.wgReadersWaiting.Done()
	}
	b.lock.RUnlock()
	if err == nil {
		err = io.EOF
	}
	wgFlushing.Wait()
	return readOffset - originalReadOffset, err
}
<commit_msg>Fix typo.<commit_after>// Copyright 2015 Marc-Antoine Ruel. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.

// Package circular implements an efficient thread-safe circular byte buffer to
// keep in-memory logs. It implements both io.Writer and io.WriterTo.
package circular

import (
	"io"
	"net/http"
	"sync"
)

// Buffer is designed to keep recent logs in-memory efficiently and in a
// thread-safe manner. It implements both io.Writer and io.WriterTo. It must be
// instantiated with MakeBuffer().
//
// No allocation while writing to it. Independent readers each have their read
// position and are synchronized with the writer to not have any data loss.
type Buffer struct {
	wgReaders        sync.WaitGroup // number of readers active.
	wgReadersWaiting sync.WaitGroup // number of readers waiting for new data.
	wgWriterDone     sync.WaitGroup // safe for readers to get back asleep.
	lock             sync.RWMutex   //
	newData          *sync.Cond     // used to unblock readers all at once.
	buf              []byte         //
	closed           bool           // set to true by Close().
	bytesWritten     int            // total bytes written.
}

// MakeBuffer returns an initialized Buffer.
func MakeBuffer(size int) *Buffer {
	if size <= 0 {
		return nil
	}
	b := &Buffer{
		buf: make([]byte, size),
	}
	b.newData = sync.NewCond(b.lock.RLocker())
	return b
}

// Write implements io.Writer.
//
// If p is longer or equal to the internal buffer, this call will block until
// all readers have kept up with the data. To not get into this condition and
// keep Write() performant, ensure the internal buffer is significantly larger
// than the largest writes.
func (b *Buffer) Write(p []byte) (int, error) {
	s := len(b.buf)
	if s == 0 {
		// Wasn't instantiated with MakeBuffer().
		return 0, io.ErrClosedPipe
	}

	b.lock.Lock()
	defer b.lock.Unlock()
	if b.closed {
		return 0, io.ErrClosedPipe
	}
	originalbytesWritten := b.bytesWritten
	for chunkSize := len(p); chunkSize != 0; chunkSize = len(p) {
		writeOffset := b.bytesWritten % s
		if chunkSize > s-writeOffset {
			chunkSize = s - writeOffset
		}
		copy(b.buf[writeOffset:], p[:chunkSize])
		b.bytesWritten += chunkSize
		p = p[chunkSize:]

		b.wakeAllReaders()

		if b.closed {
			return b.bytesWritten - originalbytesWritten, io.ErrClosedPipe
		}
	}
	return b.bytesWritten - originalbytesWritten, nil
}

// Close implements io.Closer. It closes all WriteTo() streamers synchronously.
func (b *Buffer) Close() error {
	inner := func() error {
		b.lock.Lock()
		defer b.lock.Unlock()
		if b.closed {
			return io.ErrClosedPipe
		}
		// There could be a Write() function underway. Make sure it's properly
		// awaken.
		b.closed = true

		b.wakeAllReaders()

		return nil
	}

	err := inner()
	// Wait for all readers to be done.
	b.wgReaders.Wait()
	return err
}

func (b *Buffer) wakeAllReaders() {
	// Carefully tuned locking sequence to ensure all readers caught up.
	b.wgWriterDone.Add(1)
	b.lock.Unlock()
	b.newData.Broadcast()
	b.wgReadersWaiting.Wait()
	b.wgWriterDone.Done()
	b.lock.Lock()
}

// WriteTo implements io.WriterTo. It streams a Buffer to a io.Writer until
// the Buffer is closed. It forcibly flushes the output if w supports
// http.Flusher so it is sent to the underlying TCP connection as data is
// appended.
func (b *Buffer) WriteTo(w io.Writer) (int, error) {
	b.wgReaders.Add(1)
	defer b.wgReaders.Done()

	f, _ := w.(http.Flusher)
	s := len(b.buf)
	var err error
	readOffset := 0

	b.lock.RLock()

	if b.bytesWritten > s {
		// Had rolled over already, initial data is lost.
		readOffset = b.bytesWritten - s
	}
	originalReadOffset := readOffset

	// One of the important property is that when the Buffer is quickly written
	// to then closed, the remaining data is still sent to all readers.
	var wgFlushing sync.WaitGroup
	for (!b.closed || readOffset != b.bytesWritten) && err == nil {
		wrote := false
		for readOffset < b.bytesWritten && err == nil {
			off := readOffset % s
			end := (b.bytesWritten % s)
			if end <= off {
				end = s
			}
			// Never call .Write() and .Flush() concurrently.
			wgFlushing.Wait()
			var n int
			n, err = w.Write(b.buf[off:end])
			readOffset += n
			wrote = n != 0
			if n == 0 {
				break
			}
		}
		if f != nil && wrote {
			wgFlushing.Add(1)
			go func() {
				defer wgFlushing.Done()
				// Flush concurrently to the writer.
				f.Flush()
			}()
		}
		if err != nil {
			break
		}
		b.wgWriterDone.Wait()
		b.wgReadersWaiting.Add(1)
		b.newData.Wait()
		b.wgReadersWaiting.Done()
	}
	b.lock.RUnlock()
	if err == nil {
		err = io.EOF
	}
	wgFlushing.Wait()
	return readOffset - originalReadOffset, err
}
<|endoftext|>


<commit_before>// Copyright © 2016 Sidharth Kshatriya
//
// 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 engine

import (
	"fmt"
	"strconv"
)

type engineFeatureBool struct {
	value    bool
	readOnly bool
}
type engineFeatureInt struct {
	value    int
	readOnly bool
}
type engineFeatureString struct {
	value    string
	readOnly bool
}

type engineFeatureValue interface {
	set(value string)
	String() string
}

func (feature *engineFeatureBool) set(value string) {
	if feature.readOnly {
		panicWith(fmt.Sprintf("Trying assign %v to a read only value: %v", value, feature.value))
	}

	if value == "0" {
		feature.value = false
	} else if value == "1" {
		feature.value = true
	} else {
		panicWith(fmt.Sprintf("Trying to assign a non-boolean value %v to a boolean: %v", value, feature.value))
	}
}

func (feature engineFeatureBool) String() string {
	if feature.value {
		return "1"
	}

	return "0"
}

func (feature *engineFeatureString) set(value string) {
	if feature.readOnly {
		panicWith(fmt.Sprintf("Trying assign %v to a read only value: %v", value, feature.value))
	}
	feature.value = value
}

func (feature engineFeatureInt) String() string {
	return strconv.Itoa(feature.value)
}

func (feature *engineFeatureInt) set(value string) {
	if feature.readOnly {
		panicWith(fmt.Sprintf("Trying assign %v to a read only value: %v", value, feature.value))
	}
	var err error
	feature.value, err = strconv.Atoi(value)
	panicIf(err)
}

func (feature engineFeatureString) String() string {
	return feature.value
}

func initFeatureMap() map[string]engineFeatureValue {
	var featureMap = map[string]engineFeatureValue{
		"language_supports_threads": &engineFeatureBool{false, true},
		"language_name":             &engineFeatureString{"PHP", true},
		// @TODO should the exact version be ascertained?
		"language_version":           &engineFeatureString{"7.0", true},
		"encoding":                   &engineFeatureString{"ISO-8859-1", true},
		"protocol_version":           &engineFeatureInt{1, true},
		"supports_async":             &engineFeatureBool{false, true},
		"supports_reverse_debugging": &engineFeatureBool{true, true},
		// @TODO implement full list eventually
		// "breakpoint_types" : &FeatureString{"line call return exception conditional watch", true},
		"breakpoint_types":    &engineFeatureString{"line", true},
		"multiple_sessions":   &engineFeatureBool{false, false},
		"max_children":        &engineFeatureInt{64, false},
		"max_data":            &engineFeatureInt{2048, false},
		"max_depth":           &engineFeatureInt{1, false},
		"extended_properties": &engineFeatureBool{false, false},
		"show_hidden":         &engineFeatureBool{false, false},
	}

	return featureMap
}

func handleFeatureSet(es *engineState, dCmd dbgpCmd) string {
	n, ok := dCmd.options["n"]
	if !ok {
		panicWith("Please provide -n option in feature_set")
	}

	v, ok := dCmd.options["v"]
	if !ok {
		panicWith("Not provided -v option in feature_set")
	}

	var featureVal engineFeatureValue
	featureVal, ok = es.featureMap[n]
	if !ok {
		panicWith("Unknown option: " + n)
	}

	featureVal.set(v)
	return fmt.Sprintf(gFeatureSetXMLResponseFormat, dCmd.seqNum, n, 1)
}

func handleFeatureGet(es *engineState, dCmd dbgpCmd) string {
	n, ok := dCmd.options["n"]
	if !ok {
		panicWith("Please provide -n option in feature_get")
	}

	var featureVal engineFeatureValue
	featureVal, ok = es.featureMap[n]
	supported := 1
	if !ok {
		supported = 0
	}

	return fmt.Sprintf(gFeatureGetXMLResponseFormat, dCmd.seqNum, n, supported, featureVal)
}
<commit_msg>Handle notify_ok and ignore settings you don't know about<commit_after>// Copyright © 2016 Sidharth Kshatriya
//
// 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 engine

import (
	"fmt"
	"strconv"
)

type engineFeatureBool struct {
	value    bool
	readOnly bool
}
type engineFeatureInt struct {
	value    int
	readOnly bool
}
type engineFeatureString struct {
	value    string
	readOnly bool
}

type engineFeatureValue interface {
	set(value string)
	String() string
}

func (feature *engineFeatureBool) set(value string) {
	if feature.readOnly {
		panicWith(fmt.Sprintf("Trying assign %v to a read only value: %v", value, feature.value))
	}

	if value == "0" {
		feature.value = false
	} else if value == "1" {
		feature.value = true
	} else {
		panicWith(fmt.Sprintf("Trying to assign a non-boolean value %v to a boolean: %v", value, feature.value))
	}
}

func (feature engineFeatureBool) String() string {
	if feature.value {
		return "1"
	}

	return "0"
}

func (feature *engineFeatureString) set(value string) {
	if feature.readOnly {
		panicWith(fmt.Sprintf("Trying assign %v to a read only value: %v", value, feature.value))
	}
	feature.value = value
}

func (feature engineFeatureInt) String() string {
	return strconv.Itoa(feature.value)
}

func (feature *engineFeatureInt) set(value string) {
	if feature.readOnly {
		panicWith(fmt.Sprintf("Trying assign %v to a read only value: %v", value, feature.value))
	}
	var err error
	feature.value, err = strconv.Atoi(value)
	panicIf(err)
}

func (feature engineFeatureString) String() string {
	return feature.value
}

func initFeatureMap() map[string]engineFeatureValue {
	var featureMap = map[string]engineFeatureValue{
		"language_supports_threads": &engineFeatureBool{false, true},
		"language_name":             &engineFeatureString{"PHP", true},
		// @TODO should the exact version be ascertained?
		"language_version":           &engineFeatureString{"7.0", true},
		"encoding":                   &engineFeatureString{"ISO-8859-1", true},
		"protocol_version":           &engineFeatureInt{1, true},
		"supports_async":             &engineFeatureBool{false, true},
		"supports_reverse_debugging": &engineFeatureBool{true, true},
		// @TODO implement full list eventually
		// "breakpoint_types" : &FeatureString{"line call return exception conditional watch", true},
		"breakpoint_types":    &engineFeatureString{"line", true},
		"multiple_sessions":   &engineFeatureBool{false, false},
		"max_children":        &engineFeatureInt{64, false},
		"max_data":            &engineFeatureInt{2048, false},
		"max_depth":           &engineFeatureInt{1, false},
		"notify_ok":           &engineFeatureInt{0, false},
		"extended_properties": &engineFeatureBool{false, false},
		"show_hidden":         &engineFeatureBool{false, false},
	}

	return featureMap
}

func handleFeatureSet(es *engineState, dCmd dbgpCmd) string {
	n, ok := dCmd.options["n"]
	if !ok {
		panicWith("Please provide -n option in feature_set")
	}

	v, ok := dCmd.options["v"]
	if !ok {
		panicWith("Not provided -v option in feature_set")
	}

	var featureVal engineFeatureValue
	featureVal, ok = es.featureMap[n]
	if !ok {
		return fmt.Sprintf(gFeatureSetXMLResponseFormat, dCmd.seqNum, n, 0)
	}

	featureVal.set(v)
	return fmt.Sprintf(gFeatureSetXMLResponseFormat, dCmd.seqNum, n, 1)
}

func handleFeatureGet(es *engineState, dCmd dbgpCmd) string {
	n, ok := dCmd.options["n"]
	if !ok {
		panicWith("Please provide -n option in feature_get")
	}

	var featureVal engineFeatureValue
	featureVal, ok = es.featureMap[n]
	supported := 1
	if !ok {
		supported = 0
	}

	return fmt.Sprintf(gFeatureGetXMLResponseFormat, dCmd.seqNum, n, supported, featureVal)
}
<|endoftext|>


<commit_before>package archiver

import (
	"bufio"
	"compress/gzip"
	"io/ioutil"
	"os"

	"github.com/labstack/gommon/log"
)

func (a *Archiver) gzipFile(filePath string) {
	file, err := os.Open(filePath)
	if err != nil {
		log.Errorf("File not found: %s Error: %s", filePath, err.Error())
		return
	}
	defer file.Close()
	log.Info("converting" + filePath)

	reader := bufio.NewReader(file)
	content, err := ioutil.ReadAll(reader)
	if err != nil {
		log.Errorf("Failure reading file: %s Error: %s", filePath, err.Error())
		return
	}

	gzipFile, err := os.Create(filePath + ".gz")
	if err != nil {
		log.Errorf("Failure creating file: %s.gz Error: %s", filePath, err.Error())
		return
	}
	defer gzipFile.Close()

	w := gzip.NewWriter(gzipFile)
	_, err = w.Write(content)
	if err != nil {
		log.Errorf("Failure writing content in file: %s.gz Error: %s", filePath, err.Error())
	}
	w.Close()

	err = os.Remove(filePath)
	if err != nil {
		log.Errorf("Failure deleting file: %s Error: %s", filePath, err.Error())
	}
}
<commit_msg>use better logger<commit_after>package archiver

import (
	"bufio"
	"compress/gzip"
	"io/ioutil"
	"os"

	log "github.com/sirupsen/logrus"
)

func (a *Archiver) gzipFile(filePath string) {
	file, err := os.Open(filePath)
	if err != nil {
		log.Errorf("File not found: %s Error: %s", filePath, err.Error())
		return
	}
	defer file.Close()

	log.Infof("Archiving: %s", filePath)

	reader := bufio.NewReader(file)
	content, err := ioutil.ReadAll(reader)
	if err != nil {
		log.Errorf("Failure reading file: %s Error: %s", filePath, err.Error())
		return
	}

	gzipFile, err := os.Create(filePath + ".gz")
	if err != nil {
		log.Errorf("Failure creating file: %s.gz Error: %s", filePath, err.Error())
		return
	}
	defer gzipFile.Close()

	w := gzip.NewWriter(gzipFile)
	_, err = w.Write(content)
	if err != nil {
		log.Errorf("Failure writing content in file: %s.gz Error: %s", filePath, err.Error())
	}
	w.Close()

	err = os.Remove(filePath)
	if err != nil {
		log.Errorf("Failure deleting file: %s Error: %s", filePath, err.Error())
	}
}
<|endoftext|>