<commit_before>package suppress_test

import (
	"testing"

	"math"
	"runtime"
	"sync"
	"sync/atomic"
	"time"

	"github.com/fastly/go-utils/suppress"
)

func TestSilencer1(t *testing.T) {
	test(t, []string{""}, 1, 1000*time.Millisecond, 100*time.Millisecond, 11)
}

func TestSilencer2(t *testing.T) {
	test(t, []string{"spot1", "spot2"}, 1, 1000*time.Millisecond, 100*time.Millisecond, 11)
}

func TestSilencer3(t *testing.T) {
	test(t, []string{""}, 3, 1000*time.Millisecond, 100*time.Millisecond, 11)
}

func TestSilencer4(t *testing.T) {
	test(t, []string{"#1", "#2"}, 3, 1000*time.Millisecond, 100*time.Millisecond, 11)
}

func TestSilencer5(t *testing.T) {
	test(t, []string{"#1", "#2"}, 3, 10*time.Millisecond, 100*time.Millisecond, 2)
}

func test(t *testing.T, ids []string, invocations int, testTime time.Duration, suppressTime time.Duration, expectedPerInvocation int) {
	var attempts, firings, errors int64
	var lasts struct {
		sync.RWMutex
		m map[string]time.Time
	}
	lasts.m = make(map[string]time.Time)

	f := func(count int, tag string) {
		lasts.RLock()
		last := lasts.m[tag]
		lasts.RUnlock()

		now := time.Now()
		if last.IsZero() || math.Abs(float64(now.Sub(last)-suppressTime)) < float64(5*time.Millisecond) {
			atomic.AddInt64(&firings, 1)
		} else {
			t.Logf("Error %q at %v; delta=%v attempts=%d last=%v count=%d",
				tag, time.Now(), now.Sub(last), atomic.LoadInt64(&attempts), last, count)
			atomic.AddInt64(&errors, 1)
		}

		lasts.Lock()
		lasts.m[tag] = now
		lasts.Unlock()
	}

	expected := invocations * len(ids) * expectedPerInvocation

	start := time.Now()
	end := start.Add(testTime)
	for time.Now().Before(end) {
		att := atomic.AddInt64(&attempts, 1)
		if atomic.LoadInt64(&firings) >= int64(expected) {
			break
		}
		tag := ids[att%int64(len(ids))]
		// use separate calls so program counter is different for each
		if invocations > 0 {
			suppress.For(suppressTime, tag, f)
		}
		if invocations > 1 {
			suppress.For(suppressTime, tag, f)
		}
		if invocations > 2 {
			suppress.For(suppressTime, tag, f)
		}
		runtime.Gosched() // yield to other goroutines
	}

	// wait for flusher goroutines to finish
	finished := time.Now()
	time.Sleep(2 * suppressTime)
	finishedAndWaited := time.Now()

	elapsed := finished.Sub(start)
	longElapsed := finishedAndWaited.Sub(start)

	frng := atomic.LoadInt64(&firings)
	e := atomic.LoadInt64(&errors)
	t.Logf("Ran %d iterations in %v (%v with wait), fired correctly %d times (wanted %d) and %d incorrectly",
		attempts, elapsed, longElapsed, frng, expected, e)
	if frng != int64(expected) {
		t.Errorf("Expected %d firings, got %d", expected, frng)
	}
	if e > 0 {
		t.Errorf("Silencer failed to suppress %d times", e)
	}
}

func TestSilencerStalled(t *testing.T) {
	type Event struct {
		time time.Time
		n    int
	}
	events := make([]Event, 0)

	var mu sync.Mutex

	// fire 5 events in rapid succession, all within the suppress window. the
	// first call should happen immediately but the next four should be
	// coalesced at the end of the suppress period.
	start := time.Now()
	for i := 0; i < 5; i++ {
		suppress.For(100*time.Millisecond, "anon", func(n int, tag string) {
			mu.Lock()
			defer mu.Unlock()
			events = append(events, Event{time.Now(), n})
			t.Logf("%v", tag)
		})
		time.Sleep(10 * time.Millisecond)
	}
	time.Sleep(start.Add(110 * time.Millisecond).Sub(time.Now()))

	mu.Lock()
	defer mu.Unlock()
	if len(events) != 2 || events[0].n != 1 || events[1].n != 4 {
		t.Errorf("unexpected event stream: %+v", events)
	}
}
<commit_msg>comment out racy suppress tests<commit_after>package suppress_test

import (
	"testing"

	"math"
	"runtime"
	"sync"
	"sync/atomic"
	"time"

	"github.com/fastly/go-utils/suppress"
)

/* racy tests that should be ran and validated manually
func TestSilencer1(t *testing.T) {
	test(t, []string{""}, 1, 1000*time.Millisecond, 100*time.Millisecond, 11)
}

func TestSilencer2(t *testing.T) {
	test(t, []string{"spot1", "spot2"}, 1, 1000*time.Millisecond, 100*time.Millisecond, 11)
}

func TestSilencer3(t *testing.T) {
	test(t, []string{""}, 3, 1000*time.Millisecond, 100*time.Millisecond, 11)
}

func TestSilencer4(t *testing.T) {
	test(t, []string{"#1", "#2"}, 3, 1000*time.Millisecond, 100*time.Millisecond, 11)
}

func TestSilencer5(t *testing.T) {
	test(t, []string{"#1", "#2"}, 3, 10*time.Millisecond, 100*time.Millisecond, 2)
}
*/

func test(t *testing.T, ids []string, invocations int, testTime time.Duration, suppressTime time.Duration, expectedPerInvocation int) {
	var attempts, firings, errors int64
	var lasts struct {
		sync.RWMutex
		m map[string]time.Time
	}
	lasts.m = make(map[string]time.Time)

	f := func(count int, tag string) {
		lasts.RLock()
		last := lasts.m[tag]
		lasts.RUnlock()

		now := time.Now()
		if last.IsZero() || math.Abs(float64(now.Sub(last)-suppressTime)) < float64(5*time.Millisecond) {
			atomic.AddInt64(&firings, 1)
		} else {
			t.Logf("Error %q at %v; delta=%v attempts=%d last=%v count=%d",
				tag, time.Now(), now.Sub(last), atomic.LoadInt64(&attempts), last, count)
			atomic.AddInt64(&errors, 1)
		}

		lasts.Lock()
		lasts.m[tag] = now
		lasts.Unlock()
	}

	expected := invocations * len(ids) * expectedPerInvocation

	start := time.Now()
	end := start.Add(testTime)
	for time.Now().Before(end) {
		att := atomic.AddInt64(&attempts, 1)
		if atomic.LoadInt64(&firings) >= int64(expected) {
			break
		}
		tag := ids[att%int64(len(ids))]
		// use separate calls so program counter is different for each
		if invocations > 0 {
			suppress.For(suppressTime, tag, f)
		}
		if invocations > 1 {
			suppress.For(suppressTime, tag, f)
		}
		if invocations > 2 {
			suppress.For(suppressTime, tag, f)
		}
		runtime.Gosched() // yield to other goroutines
	}

	// wait for flusher goroutines to finish
	finished := time.Now()
	time.Sleep(2 * suppressTime)
	finishedAndWaited := time.Now()

	elapsed := finished.Sub(start)
	longElapsed := finishedAndWaited.Sub(start)

	frng := atomic.LoadInt64(&firings)
	e := atomic.LoadInt64(&errors)
	t.Logf("Ran %d iterations in %v (%v with wait), fired correctly %d times (wanted %d) and %d incorrectly",
		attempts, elapsed, longElapsed, frng, expected, e)
	if frng != int64(expected) {
		t.Errorf("Expected %d firings, got %d", expected, frng)
	}
	if e > 0 {
		t.Errorf("Silencer failed to suppress %d times", e)
	}
}

func TestSilencerStalled(t *testing.T) {
	type Event struct {
		time time.Time
		n    int
	}
	events := make([]Event, 0)

	var mu sync.Mutex

	// fire 5 events in rapid succession, all within the suppress window. the
	// first call should happen immediately but the next four should be
	// coalesced at the end of the suppress period.
	start := time.Now()
	for i := 0; i < 5; i++ {
		suppress.For(100*time.Millisecond, "anon", func(n int, tag string) {
			mu.Lock()
			defer mu.Unlock()
			events = append(events, Event{time.Now(), n})
			t.Logf("%v", tag)
		})
		time.Sleep(10 * time.Millisecond)
	}
	time.Sleep(start.Add(110 * time.Millisecond).Sub(time.Now()))

	mu.Lock()
	defer mu.Unlock()
	if len(events) != 2 || events[0].n != 1 || events[1].n != 4 {
		t.Errorf("unexpected event stream: %+v", events)
	}
}
<|endoftext|>


<commit_before>package cmd

import (
	"errors"
	"fmt"
	"os"
	"strings"

	"github.com/driusan/dgit/git"
)

// Since libgit is somewhat out of our control and we can't implement
// a fmt.Stringer interface there, we use this helper.
func printCommit(c *git.Client, cmt git.CommitID) {
	author, err := cmt.GetAuthor(c)
	if err != nil {
		panic(err)
	}
	fmt.Printf("commit %s\n", cmt)
	if parents, err := cmt.Parents(c); len(parents) > 1 && err == nil {
		fmt.Printf("Merge: ")
		for i, p := range parents {
			fmt.Printf("%s", p)
			if i != len(parents)-1 {
				fmt.Printf(" ")
			}
		}
		fmt.Println()
	}
	date, err := cmt.GetDate(c)
	if err != nil {
		panic(err)
	}
	fmt.Printf("Author: %v\nDate:   %v\n\n", author, date.Format("Mon Jan 2 15:04:05 2006 -0700"))
	//fmt.Printf("commit %v\nAuthor: %v\nDate: %v\n\n", c.Id, c.Author, c.Author.When.Format("Mon Jan 2 15:04:05 2006 -0700"))

	msg, err := cmt.GetCommitMessage(c)
	lines := strings.Split(strings.TrimSpace(msg), "\n")
	for _, l := range lines {
		fmt.Printf("    %v\n", l)
	}
	fmt.Printf("\n")
}

func Log(c *git.Client, args []string) error {
	if len(args) != 0 {
		fmt.Fprintf(os.Stderr, "Usage: go-git log\nNo options are currently supported.\n")
		return errors.New("No options are currently supported for log")
	}

	head, err := c.GetHeadCommit()
	if err != nil {
		return err
	}

	ancestors, err := head.Ancestors(c)
	if err != nil {
		return err
	}

	for _, cmt := range ancestors {
		printCommit(c, cmt)
	}
	return nil

}
<commit_msg>Made git log slightly more robust<commit_after>package cmd

import (
	"errors"
	"fmt"
	"os"
	"strings"

	"github.com/driusan/dgit/git"
)

// Since libgit is somewhat out of our control and we can't implement
// a fmt.Stringer interface there, we use this helper.
func printCommit(c *git.Client, cmt git.CommitID) {
	author, err := cmt.GetAuthor(c)
	if err != nil {
		panic(err)
	}
	fmt.Printf("commit %s\n", cmt)
	if parents, err := cmt.Parents(c); len(parents) > 1 && err == nil {
		fmt.Printf("Merge: ")
		for i, p := range parents {
			fmt.Printf("%s", p)
			if i != len(parents)-1 {
				fmt.Printf(" ")
			}
		}
		fmt.Println()
	}
	date, err := cmt.GetDate(c)
	if err != nil {
		panic(err)
	}
	fmt.Printf("Author: %v\nDate:   %v\n\n", author, date.Format("Mon Jan 2 15:04:05 2006 -0700"))
	//fmt.Printf("commit %v\nAuthor: %v\nDate: %v\n\n", c.Id, c.Author, c.Author.When.Format("Mon Jan 2 15:04:05 2006 -0700"))

	msg, err := cmt.GetCommitMessage(c)
	lines := strings.Split(strings.TrimSpace(msg), "\n")
	for _, l := range lines {
		fmt.Printf("    %v\n", l)
	}
	fmt.Printf("\n")
}

func Log(c *git.Client, args []string) error {
	if len(args) >= 2 {
		fmt.Fprintf(os.Stderr, "Usage: %s log [commitish]\n", os.Args[0])
		return errors.New("No options are currently supported for log")
	}

	var commit git.Commitish
	var err error
	if len(args) == 0 {
		commit, err = git.RevParseCommitish(c, &git.RevParseOptions{}, "HEAD")
	} else {
		commit, err = git.RevParseCommitish(c, &git.RevParseOptions{}, args[0])
	}
	if err != nil {
		return err
	}

	cmt, err := commit.CommitID(c)
	if err != nil {
		return err
	}

	ancestors, err := cmt.Ancestors(c)
	if err != nil {
		return err
	}

	for _, cmt := range ancestors {
		printCommit(c, cmt)
	}
	return nil

}
<|endoftext|>


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

package integration

import (
	"context"
	"math/rand"
	"strings"
	"testing"
	"time"

	"github.com/coreos/etcd/clientv3"
	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
	"github.com/coreos/etcd/integration"
	"github.com/coreos/etcd/pkg/testutil"
	"github.com/coreos/etcd/pkg/transport"
	"google.golang.org/grpc"
)

var (
	testTLSInfo = transport.TLSInfo{
		KeyFile:        "../../integration/fixtures/server.key.insecure",
		CertFile:       "../../integration/fixtures/server.crt",
		TrustedCAFile:  "../../integration/fixtures/ca.crt",
		ClientCertAuth: true,
	}

	testTLSInfoExpired = transport.TLSInfo{
		KeyFile:        "../../integration/fixtures-expired/server.key.insecure",
		CertFile:       "../../integration/fixtures-expired/server.crt",
		TrustedCAFile:  "../../integration/fixtures-expired/ca.crt",
		ClientCertAuth: true,
	}
)

// TestDialTLSExpired tests client with expired certs fails to dial.
func TestDialTLSExpired(t *testing.T) {
	defer testutil.AfterTest(t)
	clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1, PeerTLS: &testTLSInfo, ClientTLS: &testTLSInfo, SkipCreatingClient: true})
	defer clus.Terminate(t)

	tls, err := testTLSInfoExpired.ClientConfig()
	if err != nil {
		t.Fatal(err)
	}
	// expect remote errors "tls: bad certificate"
	_, err = clientv3.New(clientv3.Config{
		Endpoints:   []string{clus.Members[0].GRPCAddr()},
		DialTimeout: 3 * time.Second,
		DialOptions: []grpc.DialOption{grpc.WithBlock()},
		TLS:         tls,
	})
	if !isClientTimeout(err) {
		t.Fatalf("expected dial timeout error, got %v", err)
	}
}

// TestDialTLSNoConfig ensures the client fails to dial / times out
// when TLS endpoints (https, unixs) are given but no tls config.
func TestDialTLSNoConfig(t *testing.T) {
	defer testutil.AfterTest(t)
	clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1, ClientTLS: &testTLSInfo, SkipCreatingClient: true})
	defer clus.Terminate(t)
	// expect "signed by unknown authority"
	c, err := clientv3.New(clientv3.Config{
		Endpoints:   []string{clus.Members[0].GRPCAddr()},
		DialTimeout: time.Second,
		DialOptions: []grpc.DialOption{grpc.WithBlock()},
	})
	defer c.Close()

	// TODO: this should not be required when we set grpc.WithBlock()
	if c != nil {
		ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
		_, err = c.KV.Get(ctx, "/")
		cancel()
	}
	if !isClientTimeout(err) {
		t.Fatalf("expected dial timeout error, got %v", err)
	}
}

// TestDialSetEndpointsBeforeFail ensures SetEndpoints can replace unavailable
// endpoints with available ones.
func TestDialSetEndpointsBeforeFail(t *testing.T) {
	testDialSetEndpoints(t, true)
}

func TestDialSetEndpointsAfterFail(t *testing.T) {
	testDialSetEndpoints(t, false)
}

// testDialSetEndpoints ensures SetEndpoints can replace unavailable endpoints with available ones.
func testDialSetEndpoints(t *testing.T, setBefore bool) {
	defer testutil.AfterTest(t)
	clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 3, SkipCreatingClient: true})
	defer clus.Terminate(t)

	// get endpoint list
	eps := make([]string, 3)
	for i := range eps {
		eps[i] = clus.Members[i].GRPCAddr()
	}
	toKill := rand.Intn(len(eps))

	cfg := clientv3.Config{
		Endpoints:   []string{eps[toKill]},
		DialTimeout: 1 * time.Second,
		DialOptions: []grpc.DialOption{grpc.WithBlock()},
	}
	cli, err := clientv3.New(cfg)
	if err != nil {
		t.Fatal(err)
	}
	defer cli.Close()

	if setBefore {
		cli.SetEndpoints(eps[toKill%3], eps[(toKill+1)%3])
	}
	// make a dead node
	clus.Members[toKill].Stop(t)
	clus.WaitLeader(t)

	if !setBefore {
		cli.SetEndpoints(eps[toKill%3], eps[(toKill+1)%3])
	}
	time.Sleep(time.Second * 2)
	ctx, cancel := context.WithTimeout(context.Background(), integration.RequestWaitTimeout)
	if _, err = cli.Get(ctx, "foo", clientv3.WithSerializable()); err != nil {
		t.Fatal(err)
	}
	cancel()
}

// TestSwitchSetEndpoints ensures SetEndpoints can switch one endpoint
// with a new one that doesn't include original endpoint.
func TestSwitchSetEndpoints(t *testing.T) {
	defer testutil.AfterTest(t)
	clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 3})
	defer clus.Terminate(t)

	// get non partitioned members endpoints
	eps := []string{clus.Members[1].GRPCAddr(), clus.Members[2].GRPCAddr()}

	cli := clus.Client(0)
	clus.Members[0].InjectPartition(t, clus.Members[1:]...)

	cli.SetEndpoints(eps...)

	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	if _, err := cli.Get(ctx, "foo"); err != nil {
		t.Fatal(err)
	}
}

func TestRejectOldCluster(t *testing.T) {
	defer testutil.AfterTest(t)
	// 2 endpoints to test multi-endpoint Status
	clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 2, SkipCreatingClient: true})
	defer clus.Terminate(t)

	cfg := clientv3.Config{
		Endpoints:        []string{clus.Members[0].GRPCAddr(), clus.Members[1].GRPCAddr()},
		DialTimeout:      5 * time.Second,
		DialOptions:      []grpc.DialOption{grpc.WithBlock()},
		RejectOldCluster: true,
	}
	cli, err := clientv3.New(cfg)
	if err != nil {
		t.Fatal(err)
	}
	cli.Close()
}

// TestDialForeignEndpoint checks an endpoint that is not registered
// with the balancer can be dialed.
func TestDialForeignEndpoint(t *testing.T) {
	defer testutil.AfterTest(t)
	clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 2})
	defer clus.Terminate(t)

	conn, err := clus.Client(0).Dial(clus.Client(1).Endpoints()[0])
	if err != nil {
		t.Fatal(err)
	}
	defer conn.Close()

	// grpc can return a lazy connection that's not connected yet; confirm
	// that it can communicate with the cluster.
	kvc := clientv3.NewKVFromKVClient(pb.NewKVClient(conn), clus.Client(0))
	ctx, cancel := context.WithTimeout(context.TODO(), 5*time.Second)
	defer cancel()
	if _, gerr := kvc.Get(ctx, "abc"); gerr != nil {
		t.Fatal(err)
	}
}

// TestSetEndpointAndPut checks that a Put following a SetEndpoints
// to a working endpoint will always succeed.
func TestSetEndpointAndPut(t *testing.T) {
	defer testutil.AfterTest(t)
	clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 2})
	defer clus.Terminate(t)

	clus.Client(1).SetEndpoints(clus.Members[0].GRPCAddr())
	_, err := clus.Client(1).Put(context.TODO(), "foo", "bar")
	if err != nil && !strings.Contains(err.Error(), "closing") {
		t.Fatal(err)
	}
}
<commit_msg>clientv3/integration: Add err check to TestDialTLSNoConfig to prevent nil pointer dereference on c.Close()<commit_after>// Copyright 2016 The etcd Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package integration

import (
	"context"
	"math/rand"
	"strings"
	"testing"
	"time"

	"github.com/coreos/etcd/clientv3"
	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
	"github.com/coreos/etcd/integration"
	"github.com/coreos/etcd/pkg/testutil"
	"github.com/coreos/etcd/pkg/transport"
	"google.golang.org/grpc"
)

var (
	testTLSInfo = transport.TLSInfo{
		KeyFile:        "../../integration/fixtures/server.key.insecure",
		CertFile:       "../../integration/fixtures/server.crt",
		TrustedCAFile:  "../../integration/fixtures/ca.crt",
		ClientCertAuth: true,
	}

	testTLSInfoExpired = transport.TLSInfo{
		KeyFile:        "../../integration/fixtures-expired/server.key.insecure",
		CertFile:       "../../integration/fixtures-expired/server.crt",
		TrustedCAFile:  "../../integration/fixtures-expired/ca.crt",
		ClientCertAuth: true,
	}
)

// TestDialTLSExpired tests client with expired certs fails to dial.
func TestDialTLSExpired(t *testing.T) {
	defer testutil.AfterTest(t)
	clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1, PeerTLS: &testTLSInfo, ClientTLS: &testTLSInfo, SkipCreatingClient: true})
	defer clus.Terminate(t)

	tls, err := testTLSInfoExpired.ClientConfig()
	if err != nil {
		t.Fatal(err)
	}
	// expect remote errors "tls: bad certificate"
	_, err = clientv3.New(clientv3.Config{
		Endpoints:   []string{clus.Members[0].GRPCAddr()},
		DialTimeout: 3 * time.Second,
		DialOptions: []grpc.DialOption{grpc.WithBlock()},
		TLS:         tls,
	})
	if !isClientTimeout(err) {
		t.Fatalf("expected dial timeout error, got %v", err)
	}
}

// TestDialTLSNoConfig ensures the client fails to dial / times out
// when TLS endpoints (https, unixs) are given but no tls config.
func TestDialTLSNoConfig(t *testing.T) {
	defer testutil.AfterTest(t)
	clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1, ClientTLS: &testTLSInfo, SkipCreatingClient: true})
	defer clus.Terminate(t)
	// expect "signed by unknown authority"
	c, err := clientv3.New(clientv3.Config{
		Endpoints:   []string{clus.Members[0].GRPCAddr()},
		DialTimeout: time.Second,
		DialOptions: []grpc.DialOption{grpc.WithBlock()},
	})
	if err != nil {
		t.Fatal(err)
	}
	defer c.Close()

	// TODO: this should not be required when we set grpc.WithBlock()
	if c != nil {
		ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
		_, err = c.KV.Get(ctx, "/")
		cancel()
	}
	if !isClientTimeout(err) {
		t.Fatalf("expected dial timeout error, got %v", err)
	}
}

// TestDialSetEndpointsBeforeFail ensures SetEndpoints can replace unavailable
// endpoints with available ones.
func TestDialSetEndpointsBeforeFail(t *testing.T) {
	testDialSetEndpoints(t, true)
}

func TestDialSetEndpointsAfterFail(t *testing.T) {
	testDialSetEndpoints(t, false)
}

// testDialSetEndpoints ensures SetEndpoints can replace unavailable endpoints with available ones.
func testDialSetEndpoints(t *testing.T, setBefore bool) {
	defer testutil.AfterTest(t)
	clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 3, SkipCreatingClient: true})
	defer clus.Terminate(t)

	// get endpoint list
	eps := make([]string, 3)
	for i := range eps {
		eps[i] = clus.Members[i].GRPCAddr()
	}
	toKill := rand.Intn(len(eps))

	cfg := clientv3.Config{
		Endpoints:   []string{eps[toKill]},
		DialTimeout: 1 * time.Second,
		DialOptions: []grpc.DialOption{grpc.WithBlock()},
	}
	cli, err := clientv3.New(cfg)
	if err != nil {
		t.Fatal(err)
	}
	defer cli.Close()

	if setBefore {
		cli.SetEndpoints(eps[toKill%3], eps[(toKill+1)%3])
	}
	// make a dead node
	clus.Members[toKill].Stop(t)
	clus.WaitLeader(t)

	if !setBefore {
		cli.SetEndpoints(eps[toKill%3], eps[(toKill+1)%3])
	}
	time.Sleep(time.Second * 2)
	ctx, cancel := context.WithTimeout(context.Background(), integration.RequestWaitTimeout)
	if _, err = cli.Get(ctx, "foo", clientv3.WithSerializable()); err != nil {
		t.Fatal(err)
	}
	cancel()
}

// TestSwitchSetEndpoints ensures SetEndpoints can switch one endpoint
// with a new one that doesn't include original endpoint.
func TestSwitchSetEndpoints(t *testing.T) {
	defer testutil.AfterTest(t)
	clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 3})
	defer clus.Terminate(t)

	// get non partitioned members endpoints
	eps := []string{clus.Members[1].GRPCAddr(), clus.Members[2].GRPCAddr()}

	cli := clus.Client(0)
	clus.Members[0].InjectPartition(t, clus.Members[1:]...)

	cli.SetEndpoints(eps...)

	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	if _, err := cli.Get(ctx, "foo"); err != nil {
		t.Fatal(err)
	}
}

func TestRejectOldCluster(t *testing.T) {
	defer testutil.AfterTest(t)
	// 2 endpoints to test multi-endpoint Status
	clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 2, SkipCreatingClient: true})
	defer clus.Terminate(t)

	cfg := clientv3.Config{
		Endpoints:        []string{clus.Members[0].GRPCAddr(), clus.Members[1].GRPCAddr()},
		DialTimeout:      5 * time.Second,
		DialOptions:      []grpc.DialOption{grpc.WithBlock()},
		RejectOldCluster: true,
	}
	cli, err := clientv3.New(cfg)
	if err != nil {
		t.Fatal(err)
	}
	cli.Close()
}

// TestDialForeignEndpoint checks an endpoint that is not registered
// with the balancer can be dialed.
func TestDialForeignEndpoint(t *testing.T) {
	defer testutil.AfterTest(t)
	clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 2})
	defer clus.Terminate(t)

	conn, err := clus.Client(0).Dial(clus.Client(1).Endpoints()[0])
	if err != nil {
		t.Fatal(err)
	}
	defer conn.Close()

	// grpc can return a lazy connection that's not connected yet; confirm
	// that it can communicate with the cluster.
	kvc := clientv3.NewKVFromKVClient(pb.NewKVClient(conn), clus.Client(0))
	ctx, cancel := context.WithTimeout(context.TODO(), 5*time.Second)
	defer cancel()
	if _, gerr := kvc.Get(ctx, "abc"); gerr != nil {
		t.Fatal(err)
	}
}

// TestSetEndpointAndPut checks that a Put following a SetEndpoints
// to a working endpoint will always succeed.
func TestSetEndpointAndPut(t *testing.T) {
	defer testutil.AfterTest(t)
	clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 2})
	defer clus.Terminate(t)

	clus.Client(1).SetEndpoints(clus.Members[0].GRPCAddr())
	_, err := clus.Client(1).Put(context.TODO(), "foo", "bar")
	if err != nil && !strings.Contains(err.Error(), "closing") {
		t.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package blinker

import (
	"fmt"
	"github.com/golang/glog"
	"io"
	"os"
	"os/exec"
	"path/filepath"
)

type serviceImpl struct {
	settings Settings
}

func getPath(root, country, region, id string) string {
	return filepath.Join(root, fmt.Sprintf("%s-%s-%s", country, region, id))
}

func NewService(settings Settings) (Service, error) {

	impl := &serviceImpl{
		settings: settings,
	}
	return impl, nil
}

func (this *serviceImpl) GetImage(country, region, id string) (bytes io.ReadCloser, size int64, err error) {
	path := getPath(this.settings.FsSettings.RootDir, country, region, id)
	glog.Infoln("Reading from file", path)

	f, err := os.Open(path)
	if err != nil {
		return
	}

	stat, err := f.Stat()
	if err != nil {
		return
	}

	bytes = f
	size = stat.Size()
	return
}

func (this *serviceImpl) ExecAlpr(country, region, id string, image io.ReadCloser) (stdout []byte, err error) {
	path := getPath(this.settings.FsSettings.RootDir, country, region, id)

	glog.Infoln("ExecAlpr: saving to file", path)

	dst, err := os.Create(path)
	defer dst.Close()

	if err != nil {
		return
	}

	_, err = io.Copy(dst, image)
	if err != nil {
		return
	}

	alpr := &AlprCommand{
		Country: country,
		Region:  region,
		Path:    path,
	}

	stdout, err = alpr.Execute()
	if err != nil {
		return
	}

	// copy the results
	json, err := os.Create(path + ".json")

	defer json.Close()

	glog.Infoln("ExecAlpr: saving results to", json.Name())
	json.Write(stdout)

	return
}

func (this *serviceImpl) Close() {
	glog.Infoln("Service closed")
}

func (this *AlprCommand) Execute() (stdout []byte, err error) {
	cmd := exec.Command("alpr", "-c", this.Country, "-t", this.Region, "-j", this.Path)
	glog.Infoln("exec command:", cmd)
	return cmd.Output()
}
<commit_msg>Additional logging 2<commit_after>package blinker

import (
	"fmt"
	"github.com/golang/glog"
	"io"
	"os"
	"os/exec"
	"path/filepath"
)

type serviceImpl struct {
	settings Settings
}

func getPath(root, country, region, id string) string {
	return filepath.Join(root, fmt.Sprintf("%s-%s-%s", country, region, id))
}

func NewService(settings Settings) (Service, error) {

	impl := &serviceImpl{
		settings: settings,
	}
	return impl, nil
}

func (this *serviceImpl) GetImage(country, region, id string) (bytes io.ReadCloser, size int64, err error) {
	path := getPath(this.settings.FsSettings.RootDir, country, region, id)
	glog.Infoln("Reading from file", path)

	f, err := os.Open(path)
	if err != nil {
		return
	}

	stat, err := f.Stat()
	if err != nil {
		return
	}

	bytes = f
	size = stat.Size()
	return
}

func (this *serviceImpl) ExecAlpr(country, region, id string, image io.ReadCloser) (stdout []byte, err error) {
	path := getPath(this.settings.FsSettings.RootDir, country, region, id)

	glog.Infoln("ExecAlpr: saving to file", path)

	dst, err := os.Create(path)
	defer dst.Close()

	if err != nil {
		return
	}

	_, err = io.Copy(dst, image)
	if err != nil {
		return
	}

	alpr := &AlprCommand{
		Country: country,
		Region:  region,
		Path:    path,
	}

	stdout, err = alpr.Execute()
	if err != nil {
		return
	}

	// copy the results
	json, err := os.Create(path + ".json")

	defer json.Close()

	glog.Infoln("ExecAlpr: saving results to", json.Name())
	json.Write(stdout)

	return
}

func (this *serviceImpl) Close() {
	glog.Infoln("Service closed")
}

func (this *AlprCommand) Execute() (stdout []byte, err error) {
	cmd := exec.Command("alpr", "-c", this.Country, "-t", this.Region, "-j", this.Path)
	glog.Infoln("exec command:", cmd)
	stdout, err = cmd.Output()
	glog.Infoln("exec result", stdout, err)
	return
}
<|endoftext|>


<commit_before>package docs

import (
	"database/sql"
	"errors"
	"fmt"
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
	"github.com/tochti/docMa-handler/accountingData"
	"github.com/tochti/docMa-handler/labels"
	"github.com/tochti/docMa-handler/valid"
	"github.com/tochti/gin-gum/gumrest"
	"gopkg.in/gorp.v1"
)

func CreateDocHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	doc := Doc{}
	if err := ginCtx.BindJSON(&doc); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	err := valid.Struct(doc)
	if err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	err = db.Insert(&doc)
	if err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusCreated, doc)
}

func ReadOneDocHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	id, err := ReadDocID(ginCtx)
	if err != nil {
		return
	}

	doc := Doc{}
	err = db.SelectOne(&doc, "SELECT * FROM docs WHERE id=?", id)
	if err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusOK, doc)

}

// Attention: its only possible to update the complet doc
func UpdateDocHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	id, err := ReadDocID(ginCtx)
	if err != nil {
		return
	}

	doc := Doc{}
	if err := ginCtx.BindJSON(&doc); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	doc.ID = id
	_, err = db.Update(&doc)
	if err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusOK, doc)
}

func UpdateDocNameHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	id, err := ReadDocID(ginCtx)
	if err != nil {
		return
	}

	doc := Doc{}
	if err := ginCtx.BindJSON(&doc); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	if err := valid.Struct(doc); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	q := Q("UPDATE %v SET name=? WHERE id=?", DocsTable)
	_, err = db.Exec(q, doc.Name, id)
	if err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusOK, nil)
}

func CreateDocNumberHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	docNumber := DocNumber{}
	if err := ginCtx.BindJSON(&docNumber); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	if err := valid.Struct(docNumber); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	if err := db.Insert(&docNumber); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusCreated, docNumber)
}

func ReadAllDocNumbersHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	id, err := ReadDocID(ginCtx)
	if err != nil {
		return
	}

	docNumbers := []DocNumber{}
	q := Q("SELECT * FROM %v WHERE doc_id=?", DocNumbersTable)
	if _, err := db.Select(&docNumbers, q, id); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusOK, docNumbers)
}

func DeleteDocNumberHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	id, err := ReadDocID(ginCtx)
	if err != nil {
		return
	}

	number, ok := ginCtx.Params.Get("docNumber")
	if !ok {
		err := errors.New("Missing number parameter")
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	docNumber := DocNumber{
		DocID:  id,
		Number: number,
	}

	if _, err = db.Delete(&docNumber); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusOK, nil)

}

func CreateDocAccountDataHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	docAccountData := DocAccountData{}
	if err := ginCtx.BindJSON(&docAccountData); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	if err := valid.Struct(docAccountData); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	if err := db.Insert(&docAccountData); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusCreated, docAccountData)
}

func ReadOneDocAccountDataHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	id, err := ReadDocID(ginCtx)
	if err != nil {
		return
	}

	docAccountData := DocAccountData{}
	q := Q("SELECT * FROM %v WHERE doc_id=?", DocAccountDataTable)
	if err := db.SelectOne(&docAccountData, q, id); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusOK, docAccountData)
}

func UpdateDocAccountDataHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	id, err := ReadDocID(ginCtx)
	if err != nil {
		return
	}

	docAccountData := DocAccountData{}
	if err := ginCtx.BindJSON(&docAccountData); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	docAccountData.DocID = id
	if err := valid.Struct(docAccountData); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	if _, err := db.Update(&docAccountData); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusOK, docAccountData)

}

func FindAllLabelsOfDocHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	id, err := ReadDocID(ginCtx)
	if err != nil {
		return
	}

	labelList, err := FindLabelsOfDoc(db, id)
	if err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusOK, labelList)
}

func FindAllAccountingDataOfDocHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	id, err := ReadDocID(ginCtx)
	if err != nil {
		return
	}

	tmp, err := ReadDocNumbers(db, id)
	if err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}
	docNumbers := []string{}
	for _, x := range tmp {
		docNumbers = append(docNumbers, x.Number)
	}

	var r1 []accountingData.AccountingData
	if len(docNumbers) > 0 {
		var err error
		r1, err = accountingData.FindAccountingDataByDocNumbers(db, docNumbers)
		if err != nil {
			gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
			return
		}
	}

	accountData, err := ReadAccountData(db, id)
	if err != nil {
		if err != sql.ErrNoRows {
			gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
			return
		}
	}

	var r2 []accountingData.AccountingData
	if err != sql.ErrNoRows {
		var err error
		r2, err = accountingData.FindAccountingDataByAccountNumber(
			db,
			accountData.AccountNumber,
			accountData.PeriodFrom,
			accountData.PeriodTo,
		)
		if err != nil {
			gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
			return
		}
	}

	r := mergeAccountingData(r1, r2)

	ginCtx.JSON(http.StatusOK, r)
}

func JoinLabelHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	docsLabels := DocsLabels{}
	if err := ginCtx.BindJSON(&docsLabels); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	if err := valid.Struct(docsLabels); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	if err := db.Insert(&docsLabels); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusCreated, docsLabels)
}

func DetachLabelHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	docID, err := ReadIntParam(ginCtx, "docID")
	if err != nil {
		return
	}
	labelID, err := ReadIntParam(ginCtx, "labelID")
	if err != nil {
		return
	}

	docsLabels := DocsLabels{
		DocID:   int64(docID),
		LabelID: int64(labelID),
	}

	if _, err := db.Delete(&docsLabels); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusOK, nil)
}

func FindDocsWithLabelHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	labelID, err := labels.ReadLabelID(ginCtx)
	if err != nil {
		return
	}

	docs, err := FindDocsWithLabel(db, labelID)
	if err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusOK, docs)
}

func mergeAccountingData(a1, a2 []accountingData.AccountingData) []accountingData.AccountingData {
	ids := map[int64]bool{}
	r := a1

	for _, e := range a1 {
		ids[e.ID] = true
	}

	for _, e := range a2 {
		if _, ok := ids[e.ID]; !ok {
			r = append(r, e)
		}
	}

	return r
}

func ReadDocID(c *gin.Context) (int64, error) {
	i, err := ReadIntParam(c, "docID")
	return int64(i), err
}

func ReadIntParam(c *gin.Context, name string) (int, error) {
	tmp := c.Params.ByName(name)
	i, err := strconv.Atoi(tmp)
	if err != nil {
		gumrest.ErrorResponse(
			c,
			http.StatusBadRequest,
			err,
		)
		return -1, err
	}

	return i, nil
}

func Q(q string, p ...interface{}) string {
	return fmt.Sprintf(q, p...)
}
<commit_msg>add ReadDocFileHandler<commit_after>package docs

import (
	"database/sql"
	"errors"
	"fmt"
	"net/http"
	"path"
	"strconv"
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/tochti/docMa-handler/accountingData"
	"github.com/tochti/docMa-handler/labels"
	"github.com/tochti/docMa-handler/valid"
	"github.com/tochti/gin-gum/gumrest"
	"gopkg.in/gorp.v1"
)

func CreateDocHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	doc := Doc{}
	if err := ginCtx.BindJSON(&doc); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	err := valid.Struct(doc)
	if err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	err = db.Insert(&doc)
	if err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusCreated, doc)
}

func ReadOneDocHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	id, err := ReadDocID(ginCtx)
	if err != nil {
		return
	}

	doc := Doc{}
	err = db.SelectOne(&doc, "SELECT * FROM docs WHERE id=?", id)
	if err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusOK, doc)

}

func ReadDocFileHandler(c *gin.Context, specs Specs) {
	filename := strings.Trim(c.Params.ByName("name"), "\"")
	filepath := path.Join(specs.Files, filename)
	c.File(filepath)
}

// Attention: its only possible to update the complet doc
func UpdateDocHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	id, err := ReadDocID(ginCtx)
	if err != nil {
		return
	}

	doc := Doc{}
	if err := ginCtx.BindJSON(&doc); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	doc.ID = id
	_, err = db.Update(&doc)
	if err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusOK, doc)
}

func UpdateDocNameHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	id, err := ReadDocID(ginCtx)
	if err != nil {
		return
	}

	doc := Doc{}
	if err := ginCtx.BindJSON(&doc); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	if err := valid.Struct(doc); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	q := Q("UPDATE %v SET name=? WHERE id=?", DocsTable)
	_, err = db.Exec(q, doc.Name, id)
	if err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusOK, nil)
}

func CreateDocNumberHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	docNumber := DocNumber{}
	if err := ginCtx.BindJSON(&docNumber); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	if err := valid.Struct(docNumber); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	if err := db.Insert(&docNumber); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusCreated, docNumber)
}

func ReadAllDocNumbersHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	id, err := ReadDocID(ginCtx)
	if err != nil {
		return
	}

	docNumbers := []DocNumber{}
	q := Q("SELECT * FROM %v WHERE doc_id=?", DocNumbersTable)
	if _, err := db.Select(&docNumbers, q, id); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusOK, docNumbers)
}

func DeleteDocNumberHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	id, err := ReadDocID(ginCtx)
	if err != nil {
		return
	}

	number, ok := ginCtx.Params.Get("docNumber")
	if !ok {
		err := errors.New("Missing number parameter")
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	docNumber := DocNumber{
		DocID:  id,
		Number: number,
	}

	if _, err = db.Delete(&docNumber); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusOK, nil)

}

func CreateDocAccountDataHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	docAccountData := DocAccountData{}
	if err := ginCtx.BindJSON(&docAccountData); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	if err := valid.Struct(docAccountData); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	if err := db.Insert(&docAccountData); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusCreated, docAccountData)
}

func ReadOneDocAccountDataHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	id, err := ReadDocID(ginCtx)
	if err != nil {
		return
	}

	docAccountData := DocAccountData{}
	q := Q("SELECT * FROM %v WHERE doc_id=?", DocAccountDataTable)
	if err := db.SelectOne(&docAccountData, q, id); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusOK, docAccountData)
}

func UpdateDocAccountDataHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	id, err := ReadDocID(ginCtx)
	if err != nil {
		return
	}

	docAccountData := DocAccountData{}
	if err := ginCtx.BindJSON(&docAccountData); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	docAccountData.DocID = id
	if err := valid.Struct(docAccountData); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	if _, err := db.Update(&docAccountData); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusOK, docAccountData)

}

func FindAllLabelsOfDocHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	id, err := ReadDocID(ginCtx)
	if err != nil {
		return
	}

	labelList, err := FindLabelsOfDoc(db, id)
	if err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusOK, labelList)
}

func FindAllAccountingDataOfDocHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	id, err := ReadDocID(ginCtx)
	if err != nil {
		return
	}

	tmp, err := ReadDocNumbers(db, id)
	if err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}
	docNumbers := []string{}
	for _, x := range tmp {
		docNumbers = append(docNumbers, x.Number)
	}

	var r1 []accountingData.AccountingData
	if len(docNumbers) > 0 {
		var err error
		r1, err = accountingData.FindAccountingDataByDocNumbers(db, docNumbers)
		if err != nil {
			gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
			return
		}
	}

	accountData, err := ReadAccountData(db, id)
	if err != nil {
		if err != sql.ErrNoRows {
			gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
			return
		}
	}

	var r2 []accountingData.AccountingData
	if err != sql.ErrNoRows {
		var err error
		r2, err = accountingData.FindAccountingDataByAccountNumber(
			db,
			accountData.AccountNumber,
			accountData.PeriodFrom,
			accountData.PeriodTo,
		)
		if err != nil {
			gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
			return
		}
	}

	r := mergeAccountingData(r1, r2)

	ginCtx.JSON(http.StatusOK, r)
}

func JoinLabelHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	docsLabels := DocsLabels{}
	if err := ginCtx.BindJSON(&docsLabels); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	if err := valid.Struct(docsLabels); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	if err := db.Insert(&docsLabels); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusCreated, docsLabels)
}

func DetachLabelHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	docID, err := ReadIntParam(ginCtx, "docID")
	if err != nil {
		return
	}
	labelID, err := ReadIntParam(ginCtx, "labelID")
	if err != nil {
		return
	}

	docsLabels := DocsLabels{
		DocID:   int64(docID),
		LabelID: int64(labelID),
	}

	if _, err := db.Delete(&docsLabels); err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusOK, nil)
}

func FindDocsWithLabelHandler(ginCtx *gin.Context, db *gorp.DbMap) {
	labelID, err := labels.ReadLabelID(ginCtx)
	if err != nil {
		return
	}

	docs, err := FindDocsWithLabel(db, labelID)
	if err != nil {
		gumrest.ErrorResponse(ginCtx, http.StatusBadRequest, err)
		return
	}

	ginCtx.JSON(http.StatusOK, docs)
}

func mergeAccountingData(a1, a2 []accountingData.AccountingData) []accountingData.AccountingData {
	ids := map[int64]bool{}
	r := a1

	for _, e := range a1 {
		ids[e.ID] = true
	}

	for _, e := range a2 {
		if _, ok := ids[e.ID]; !ok {
			r = append(r, e)
		}
	}

	return r
}

func ReadDocID(c *gin.Context) (int64, error) {
	i, err := ReadIntParam(c, "docID")
	return int64(i), err
}

func ReadIntParam(c *gin.Context, name string) (int, error) {
	tmp := c.Params.ByName(name)
	i, err := strconv.Atoi(tmp)
	if err != nil {
		gumrest.ErrorResponse(
			c,
			http.StatusBadRequest,
			err,
		)
		return -1, err
	}

	return i, nil
}

func Q(q string, p ...interface{}) string {
	return fmt.Sprintf(q, p...)
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"os/exec"
	"syscall"
)

// ExecCmd returns exit code
func ExecCmd(c []string) int {
	var cmd *exec.Cmd

	if len(c) > 1 {
		cmd = exec.Command(c[0], c[1:]...)
	} else {
		cmd = exec.Command(c[0])
	}

	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	err := cmd.Run()

	if exiterr, ok := err.(*exec.ExitError); ok {
		if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
			return status.ExitStatus()
		}
	}

	return ExitCodeOK
}
<commit_msg>add BuildShellCmd<commit_after>package main

import (
	"os"
	"os/exec"
	"strings"
	"syscall"

	"github.com/mattn/go-shellwords"
)

// ExecCmd returns exit code
func ExecCmd(c []string) int {
	var cmd *exec.Cmd

	if len(c) > 1 {
		cmd = exec.Command(c[0], c[1:]...)
	} else {
		cmd = exec.Command(c[0])
	}

	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	err := cmd.Run()

	if exiterr, ok := err.(*exec.ExitError); ok {
		if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
			return status.ExitStatus()
		}
		return ExitCodeError
	}

	return ExitCodeOK
}

// BuildShellCmd returns args as exec.Command
func BuildShellCmd(args []string) ([]string, error) {
	shell := os.Getenv("SHELL")
	cmd := append([]string{shell, "-c"}, args...)

	s := shellwords.NewParser()
	s.ParseEnv = true
	s.ParseBacktick = true

	return s.Parse(strings.Join(cmd, " "))
}
<|endoftext|>


<commit_before>package pearl

import "fmt"

// Command represents a cell packet command byte.
type Command byte

// Enumerate all possible cell commands.
//
// Reference: https://github.com/torproject/torspec/blob/master/tor-spec.txt#L418-L438
//
//	   The 'Command' field of a fixed-length cell holds one of the following
//	   values:
//	         0 -- PADDING     (Padding)                 (See Sec 7.2)
//	         1 -- CREATE      (Create a circuit)        (See Sec 5.1)
//	         2 -- CREATED     (Acknowledge create)      (See Sec 5.1)
//	         3 -- RELAY       (End-to-end data)         (See Sec 5.5 and 6)
//	         4 -- DESTROY     (Stop using a circuit)    (See Sec 5.4)
//	         5 -- CREATE_FAST (Create a circuit, no PK) (See Sec 5.1)
//	         6 -- CREATED_FAST (Circuit created, no PK) (See Sec 5.1)
//	         8 -- NETINFO     (Time and address info)   (See Sec 4.5)
//	         9 -- RELAY_EARLY (End-to-end data; limited)(See Sec 5.6)
//	         10 -- CREATE2    (Extended CREATE cell)    (See Sec 5.1)
//	         11 -- CREATED2   (Extended CREATED cell)    (See Sec 5.1)
//
//	    Variable-length command values are:
//	         7 -- VERSIONS    (Negotiate proto version) (See Sec 4)
//	         128 -- VPADDING  (Variable-length padding) (See Sec 7.2)
//	         129 -- CERTS     (Certificates)            (See Sec 4.2)
//	         130 -- AUTH_CHALLENGE (Challenge value)    (See Sec 4.3)
//	         131 -- AUTHENTICATE (Client authentication)(See Sec 4.5)
//	         132 -- AUTHORIZE (Client authorization)    (Not yet used)
//
const (
	Padding       Command = 0
	Create        Command = 1
	Created       Command = 2
	Relay         Command = 3
	Destroy       Command = 4
	CreateFast    Command = 5
	CreatedFast   Command = 6
	Netinfo       Command = 8
	RelayEarly    Command = 9
	Create2       Command = 10
	Created2      Command = 11
	Versions      Command = 7
	Vpadding      Command = 128
	Certs         Command = 129
	AuthChallenge Command = 130
	Authenticate  Command = 131
	Authorize     Command = 132
)

var commandStrings = map[Command]string{
	0:   "PADDING",
	1:   "CREATE",
	2:   "CREATED",
	3:   "RELAY",
	4:   "DESTROY",
	5:   "CREATE_FAST",
	6:   "CREATED_FAST",
	8:   "NETINFO",
	9:   "RELAY_EARLY",
	10:  "CREATE2",
	11:  "CREATED2",
	7:   "VERSIONS",
	128: "VPADDING",
	129: "CERTS",
	130: "AUTH_CHALLENGE",
	131: "AUTHENTICATE",
	132: "AUTHORIZE",
}

func (c Command) String() string {
	s, ok := commandStrings[c]
	if ok {
		return s
	}
	return fmt.Sprintf("Command(%d)", byte(c))
}

// IsCommand determines whether the given byte is a recognized cell command.
func IsCommand(c byte) bool {
	_, ok := commandStrings[c]
	return ok
}
<commit_msg>fix bug in generated code<commit_after>package pearl

import "fmt"

// Command represents a cell packet command byte.
type Command byte

// Enumerate all possible cell commands.
//
// Reference: https://github.com/torproject/torspec/blob/master/tor-spec.txt#L418-L438
//
//	   The 'Command' field of a fixed-length cell holds one of the following
//	   values:
//	         0 -- PADDING     (Padding)                 (See Sec 7.2)
//	         1 -- CREATE      (Create a circuit)        (See Sec 5.1)
//	         2 -- CREATED     (Acknowledge create)      (See Sec 5.1)
//	         3 -- RELAY       (End-to-end data)         (See Sec 5.5 and 6)
//	         4 -- DESTROY     (Stop using a circuit)    (See Sec 5.4)
//	         5 -- CREATE_FAST (Create a circuit, no PK) (See Sec 5.1)
//	         6 -- CREATED_FAST (Circuit created, no PK) (See Sec 5.1)
//	         8 -- NETINFO     (Time and address info)   (See Sec 4.5)
//	         9 -- RELAY_EARLY (End-to-end data; limited)(See Sec 5.6)
//	         10 -- CREATE2    (Extended CREATE cell)    (See Sec 5.1)
//	         11 -- CREATED2   (Extended CREATED cell)    (See Sec 5.1)
//
//	    Variable-length command values are:
//	         7 -- VERSIONS    (Negotiate proto version) (See Sec 4)
//	         128 -- VPADDING  (Variable-length padding) (See Sec 7.2)
//	         129 -- CERTS     (Certificates)            (See Sec 4.2)
//	         130 -- AUTH_CHALLENGE (Challenge value)    (See Sec 4.3)
//	         131 -- AUTHENTICATE (Client authentication)(See Sec 4.5)
//	         132 -- AUTHORIZE (Client authorization)    (Not yet used)
//
const (
	Padding       Command = 0
	Create        Command = 1
	Created       Command = 2
	Relay         Command = 3
	Destroy       Command = 4
	CreateFast    Command = 5
	CreatedFast   Command = 6
	Netinfo       Command = 8
	RelayEarly    Command = 9
	Create2       Command = 10
	Created2      Command = 11
	Versions      Command = 7
	Vpadding      Command = 128
	Certs         Command = 129
	AuthChallenge Command = 130
	Authenticate  Command = 131
	Authorize     Command = 132
)

var commandStrings = map[Command]string{
	0:   "PADDING",
	1:   "CREATE",
	2:   "CREATED",
	3:   "RELAY",
	4:   "DESTROY",
	5:   "CREATE_FAST",
	6:   "CREATED_FAST",
	8:   "NETINFO",
	9:   "RELAY_EARLY",
	10:  "CREATE2",
	11:  "CREATED2",
	7:   "VERSIONS",
	128: "VPADDING",
	129: "CERTS",
	130: "AUTH_CHALLENGE",
	131: "AUTHENTICATE",
	132: "AUTHORIZE",
}

func (c Command) String() string {
	s, ok := commandStrings[c]
	if ok {
		return s
	}
	return fmt.Sprintf("Command(%d)", byte(c))
}

// IsCommand determines whether the given byte is a recognized cell command.
func IsCommand(c byte) bool {
	_, ok := commandStrings[Command(c)]
	return ok
}
<|endoftext|>


<commit_before>package models

import (
	"errors"
	"fmt"

	"github.com/jinzhu/gorm"
	"github.com/koding/bongo"
)

type Account struct {
	// unique id of the account
	Id int64 `json:"id"`
	// old id of the account, which is coming from mongo
	OldId string `json:"oldId"`
}

func NewAccount() *Account {
	return &Account{}
}

func (a *Account) GetId() int64 {
	return a.Id
}

func (a *Account) TableName() string {
	return "account"
}

func (a *Account) Self() bongo.Modellable {
	return a
}
func (a *Account) FetchChannels(q *Query) ([]Channel, error) {
	cp := NewChannelParticipant()
	// fetch channel ids
	cids, err := cp.FetchParticipatedChannelIds(a)
	if err != nil {
		return nil, err
	}

	// fetch channels by their ids
	c := NewChannel()
	channels, err := c.FetchByIds(cids)
	if err != nil {
		return nil, err
	}

	return channels, nil
}

func (a *Account) Follow(targetId int64) (*ChannelParticipant, error) {
	c, err := a.FetchChannel(Channel_TYPE_FOLLOWERS)
	if err == nil {
		return c.AddParticipant(targetId)
	}

	if err == gorm.RecordNotFound {
		c, err := a.CreateFollowingFeedChannel()
		if err != nil {
			return nil, err
		}
		return c.AddParticipant(targetId)
	}
	return nil, err
}

func (a *Account) Unfollow(targetId int64) error {
	c, err := a.FetchChannel(Channel_TYPE_FOLLOWERS)
	if err != nil {
		fmt.Println(1, err)
		return err
	}
	fmt.Println(2)

	return c.RemoveParticipant(targetId)
}

func (a *Account) FetchFollowerIds() ([]int64, error) {
	followerIds := make([]int64, 0)
	if a.Id == 0 {
		return nil, errors.New(
			"Account id is not set for FetchFollowerChannelIds function ",
		)
	}

	c, err := a.FetchChannel(Channel_TYPE_FOLLOWERS)
	if err != nil {
		return followerIds, err
	}

	participants, err := c.FetchParticipantIds()
	if err != nil {
		return followerIds, err
	}

	return participants, nil
}

func (a *Account) FetchChannel(channelType string) (*Channel, error) {
	if a.Id == 0 {
		return nil, errors.New("Account id is not set")
	}

	c := NewChannel()
	selector := map[string]interface{}{
		"creator_id": a.Id,
		"type":       channelType,
	}

	if err := c.One(selector); err != nil {
		return nil, err
	}

	return c, nil
}

func (a *Account) CreateFollowingFeedChannel() (*Channel, error) {
	if a.Id == 0 {
		return nil, errors.New("Account id is not set")
	}

	c := NewChannel()
	c.CreatorId = a.Id
	c.Name = fmt.Sprintf("%d-FollowingFeedChannel", a.Id)
	c.Group = Channel_KODING_NAME
	c.Purpose = "Following Feed for Me"
	c.Type = Channel_TYPE_FOLLOWERS
	if err := c.Create(); err != nil {
		return nil, err
	}

	return c, nil
}

func (a *Account) FetchFollowerChannelIds() ([]int64, error) {

	followerIds, err := a.FetchFollowerIds()
	if err != nil {
		return nil, err
	}

	cp := NewChannelParticipant()
	var channelIds []int64
	err = bongo.B.DB.
		Table(cp.TableName()).
		Where(
		"creator_id IN (?) and type = ?",
		followerIds,
		Channel_TYPE_FOLLOWINGFEED,
	).Find(&channelIds).Error

	if err != nil {
		return nil, err
	}

	return channelIds, nil
}
<commit_msg>Social: add model functions<commit_after>package models

import (
	"errors"
	"fmt"

	"github.com/jinzhu/gorm"
	"github.com/koding/bongo"
)

type Account struct {
	// unique id of the account
	Id int64 `json:"id"`
	// old id of the account, which is coming from mongo
	OldId string `json:"oldId"`
}

func NewAccount() *Account {
	return &Account{}
}

func (a *Account) GetId() int64 {
	return a.Id
}

func (a *Account) TableName() string {
	return "account"
}

func (a *Account) Self() bongo.Modellable {
	return a
}

func (a *Account) One(selector map[string]interface{}) error {
	return bongo.B.One(a, a, selector)
}

func (a *Account) FetchOrCreate() error {
	if a.OldId == "" {
		return errors.New("old id is not set")
	}

	selector := map[string]interface{}{
		"old_id": a.OldId,
	}

	err := a.One(selector)
	if err == gorm.RecordNotFound {
		if err := a.Create(); err != nil {
			return err
		}
		return nil
	}
	if err != nil {
		return err
	}

	return nil
}

func (a *Account) Create() error {
	if a.OldId == "" {
		return errors.New("old id is not set")
	}
	return bongo.B.Create(a)
}

func (a *Account) FetchChannels(q *Query) ([]Channel, error) {
	cp := NewChannelParticipant()
	// fetch channel ids
	cids, err := cp.FetchParticipatedChannelIds(a)
	if err != nil {
		return nil, err
	}

	// fetch channels by their ids
	c := NewChannel()
	channels, err := c.FetchByIds(cids)
	if err != nil {
		return nil, err
	}

	return channels, nil
}

func (a *Account) Follow(targetId int64) (*ChannelParticipant, error) {
	c, err := a.FetchChannel(Channel_TYPE_FOLLOWERS)
	if err == nil {
		return c.AddParticipant(targetId)
	}

	if err == gorm.RecordNotFound {
		c, err := a.CreateFollowingFeedChannel()
		if err != nil {
			return nil, err
		}
		return c.AddParticipant(targetId)
	}
	return nil, err
}

func (a *Account) Unfollow(targetId int64) error {
	c, err := a.FetchChannel(Channel_TYPE_FOLLOWERS)
	if err != nil {
		fmt.Println(1, err)
		return err
	}
	fmt.Println(2)

	return c.RemoveParticipant(targetId)
}

func (a *Account) FetchFollowerIds() ([]int64, error) {
	followerIds := make([]int64, 0)
	if a.Id == 0 {
		return nil, errors.New(
			"Account id is not set for FetchFollowerChannelIds function ",
		)
	}

	c, err := a.FetchChannel(Channel_TYPE_FOLLOWERS)
	if err != nil {
		return followerIds, err
	}

	participants, err := c.FetchParticipantIds()
	if err != nil {
		return followerIds, err
	}

	return participants, nil
}

func (a *Account) FetchChannel(channelType string) (*Channel, error) {
	if a.Id == 0 {
		return nil, errors.New("Account id is not set")
	}

	c := NewChannel()
	selector := map[string]interface{}{
		"creator_id": a.Id,
		"type":       channelType,
	}

	if err := c.One(selector); err != nil {
		return nil, err
	}

	return c, nil
}

func (a *Account) CreateFollowingFeedChannel() (*Channel, error) {
	if a.Id == 0 {
		return nil, errors.New("Account id is not set")
	}

	c := NewChannel()
	c.CreatorId = a.Id
	c.Name = fmt.Sprintf("%d-FollowingFeedChannel", a.Id)
	c.Group = Channel_KODING_NAME
	c.Purpose = "Following Feed for Me"
	c.Type = Channel_TYPE_FOLLOWERS
	if err := c.Create(); err != nil {
		return nil, err
	}

	return c, nil
}

func (a *Account) FetchFollowerChannelIds() ([]int64, error) {

	followerIds, err := a.FetchFollowerIds()
	if err != nil {
		return nil, err
	}

	cp := NewChannelParticipant()
	var channelIds []int64
	err = bongo.B.DB.
		Table(cp.TableName()).
		Where(
		"creator_id IN (?) and type = ?",
		followerIds,
		Channel_TYPE_FOLLOWINGFEED,
	).Find(&channelIds).Error

	if err != nil {
		return nil, err
	}

	return channelIds, nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"image"
	"image/color"
	"image/png"
	"math/cmplx"
	"os"

	"github.com/krasoffski/gomill/htcmap"
)

func main() {
	const (
		xmin, ymin    = -2, -2
		xmax, ymax    = +2, +2
		width, height = 2048, 2048
	)

	img := image.NewRGBA(image.Rect(0, 0, width, height))
	for py := 0; py < height; py++ {
		y := float64(py)/height*(ymax-ymin) + ymin
		for px := 0; px < width; px++ {
			x := float64(px)/width*(xmax-xmin) + xmin
			z := complex(x, y)
			img.Set(px, py, mandelbrot(z))
		}
	}
	if err := png.Encode(os.Stdout, img); err != nil {
		fmt.Fprintf(os.Stderr, "error encoding png: %s", err)
	}
}

func mandelbrot(z complex128) color.Color {
	const iterations = 255
	const contrast = 42

	var v complex128
	for n := uint8(0); n < iterations; n++ {
		v = v*v + z
		if cmplx.Abs(v) > 2 {
			r, g, b := htcmap.AsUInt8(float64(n*contrast), 0, iterations)
			return color.RGBA{r, g, b, 255}
		}
	}
	return color.Black
}
<commit_msg>Added smoothing.<commit_after>package main

import (
	"fmt"
	"image"
	"image/color"
	"image/png"
	"math"
	"math/cmplx"
	"os"

	"github.com/krasoffski/gomill/htcmap"
)

func main() {
	const (
		xmin, ymin    = -2, -2
		xmax, ymax    = +2, +2
		width, height = 2048, 2048
	)

	img := image.NewRGBA(image.Rect(0, 0, width, height))
	for py := 0; py < height; py++ {
		y := float64(py)/height*(ymax-ymin) + ymin
		for px := 0; px < width; px++ {
			x := float64(px)/width*(xmax-xmin) + xmin
			z := complex(x, y)
			img.Set(px, py, mandelbrot(z))
		}
	}
	if err := png.Encode(os.Stdout, img); err != nil {
		fmt.Fprintf(os.Stderr, "error encoding png: %s", err)
	}
}

func mandelbrot(z complex128) color.Color {
	const iterations = 255
	const contrast = 15

	var v complex128
	for n := uint8(0); n < iterations; n++ {
		v = v*v + z
		vAbs := cmplx.Abs(v)
		if vAbs > 2 && n > 5 {
			smooth := float64(n) + 1 - math.Log(math.Log(vAbs))/math.Log(2)
			r, g, b := htcmap.AsUInt8(float64(smooth*contrast), 0, iterations)
			return color.RGBA{r, g, b, 255}
		}
	}
	return color.Black
}
<|endoftext|>


<commit_before>package autorestart

import (
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"syscall"

	"gopkg.in/fsnotify.v1"
)

func logf(format string, args ...interface{}) {
	log.Printf("[autorestart] "+format+"\n", args...)
}

const errorPath = "*error*"

var _exePath = errorPath

func getExePath() string {
	var err error
	if _exePath == errorPath {
		_exePath, err = exec.LookPath(os.Args[0])
		if err != nil {
			logf("Failed to resolve path to current program: %s", err)
			_exePath = errorPath
		} else {
			_exePath, err = filepath.Abs(_exePath)
			if err != nil {
				logf("Failed to resolve absolute path to current program: %s", err)
				_exePath = errorPath
			} else {
				_exePath = filepath.Clean(_exePath)
			}
		}
	}
	return _exePath
}

// Restart the current program when the program's executable is updated.
// This function is a wrapper around NotifyOnChange and RestartViaExec, calling the
// latter when the former signals that a change was detected.
func RestartOnChange() {
	notifyChan := NotifyOnChange()
	<-notifyChan
	logf("%s changed. Restarting via exec.", getExePath())
	RestartViaExec()
}

// Subscribe to a notification when the current process' executable file is modified.
// Returns a channel to which notifications (just `true`) will be sent whenever a
// change is detected.
func NotifyOnChange() chan bool {
	notifyChan := make(chan bool)
	go func() {
		exePath := getExePath()
		if exePath == errorPath {
			return
		}
		exeDir := filepath.Dir(exePath)
		watcher, err := fsnotify.NewWatcher()
		if err != nil {
			logf("Failed to initialize howeyc/fsnotify watcher: %s", err)
			return
		}
		abs, _ := filepath.Abs(exeDir)
		err = watcher.Add(abs)
		if err != nil {
			logf("Failed to start filesystem watcher on %s: %s", exeDir, err)
			return
		}
		for {
			select {
			case err := <-watcher.Errors:
				logf("Watcher error: %s", err)
			case ev := <-watcher.Events:
				// log.Println("change", ev.Name, exePath, ev)
				if ev.Name == exePath {
					notifyChan <- true
				}
			}
		}
	}()
	return notifyChan
}

// Restart the current process by calling syscall.Exec, using os.Args (with filepath.LookPath)
// and os.Environ() to recreate the same args & environment that was used when the process was
// originally started.
// Due to using syscall.Exec, this function is not portable to systems that don't support exec.
func RestartViaExec() {
	exePath := getExePath()
	if exePath == errorPath {
		return
	}
	syscall.Exec(exePath, os.Args, os.Environ())
}
<commit_msg>Work around a bug with syscall.Exec not always working<commit_after>package autorestart

import (
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"syscall"
	"time"

	"gopkg.in/fsnotify.v1"
)

func logf(format string, args ...interface{}) {
	log.Printf("[autorestart] "+format+"\n", args...)
}

const errorPath = "*error*"

var _exePath = errorPath

func getExePath() string {
	var err error
	if _exePath == errorPath {
		_exePath, err = exec.LookPath(os.Args[0])
		if err != nil {
			logf("Failed to resolve path to current program: %s", err)
			_exePath = errorPath
		} else {
			_exePath, err = filepath.Abs(_exePath)
			if err != nil {
				logf("Failed to resolve absolute path to current program: %s", err)
				_exePath = errorPath
			} else {
				_exePath = filepath.Clean(_exePath)
			}
		}
	}
	return _exePath
}

// Restart the current program when the program's executable is updated.
// This function is a wrapper around NotifyOnChange and RestartViaExec, calling the
// latter when the former signals that a change was detected.
func RestartOnChange() {
	notifyChan := NotifyOnChange()
	<-notifyChan
	logf("%s changed. Restarting via exec.", getExePath())
	// Sort of a maybe-workaround for the issue detailed in RestartViaExec:
	time.Sleep(1 * time.Millisecond)
	RestartViaExec()
}

// Subscribe to a notification when the current process' executable file is modified.
// Returns a channel to which notifications (just `true`) will be sent whenever a
// change is detected.
func NotifyOnChange() chan bool {
	notifyChan := make(chan bool)
	go func() {
		exePath := getExePath()
		if exePath == errorPath {
			return
		}
		exeDir := filepath.Dir(exePath)
		watcher, err := fsnotify.NewWatcher()
		if err != nil {
			logf("Failed to initialize gopkg.in/fsnotify.v1 watcher: %s", err)
			return
		}
		abs, _ := filepath.Abs(exeDir)
		err = watcher.Add(abs)
		if err != nil {
			logf("Failed to start filesystem watcher on %s: %s", exeDir, err)
			return
		}
		for {
			select {
			case err := <-watcher.Errors:
				logf("Watcher error: %s", err)
			case ev := <-watcher.Events:
				// log.Println("change", ev.Name, exePath, ev)
				if ev.Name == exePath {
					notifyChan <- true
				}
			}
		}
	}()
	return notifyChan
}

// Restart the current process by calling syscall.Exec, using os.Args (with filepath.LookPath)
// and os.Environ() to recreate the same args & environment that was used when the process was
// originally started.
// Due to using syscall.Exec, this function is not portable to systems that don't support exec.
func RestartViaExec() {
	exePath := getExePath()
	if exePath == errorPath {
		return
	}
	for {
		args := os.Args
		env := os.Environ()
		// logf("calling syscall.Exec with %q, %q, %q", exePath, args, env)
		syscall.Exec(exePath, args, env)
		// Not sure if this is due to user error, a Go regression in 1.5.x, or arch something,
		// but this started failing when called immediately; a short delay (perhaps to switch
		// to a different thread? or maybe to actually delay for some reason?) seems to work
		// all the time. though.
		logf("syscall.Exec failed, trying again in one second...")
		time.Sleep(1 * time.Second)
	}
}
<|endoftext|>


<commit_before>package autorestart

import (
	"log"
	"os"
	"os/exec"
	"os/signal"
	"path/filepath"
	"syscall"
	"time"

	"gopkg.in/fsnotify.v1"
)

func logf(format string, args ...interface{}) {
	log.Printf("[autorestart] "+format+"\n", args...)
}

const errorPath = "*error*"

var _exePath = errorPath

func getExePath() string {
	var err error
	if _exePath == errorPath {
		_exePath, err = exec.LookPath(os.Args[0])
		if err != nil {
			logf("Failed to resolve path to current program: %s", err)
			_exePath = errorPath
		} else {
			_exePath, err = filepath.Abs(_exePath)
			if err != nil {
				logf("Failed to resolve absolute path to current program: %s", err)
				_exePath = errorPath
			} else {
				_exePath = filepath.Clean(_exePath)
			}
		}
	}
	return _exePath
}

// Restart the current program when the program's executable is updated.
// This function is a wrapper around NotifyOnChange and RestartViaExec, calling the
// latter when the former signals that a change was detected.
func RestartOnChange() {
	notifyChan := NotifyOnChange()
	<-notifyChan
	logf("%s changed. Restarting via exec.", getExePath())
	// Sort of a maybe-workaround for the issue detailed in RestartViaExec:
	time.Sleep(1 * time.Millisecond)
	RestartViaExec()
}

// Subscribe to a notification when the current process' executable file is modified.
// Returns a channel to which notifications (just `true`) will be sent whenever a
// change is detected.
func NotifyOnChange() chan bool {
	notifyChan := make(chan bool)
	go func() {
		exePath := getExePath()
		if exePath == errorPath {
			return
		}
		exeDir := filepath.Dir(exePath)
		watcher, err := fsnotify.NewWatcher()
		if err != nil {
			logf("Failed to initialize gopkg.in/fsnotify.v1 watcher: %s", err)
			return
		}
		abs, _ := filepath.Abs(exeDir)
		err = watcher.Add(abs)
		if err != nil {
			logf("Failed to start filesystem watcher on %s: %s", exeDir, err)
			return
		}
		for {
			select {
			case err := <-watcher.Errors:
				logf("Watcher error: %s", err)
			case ev := <-watcher.Events:
				// log.Println("change", ev.Name, exePath, ev)
				if ev.Name == exePath {
					notifyChan <- true
				}
			}
		}
	}()
	return notifyChan
}

// Restart the current process by calling syscall.Exec, using os.Args (with filepath.LookPath)
// and os.Environ() to recreate the same args & environment that was used when the process was
// originally started.
// Due to using syscall.Exec, this function is not portable to systems that don't support exec.
func RestartViaExec() {
	exePath := getExePath()
	if exePath == errorPath {
		return
	}
	for {
		args := os.Args
		env := os.Environ()
		// logf("calling syscall.Exec with %q, %q, %q", exePath, args, env)
		err := syscall.Exec(exePath, args, env)
		// Not sure if this is due to user error, a Go regression in 1.5.x, or arch something,
		// but this started failing when called immediately; a short delay (perhaps to switch
		// to a different thread? or maybe to actually delay for some reason?) seems to work
		// all the time. though.
		logf("syscall.Exec failed [%v], trying again in one second...", err)
		time.Sleep(1 * time.Second)
	}
}

func NotifyOnSighup() chan os.Signal {
	sigChan := make(chan os.Signal)
	signal.Notify(sigChan, syscall.SIGHUP)
	return sigChan
}
<commit_msg>Add support for polling<commit_after>package autorestart

import (
	"log"
	"os"
	"os/exec"
	"os/signal"
	"path/filepath"
	"syscall"
	"time"

	"github.com/tillberg/watcher"
)

func logf(format string, args ...interface{}) {
	log.Printf("[autorestart] "+format+"\n", args...)
}

const errorPath = "*error*"

var _exePath = errorPath

func getExePath() string {
	var err error
	if _exePath == errorPath {
		_exePath, err = exec.LookPath(os.Args[0])
		if err != nil {
			logf("Failed to resolve path to current program: %s", err)
			_exePath = errorPath
		} else {
			_exePath, err = filepath.Abs(_exePath)
			if err != nil {
				logf("Failed to resolve absolute path to current program: %s", err)
				_exePath = errorPath
			} else {
				_exePath = filepath.Clean(_exePath)
			}
		}
	}
	return _exePath
}

// Restart the current program when the program's executable is updated.
// This function is a wrapper around NotifyOnChange and RestartViaExec, calling the
// latter when the former signals that a change was detected.
func RestartOnChange() {
	notifyChan := NotifyOnChange(true)
	<-notifyChan
	logf("%s changed. Restarting via exec.", getExePath())
	// Sort of a maybe-workaround for the issue detailed in RestartViaExec:
	time.Sleep(1 * time.Millisecond)
	RestartViaExec()
}

// Subscribe to a notification when the current process' executable file is modified.
// Returns a channel to which notifications (just `true`) will be sent whenever a
// change is detected.
func NotifyOnChange(usePolling bool) chan bool {
	notifyChan := make(chan bool)
	go func() {
		exePath := getExePath()
		if exePath == errorPath {
			return
		}
		notify, err := watcher.WatchExecutable(exePath, usePolling)
		if err != nil {
			logf("Failed to initialize watcher: %v", err)
			return
		}
		for range notify {
			notifyChan <- true
		}
	}()
	return notifyChan
}

// Restart the current process by calling syscall.Exec, using os.Args (with filepath.LookPath)
// and os.Environ() to recreate the same args & environment that was used when the process was
// originally started.
// Due to using syscall.Exec, this function is not portable to systems that don't support exec.
func RestartViaExec() {
	exePath := getExePath()
	if exePath == errorPath {
		return
	}
	for {
		err := syscall.Exec(exePath, os.Args, os.Environ())
		// Not sure if this is due to user error, a Go regression in 1.5.x, or arch something,
		// but this started failing when called immediately; a short delay (perhaps to switch
		// to a different thread? or maybe to actually delay for some reason?) seems to work
		// all the time. though.
		logf("syscall.Exec failed [%v], trying again in one second...", err)
		time.Sleep(1 * time.Second)
	}
}

func NotifyOnSighup() chan os.Signal {
	sigChan := make(chan os.Signal)
	signal.Notify(sigChan, syscall.SIGHUP)
	return sigChan
}
<|endoftext|>


<commit_before>package piccolo

import (
	"log"
	"time"
)

type timingFunc struct {
	FuncJob func()
	Ticker  int
}

var (
	timingFuncs map[string]*timingFunc
)

func init() {
	timingFuncs = map[string]*timingFunc{}
}

func AddTimingFunc(name string, ticker int, funcJob func()) {
	fn := new(timingFunc)
	fn.FuncJob = funcJob
	fn.Ticker = ticker
	timingFuncs[name] = fn
}

func StartTiming(interval time.Duration) {
	flag := make(chan bool)
	ticker := time.NewTicker(interval)
	go doTimingJob(ticker.C, flag)
	<-flag
}

func doTimingJob(c <-chan time.Time, flag chan<- bool) {
	for {
		<-c
		for _, fn := range timingFuncs {
			if fn.Ticker == -1 {
				fn.FuncJob()
				continue
			}
			if fn.Ticker > 0 {
				log.Println(fn.Ticker)
				fn.FuncJob()
				fn.Ticker--
			} else {
				goto DONE
			}
		}
	}
DONE:
	flag <- true
}
<commit_msg>update chan<commit_after>package piccolo

import (
	"log"
	"time"
)

type timingFunc struct {
	FuncJob func()
	Ticker  int
}

var (
	timingFuncs map[string]*timingFunc
)

func init() {
	timingFuncs = map[string]*timingFunc{}
}

func AddTimingFunc(name string, ticker int, funcJob func()) {
	fn := new(timingFunc)
	fn.FuncJob = funcJob
	fn.Ticker = ticker
	timingFuncs[name] = fn
}

func StartTiming(interval time.Duration) {
	flag := make(chan struct{})
	ticker := time.NewTicker(interval)
	go doTimingJob(ticker.C, flag)
	<-flag
}

func doTimingJob(c <-chan time.Time, flag chan<- struct{}) {
	for {
		<-c
		for _, fn := range timingFuncs {
			if fn.Ticker == -1 {
				fn.FuncJob()
				continue
			}
			if fn.Ticker > 0 {
				log.Println(fn.Ticker)
				fn.FuncJob()
				fn.Ticker--
			} else {
				goto DONE
			}
		}
	}
DONE:
	flag <- struct{}{}
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/joushou/serve2"
	"net"
)

//
// To test:
//   nc localhost 8080
//
// ... And then write "ECHO" or "DISCARD", followed by return, and what you
// want echooed or discarded

func main() {

	l, err := net.Listen("tcp", ":8080")
	if err != nil {
		panic(err)
	}

	server := serve2.New()

	// These two are silly, and requires that you write "ECHO" or "DISCARD" when
	// the connection is opened to recognize the protocol, as neither of these
	// actually have any initial request or handshake.
	echo := serve2.NewEchoProtoHandler()
	discard := serve2.NewDiscardProtoHandler()

	server.AddHandlers(echo, discard)
	server.Serve(l)
}
<commit_msg>Add HTTP to simple test<commit_after>package main

import (
	"fmt"
	"github.com/joushou/serve2"
	"net"
	"net/http"
)

//
// Accepts HTTP, ECHO and DISCARD. HTTP can be tested with a browser or
// curl/wget.
//
// To test ECHO/DISCARD
//   nc localhost 8080
//
// ... And then write "ECHO" or "DISCARD", followed by return, and what you
// want echooed or discarded

type HTTPHandler struct{}

func (h *HTTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if r.Method == "OPTIONS" || r.Method == "HEAD" {
		return
	}

	fmt.Fprintf(w, "<!DOCTYPE html>Welcome to %s", r.URL.Path)

}

func main() {

	l, err := net.Listen("tcp", ":8080")
	if err != nil {
		panic(err)
	}

	server := serve2.New()

	// See the HTTPHandler above
	http, err := serve2.NewHTTPProtoHandler(&HTTPHandler{}, l.Addr())
	if err != nil {
		panic(err)
	}

	echo := serve2.NewEchoProtoHandler()
	discard := serve2.NewDiscardProtoHandler()

	server.AddHandlers(echo, discard, http)
	server.Serve(l)
}
<|endoftext|>


<commit_before>package fld

import (
	"fmt"
	"net"
)

var (
	Instance *Fld
)

type Fld struct {
	outgoing chan string
	address  string
	conn     net.Conn
}

func init() {
	Start("127.0.0.1:8127")
}

func Start(address string) {
	Instance = &Fld{address: address, outgoing: make(chan string, 100000)}
	Instance.connect()

	go Instance.processOutgoing()
}

func (fld *Fld) connect() error {
	conn, err := net.Dial("udp", fld.address)
	if err != nil {
		return err
	}

	fld.conn = conn
	return nil
}

func (fld *Fld) processOutgoing() {
	for outgoing := range fld.outgoing {
		if _, err := fld.conn.Write([]byte(outgoing)); err != nil {
			fld.connect()
		}
	}
}

func Info(entry string) {
	payload := createPayload(entry, "info")
	send(payload)
}

func Debug(entry string) {
	payload := createPayload(entry, "debug")
	send(payload)
}
func Warning(entry string) {
	payload := createPayload(entry, "warning")
	send(payload)
}
func Error(entry string) {
	payload := createPayload(entry, "error")
	send(payload)
}
func createPayload(name string, severity string) string {
	return fmt.Sprintf("%s|%s", name, severity)
}

func send(payload string) {
	length := float64(len(Instance.outgoing))
	capacity := float64(cap(Instance.outgoing))

	if length < capacity*0.9 {
		Instance.outgoing <- payload
	}
}
<commit_msg>long fld to go-logging<commit_after>package fld

import (
	"flag"
	"net"

	"github.com/op/go-logging"
)

var (
	Instance *Fld
	address  *string = flag.String("logsd", "127.0.0.1:8127", "UDP endpoint for LogsD daemon")
)

type Fld struct {
	outgoing chan []byte
	conn     net.Conn
}

func (fld *Fld) Log(level logging.Level, depth int, rec *logging.Record) error {

	switch level {
	case logging.CRITICAL:
		return send(fld, "crit", rec.Formatted())
	case logging.ERROR:
		return send(fld, "err", rec.Formatted())
	case logging.WARNING:
		return send(fld, "warning", rec.Formatted())
	case logging.NOTICE:
		return send(fld, "notice", rec.Formatted())
	case logging.INFO:
		return send(fld, "info", rec.Formatted())
	case logging.DEBUG:
		return send(fld, "debug", rec.Formatted())
	default:
	}
	panic("unhandled log level")
}

func init() {
	start()
}

func start() {
	Instance = &Fld{outgoing: make(chan []byte, 100000)}
	go Instance.processOutgoing()
}

func send(fld *Fld, severity string, name string) error {
	length := float64(len(Instance.outgoing))
	capacity := float64(cap(Instance.outgoing))

	if length < capacity*0.9 {
		payload := severity + "|" + name
		Instance.outgoing <- []byte(payload)
	}
	return nil
}

func (fld *Fld) connect() error {
	conn, err := net.Dial("udp", *address)
	if err != nil {
		return err
	}

	fld.conn = conn
	return nil
}

func (fld *Fld) processOutgoing() {
	for outgoing := range fld.outgoing {

		if nil == fld.conn {
			fld.connect()
		}

		if _, err := fld.conn.Write(outgoing); err != nil {
			fld.connect()
		}
	}
}
<|endoftext|>


<commit_before>package clrs

import (
	"testing"
)

var (
	bTreeNodes []*bTreeNode
)

func buildTestBTree() *bTree {
	bt := new(bTree)
	bt._t = 3
	bt.bTreeCreate()
	bTreeNodes = append(bTreeNodes, bt.root)

	for _, keys := range [][]rune{
		{'A', 'C', 'D', 'E'},
		{'J', 'K'},
		{'N', 'O'},
		{'R', 'S', 'T', 'U', 'V'},
		{'Y', 'Z'},
	} {
		node := bt.allocateNode()
		node.n = len(keys)
		node.leaf = true
		for i, k := range keys {
			node.key[i] = k
		}
		bTreeNodes = append(bTreeNodes, node)
	}

	bt.root.n = 4
	bt.root.leaf = false
	for i, k := range []rune{'G', 'M', 'P', 'X'} {
		bt.root.key[i] = k
	}
	for i, n := range bTreeNodes[1:] {
		bt.root.c[i] = n
	}
	return bt
}

func TestBTreeSearch(t *testing.T) {
	bt := buildTestBTree()
	cases := []struct {
		k         rune
		wantNode  *bTreeNode
		wantIndex int
	}{
		{'B', nil, 0},
		{'G', bTreeNodes[0], 1},
		{'M', bTreeNodes[0], 2},
		{'P', bTreeNodes[0], 3},
		{'X', bTreeNodes[0], 4},
		{'A', bTreeNodes[1], 1},
		{'C', bTreeNodes[1], 2},
		{'K', bTreeNodes[2], 2},
		{'N', bTreeNodes[3], 1},
		{'V', bTreeNodes[4], 5},
		{'Y', bTreeNodes[5], 1},
	}
	for _, c := range cases {
		node, index := bt.bTreeSearch(bt.root, c.k)
		if node != c.wantNode || index != c.wantIndex {
			t.Errorf("search %c", c.k)
			t.Errorf(" got node %v[%v]", node, index)
			t.Errorf("want node %v[%v]", c.wantNode, c.wantIndex)
		}
	}
}
<commit_msg>UT of bTreeInsert<commit_after>package clrs

import (
	"reflect"
	"testing"
)

var (
	bTreeNodes []*bTreeNode
)

func buildTestBTree() *bTree {
	bTreeNodes = make([]*bTreeNode, 0)
	bt := new(bTree)
	bt._t = 3
	bt.bTreeCreate()
	bTreeNodes = append(bTreeNodes, bt.root)

	for _, keys := range [][]rune{
		{'A', 'C', 'D', 'E'},
		{'J', 'K'},
		{'N', 'O'},
		{'R', 'S', 'T', 'U', 'V'},
		{'Y', 'Z'},
	} {
		node := bt.allocateNode()
		node.n = len(keys)
		node.leaf = true
		for i, k := range keys {
			node.key[i] = k
		}
		bTreeNodes = append(bTreeNodes, node)
	}

	bt.root.n = 4
	bt.root.leaf = false
	for i, k := range []rune{'G', 'M', 'P', 'X'} {
		bt.root.key[i] = k
	}
	for i, n := range bTreeNodes[1:] {
		bt.root.c[i] = n
	}
	return bt
}

func TestBTreeSearch(t *testing.T) {
	bt := buildTestBTree()
	cases := []struct {
		k         rune
		wantNode  *bTreeNode
		wantIndex int
	}{
		{'B', nil, 0},
		{'G', bTreeNodes[0], 1},
		{'M', bTreeNodes[0], 2},
		{'P', bTreeNodes[0], 3},
		{'X', bTreeNodes[0], 4},
		{'A', bTreeNodes[1], 1},
		{'C', bTreeNodes[1], 2},
		{'K', bTreeNodes[2], 2},
		{'N', bTreeNodes[3], 1},
		{'V', bTreeNodes[4], 5},
		{'Y', bTreeNodes[5], 1},
	}
	for _, c := range cases {
		node, index := bt.bTreeSearch(bt.root, c.k)
		if node != c.wantNode || index != c.wantIndex {
			t.Errorf("   search %c", c.k)
			t.Errorf(" got node %v[%v]", node, index)
			t.Errorf("want node %v[%v]", c.wantNode, c.wantIndex)
		}
	}
}

func TestBTreeInsert(t *testing.T) {
	bt := buildTestBTree()
	bt.bTreeInsert('B')
	wantRoot := []rune{'G', 'M', 'P', 'X', 0}
	if !reflect.DeepEqual(bt.root.key, wantRoot) {
		t.Errorf(" got keys %v", bt.root.key)
		t.Errorf("want keys %v", wantRoot)
	}
	wantChildren := [][]rune{
		[]rune{'A', 'B', 'C', 'D', 'E'},
		[]rune{'J', 'K'},
		[]rune{'N', 'O'},
		[]rune{'R', 'S', 'T', 'U', 'V'},
		[]rune{'Y', 'Z'},
	}
	for i, c := range wantChildren {
		node := bt.root.c[i]
		if !reflect.DeepEqual(node.key[:node.n], c) {
			t.Errorf("after insert B:")
			t.Errorf(" got keys %v", node.key[:node.n])
			t.Errorf("want keys %v", c)
		}
	}

	bt.bTreeInsert('Q')
	wantRoot = []rune{'G', 'M', 'P', 'T', 'X'}
	if !reflect.DeepEqual(bt.root.key, wantRoot) {
		t.Errorf("after insert Q:")
		t.Errorf(" got keys %v", bt.root.key)
		t.Errorf("want keys %v", wantRoot)
	}
	wantChildren = [][]rune{
		[]rune{'A', 'B', 'C', 'D', 'E'},
		[]rune{'J', 'K'},
		[]rune{'N', 'O'},
		[]rune{'Q', 'R', 'S'},
		[]rune{'U', 'V'},
		[]rune{'Y', 'Z'},
	}
	for i, c := range wantChildren {
		node := bt.root.c[i]
		if !reflect.DeepEqual(node.key[:node.n], c) {
			t.Errorf("after insert Q:")
			t.Errorf(" got keys %v", node.key[:node.n])
			t.Errorf("want keys %v", c)
		}
	}

	bt.bTreeInsert('L')
	wantRoot = []rune{'P'}
	if !reflect.DeepEqual(bt.root.key[:bt.root.n], wantRoot) {
		t.Errorf("after insert L:")
		t.Errorf(" got keys %v", bt.root.key[:bt.root.n])
		t.Errorf("want keys %v", wantRoot)
	}
	wantChildren = [][]rune{
		[]rune{'G', 'M'},
		[]rune{'T', 'X'},
	}
	for i, c := range wantChildren {
		node := bt.root.c[i]
		if !reflect.DeepEqual(node.key[:node.n], c) {
			t.Errorf("after insert L:")
			t.Errorf(" got keys %v", node.key[:node.n])
			t.Errorf("want keys %v", c)
		}
	}
	lnode := bt.root.c[0]
	rnode := bt.root.c[1]
	wantChildren = [][]rune{
		[]rune{'A', 'B', 'C', 'D', 'E'},
		[]rune{'J', 'K', 'L'},
		[]rune{'N', 'O'},
	}
	for i, c := range wantChildren {
		node := lnode.c[i]
		if !reflect.DeepEqual(node.key[:node.n], c) {
			t.Errorf("after insert L:")
			t.Errorf(" got keys %v", node.key[:node.n])
			t.Errorf("want keys %v", c)
		}
	}
	wantChildren = [][]rune{
		[]rune{'Q', 'R', 'S'},
		[]rune{'U', 'V'},
		[]rune{'Y', 'Z'},
	}
	for i, c := range wantChildren {
		node := rnode.c[i]
		if !reflect.DeepEqual(node.key[:node.n], c) {
			t.Errorf("after insert L:")
			t.Errorf(" got keys %v", node.key[:node.n])
			t.Errorf("want keys %v", c)
		}
	}

	bt.bTreeInsert('F')
	wantRoot = []rune{'P'}
	if !reflect.DeepEqual(bt.root.key[:bt.root.n], wantRoot) {
		t.Errorf("after insert F:")
		t.Errorf(" got keys %v", bt.root.key[:bt.root.n])
		t.Errorf("want keys %v", wantRoot)
	}
	wantChildren = [][]rune{
		[]rune{'C', 'G', 'M'},
		[]rune{'T', 'X'},
	}
	for i, c := range wantChildren {
		node := bt.root.c[i]
		if !reflect.DeepEqual(node.key[:node.n], c) {
			t.Errorf("after insert F:")
			t.Errorf(" got keys %v", node.key[:node.n])
			t.Errorf("want keys %v", c)
		}
	}
	lnode = bt.root.c[0]
	rnode = bt.root.c[1]
	wantChildren = [][]rune{
		[]rune{'A', 'B'},
		[]rune{'D', 'E', 'F'},
		[]rune{'J', 'K', 'L'},
		[]rune{'N', 'O'},
	}
	for i, c := range wantChildren {
		node := lnode.c[i]
		if !reflect.DeepEqual(node.key[:node.n], c) {
			t.Errorf("after insert F:")
			t.Errorf(" got keys %v", node.key[:node.n])
			t.Errorf("want keys %v", c)
		}
	}
	wantChildren = [][]rune{
		[]rune{'Q', 'R', 'S'},
		[]rune{'U', 'V'},
		[]rune{'Y', 'Z'},
	}
	for i, c := range wantChildren {
		node := rnode.c[i]
		if !reflect.DeepEqual(node.key[:node.n], c) {
			t.Errorf("after insert F:")
			t.Errorf(" got keys %v", node.key[:node.n])
			t.Errorf("want keys %v", c)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"github.com/codegangsta/cli"
	_ "github.com/mattn/go-sqlite3"
	//	"github.com/fumiyas/qrc/cmd/qrc"
	"fmt"
	"log"
	"os"
)

func dump() {
	fmt.Println("Dumping databse...")
	db, err := sql.Open("sqlite3", "./test.sqlite")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	rows, err := db.Query("select email, secret from accounts")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()
	for rows.Next() {
		var email string
		var secret string
		rows.Scan(&email, &secret)
		fmt.Println(email, secret)
	}
	rows.Close()
}

func main() {

	app := cli.NewApp()
	app.Name = "qr_auth_dump"
	app.Usage = "Dump secrets from a Google Authenticator database and spit out QR codes"
	app.Action = func(c *cli.Context) {
		dump()
	}

	app.Run(os.Args)

}
<commit_msg>Actually print qr codes<commit_after>package main

import (
	"code.google.com/p/rsc/qr"
	"database/sql"
	"fmt"
	"github.com/codegangsta/cli"
	"github.com/fumiyas/qrc/lib"
	_ "github.com/mattn/go-sqlite3"
	"log"
	"os"
)

// generate_otp_uri takes in an email and string and spits out an otp
// uri per the spec:
// https://code.google.com/p/google-authenticator/wiki/KeyUriFormat
// otpauth://TYPE/LABEL?PARAMETERS
//
// Example:
// otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Example
func generate_otp_uri(email string, secret string) string {
	return fmt.Sprintf("otpauth://totp/%s?secret=%s", email, secret)
}

func display_qr(email string, secret string) {
	text := generate_otp_uri(email, secret)
	code, _ := qr.Encode(text, qr.M)
	fmt.Printf("Code for %s (secret %s):\n", email, secret)
	qrc.PrintAA(os.Stdout, code, false)
	fmt.Println()
}

func dump() {
	fmt.Println("Dumping databse...")
	db, err := sql.Open("sqlite3", "./example.db")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	rows, err := db.Query("select email, secret from accounts")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()
	for rows.Next() {
		var email string
		var secret string
		rows.Scan(&email, &secret)
		display_qr(email, secret)
	}
	rows.Close()
}

func main() {

	app := cli.NewApp()
	app.Name = "qr_auth_dump"
	app.Usage = "Dump secrets from a Google Authenticator database and spit out QR codes"
	app.Action = func(c *cli.Context) {
		dump()
	}

	app.Run(os.Args)

}
<|endoftext|>