<commit_before>package tgff

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"path"
	"strings"
	"testing"

	"github.com/goesd/support/assert"
)

const (
	fixturePath = "fixtures"
)

func TestParseSuccess(t *testing.T) {
	file := openFixture("simple")
	defer file.Close()

	r, err := Parse(file)

	assert.Success(err, t)

	assert.Equal(r.Period, uint32(1180), t)
	assert.Equal(len(r.Graphs), 5, t)
	assert.Equal(len(r.Tables), 3, t)

	graphs := []struct {
		period    uint32
		tasks     int
		arcs      int
		deadlines int
	}{
		{590, 12, 19, 1},
		{1180, 20, 25, 6},
		{1180, 24, 28, 8},
		{590, 8, 7, 3},
		{1180, 20, 24, 6},
	}

	for i, graph := range graphs {
		assert.Equal(r.Graphs[i].Name, "TASK_GRAPH", t)
		assert.Equal(r.Graphs[i].Number, uint32(i), t)
		assert.Equal(r.Graphs[i].Period, graph.period, t)

		assert.Equal(len(r.Graphs[i].Tasks), graph.tasks, t)
		assert.Equal(len(r.Graphs[i].Arcs), graph.arcs, t)
		assert.Equal(len(r.Graphs[i].Deadlines), graph.deadlines, t)
	}

	tables := []struct {
		price float64
	}{
		{70.1121},
		{71.4235},
		{80.491},
	}

	for i, table := range tables {
		assert.Equal(r.Tables[i].Name, "COMMUN", t)
		assert.Equal(r.Tables[i].Number, uint32(i), t)
		assert.Equal(r.Tables[i].Attributes["price"], table.price, t)

		assert.Equal(len(r.Tables[i].Columns), 2, t)
		assert.Equal(r.Tables[i].Columns[0].Name, "type", t)
		assert.Equal(r.Tables[i].Columns[1].Name, "exec_time", t)
	}

	assert.DeepEqual(r.Tables[1].Columns[1].Data, fixtureSimpleTable1Column1, t)
}

func TestParseFailure(t *testing.T) {
	reader := strings.NewReader("  @ garbage")

	_, err := Parse(reader)

	assert.Failure(err, t)
}

func BenchmarkParseSimple(b *testing.B) {
	data := readFixture("simple")

	for i := 0; i < b.N; i++ {
		Parse(bytes.NewReader(data))
	}
}

func BenchmarkParseComplex(b *testing.B) {
	data := readFixture("complex")

	for i := 0; i < b.N; i++ {
		Parse(bytes.NewReader(data))
	}
}

func ExampleParseFile() {
	result, _ := ParseFile("fixtures/simple.tgff")

	fmt.Println("Task graphs:", len(result.Graphs))
	fmt.Println("Data tables:", len(result.Tables))

	// Output:
	// Task graphs: 5
	// Data tables: 3
}

func readFixture(name string) []byte {
	path := path.Join(fixturePath, fmt.Sprintf("%s.tgff", name))
	data, _ := ioutil.ReadFile(path)

	return data
}

func openFixture(name string) *os.File {
	path := path.Join(fixturePath, fmt.Sprintf("%s.tgff", name))
	file, _ := os.Open(path)

	return file
}

var fixtureSimpleTable1Column1 = []float64{
	48.5893,
	33.4384,
	34.2468,
	51.2027,
	51.3571,
	30.3827,
	43.3982,
	60.9097,
	36.0322,
	34.7446,
	45.3479,
	31.7221,
	49.6842,
	52.0635,
	44.7690,
	37.7183,
	54.7523,
	58.4432,
	33.1266,
	48.2143,
	31.2946,
	45.9168,
	36.4521,
	61.6448,
	49.4966,
	37.1130,
	40.1642,
	38.9454,
	41.6213,
	42.1084,
	42.4186,
	42.5145,
	34.4180,
	33.4178,
	32.4243,
	63.7925,
	50.3810,
	51.9030,
	46.4714,
	35.0566,
	41.8399,
	30.1513,
	31.7449,
	57.3263,
	61.2321,
	44.9932,
	32.0830,
	37.9489,
	62.4774,
	39.2500,
}
<commit_msg>Use Equal instead of DeepEqual<commit_after>package tgff

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"path"
	"strings"
	"testing"

	"github.com/goesd/support/assert"
)

const (
	fixturePath = "fixtures"
)

func TestParseSuccess(t *testing.T) {
	file := openFixture("simple")
	defer file.Close()

	r, err := Parse(file)

	assert.Success(err, t)

	assert.Equal(r.Period, uint32(1180), t)
	assert.Equal(len(r.Graphs), 5, t)
	assert.Equal(len(r.Tables), 3, t)

	graphs := []struct {
		period    uint32
		tasks     int
		arcs      int
		deadlines int
	}{
		{590, 12, 19, 1},
		{1180, 20, 25, 6},
		{1180, 24, 28, 8},
		{590, 8, 7, 3},
		{1180, 20, 24, 6},
	}

	for i, graph := range graphs {
		assert.Equal(r.Graphs[i].Name, "TASK_GRAPH", t)
		assert.Equal(r.Graphs[i].Number, uint32(i), t)
		assert.Equal(r.Graphs[i].Period, graph.period, t)

		assert.Equal(len(r.Graphs[i].Tasks), graph.tasks, t)
		assert.Equal(len(r.Graphs[i].Arcs), graph.arcs, t)
		assert.Equal(len(r.Graphs[i].Deadlines), graph.deadlines, t)
	}

	tables := []struct {
		price float64
	}{
		{70.1121},
		{71.4235},
		{80.491},
	}

	for i, table := range tables {
		assert.Equal(r.Tables[i].Name, "COMMUN", t)
		assert.Equal(r.Tables[i].Number, uint32(i), t)
		assert.Equal(r.Tables[i].Attributes["price"], table.price, t)

		assert.Equal(len(r.Tables[i].Columns), 2, t)
		assert.Equal(r.Tables[i].Columns[0].Name, "type", t)
		assert.Equal(r.Tables[i].Columns[1].Name, "exec_time", t)
	}

	assert.Equal(r.Tables[1].Columns[1].Data, fixtureSimpleTable1Column1, t)
}

func TestParseFailure(t *testing.T) {
	reader := strings.NewReader("  @ garbage")

	_, err := Parse(reader)

	assert.Failure(err, t)
}

func BenchmarkParseSimple(b *testing.B) {
	data := readFixture("simple")

	for i := 0; i < b.N; i++ {
		Parse(bytes.NewReader(data))
	}
}

func BenchmarkParseComplex(b *testing.B) {
	data := readFixture("complex")

	for i := 0; i < b.N; i++ {
		Parse(bytes.NewReader(data))
	}
}

func ExampleParseFile() {
	result, _ := ParseFile("fixtures/simple.tgff")

	fmt.Println("Task graphs:", len(result.Graphs))
	fmt.Println("Data tables:", len(result.Tables))

	// Output:
	// Task graphs: 5
	// Data tables: 3
}

func readFixture(name string) []byte {
	path := path.Join(fixturePath, fmt.Sprintf("%s.tgff", name))
	data, _ := ioutil.ReadFile(path)

	return data
}

func openFixture(name string) *os.File {
	path := path.Join(fixturePath, fmt.Sprintf("%s.tgff", name))
	file, _ := os.Open(path)

	return file
}

var fixtureSimpleTable1Column1 = []float64{
	48.5893,
	33.4384,
	34.2468,
	51.2027,
	51.3571,
	30.3827,
	43.3982,
	60.9097,
	36.0322,
	34.7446,
	45.3479,
	31.7221,
	49.6842,
	52.0635,
	44.7690,
	37.7183,
	54.7523,
	58.4432,
	33.1266,
	48.2143,
	31.2946,
	45.9168,
	36.4521,
	61.6448,
	49.4966,
	37.1130,
	40.1642,
	38.9454,
	41.6213,
	42.1084,
	42.4186,
	42.5145,
	34.4180,
	33.4178,
	32.4243,
	63.7925,
	50.3810,
	51.9030,
	46.4714,
	35.0566,
	41.8399,
	30.1513,
	31.7449,
	57.3263,
	61.2321,
	44.9932,
	32.0830,
	37.9489,
	62.4774,
	39.2500,
}
<|endoftext|>


<commit_before>package server

// broadcastMessage processes messages and either broadcasts
// them to all connected users, or to a single user.
func (sc *signedConn) broadcastMessage() error {
	return nil
}
<commit_msg>Added unicast<commit_after>package server

import "errors"

// broadcastMessage processes messages and either broadcasts
// them to all connected users, or to a single user.
func (sc *signedConn) broadcastMessage() error {
	to := sc.message.GetPacket().GetTo().String()

	if to == "" {
		err := sc.broadcastAll()
		if err != nil {
			return err
		}
	} else {
		td := sc.tracker.getVerificationKeyData(to)
		if td == nil {
			return errors.New("peer disconnected")
		}

		err := writeMessage(td.conn, sc.message)
		if err != nil {
			return err
		}
	}

	return nil
}

// broadcastAll broadcasts to all participants.
func (sc *signedConn) broadcastAll() error {

	return nil
}
<|endoftext|>


<commit_before>package common

import (
	"sync/atomic"
	"time"
)

/*
ThrottleTimer fires an event at most "dur" after each .Set() call.
If a short burst of .Set() calls happens, ThrottleTimer fires once.
If a long continuous burst of .Set() calls happens, ThrottleTimer fires
at most once every "dur".
*/
type ThrottleTimer struct {
	Name  string
	Ch    chan struct{}
	quit  chan struct{}
	dur   time.Duration
	timer *time.Timer
	isSet uint32
}

func NewThrottleTimer(name string, dur time.Duration) *ThrottleTimer {
	var ch = make(chan struct{})
	var quit = make(chan struct{})
	var t = &ThrottleTimer{Name: name, Ch: ch, dur: dur, quit: quit}
	t.timer = time.AfterFunc(dur, t.fireRoutine)
	t.timer.Stop()
	return t
}

func (t *ThrottleTimer) fireRoutine() {
	select {
	case t.Ch <- struct{}{}:
		atomic.StoreUint32(&t.isSet, 0)
	case <-t.quit:
		// do nothing
	default:
		t.timer.Reset(t.dur)
	}
}

func (t *ThrottleTimer) Set() {
	if atomic.CompareAndSwapUint32(&t.isSet, 0, 1) {
		t.timer.Reset(t.dur)
	}
}

func (t *ThrottleTimer) Unset() {
	t.timer.Stop()
}

// For ease of .Stop()'ing services before .Start()'ing them,
// we ignore .Stop()'s on nil ThrottleTimers
func (t *ThrottleTimer) Stop() bool {
	if t == nil {
		return false
	}
	close(t.quit)
	return t.timer.Stop()
}
<commit_msg>Fix bug where Unset halts ThrottleTimer<commit_after>package common

import (
	"sync/atomic"
	"time"
)

/*
ThrottleTimer fires an event at most "dur" after each .Set() call.
If a short burst of .Set() calls happens, ThrottleTimer fires once.
If a long continuous burst of .Set() calls happens, ThrottleTimer fires
at most once every "dur".
*/
type ThrottleTimer struct {
	Name  string
	Ch    chan struct{}
	quit  chan struct{}
	dur   time.Duration
	timer *time.Timer
	isSet uint32
}

func NewThrottleTimer(name string, dur time.Duration) *ThrottleTimer {
	var ch = make(chan struct{})
	var quit = make(chan struct{})
	var t = &ThrottleTimer{Name: name, Ch: ch, dur: dur, quit: quit}
	t.timer = time.AfterFunc(dur, t.fireRoutine)
	t.timer.Stop()
	return t
}

func (t *ThrottleTimer) fireRoutine() {
	select {
	case t.Ch <- struct{}{}:
		atomic.StoreUint32(&t.isSet, 0)
	case <-t.quit:
		// do nothing
	default:
		t.timer.Reset(t.dur)
	}
}

func (t *ThrottleTimer) Set() {
	if atomic.CompareAndSwapUint32(&t.isSet, 0, 1) {
		t.timer.Reset(t.dur)
	}
}

func (t *ThrottleTimer) Unset() {
	atomic.StoreUint32(&t.isSet, 0)
	t.timer.Stop()
}

// For ease of .Stop()'ing services before .Start()'ing them,
// we ignore .Stop()'s on nil ThrottleTimers
func (t *ThrottleTimer) Stop() bool {
	if t == nil {
		return false
	}
	close(t.quit)
	return t.timer.Stop()
}
<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. All Rights Reserved.
// Author: jacobsa@google.com (Aaron Jacobs)

package timeutil

import (
	"sync"
	"time"
)

type Clock interface {
	Now() time.Time
}

////////////////////////////////////////////////////////////////////////
// Real clock
////////////////////////////////////////////////////////////////////////

type realClock struct{}

func (c realClock) Now() time.Time {
	return time.Now()
}

// Return a clock that follows the real time, according to the system.
func RealClock() Clock {
	return realClock{}
}

////////////////////////////////////////////////////////////////////////
// Simulated clock
////////////////////////////////////////////////////////////////////////

// A clock that allows for manipulation of the time, which does not change
// unless AdvanceTime is called. The zero value is a clock initialized to the
// zero time.
type SimulatedClock struct {
	Clock

	mu sync.RWMutex
	t  time.Time // GUARDED_BY(mu)
}

func (sc *SimulatedClock) Now() time.Time {
	sc.mu.RLock()
	defer sc.mu.RUnlock()

	return sc.t
}

// Advance the current time according to the clock by the supplied duration.
func (sc *SimulatedClock) AdvanceTime(d time.Duration) {
	sc.mu.Lock()
	defer sc.mu.Unlock()

	sc.t = sc.t.Add(d)
}
<commit_msg>Added a SetTime method.<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
// Author: jacobsa@google.com (Aaron Jacobs)

package timeutil

import (
	"sync"
	"time"
)

type Clock interface {
	Now() time.Time
}

////////////////////////////////////////////////////////////////////////
// Real clock
////////////////////////////////////////////////////////////////////////

type realClock struct{}

func (c realClock) Now() time.Time {
	return time.Now()
}

// Return a clock that follows the real time, according to the system.
func RealClock() Clock {
	return realClock{}
}

////////////////////////////////////////////////////////////////////////
// Simulated clock
////////////////////////////////////////////////////////////////////////

// A clock that allows for manipulation of the time, which does not change
// unless AdvanceTime is called. The zero value is a clock initialized to the
// zero time.
type SimulatedClock struct {
	Clock

	mu sync.RWMutex
	t  time.Time // GUARDED_BY(mu)
}

func (sc *SimulatedClock) Now() time.Time {
	sc.mu.RLock()
	defer sc.mu.RUnlock()

	return sc.t
}

// Set the current time according to the clock.
func (sc *SimulatedClock) SetTime(t time.Time) {
	sc.mu.Lock()
	defer sc.mu.Unlock()

	sc.t = t
}

// Advance the current time according to the clock by the supplied duration.
func (sc *SimulatedClock) AdvanceTime(d time.Duration) {
	sc.mu.Lock()
	defer sc.mu.Unlock()

	sc.t = sc.t.Add(d)
}
<|endoftext|>


<commit_before>// Copyright 2009 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 tls

import "strconv"

type alert uint8

const (
	// alert level
	alertLevelWarning = 1
	alertLevelError   = 2
)

const (
	alertCloseNotify            alert = 0
	alertUnexpectedMessage      alert = 10
	alertBadRecordMAC           alert = 20
	alertDecryptionFailed       alert = 21
	alertRecordOverflow         alert = 22
	alertDecompressionFailure   alert = 30
	alertHandshakeFailure       alert = 40
	alertBadCertificate         alert = 42
	alertUnsupportedCertificate alert = 43
	alertCertificateRevoked     alert = 44
	alertCertificateExpired     alert = 45
	alertCertificateUnknown     alert = 46
	alertIllegalParameter       alert = 47
	alertUnknownCA              alert = 48
	alertAccessDenied           alert = 49
	alertDecodeError            alert = 50
	alertDecryptError           alert = 51
	alertProtocolVersion        alert = 70
	alertInsufficientSecurity   alert = 71
	alertInternalError          alert = 80
	alertUserCanceled           alert = 90
	alertNoRenegotiation        alert = 100
)

var alertText = map[alert]string{
	alertCloseNotify:            "close notify",
	alertUnexpectedMessage:      "unexpected message",
	alertBadRecordMAC:           "bad record MAC",
	alertDecryptionFailed:       "decryption failed",
	alertRecordOverflow:         "record overflow",
	alertDecompressionFailure:   "decompression failure",
	alertHandshakeFailure:       "handshake failure",
	alertBadCertificate:         "bad certificate",
	alertUnsupportedCertificate: "unsupported certificate",
	alertCertificateRevoked:     "revoked certificate",
	alertCertificateExpired:     "expired certificate",
	alertCertificateUnknown:     "unknown certificate",
	alertIllegalParameter:       "illegal parameter",
	alertUnknownCA:              "unknown certificate authority",
	alertAccessDenied:           "access denied",
	alertDecodeError:            "error decoding message",
	alertDecryptError:           "error decrypting message",
	alertProtocolVersion:        "protocol version not supported",
	alertInsufficientSecurity:   "insufficient security level",
	alertInternalError:          "internal error",
	alertUserCanceled:           "user canceled",
	alertNoRenegotiation:        "no renegotiation",
}

func (e alert) String() string {
	s, ok := alertText[e]
	if ok {
		return s
	}
	return "alert(" + strconv.Itoa(int(e)) + ")"
}
<commit_msg>crypto/tls: add Error method to alert<commit_after>// Copyright 2009 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 tls

import "strconv"

type alert uint8

const (
	// alert level
	alertLevelWarning = 1
	alertLevelError   = 2
)

const (
	alertCloseNotify            alert = 0
	alertUnexpectedMessage      alert = 10
	alertBadRecordMAC           alert = 20
	alertDecryptionFailed       alert = 21
	alertRecordOverflow         alert = 22
	alertDecompressionFailure   alert = 30
	alertHandshakeFailure       alert = 40
	alertBadCertificate         alert = 42
	alertUnsupportedCertificate alert = 43
	alertCertificateRevoked     alert = 44
	alertCertificateExpired     alert = 45
	alertCertificateUnknown     alert = 46
	alertIllegalParameter       alert = 47
	alertUnknownCA              alert = 48
	alertAccessDenied           alert = 49
	alertDecodeError            alert = 50
	alertDecryptError           alert = 51
	alertProtocolVersion        alert = 70
	alertInsufficientSecurity   alert = 71
	alertInternalError          alert = 80
	alertUserCanceled           alert = 90
	alertNoRenegotiation        alert = 100
)

var alertText = map[alert]string{
	alertCloseNotify:            "close notify",
	alertUnexpectedMessage:      "unexpected message",
	alertBadRecordMAC:           "bad record MAC",
	alertDecryptionFailed:       "decryption failed",
	alertRecordOverflow:         "record overflow",
	alertDecompressionFailure:   "decompression failure",
	alertHandshakeFailure:       "handshake failure",
	alertBadCertificate:         "bad certificate",
	alertUnsupportedCertificate: "unsupported certificate",
	alertCertificateRevoked:     "revoked certificate",
	alertCertificateExpired:     "expired certificate",
	alertCertificateUnknown:     "unknown certificate",
	alertIllegalParameter:       "illegal parameter",
	alertUnknownCA:              "unknown certificate authority",
	alertAccessDenied:           "access denied",
	alertDecodeError:            "error decoding message",
	alertDecryptError:           "error decrypting message",
	alertProtocolVersion:        "protocol version not supported",
	alertInsufficientSecurity:   "insufficient security level",
	alertInternalError:          "internal error",
	alertUserCanceled:           "user canceled",
	alertNoRenegotiation:        "no renegotiation",
}

func (e alert) String() string {
	s, ok := alertText[e]
	if ok {
		return s
	}
	return "alert(" + strconv.Itoa(int(e)) + ")"
}

func (e alert) Error() string {
	return e.String()
}
<|endoftext|>


<commit_before>package todo

import "testing"

func newTaskOrFatal(t *testing.T, title string) *Task {
	task, err := NewTask("learn Go")
	if err != nil {
		t.Fatalf("new task: %v", err)
	}
	return task
}

func TestNewTask(t *testing.T) {
	title := "learn Go"
	task := newTaskOrFatal(t, title)
	if task.Title != title {
		t.Errorf("expected title %q, got %q", title, task.Title)
	}
	if task.Done {
		t.Errorf("new task is done")
	}
}

func TestNewTaskEmptyTitle(t *testing.T) {
	_, err := NewTask("")
	if err == nil {
		t.Errorf("task with empty title created")
	}
}

func TestSaveTaskAndRetrieve(t *testing.T) {
	task := newTaskOrFatal(t, "learn Go")

	m := NewTaskManager()
	m.Save(task)

	all := m.All()
	if len(all) != 1 {
		t.Errorf("expected 1 task, got %v", len(all))
	}
	if *all[0] != *task {
		t.Errorf("expected %v, got %v", task, all)
	}
}

func TestSaveAndRetrieveTwoTasks(t *testing.T) {
	learnGo := newTaskOrFatal(t, "learn Go")
	learnTDD := newTaskOrFatal(t, "learn TDD")

	m := NewTaskManager()
	m.Save(learnGo)
	m.Save(learnTDD)

	all := m.All()
	if len(all) != 2 {
		t.Errorf("expected 2 tasks, got %v", len(all))
	}
	if *all[0] != *learnGo && *all[1] != *learnGo {
		t.Errorf("missing task: %v", learnGo)
	}
	if *all[0] != *learnTDD && *all[2] != *learnTDD {
		t.Errorf("missing task: %v", learnTDD)
	}
}

func TestSaveModifyAndRetrieve(t *testing.T) {
	task := newTaskOrFatal(t, "learn Go")
	m := NewTaskManager()
	m.Save(task)

	task.Done = true

	all := m.All()
	if all[0].Done {
		t.Errorf("saved task wasn't done")
	}
}
<commit_msg>modifying after saving doesn't change saved copy<commit_after>package todo

import "testing"

func newTaskOrFatal(t *testing.T, title string) *Task {
	task, err := NewTask("learn Go")
	if err != nil {
		t.Fatalf("new task: %v", err)
	}
	return task
}

func TestNewTask(t *testing.T) {
	title := "learn Go"
	task := newTaskOrFatal(t, title)
	if task.Title != title {
		t.Errorf("expected title %q, got %q", title, task.Title)
	}
	if task.Done {
		t.Errorf("new task is done")
	}
}

func TestNewTaskEmptyTitle(t *testing.T) {
	_, err := NewTask("")
	if err == nil {
		t.Errorf("task with empty title created")
	}
}

func TestSaveTaskAndRetrieve(t *testing.T) {
	task := newTaskOrFatal(t, "learn Go")

	m := NewTaskManager()
	m.Save(task)

	all := m.All()
	if len(all) != 1 {
		t.Errorf("expected 1 task, got %v", len(all))
	}
	if *all[0] != *task {
		t.Errorf("expected %v, got %v", task, all)
	}
}

func TestSaveAndRetrieveTwoTasks(t *testing.T) {
	learnGo := newTaskOrFatal(t, "learn Go")
	learnTDD := newTaskOrFatal(t, "learn TDD")

	m := NewTaskManager()
	m.Save(learnGo)
	m.Save(learnTDD)

	all := m.All()
	if len(all) != 2 {
		t.Errorf("expected 2 tasks, got %v", len(all))
	}
	if *all[0] != *learnGo && *all[1] != *learnGo {
		t.Errorf("missing task: %v", learnGo)
	}
	if *all[0] != *learnTDD && *all[2] != *learnTDD {
		t.Errorf("missing task: %v", learnTDD)
	}
}

func TestSaveModifyAndRetrieve(t *testing.T) {
	task := newTaskOrFatal(t, "learn Go")
	m := NewTaskManager()
	m.Save(task)

	task.Done = true
	if m.All()[0].Done {
		t.Errorf("saved task wasn't done")
	}
}

func TestSaveTwiceAndRetrieve(t *testing.T) {
	task := newTaskOrFatal(t, "learn Go")
	m := NewTaskManager()
	m.Save(task)
	m.Save(task)

	all := m.All()
	if len(all) != 1 {
		t.Errorf("expected 1 task, got %v", len(all))
	}
	if *all[0] != *task {
		t.Errorf("expected task %v, got %v", task, all[0])
	}

}
<|endoftext|>


<commit_before>package mario

import (
	"fmt"
	neural "github.com/poseidon4o/go-neural/src/neural"
	util "github.com/poseidon4o/go-neural/src/util"
	"math"
	"sort"
)

type NeuronName int

const (
	posX      NeuronName = iota
	H1        NeuronName = iota
	H2        NeuronName = iota
	H3        NeuronName = iota
	H4        NeuronName = iota
	H5        NeuronName = iota
	H6        NeuronName = iota
	H7        NeuronName = iota
	H8        NeuronName = iota
	jump      NeuronName = iota
	xMove     NeuronName = iota
	NRN_COUNT int        = iota
)

func nrn(name NeuronName) int {
	return int(name)
}

type MarioNode struct {
	fig   *Figure
	brain *neural.Net
	bestX float64
	dead  bool
}

type MarioCol []MarioNode

func (figs MarioCol) Len() int {
	return len(figs)
}

func (figs MarioCol) Less(c, r int) bool {
	return figs[c].bestX > figs[r].bestX
}

func (figs MarioCol) Swap(c, r int) {
	figs[c], figs[r] = figs[r], figs[c]
}

type Mario struct {
	figures  MarioCol
	lvl      Level
	drawCb   func(pos, size *util.Vector, color uint32)
	drawSize int
}

func (m *Mario) Completed() float64 {
	return m.figures[0].fig.pos.X / m.lvl.size.X
}

func (m *Mario) Done() bool {
	return false
}

func (m *Mario) SetDrawRectCb(cb func(pos, size *util.Vector, color uint32)) {
	m.drawCb = cb
}

func (m *Mario) LogicTick(dt float64) {
	m.lvl.Step(dt)
	m.checkStep()
	m.mutateStep()
	m.thnikStep()
}

func (m *MarioNode) Jump() {
	m.fig.Jump()
}

func (m *MarioNode) Move(dir int) {
	m.fig.Move(dir)
}

func (m *Mario) Figs() MarioCol {
	return m.figures
}

func NewMario(figCount int, size *util.Vector) *Mario {
	fmt.Println("")
	level := NewLevel(int(size.X), int(size.Y))
	level.AddFigures(figCount)

	nets := make([]*neural.Net, figCount, figCount)
	for c := range nets {
		nets[c] = neural.NewNet(NRN_COUNT)

		for r := 0; r < (nrn(H8) - nrn(H1)); r++ {
			// input to hidden
			*nets[c].Synapse(nrn(posX), r+nrn(H1)) = 0.0

			// hiden to output
			*nets[c].Synapse(r+nrn(H1), nrn(jump)) = 0.0
			*nets[c].Synapse(r+nrn(H1), nrn(xMove)) = 0.0
		}

		nets[c].Randomize()
	}

	figs := make(MarioCol, figCount, figCount)
	for c := range figs {
		figs[c].brain = nets[c]
		figs[c].dead = false
		figs[c].bestX = 0
		figs[c].fig = level.figures[c]
	}

	return &Mario{
		figures:  figs,
		lvl:      *level,
		drawCb:   func(pos, size *util.Vector, color uint32) {},
		drawSize: 5,
	}
}

func (m *Mario) DrawTick() {
	var (
		red   = uint32(0xffff0000)
		green = uint32(0xff00ff00)
		blue  = uint32(0xff0000ff)
	)

	blSize := util.NewVector(float64(BLOCK_SIZE), float64(BLOCK_SIZE))
	blSizeSmall := blSize.Scale(0.5)

	translate := util.NewVector(6, 6)

	size := util.NewVector(float64(m.drawSize), float64(m.drawSize))

	for c := range m.lvl.blocks {
		for r := range m.lvl.blocks[c] {
			m.drawCb(&m.lvl.blocks[c][r], blSize, red)
			m.drawCb(m.lvl.blocks[c][r].Add(translate), blSizeSmall, green)
		}
	}

	for c := range m.figures {
		m.drawCb(m.figures[c].fig.pos.Add(size.Scale(0.5).Neg()), size, blue)
	}
}

func (m *Mario) checkStep() {
	// fmt.Println(fig.pos)
	for c := range m.figures {
		fig := m.figures[c].fig

		if fig.nextPos.Y > m.lvl.size.Y || fig.nextPos.Y < 0 {
			m.figures[c].dead = true
			continue
		}

		if fig.nextPos.X < 0 {
			fig.nextPos.X = 0
		} else if fig.nextPos.X > m.lvl.size.X {
			fig.nextPos.X = m.lvl.size.X
		}

		block := m.lvl.FloorAt(&fig.pos)

		if fig.nextPos.Y < block.Y {
			fig.pos = fig.nextPos
		} else {
			// land on block
			fig.vel.Y = 0
			fig.pos.Y = block.Y - 1
			fig.pos.X = fig.nextPos.X
			fig.Land()
		}
	}
}

func (m *Mario) thnikStep() {
	wg := make(chan struct{}, len(m.figures))

	thinkBird := func(c int) {
		m.figures[c].brain.Stimulate(nrn(posX), m.figures[c].fig.pos.X)

		m.figures[c].brain.Step()

		if m.figures[c].brain.ValueOf(nrn(jump)) > 0.75 {
			m.figures[c].fig.Jump()
		}

		xMoveValue := m.figures[c].brain.ValueOf(nrn(xMove))
		if math.Abs(xMoveValue) > 0.75 {
			m.figures[c].fig.Move(int(xMoveValue * 10))
		}

		m.figures[c].brain.Clear()
		wg <- struct{}{}
	}

	for c := 0; c < len(m.figures); c++ {
		go thinkBird(c)
	}

	for c := 0; c < len(m.figures); c++ {
		<-wg
	}
}

func (m *Mario) mutateStep() {
	sort.Sort(m.figures)

	randNet := func() *neural.Net {
		return m.figures[int(neural.RandMax(float64(len(m.figures))))].brain
	}

	best := m.figures[0].brain

	for c := range m.figures {
		if m.figures[c].dead {
			m.figures[c].dead = false
			m.figures[c].fig.pos = *m.lvl.NewFigurePos()
			m.figures[c].fig.vel = *util.NewVector(0, 0)

			m.figures[c].brain = neural.Cross(best, randNet())

			if neural.Chance(0.1) {
				// penalize best achievement due to mutation
				m.figures[c].bestX *= 0.99
				m.figures[c].brain.Mutate(0.33)
			}
		} else {
			m.figures[c].bestX = math.Max(m.figures[c].fig.pos.X, m.figures[c].bestX)
		}
	}

}
<commit_msg>Make marios brain bigger and penalize idle figs<commit_after>package mario

import (
	"fmt"
	neural "github.com/poseidon4o/go-neural/src/neural"
	util "github.com/poseidon4o/go-neural/src/util"
	"math"
	"sort"
)

type NeuronName int

const (
	posX      NeuronName = iota
	posY      NeuronName = iota
	velY      NeuronName = iota
	velX      NeuronName = iota
	H1        NeuronName = iota
	H2        NeuronName = iota
	H3        NeuronName = iota
	H4        NeuronName = iota
	H5        NeuronName = iota
	H6        NeuronName = iota
	H7        NeuronName = iota
	H8        NeuronName = iota
	R1        NeuronName = iota
	R2        NeuronName = iota
	R3        NeuronName = iota
	R4        NeuronName = iota
	R5        NeuronName = iota
	R6        NeuronName = iota
	R7        NeuronName = iota
	R8        NeuronName = iota
	jump      NeuronName = iota
	xMove     NeuronName = iota
	NRN_COUNT int        = iota
)

func nrn(name NeuronName) int {
	return int(name)
}

type MarioNode struct {
	fig        *Figure
	brain      *neural.Net
	bestX      float64
	dead       bool
	idleFrames uint32
}

type MarioCol []MarioNode

func (figs MarioCol) Len() int {
	return len(figs)
}

func (figs MarioCol) Less(c, r int) bool {
	return figs[c].bestX > figs[r].bestX
}

func (figs MarioCol) Swap(c, r int) {
	figs[c], figs[r] = figs[r], figs[c]
}

type Mario struct {
	figures  MarioCol
	lvl      Level
	drawCb   func(pos, size *util.Vector, color uint32)
	drawSize int
}

func (m *Mario) Completed() float64 {
	return m.figures[0].bestX / m.lvl.size.X
}

func (m *Mario) Done() bool {
	return false
}

func (m *Mario) SetDrawRectCb(cb func(pos, size *util.Vector, color uint32)) {
	m.drawCb = cb
}

func (m *Mario) LogicTick(dt float64) {
	m.lvl.Step(dt)
	m.checkStep()
	m.mutateStep()
	m.thnikStep()
}

func (m *MarioNode) Jump() {
	m.fig.Jump()
}

func (m *MarioNode) Move(dir int) {
	m.fig.Move(dir)
}

func (m *Mario) Figs() MarioCol {
	return m.figures
}

func NewMario(figCount int, size *util.Vector) *Mario {
	fmt.Println("")
	level := NewLevel(int(size.X), int(size.Y))
	level.AddFigures(figCount)

	nets := make([]*neural.Net, figCount, figCount)
	for c := range nets {
		nets[c] = neural.NewNet(NRN_COUNT)

		for r := 0; r < (nrn(H8) - nrn(H1)); r++ {
			// input to H
			*nets[c].Synapse(nrn(posX), r+nrn(H1)) = 0.0
			*nets[c].Synapse(nrn(posY), r+nrn(H1)) = 0.0
			*nets[c].Synapse(nrn(velX), r+nrn(H1)) = 0.0
			*nets[c].Synapse(nrn(velY), r+nrn(H1)) = 0.0

			// R to output
			*nets[c].Synapse(r+nrn(R1), nrn(jump)) = 0.0
			*nets[c].Synapse(r+nrn(R1), nrn(xMove)) = 0.0
		}

		for r := 0; r < (nrn(H8) - nrn(H1)); r++ {
			for q := 0; q < (nrn(H8) - nrn(H1)); q++ {
				*nets[c].Synapse(r+nrn(H1), q+nrn(R1)) = 0.0
			}
		}

		nets[c].Randomize()
	}

	figs := make(MarioCol, figCount, figCount)
	for c := range figs {
		figs[c].brain = nets[c]
		figs[c].dead = false
		figs[c].bestX = 0
		figs[c].fig = level.figures[c]
	}

	return &Mario{
		figures:  figs,
		lvl:      *level,
		drawCb:   func(pos, size *util.Vector, color uint32) {},
		drawSize: 5,
	}
}

func (m *Mario) DrawTick() {
	var (
		red   = uint32(0xffff0000)
		green = uint32(0xff00ff00)
		blue  = uint32(0xff0000ff)
	)

	blSize := util.NewVector(float64(BLOCK_SIZE), float64(BLOCK_SIZE))
	blSizeSmall := blSize.Scale(0.5)

	translate := util.NewVector(6, 6)

	size := util.NewVector(float64(m.drawSize), float64(m.drawSize))

	for c := range m.lvl.blocks {
		for r := range m.lvl.blocks[c] {
			if m.lvl.blocks[c][r] != nil {
				m.drawCb(m.lvl.blocks[c][r], blSize, red)
				m.drawCb(m.lvl.blocks[c][r].Add(translate), blSizeSmall, green)
			}
		}
	}

	for c := range m.figures {
		m.drawCb(m.figures[c].fig.pos.Add(size.Scale(0.5).Neg()), size, blue)
	}
}

func (m *Mario) checkStep() {
	for c := range m.figures {
		fig := m.figures[c].fig

		if fig.nextPos.Y > m.lvl.size.Y || fig.nextPos.Y < 0 {
			m.figures[c].dead = true
			continue
		}

		if fig.nextPos.X < 0 {
			fig.nextPos.X = 0
		} else if fig.nextPos.X > m.lvl.size.X {
			fig.nextPos.X = m.lvl.size.X
		}

		block := m.lvl.FloorAt(&fig.pos)

		if block == nil || fig.nextPos.Y < block.Y {
			fig.pos = fig.nextPos
		} else {
			// land on block
			fig.vel.Y = 0
			fig.pos.Y = block.Y - 1
			fig.pos.X = fig.nextPos.X
			fig.Land()
		}
	}
}

func (m *Mario) thnikStep() {
	wg := make(chan struct{}, len(m.figures))

	thinkBird := func(c int) {
		m.figures[c].brain.Stimulate(nrn(posX), m.figures[c].fig.pos.X)
		m.figures[c].brain.Stimulate(nrn(posY), m.figures[c].fig.pos.Y)
		m.figures[c].brain.Stimulate(nrn(velX), m.figures[c].fig.vel.X)
		m.figures[c].brain.Stimulate(nrn(velY), m.figures[c].fig.vel.Y)

		m.figures[c].brain.Step()

		if m.figures[c].brain.ValueOf(nrn(jump)) > 0.75 {
			m.figures[c].fig.Jump()
		}

		xMoveValue := m.figures[c].brain.ValueOf(nrn(xMove))
		if math.Abs(xMoveValue) > 0.75 {
			m.figures[c].fig.Move(int(xMoveValue * 10))
		}

		m.figures[c].brain.Clear()
		wg <- struct{}{}
	}

	for c := 0; c < len(m.figures); c++ {
		go thinkBird(c)
	}

	for c := 0; c < len(m.figures); c++ {
		<-wg
	}
}

func (m *Mario) mutateStep() {
	sort.Sort(m.figures)

	randNet := func() *neural.Net {
		return m.figures[int(neural.RandMax(float64(len(m.figures))))].brain
	}

	best := m.figures[0].brain

	var idleThreshold uint32 = 600

	for c := range m.figures {
		if m.figures[c].dead {
			m.figures[c].dead = false
			m.figures[c].fig.pos = *m.lvl.NewFigurePos()
			m.figures[c].fig.vel = *util.NewVector(0, 0)

			if m.figures[c].idleFrames >= idleThreshold {
				m.figures[c].brain.Mutate(0.75)
				m.figures[c].bestX *= 0.25
			} else {
				m.figures[c].brain = neural.Cross(best, randNet())
				if neural.Chance(0.01) {
					// penalize best achievement due to mutation
					m.figures[c].bestX *= 0.8
					m.figures[c].brain.Mutate(0.25)
				}
			}

			m.figures[c].idleFrames = 0

		} else {
			if m.figures[c].fig.pos.X > m.figures[c].bestX {
				m.figures[c].bestX = m.figures[c].fig.pos.X
			} else {
				m.figures[c].idleFrames++
				if m.figures[c].idleFrames >= 600 {
					m.figures[c].dead = true
					c--
				}
			}

		}
	}

}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/iot"
	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)

func resourceAwsIotCertificate() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsIotCertificateCreate,
		Read:   resourceAwsIotCertificateRead,
		Update: resourceAwsIotCertificateUpdate,
		Delete: resourceAwsIotCertificateDelete,
		Schema: map[string]*schema.Schema{
			"csr": {
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
			},
			"active": {
				Type:     schema.TypeBool,
				Required: true,
			},
			"arn": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"certificate_pem": {
				Type:      schema.TypeString,
				Computed:  true,
				Sensitive: true,
			},
			"public_key": {
				Type:      schema.TypeString,
				Computed:  true,
				Sensitive: true,
			},
			"private_key": {
				Type:      schema.TypeString,
				Computed:  true,
				Sensitive: true,
			},
		},
	}
}

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

	if _, ok := d.GetOk("csr"); ok {
		log.Printf("[DEBUG] Creating certificate from CSR")
		out, err := conn.CreateCertificateFromCsr(&iot.CreateCertificateFromCsrInput{
			CertificateSigningRequest: aws.String(d.Get("csr").(string)),
			SetAsActive:               aws.Bool(d.Get("active").(bool)),
		})
		if err != nil {
			return fmt.Errorf("error creating certificate from CSR: %v", err)
		}
		log.Printf("[DEBUG] Created certificate from CSR")

		d.SetId(*out.CertificateId)
	} else {
		log.Printf("[DEBUG] Creating keys and certificate")
		out, err := conn.CreateKeysAndCertificate(&iot.CreateKeysAndCertificateInput{
			SetAsActive: aws.Bool(d.Get("active").(bool)),
		})
		if err != nil {
			return fmt.Errorf("error creating keys and certificate: %v", err)
		}
		log.Printf("[DEBUG] Created keys and certificate")

		d.SetId(*out.CertificateId)
		d.Set("public_key", *out.KeyPair.PublicKey)
		d.Set("private_key", *out.KeyPair.PrivateKey)
	}

	return resourceAwsIotCertificateRead(d, meta)
}

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

	out, err := conn.DescribeCertificate(&iot.DescribeCertificateInput{
		CertificateId: aws.String(d.Id()),
	})
	if err != nil {
		return fmt.Errorf("error reading certificate details: %v", err)
	}

	d.Set("active", aws.Bool(*out.CertificateDescription.Status == iot.CertificateStatusActive))
	d.Set("arn", out.CertificateDescription.CertificateArn)
	d.Set("certificate_pem", out.CertificateDescription.CertificatePem)

	return nil
}

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

	if d.HasChange("active") {
		status := iot.CertificateStatusInactive
		if d.Get("active").(bool) {
			status = iot.CertificateStatusActive
		}

		_, err := conn.UpdateCertificate(&iot.UpdateCertificateInput{
			CertificateId: aws.String(d.Id()),
			NewStatus:     aws.String(status),
		})
		if err != nil {
			return fmt.Errorf("error updating certificate: %v", err)
		}
	}

	return resourceAwsIotCertificateRead(d, meta)
}

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

	_, err := conn.UpdateCertificate(&iot.UpdateCertificateInput{
		CertificateId: aws.String(d.Id()),
		NewStatus:     aws.String("INACTIVE"),
	})
	if err != nil {
		return fmt.Errorf("error inactivating certificate: %v", err)
	}

	_, err = conn.DeleteCertificate(&iot.DeleteCertificateInput{
		CertificateId: aws.String(d.Id()),
	})
	if err != nil {
		return fmt.Errorf("error deleting certificate: %v", err)
	}

	return nil
}
<commit_msg>resource/aws_iot_certificate: Fixes for tfproviderlint R002 (#12026)<commit_after>package aws

import (
	"fmt"
	"log"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/iot"
	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)

func resourceAwsIotCertificate() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsIotCertificateCreate,
		Read:   resourceAwsIotCertificateRead,
		Update: resourceAwsIotCertificateUpdate,
		Delete: resourceAwsIotCertificateDelete,
		Schema: map[string]*schema.Schema{
			"csr": {
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
			},
			"active": {
				Type:     schema.TypeBool,
				Required: true,
			},
			"arn": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"certificate_pem": {
				Type:      schema.TypeString,
				Computed:  true,
				Sensitive: true,
			},
			"public_key": {
				Type:      schema.TypeString,
				Computed:  true,
				Sensitive: true,
			},
			"private_key": {
				Type:      schema.TypeString,
				Computed:  true,
				Sensitive: true,
			},
		},
	}
}

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

	if _, ok := d.GetOk("csr"); ok {
		log.Printf("[DEBUG] Creating certificate from CSR")
		out, err := conn.CreateCertificateFromCsr(&iot.CreateCertificateFromCsrInput{
			CertificateSigningRequest: aws.String(d.Get("csr").(string)),
			SetAsActive:               aws.Bool(d.Get("active").(bool)),
		})
		if err != nil {
			return fmt.Errorf("error creating certificate from CSR: %v", err)
		}
		log.Printf("[DEBUG] Created certificate from CSR")

		d.SetId(aws.StringValue(out.CertificateId))
	} else {
		log.Printf("[DEBUG] Creating keys and certificate")
		out, err := conn.CreateKeysAndCertificate(&iot.CreateKeysAndCertificateInput{
			SetAsActive: aws.Bool(d.Get("active").(bool)),
		})
		if err != nil {
			return fmt.Errorf("error creating keys and certificate: %v", err)
		}
		log.Printf("[DEBUG] Created keys and certificate")

		d.SetId(aws.StringValue(out.CertificateId))
		d.Set("public_key", out.KeyPair.PublicKey)
		d.Set("private_key", out.KeyPair.PrivateKey)
	}

	return resourceAwsIotCertificateRead(d, meta)
}

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

	out, err := conn.DescribeCertificate(&iot.DescribeCertificateInput{
		CertificateId: aws.String(d.Id()),
	})
	if err != nil {
		return fmt.Errorf("error reading certificate details: %v", err)
	}

	d.Set("active", aws.Bool(*out.CertificateDescription.Status == iot.CertificateStatusActive))
	d.Set("arn", out.CertificateDescription.CertificateArn)
	d.Set("certificate_pem", out.CertificateDescription.CertificatePem)

	return nil
}

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

	if d.HasChange("active") {
		status := iot.CertificateStatusInactive
		if d.Get("active").(bool) {
			status = iot.CertificateStatusActive
		}

		_, err := conn.UpdateCertificate(&iot.UpdateCertificateInput{
			CertificateId: aws.String(d.Id()),
			NewStatus:     aws.String(status),
		})
		if err != nil {
			return fmt.Errorf("error updating certificate: %v", err)
		}
	}

	return resourceAwsIotCertificateRead(d, meta)
}

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

	_, err := conn.UpdateCertificate(&iot.UpdateCertificateInput{
		CertificateId: aws.String(d.Id()),
		NewStatus:     aws.String("INACTIVE"),
	})
	if err != nil {
		return fmt.Errorf("error inactivating certificate: %v", err)
	}

	_, err = conn.DeleteCertificate(&iot.DeleteCertificateInput{
		CertificateId: aws.String(d.Id()),
	})
	if err != nil {
		return fmt.Errorf("error deleting certificate: %v", err)
	}

	return nil
}
<|endoftext|>


<commit_before>package datadog

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"strings"
	"time"

	backendTypes "github.com/atlassian/gostatsd/backend/types"
	"github.com/atlassian/gostatsd/types"

	log "github.com/Sirupsen/logrus"
	"github.com/cenkalti/backoff"
	"github.com/spf13/viper"
	"golang.org/x/net/context"
)

const (
	apiURL = "https://app.datadoghq.com"
	// BackendName is the name of this backend.
	BackendName                  = "datadog"
	dogstatsdVersion             = "5.6.3"
	dogstatsdUserAgent           = "python-requests/2.6.0 CPython/2.7.10"
	defaultMaxRequestElapsedTime = 15 * time.Second
	defaultClientTimeout         = 9 * time.Second
	// defaultMetricsPerBatch is the default number of metrics to send in a single batch.
	defaultMetricsPerBatch uint16 = 1000
	// maxResponseSize is the maximum response size we are willing to read.
	maxResponseSize = 10 * 1024
	// gauge is datadog gauge type.
	gauge = "gauge"
	// rate is datadog rate type.
	rate = "rate"
)

// client represents a Datadog client.
type client struct {
	apiKey                string
	apiEndpoint           string
	hostname              string
	maxRequestElapsedTime time.Duration
	client                *http.Client
	metricsPerBatch       uint16
}

const sampleConfig = `
[datadog]
	## Datadog API key
	api_key = "my-secret-key" # required.

	## Connection timeout.
	# timeout = "5s"
`

// timeSeries represents a time series data structure.
type timeSeries struct {
	Series    []metric `json:"series"`
	Timestamp int64    `json:"-"`
	Hostname  string   `json:"-"`
}

// metric represents a metric data structure for Datadog.
type metric struct {
	Host     string   `json:"host,omitempty"`
	Interval float64  `json:"interval,omitempty"`
	Metric   string   `json:"metric"`
	Points   [1]point `json:"points"`
	Tags     []string `json:"tags,omitempty"`
	Type     string   `json:"type,omitempty"`
}

// point is a Datadog data point.
type point [2]float64

// AddMetric adds a metric to the series.
func (ts *timeSeries) addMetric(name, stags, metricType string, value float64, interval time.Duration) {
	hostname, tags := types.ExtractSourceFromTags(stags)
	if hostname == "" {
		hostname = ts.Hostname
	}
	ts.Series = append(ts.Series, metric{
		Host:     hostname,
		Interval: interval.Seconds(),
		Metric:   name,
		Points:   [1]point{{float64(ts.Timestamp), value}},
		Tags:     tags.Normalise(),
		Type:     metricType,
	})
}

// event represents an event data structure for Datadog.
type event struct {
	Title          string   `json:"title"`
	Text           string   `json:"text"`
	DateHappened   int64    `json:"date_happened,omitempty"`
	Hostname       string   `json:"host,omitempty"`
	AggregationKey string   `json:"aggregation_key,omitempty"`
	SourceTypeName string   `json:"source_type_name,omitempty"`
	Tags           []string `json:"tags,omitempty"`
	Priority       string   `json:"priority,omitempty"`
	AlertType      string   `json:"alert_type,omitempty"`
}

// SendMetricsAsync flushes the metrics to Datadog, preparing payload synchronously but doing the send asynchronously.
func (d *client) SendMetricsAsync(ctx context.Context, metrics *types.MetricMap, cb backendTypes.SendCallback) {
	if metrics.NumStats == 0 {
		cb(nil)
		return
	}
	var counter uint16
	results := make(chan error)
	d.processMetrics(metrics, func(ts *timeSeries) {
		go func() {
			err := d.postMetrics(ts)
			select {
			case <-ctx.Done():
			case results <- err:
			}
		}()
		counter++
	})
	go func() {
		errs := make([]error, 0, counter)
	loop:
		for c := counter; c > 0; c-- {
			select {
			case <-ctx.Done():
				errs = append(errs, ctx.Err())
				break loop
			case err := <-results:
				errs = append(errs, err)
			}
		}
		cb(errs)
	}()
}

func (d *client) processMetrics(metrics *types.MetricMap, cb func(*timeSeries)) {
	ts := &timeSeries{
		Series:    make([]metric, 0, d.metricsPerBatch),
		Timestamp: time.Now().Unix(),
		Hostname:  d.hostname,
	}

	metrics.Counters.Each(func(key, tagsKey string, counter types.Counter) {
		ts.addMetric(key, tagsKey, rate, counter.PerSecond, counter.Flush)
		ts.addMetric(fmt.Sprintf("%s.count", key), tagsKey, gauge, float64(counter.Value), counter.Flush)
		d.maybeFlush(ts, cb)
	})

	metrics.Timers.Each(func(key, tagsKey string, timer types.Timer) {
		ts.addMetric(fmt.Sprintf("%s.lower", key), tagsKey, gauge, timer.Min, timer.Flush)
		ts.addMetric(fmt.Sprintf("%s.upper", key), tagsKey, gauge, timer.Max, timer.Flush)
		ts.addMetric(fmt.Sprintf("%s.count", key), tagsKey, gauge, float64(timer.Count), timer.Flush)
		ts.addMetric(fmt.Sprintf("%s.count_ps", key), tagsKey, rate, timer.PerSecond, timer.Flush)
		ts.addMetric(fmt.Sprintf("%s.mean", key), tagsKey, gauge, timer.Mean, timer.Flush)
		ts.addMetric(fmt.Sprintf("%s.median", key), tagsKey, gauge, timer.Median, timer.Flush)
		ts.addMetric(fmt.Sprintf("%s.std", key), tagsKey, gauge, timer.StdDev, timer.Flush)
		ts.addMetric(fmt.Sprintf("%s.sum", key), tagsKey, gauge, timer.Sum, timer.Flush)
		ts.addMetric(fmt.Sprintf("%s.sum_squares", key), tagsKey, gauge, timer.SumSquares, timer.Flush)
		for _, pct := range timer.Percentiles {
			ts.addMetric(fmt.Sprintf("%s.%s", key, pct.Str), tagsKey, gauge, pct.Float, timer.Flush)
		}
		d.maybeFlush(ts, cb)
	})

	metrics.Gauges.Each(func(key, tagsKey string, g types.Gauge) {
		ts.addMetric(key, tagsKey, gauge, g.Value, g.Flush)
		d.maybeFlush(ts, cb)
	})

	metrics.Sets.Each(func(key, tagsKey string, set types.Set) {
		ts.addMetric(key, tagsKey, gauge, float64(len(set.Values)), set.Flush)
		d.maybeFlush(ts, cb)
	})

	if len(ts.Series) > 0 {
		cb(ts)
	}
}

func (d *client) maybeFlush(ts *timeSeries, cb func(*timeSeries)) {
	if len(ts.Series) >= int(d.metricsPerBatch-20) { // flush before it reaches max size and grows the slice
		cb(ts)
		*ts = timeSeries{
			Series:    make([]metric, 0, d.metricsPerBatch),
			Timestamp: ts.Timestamp,
			Hostname:  ts.Hostname,
		}
	}
}

func (d *client) postMetrics(ts *timeSeries) error {
	return d.post("/api/v1/series", "metrics", ts)
}

// SendEvent sends an event to Datadog.
func (d *client) SendEvent(ctx context.Context, e *types.Event) error {
	return d.post("/api/v1/events", "events", event{
		Title:          e.Title,
		Text:           e.Text,
		DateHappened:   e.DateHappened,
		Hostname:       e.Hostname,
		AggregationKey: e.AggregationKey,
		SourceTypeName: e.SourceTypeName,
		Tags:           e.Tags,
		Priority:       e.Priority.StringWithEmptyDefault(),
		AlertType:      e.AlertType.StringWithEmptyDefault(),
	})
}

// SampleConfig returns the sample config for the datadog backend.
func (d *client) SampleConfig() string {
	return sampleConfig
}

// BackendName returns the name of the backend.
func (d *client) BackendName() string {
	return BackendName
}

func (d *client) post(path, typeOfPost string, data interface{}) error {
	tsBytes, err := json.Marshal(data)
	if err != nil {
		return fmt.Errorf("[%s] unable to marshal %s: %v", BackendName, typeOfPost, err)
	}
	log.Debugf("[%s] %s json: %s", BackendName, typeOfPost, tsBytes)

	b := backoff.NewExponentialBackOff()
	b.MaxElapsedTime = d.maxRequestElapsedTime
	err = backoff.RetryNotify(d.doPost(path, tsBytes), b, func(err error, d time.Duration) {
		log.Warnf("[%s] failed to send %s, sleeping for %s: %v", BackendName, typeOfPost, d, err)
	})
	if err != nil {
		return fmt.Errorf("[%s] %v", BackendName, err)
	}

	return nil
}

func (d *client) doPost(path string, body []byte) backoff.Operation {
	authenticatedURL := d.authenticatedURL(path)
	return func() error {
		req, err := http.NewRequest("POST", authenticatedURL, bytes.NewBuffer(body))
		if err != nil {
			return fmt.Errorf("unable to create http.Request: %v", err)
		}
		req.Header.Add("Content-Type", "application/json")
		// Mimic dogstatsd code
		req.Header.Add("DD-Dogstatsd-Version", dogstatsdVersion)
		req.Header.Add("User-Agent", dogstatsdUserAgent)
		resp, err := d.client.Do(req)
		if err != nil {
			return fmt.Errorf("error POSTing: %s", strings.Replace(err.Error(), d.apiKey, "*****", -1))
		}
		defer resp.Body.Close()
		body := io.LimitReader(resp.Body, maxResponseSize)
		if resp.StatusCode < 200 || resp.StatusCode >= 205 {
			b, _ := ioutil.ReadAll(body)
			log.Infof("[%s] failed request status: %d\n%s", BackendName, resp.StatusCode, b)
			return fmt.Errorf("received bad status code %d", resp.StatusCode)
		}
		_, _ = io.Copy(ioutil.Discard, body)
		return nil
	}
}

func (d *client) authenticatedURL(path string) string {
	q := url.Values{
		"api_key": []string{d.apiKey},
	}
	return fmt.Sprintf("%s%s?%s", d.apiEndpoint, path, q.Encode())
}

// NewClientFromViper returns a new Datadog API client.
func NewClientFromViper(v *viper.Viper) (backendTypes.Backend, error) {
	dd := getSubViper(v, "datadog")
	dd.SetDefault("api_endpoint", apiURL)
	dd.SetDefault("metrics_per_batch", defaultMetricsPerBatch)
	dd.SetDefault("timeout", defaultClientTimeout)
	dd.SetDefault("max_request_elapsed_time", defaultMaxRequestElapsedTime)
	return NewClient(
		dd.GetString("api_endpoint"),
		dd.GetString("api_key"),
		uint16(dd.GetInt("metrics_per_batch")),
		dd.GetDuration("timeout"),
		dd.GetDuration("max_request_elapsed_time"),
	)
}

// NewClient returns a new Datadog API client.
func NewClient(apiEndpoint, apiKey string, metricsPerBatch uint16, clientTimeout, maxRequestElapsedTime time.Duration) (backendTypes.Backend, error) {
	if apiEndpoint == "" {
		return nil, fmt.Errorf("[%s] apiEndpoint is required", BackendName)
	}
	if apiKey == "" {
		return nil, fmt.Errorf("[%s] apiKey is required", BackendName)
	}
	if clientTimeout <= 0 {
		return nil, fmt.Errorf("[%s] clientTimeout must be positive", BackendName)
	}
	if maxRequestElapsedTime <= 0 {
		return nil, fmt.Errorf("[%s] maxRequestElapsedTime must be positive", BackendName)
	}
	hostname, err := os.Hostname()
	if err != nil {
		return nil, fmt.Errorf("[%s] cannot get hostname: %v", BackendName, err)
	}
	log.Infof("[%s] maxRequestElapsedTime=%s clientTimeout=%s metricsPerBatch=%d", BackendName, maxRequestElapsedTime, clientTimeout, metricsPerBatch)
	return &client{
		apiKey:                apiKey,
		apiEndpoint:           apiEndpoint,
		hostname:              hostname,
		maxRequestElapsedTime: maxRequestElapsedTime,
		client: &http.Client{
			Timeout: clientTimeout,
		},
	}, nil
}

// Workaround https://github.com/spf13/viper/pull/165 and https://github.com/spf13/viper/issues/191
func getSubViper(v *viper.Viper, key string) *viper.Viper {
	var n *viper.Viper
	namespace := v.Get(key)
	if namespace != nil {
		n = v.Sub(key)
	}
	if n == nil {
		n = viper.New()
	}
	return n
}
<commit_msg>Fix missing metricsPerBatch assignment (#42)<commit_after>package datadog

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"strings"
	"time"

	backendTypes "github.com/atlassian/gostatsd/backend/types"
	"github.com/atlassian/gostatsd/types"

	log "github.com/Sirupsen/logrus"
	"github.com/cenkalti/backoff"
	"github.com/spf13/viper"
	"golang.org/x/net/context"
)

const (
	apiURL = "https://app.datadoghq.com"
	// BackendName is the name of this backend.
	BackendName                  = "datadog"
	dogstatsdVersion             = "5.6.3"
	dogstatsdUserAgent           = "python-requests/2.6.0 CPython/2.7.10"
	defaultMaxRequestElapsedTime = 15 * time.Second
	defaultClientTimeout         = 9 * time.Second
	// defaultMetricsPerBatch is the default number of metrics to send in a single batch.
	defaultMetricsPerBatch = 1000
	// maxResponseSize is the maximum response size we are willing to read.
	maxResponseSize = 10 * 1024
	// gauge is datadog gauge type.
	gauge = "gauge"
	// rate is datadog rate type.
	rate = "rate"
)

// client represents a Datadog client.
type client struct {
	apiKey                string
	apiEndpoint           string
	hostname              string
	maxRequestElapsedTime time.Duration
	client                *http.Client
	metricsPerBatch       uint
}

const sampleConfig = `
[datadog]
	## Datadog API key
	api_key = "my-secret-key" # required.

	## Connection timeout.
	# timeout = "5s"
`

// timeSeries represents a time series data structure.
type timeSeries struct {
	Series    []metric `json:"series"`
	Timestamp int64    `json:"-"`
	Hostname  string   `json:"-"`
}

// metric represents a metric data structure for Datadog.
type metric struct {
	Host     string   `json:"host,omitempty"`
	Interval float64  `json:"interval,omitempty"`
	Metric   string   `json:"metric"`
	Points   [1]point `json:"points"`
	Tags     []string `json:"tags,omitempty"`
	Type     string   `json:"type,omitempty"`
}

// point is a Datadog data point.
type point [2]float64

// AddMetric adds a metric to the series.
func (ts *timeSeries) addMetric(name, stags, metricType string, value float64, interval time.Duration) {
	hostname, tags := types.ExtractSourceFromTags(stags)
	if hostname == "" {
		hostname = ts.Hostname
	}
	ts.Series = append(ts.Series, metric{
		Host:     hostname,
		Interval: interval.Seconds(),
		Metric:   name,
		Points:   [1]point{{float64(ts.Timestamp), value}},
		Tags:     tags.Normalise(),
		Type:     metricType,
	})
}

// event represents an event data structure for Datadog.
type event struct {
	Title          string   `json:"title"`
	Text           string   `json:"text"`
	DateHappened   int64    `json:"date_happened,omitempty"`
	Hostname       string   `json:"host,omitempty"`
	AggregationKey string   `json:"aggregation_key,omitempty"`
	SourceTypeName string   `json:"source_type_name,omitempty"`
	Tags           []string `json:"tags,omitempty"`
	Priority       string   `json:"priority,omitempty"`
	AlertType      string   `json:"alert_type,omitempty"`
}

// SendMetricsAsync flushes the metrics to Datadog, preparing payload synchronously but doing the send asynchronously.
func (d *client) SendMetricsAsync(ctx context.Context, metrics *types.MetricMap, cb backendTypes.SendCallback) {
	if metrics.NumStats == 0 {
		cb(nil)
		return
	}
	var counter uint16
	results := make(chan error)
	d.processMetrics(metrics, func(ts *timeSeries) {
		go func() {
			err := d.postMetrics(ts)
			select {
			case <-ctx.Done():
			case results <- err:
			}
		}()
		counter++
	})
	go func() {
		errs := make([]error, 0, counter)
	loop:
		for c := counter; c > 0; c-- {
			select {
			case <-ctx.Done():
				errs = append(errs, ctx.Err())
				break loop
			case err := <-results:
				errs = append(errs, err)
			}
		}
		cb(errs)
	}()
}

func (d *client) processMetrics(metrics *types.MetricMap, cb func(*timeSeries)) {
	ts := &timeSeries{
		Series:    make([]metric, 0, d.metricsPerBatch),
		Timestamp: time.Now().Unix(),
		Hostname:  d.hostname,
	}

	metrics.Counters.Each(func(key, tagsKey string, counter types.Counter) {
		ts.addMetric(key, tagsKey, rate, counter.PerSecond, counter.Flush)
		ts.addMetric(fmt.Sprintf("%s.count", key), tagsKey, gauge, float64(counter.Value), counter.Flush)
		d.maybeFlush(ts, cb)
	})

	metrics.Timers.Each(func(key, tagsKey string, timer types.Timer) {
		ts.addMetric(fmt.Sprintf("%s.lower", key), tagsKey, gauge, timer.Min, timer.Flush)
		ts.addMetric(fmt.Sprintf("%s.upper", key), tagsKey, gauge, timer.Max, timer.Flush)
		ts.addMetric(fmt.Sprintf("%s.count", key), tagsKey, gauge, float64(timer.Count), timer.Flush)
		ts.addMetric(fmt.Sprintf("%s.count_ps", key), tagsKey, rate, timer.PerSecond, timer.Flush)
		ts.addMetric(fmt.Sprintf("%s.mean", key), tagsKey, gauge, timer.Mean, timer.Flush)
		ts.addMetric(fmt.Sprintf("%s.median", key), tagsKey, gauge, timer.Median, timer.Flush)
		ts.addMetric(fmt.Sprintf("%s.std", key), tagsKey, gauge, timer.StdDev, timer.Flush)
		ts.addMetric(fmt.Sprintf("%s.sum", key), tagsKey, gauge, timer.Sum, timer.Flush)
		ts.addMetric(fmt.Sprintf("%s.sum_squares", key), tagsKey, gauge, timer.SumSquares, timer.Flush)
		for _, pct := range timer.Percentiles {
			ts.addMetric(fmt.Sprintf("%s.%s", key, pct.Str), tagsKey, gauge, pct.Float, timer.Flush)
		}
		d.maybeFlush(ts, cb)
	})

	metrics.Gauges.Each(func(key, tagsKey string, g types.Gauge) {
		ts.addMetric(key, tagsKey, gauge, g.Value, g.Flush)
		d.maybeFlush(ts, cb)
	})

	metrics.Sets.Each(func(key, tagsKey string, set types.Set) {
		ts.addMetric(key, tagsKey, gauge, float64(len(set.Values)), set.Flush)
		d.maybeFlush(ts, cb)
	})

	if len(ts.Series) > 0 {
		cb(ts)
	}
}

func (d *client) maybeFlush(ts *timeSeries, cb func(*timeSeries)) {
	if uint(len(ts.Series))+20 >= d.metricsPerBatch { // flush before it reaches max size and grows the slice
		cb(ts)
		*ts = timeSeries{
			Series:    make([]metric, 0, d.metricsPerBatch),
			Timestamp: ts.Timestamp,
			Hostname:  ts.Hostname,
		}
	}
}

func (d *client) postMetrics(ts *timeSeries) error {
	return d.post("/api/v1/series", "metrics", ts)
}

// SendEvent sends an event to Datadog.
func (d *client) SendEvent(ctx context.Context, e *types.Event) error {
	return d.post("/api/v1/events", "events", event{
		Title:          e.Title,
		Text:           e.Text,
		DateHappened:   e.DateHappened,
		Hostname:       e.Hostname,
		AggregationKey: e.AggregationKey,
		SourceTypeName: e.SourceTypeName,
		Tags:           e.Tags,
		Priority:       e.Priority.StringWithEmptyDefault(),
		AlertType:      e.AlertType.StringWithEmptyDefault(),
	})
}

// SampleConfig returns the sample config for the datadog backend.
func (d *client) SampleConfig() string {
	return sampleConfig
}

// BackendName returns the name of the backend.
func (d *client) BackendName() string {
	return BackendName
}

func (d *client) post(path, typeOfPost string, data interface{}) error {
	tsBytes, err := json.Marshal(data)
	if err != nil {
		return fmt.Errorf("[%s] unable to marshal %s: %v", BackendName, typeOfPost, err)
	}
	log.Debugf("[%s] %s json: %s", BackendName, typeOfPost, tsBytes)

	b := backoff.NewExponentialBackOff()
	b.MaxElapsedTime = d.maxRequestElapsedTime
	err = backoff.RetryNotify(d.doPost(path, tsBytes), b, func(err error, d time.Duration) {
		log.Warnf("[%s] failed to send %s, sleeping for %s: %v", BackendName, typeOfPost, d, err)
	})
	if err != nil {
		return fmt.Errorf("[%s] %v", BackendName, err)
	}

	return nil
}

func (d *client) doPost(path string, body []byte) backoff.Operation {
	authenticatedURL := d.authenticatedURL(path)
	return func() error {
		req, err := http.NewRequest("POST", authenticatedURL, bytes.NewBuffer(body))
		if err != nil {
			return fmt.Errorf("unable to create http.Request: %v", err)
		}
		req.Header.Add("Content-Type", "application/json")
		// Mimic dogstatsd code
		req.Header.Add("DD-Dogstatsd-Version", dogstatsdVersion)
		req.Header.Add("User-Agent", dogstatsdUserAgent)
		resp, err := d.client.Do(req)
		if err != nil {
			return fmt.Errorf("error POSTing: %s", strings.Replace(err.Error(), d.apiKey, "*****", -1))
		}
		defer resp.Body.Close()
		body := io.LimitReader(resp.Body, maxResponseSize)
		if resp.StatusCode < 200 || resp.StatusCode >= 205 {
			b, _ := ioutil.ReadAll(body)
			log.Infof("[%s] failed request status: %d\n%s", BackendName, resp.StatusCode, b)
			return fmt.Errorf("received bad status code %d", resp.StatusCode)
		}
		_, _ = io.Copy(ioutil.Discard, body)
		return nil
	}
}

func (d *client) authenticatedURL(path string) string {
	q := url.Values{
		"api_key": []string{d.apiKey},
	}
	return fmt.Sprintf("%s%s?%s", d.apiEndpoint, path, q.Encode())
}

// NewClientFromViper returns a new Datadog API client.
func NewClientFromViper(v *viper.Viper) (backendTypes.Backend, error) {
	dd := getSubViper(v, "datadog")
	dd.SetDefault("api_endpoint", apiURL)
	dd.SetDefault("metrics_per_batch", defaultMetricsPerBatch)
	dd.SetDefault("timeout", defaultClientTimeout)
	dd.SetDefault("max_request_elapsed_time", defaultMaxRequestElapsedTime)
	return NewClient(
		dd.GetString("api_endpoint"),
		dd.GetString("api_key"),
		uint(dd.GetInt("metrics_per_batch")),
		dd.GetDuration("timeout"),
		dd.GetDuration("max_request_elapsed_time"),
	)
}

// NewClient returns a new Datadog API client.
func NewClient(apiEndpoint, apiKey string, metricsPerBatch uint, clientTimeout, maxRequestElapsedTime time.Duration) (backendTypes.Backend, error) {
	if apiEndpoint == "" {
		return nil, fmt.Errorf("[%s] apiEndpoint is required", BackendName)
	}
	if apiKey == "" {
		return nil, fmt.Errorf("[%s] apiKey is required", BackendName)
	}
	if metricsPerBatch <= 0 {
		return nil, fmt.Errorf("[%s] metricsPerBatch must be positive", BackendName)
	}
	if clientTimeout <= 0 {
		return nil, fmt.Errorf("[%s] clientTimeout must be positive", BackendName)
	}
	if maxRequestElapsedTime <= 0 {
		return nil, fmt.Errorf("[%s] maxRequestElapsedTime must be positive", BackendName)
	}
	hostname, err := os.Hostname()
	if err != nil {
		return nil, fmt.Errorf("[%s] cannot get hostname: %v", BackendName, err)
	}
	log.Infof("[%s] maxRequestElapsedTime=%s clientTimeout=%s metricsPerBatch=%d", BackendName, maxRequestElapsedTime, clientTimeout, metricsPerBatch)
	return &client{
		apiKey:                apiKey,
		apiEndpoint:           apiEndpoint,
		hostname:              hostname,
		maxRequestElapsedTime: maxRequestElapsedTime,
		client: &http.Client{
			Timeout: clientTimeout,
		},
		metricsPerBatch: metricsPerBatch,
	}, nil
}

// Workaround https://github.com/spf13/viper/pull/165 and https://github.com/spf13/viper/issues/191
func getSubViper(v *viper.Viper, key string) *viper.Viper {
	var n *viper.Viper
	namespace := v.Get(key)
	if namespace != nil {
		n = v.Sub(key)
	}
	if n == nil {
		n = viper.New()
	}
	return n
}
<|endoftext|>


<commit_before>package victor

import (
	"github.com/brettbuddin/victor/adapter"
	"log"
	"regexp"
	"strings"
	"sync"
)

type Brain struct {
	*sync.RWMutex
	name      string
	identity  adapter.User
	listeners []ListenerFunc
	cache     *Cache
}

func NewBrain(name string) *Brain {
	return &Brain{
		RWMutex:   &sync.RWMutex{},
		name:      name,
		listeners: []ListenerFunc{},
		cache:     NewCache(),
	}
}

func (b *Brain) Cache() adapter.Cacher {
	return b.cache
}

func (b *Brain) Name() string {
	b.RLock()
	defer b.RUnlock()
	return b.name
}

func (b *Brain) Identity() adapter.User {
	b.RLock()
	defer b.RUnlock()
	return b.identity
}

func (b *Brain) SetIdentity(u adapter.User) {
	b.Lock()
	defer b.Unlock()
	b.identity = u
}

// Respond registers a listener that matches a direct message to
// the robot. This means "@botname command", "botname command" or
// "/command" forms
func (b *Brain) Respond(exp string, f func(adapter.Message)) (err error) {
	exp = strings.Join([]string{
		"(?i)", // flags
		"\\A",  // begin
		"(?:(?:@)?" + b.Name() + "[:,]?\\s*|/)", // bot name
		"(?:" + exp + ")",                       // expression
		"\\z",                                   // end
	}, "")

	return b.Hear(exp, f)
}

// Hear registers a listener that matches any instance of the
// phrase in the room. Excluding from itself.
func (b *Brain) Hear(exp string, f func(adapter.Message)) (err error) {
	pattern, err := regexp.Compile(exp)

	if err != nil {
		return err
	}

	log.Printf("LISTENER: %s\n", exp)
	b.register(listenerFunc(pattern, f))
	return
}

func (b *Brain) register(l ListenerFunc) {
	b.Lock()
	defer b.Unlock()
	b.listeners = append(b.listeners, l)
}

// Receive accepts an incoming message and applies
// it to all listeners.
func (b *Brain) Receive(m adapter.Message) {
	b.RLock()
	defer b.RUnlock()
	for _, l := range b.listeners {
		go l(m)
	}
}

type ListenerFunc func(adapter.Message)

func listenerFunc(pattern *regexp.Regexp, f ListenerFunc) ListenerFunc {
	return func(m adapter.Message) {
		results := pattern.FindAllStringSubmatch(m.Body(), -1)

		if len(results) > 0 {
			m.SetParams(results[0][1:])
			log.Printf("TRIGGER: %s\n", pattern)
			log.Printf("TRIGGER: %s\n", pattern)
			log.Printf("PARAMS: %s\n", m.Params())
			f(m)
		}
	}
}
<commit_msg>For whatever reason, this was being logged twice.<commit_after>package victor

import (
	"github.com/brettbuddin/victor/adapter"
	"log"
	"regexp"
	"strings"
	"sync"
)

type Brain struct {
	*sync.RWMutex
	name      string
	identity  adapter.User
	listeners []ListenerFunc
	cache     *Cache
}

func NewBrain(name string) *Brain {
	return &Brain{
		RWMutex:   &sync.RWMutex{},
		name:      name,
		listeners: []ListenerFunc{},
		cache:     NewCache(),
	}
}

func (b *Brain) Cache() adapter.Cacher {
	return b.cache
}

func (b *Brain) Name() string {
	b.RLock()
	defer b.RUnlock()
	return b.name
}

func (b *Brain) Identity() adapter.User {
	b.RLock()
	defer b.RUnlock()
	return b.identity
}

func (b *Brain) SetIdentity(u adapter.User) {
	b.Lock()
	defer b.Unlock()
	b.identity = u
}

// Respond registers a listener that matches a direct message to
// the robot. This means "@botname command", "botname command" or
// "/command" forms
func (b *Brain) Respond(exp string, f func(adapter.Message)) (err error) {
	exp = strings.Join([]string{
		"(?i)", // flags
		"\\A",  // begin
		"(?:(?:@)?" + b.Name() + "[:,]?\\s*|/)", // bot name
		"(?:" + exp + ")",                       // expression
		"\\z",                                   // end
	}, "")

	return b.Hear(exp, f)
}

// Hear registers a listener that matches any instance of the
// phrase in the room. Excluding from itself.
func (b *Brain) Hear(exp string, f func(adapter.Message)) (err error) {
	pattern, err := regexp.Compile(exp)

	if err != nil {
		return err
	}

	log.Printf("LISTENER: %s\n", exp)
	b.register(listenerFunc(pattern, f))
	return
}

func (b *Brain) register(l ListenerFunc) {
	b.Lock()
	defer b.Unlock()
	b.listeners = append(b.listeners, l)
}

// Receive accepts an incoming message and applies
// it to all listeners.
func (b *Brain) Receive(m adapter.Message) {
	b.RLock()
	defer b.RUnlock()
	for _, l := range b.listeners {
		go l(m)
	}
}

type ListenerFunc func(adapter.Message)

func listenerFunc(pattern *regexp.Regexp, f ListenerFunc) ListenerFunc {
	return func(m adapter.Message) {
		results := pattern.FindAllStringSubmatch(m.Body(), -1)

		if len(results) > 0 {
			m.SetParams(results[0][1:])
			log.Printf("TRIGGER: %s\n", pattern)
			log.Printf("PARAMS: %s\n", m.Params())
			f(m)
		}
	}
}
<|endoftext|>


<commit_before>package reflect

import (
	. "jvmgo/any"
	"jvmgo/jvm/rtda"
	rtc "jvmgo/jvm/rtda/class"
)

func init() {
	_nmai(invoke0, "invoke0", "(Ljava/lang/reflect/Method;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;")
}

func _nmai(method Any, name, desc string) {
	rtc.RegisterNativeMethod("sun/reflect/NativeMethodAccessorImpl", name, desc, method)
}

// private static native Object invoke0(Method method, Object o, Object[] os);
// (Ljava/lang/reflect/Method;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
func invoke0(frame *rtda.Frame) {
	stack := frame.OperandStack()
	if stack.IsEmpty() {
		frame.RevertNextPC()
		_invoke(frame)
		return
	}

	// catch return value
	if stack.IsEmpty() {
		stack.PushNull()
		return
	}
	retVal := stack.Pop()
	if retVal == nil {
		stack.PushNull()
		return
	}
	switch retVal.(type) {
		default: panic("asdfadsfadsfdsf")
	}
}

func _invoke(frame *rtda.Frame) {
	vars := frame.LocalVars()
	methodObj := vars.GetRef(0)
	obj := vars.GetRef(1)
	argArrObj := vars.GetRef(2)

	goMethod := getGoMethod(methodObj)
	args := convertArgs(obj, argArrObj, goMethod)

	stack := frame.OperandStack()
	stack.HackSetSlots(args)
	if stack.IsEmpty() {
		stack.HackSetSlots([]Any{nil}) // make room for return value
	}

	frame.Thread().InvokeMethod(goMethod)
}
<commit_msg>implementing NativeMethodAccessorImpl.invoke0()..<commit_after>package reflect

import (
	. "jvmgo/any"
	"jvmgo/jvm/rtda"
	rtc "jvmgo/jvm/rtda/class"
)

func init() {
	_nmai(invoke0, "invoke0", "(Ljava/lang/reflect/Method;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;")
}

func _nmai(method Any, name, desc string) {
	rtc.RegisterNativeMethod("sun/reflect/NativeMethodAccessorImpl", name, desc, method)
}

// private static native Object invoke0(Method method, Object o, Object[] os);
// (Ljava/lang/reflect/Method;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
func invoke0(frame *rtda.Frame) {
	stack := frame.OperandStack()
	if stack.IsEmpty() {
		frame.RevertNextPC()
		_invokeMethod(frame)
	} else {
		_convertReturnValue(stack)
	}
}

func _invokeMethod(frame *rtda.Frame) {
	vars := frame.LocalVars()
	methodObj := vars.GetRef(0)
	obj := vars.GetRef(1)
	argArrObj := vars.GetRef(2)

	goMethod := getGoMethod(methodObj)
	args := convertArgs(obj, argArrObj, goMethod)

	stack := frame.OperandStack()
	if len(args) > 0 {
		stack.HackSetSlots(args)
	} else {
		// make room for return value
		stack.HackSetSlots([]Any{nil})
	}

	frame.Thread().InvokeMethod(goMethod)
}

func _convertReturnValue(stack *rtda.OperandStack) {
	if stack.IsEmpty() {
		stack.PushNull()
		return
	}

	retVal := stack.Pop()
	if retVal == nil {
		stack.PushNull()
		return
	}

	if ref, ok := retVal.(*rtc.Obj); ok {
		stack.PushRef(ref)
	} else {
		boxed := _box(retVal)
		stack.PushRef(boxed)
	}
}

func _box(val Any) *rtc.Obj {
	// todo
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"github.com/gorilla/mux"
	"io/ioutil"
	"log"
	"net/http"
)

var (
	ServerVersion string = "pre version"
	APIVersion string = "pre api"
)

func main() {
	fmt.Println("TRACKMON SERVER\nCopyright (c) 2017, Paul Kramme under BSD 2-Clause")
	fmt.Println("Please report bugs to https://github.com/trackmon/trackmon-server")

	// Configure flags
	CreateConfigFlag := flag.Bool("createconfig", false, "Creates a standard configuration and exits")
	ConfigLocation := flag.String("config", "./trackmonserv.conf", "Location of config file. Standard is ./trackmonserv")
	ShowLicenses := flag.Bool("licenses", false, "Shows licenses and exits")
	ShowVersion := flag.Bool("version", false, "Shows version and exits")
	ShowJsonVersion:= flag.Bool("versionjson", false, "Shows version in json and exits")
	flag.Parse()

	// Check flags
	if *CreateConfigFlag == true {
		CreateConfig()
		return
	}
	if *ShowLicenses == true {
		fmt.Println("trackmon servers license\n")
		fmt.Print(trackmonlicense)
		fmt.Println("\n")

		fmt.Println("This project uses github.com/gorilla/mux\n")
		fmt.Print(muxlicense)
		fmt.Println("\n")

		return
	}
	if *ShowVersion == true {
		fmt.Printf("Server Version: %s\nAPI Version: %s\n", ServerVersion, APIVersion)
		return
	}
	if *ShowJsonVersion == true {
		fmt.Printf("{\"serverversion\":\"%s\",\"apiversion\":\"%s\"}", ServerVersion, APIVersion)
	}

	// Load config
	var Config Configuration
	Configfile, err := ioutil.ReadFile(*ConfigLocation)
	if err != nil {
		fmt.Println("Couldn't find or open config file. Create one with -createconfig")
		panic(err)
	}
	err = fromjson(string(Configfile), &Config)
	if err != nil {
		panic(err)
	}

	// Configure router and server
	r := mux.NewRouter()
	r.HandleFunc("/", RootHandler) // Returnes 200 OK, can be used for health checks
	r.HandleFunc("/version", VersionHandler)
	r.HandleFunc("/user", NewUserHandler)
	r.HandleFunc("/user/{user_id}", UserHandler)
	r.HandleFunc("/user/{user_id}/{account}", AccountHandler)
	srv := &http.Server{
		Handler: r,
		Addr:    Config.ListeningAddress,
	}

	// Start the server
	log.Println("Initialization complete")
	srv.ListenAndServe()
}

/*
 ██████  ██████  ███    ██ ███████ ██  ██████
██      ██    ██ ████   ██ ██      ██ ██
██      ██    ██ ██ ██  ██ █████   ██ ██   ███
██      ██    ██ ██  ██ ██ ██      ██ ██    ██
 ██████  ██████  ██   ████ ██      ██  ██████
*/

type Configuration struct {
	ListeningAddress string
	DatabaseAddress string
}

func CreateConfig() {
	var Config Configuration

	// Standard config
	Config.ListeningAddress = ":80"
	Config.DatabaseAddress = "localhost:5432"

	ByteJsonConfig, err := toprettyjson(Config)
	if err != nil {
		panic(err)
	}
	fmt.Println("Writing configuration to ./trackmonserv.conf")
	err = ioutil.WriteFile("./trackmonserv.conf", ByteJsonConfig, 0644)
	if err != nil {
		panic(err)
	}
}

/*
██   ██  █████  ███    ██ ██████  ██      ███████ ██████
██   ██ ██   ██ ████   ██ ██   ██ ██      ██      ██   ██
███████ ███████ ██ ██  ██ ██   ██ ██      █████   ██████
██   ██ ██   ██ ██  ██ ██ ██   ██ ██      ██      ██   ██
██   ██ ██   ██ ██   ████ ██████  ███████ ███████ ██   ██
*/

func RootHandler(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusOK)
}

func VersionHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "{\"serverversion\":\"%s\",\"apiversion\":\"%s\"}", ServerVersion, APIVersion)
	w.WriteHeader(http.StatusOK)
}

func NewUserHandler(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusOK)
	// TODO: Write function which creates new users and stores them on the DB
}

func UserHandler(w http.ResponseWriter, r *http.Request) {
	variables := mux.Vars(r)
	username, password, ok := r.BasicAuth()
	if ok != true {
		w.WriteHeader(http.StatusUnauthorized)
		return
	} // All requests below here have given basic auth
	log.Printf("User %s with pw %s wants info about all accounts of %s\n", username, password, string(variables["user_id"]))
	// TODO: Check if user exists, if and if password correct, give him info
}

func AccountHandler(w http.ResponseWriter, r *http.Request) {
	variables := mux.Vars(r)
	username, password, ok := r.BasicAuth()
	if ok != true {
		w.WriteHeader(http.StatusUnauthorized)
		return
	} // All requests below here have given basic auth
	log.Printf("User %s with pw %s wants info about account %s from %s\n", username, password, string(variables["account"]), string(variables["user_id"]))
}

/*
     ██ ███████  ██████  ███    ██
     ██ ██      ██    ██ ████   ██
     ██ ███████ ██    ██ ██ ██  ██
██   ██      ██ ██    ██ ██  ██ ██
 █████  ███████  ██████  ██   ████
*/

func fromjson(src string, v interface{}) error {
	return json.Unmarshal([]byte(src), v)
}

func tojson(v interface{}) ([]byte, error) {
	return json.Marshal(v)
}

func toprettyjson(v interface{}) ([]byte, error) {
	return json.MarshalIndent(v, "", "\t")
}

/*
██      ██  ██████ ███████ ███    ██ ███████ ███████
██      ██ ██      ██      ████   ██ ██      ██
██      ██ ██      █████   ██ ██  ██ ███████ █████
██      ██ ██      ██      ██  ██ ██      ██ ██
███████ ██  ██████ ███████ ██   ████ ███████ ███████
*/

const (
	muxlicense string = `Copyright (c) 2012 Rodrigo Moraes. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

	 * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
	 * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
	 * Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.`
	trackmonlicense string = `BSD 2-Clause License

	Copyright (c) 2017, Paul Kramme
	All rights reserved.

	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions are met:

	* Redistributions of source code must retain the above copyright notice, this
	  list of conditions and the following disclaimer.

	* Redistributions in binary form must reproduce the above copyright notice,
	  this list of conditions and the following disclaimer in the documentation
	  and/or other materials provided with the distribution.

	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
	AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
	DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
	FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
	DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
	SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
	CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
	OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
	OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
`
)
<commit_msg>Reformat gocode<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"github.com/gorilla/mux"
	"io/ioutil"
	"log"
	"net/http"
)

var (
	ServerVersion string = "pre version"
	APIVersion    string = "pre api"
)

func main() {
	fmt.Println("TRACKMON SERVER\nCopyright (c) 2017, Paul Kramme under BSD 2-Clause")
	fmt.Println("Please report bugs to https://github.com/trackmon/trackmon-server")

	// Configure flags
	CreateConfigFlag := flag.Bool("createconfig", false, "Creates a standard configuration and exits")
	ConfigLocation := flag.String("config", "./trackmonserv.conf", "Location of config file. Standard is ./trackmonserv")
	ShowLicenses := flag.Bool("licenses", false, "Shows licenses and exits")
	ShowVersion := flag.Bool("version", false, "Shows version and exits")
	ShowJsonVersion := flag.Bool("versionjson", false, "Shows version in json and exits")

	// Check flags
	flag.Parse()
	if *CreateConfigFlag == true {
		CreateConfig()
		return
	}
	if *ShowLicenses == true {
		fmt.Println("trackmon servers license\n")
		fmt.Print(trackmonlicense)
		fmt.Println("\n")

		fmt.Println("This project uses github.com/gorilla/mux\n")
		fmt.Print(muxlicense)
		fmt.Println("\n")

		return
	}
	if *ShowVersion == true {
		fmt.Printf("Server Version: %s\nAPI Version: %s\n", ServerVersion, APIVersion)
		return
	}
	if *ShowJsonVersion == true {
		fmt.Printf("{\"serverversion\":\"%s\",\"apiversion\":\"%s\"}", ServerVersion, APIVersion)
	}

	// Load config
	var Config Configuration
	Configfile, err := ioutil.ReadFile(*ConfigLocation)
	if err != nil {
		fmt.Println("Couldn't find or open config file. Create one with -createconfig")
		panic(err)
	}
	err = fromjson(string(Configfile), &Config)
	if err != nil {
		panic(err)
	}

	// Configure router and server
	r := mux.NewRouter()
	r.HandleFunc("/", RootHandler) // Returnes 200 OK, can be used for health checks
	r.HandleFunc("/version", VersionHandler)
	r.HandleFunc("/user", NewUserHandler)
	r.HandleFunc("/user/{user_id}", UserHandler)
	r.HandleFunc("/user/{user_id}/{account}", AccountHandler)

	srv := &http.Server{
		Handler: r,
		Addr:    Config.ListeningAddress,
	}

	// Start the server
	log.Println("Initialization complete")
	srv.ListenAndServe()
}

/*
 ██████  ██████  ███    ██ ███████ ██  ██████
██      ██    ██ ████   ██ ██      ██ ██
██      ██    ██ ██ ██  ██ █████   ██ ██   ███
██      ██    ██ ██  ██ ██ ██      ██ ██    ██
 ██████  ██████  ██   ████ ██      ██  ██████
*/

type Configuration struct {
	ListeningAddress string
	DatabaseAddress  string
}

func CreateConfig() {
	var Config Configuration

	// Standard config
	Config.ListeningAddress = ":80"
	Config.DatabaseAddress = "localhost:5432"

	ByteJsonConfig, err := toprettyjson(Config)
	if err != nil {
		panic(err)
	}
	fmt.Println("Writing configuration to ./trackmonserv.conf")
	err = ioutil.WriteFile("./trackmonserv.conf", ByteJsonConfig, 0644)
	if err != nil {
		panic(err)
	}
}

/*
██   ██  █████  ███    ██ ██████  ██      ███████ ██████
██   ██ ██   ██ ████   ██ ██   ██ ██      ██      ██   ██
███████ ███████ ██ ██  ██ ██   ██ ██      █████   ██████
██   ██ ██   ██ ██  ██ ██ ██   ██ ██      ██      ██   ██
██   ██ ██   ██ ██   ████ ██████  ███████ ███████ ██   ██
*/

func RootHandler(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusOK)
}

func VersionHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "{\"serverversion\":\"%s\",\"apiversion\":\"%s\"}", ServerVersion, APIVersion)
	w.WriteHeader(http.StatusOK)
}

func NewUserHandler(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusOK)
	// TODO: Write function which creates new users and stores them on the DB
}

func UserHandler(w http.ResponseWriter, r *http.Request) {
	variables := mux.Vars(r)
	username, password, ok := r.BasicAuth()
	if ok != true {
		w.WriteHeader(http.StatusUnauthorized)
		return
	} // All requests below here have given basic auth
	log.Printf("User %s with pw %s wants info about all accounts of %s\n", username, password, string(variables["user_id"]))
	// TODO: Check if user exists, if and if password correct, give him info
}

func AccountHandler(w http.ResponseWriter, r *http.Request) {
	variables := mux.Vars(r)
	username, password, ok := r.BasicAuth()
	if ok != true {
		w.WriteHeader(http.StatusUnauthorized)
		return
	} // All requests below here have given basic auth
	log.Printf("User %s with pw %s wants info about account %s from %s\n", username, password, string(variables["account"]), string(variables["user_id"]))
}

/*
     ██ ███████  ██████  ███    ██
     ██ ██      ██    ██ ████   ██
     ██ ███████ ██    ██ ██ ██  ██
██   ██      ██ ██    ██ ██  ██ ██
 █████  ███████  ██████  ██   ████
*/

func fromjson(src string, v interface{}) error {
	return json.Unmarshal([]byte(src), v)
}

func tojson(v interface{}) ([]byte, error) {
	return json.Marshal(v)
}

func toprettyjson(v interface{}) ([]byte, error) {
	return json.MarshalIndent(v, "", "\t")
}

/*
██      ██  ██████ ███████ ███    ██ ███████ ███████
██      ██ ██      ██      ████   ██ ██      ██
██      ██ ██      █████   ██ ██  ██ ███████ █████
██      ██ ██      ██      ██  ██ ██      ██ ██
███████ ██  ██████ ███████ ██   ████ ███████ ███████
*/

const (
	muxlicense string = `Copyright (c) 2012 Rodrigo Moraes. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

	 * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
	 * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
	 * Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.`
	trackmonlicense string = `BSD 2-Clause License

	Copyright (c) 2017, Paul Kramme
	All rights reserved.

	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions are met:

	* Redistributions of source code must retain the above copyright notice, this
	  list of conditions and the following disclaimer.

	* Redistributions in binary form must reproduce the above copyright notice,
	  this list of conditions and the following disclaimer in the documentation
	  and/or other materials provided with the distribution.

	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
	AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
	DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
	FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
	DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
	SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
	CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
	OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
	OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
`
)
<|endoftext|>


<commit_before>package trie

import (
	"testing"

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

func TestEmptyTrie(t *testing.T) {
	i := NewTrie()

	m := i.Find("abc")

	assert.False(t, m.Success)
	assert.False(t, m.IsCompleteMatch)
	assert.Equal(t, "", m.NearestPrefix)
}
func TestFindingEmptyString(t *testing.T) {
	i := NewTrie()
	i.Add("abc")

	m := i.Find("")

	assert.True(t, m.Success)
	assert.True(t, m.IsCompleteMatch)
	assert.Equal(t, "", m.NearestPrefix)
}

func TestSimpleMatch(t *testing.T) {
	i := NewTrie()
	i.Add("a")

	m := i.Find("a")

	assert.True(t, m.Success)
	assert.True(t, m.IsCompleteMatch)
	assert.Equal(t, "a", m.NearestPrefix)
}

func TestAddingSameKeyTwice(t *testing.T) {
	i := NewTrie()
	i.Add("abc")
	i.Add("abc")

	m := i.Find("abc")

	assert.True(t, m.Success)
	assert.True(t, m.IsCompleteMatch)
	assert.Equal(t, "abc", m.NearestPrefix)
}

func TestPrefix(t *testing.T) {
	i := NewTrie()
	i.Add("aa")
	i.Add("aabb")

	m := i.Find("aa")

	assert.True(t, m.Success)
	assert.True(t, m.IsCompleteMatch)
	assert.Equal(t, "aa", m.NearestPrefix)

	m = i.Find("aab")

	assert.True(t, m.Success)
	assert.False(t, m.IsCompleteMatch)
	assert.Equal(t, "aab", m.NearestPrefix)

	m = i.Find("aabb")

	assert.True(t, m.Success)
	assert.True(t, m.IsCompleteMatch)
	assert.Equal(t, "aabb", m.NearestPrefix)

	m = i.Find("ab")

	assert.False(t, m.Success)
	assert.False(t, m.IsCompleteMatch)
	assert.Equal(t, "a", m.NearestPrefix)
}
<commit_msg>test: More trie tests<commit_after>package trie

import (
	"testing"

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

func TestEmptyTrie(t *testing.T) {
	i := NewTrie()

	m := i.Find("abc")

	assert.False(t, m.Success)
	assert.False(t, m.IsCompleteMatch)
	assert.Equal(t, "", m.NearestPrefix)
}
func TestFindingEmptyString(t *testing.T) {
	i := NewTrie()
	i.Add("abc")

	m := i.Find("")

	assert.True(t, m.Success)
	assert.True(t, m.IsCompleteMatch)
	assert.Equal(t, "", m.NearestPrefix)
}

func TestSimpleMatch(t *testing.T) {
	i := NewTrie()
	i.Add("a")

	m := i.Find("a")

	assert.True(t, m.Success)
	assert.True(t, m.IsCompleteMatch)
	assert.Equal(t, "a", m.NearestPrefix)
}

func TestAddingSameKeyTwice(t *testing.T) {
	i := NewTrie()
	i.Add("abc")
	i.Add("abc")

	m := i.Find("abc")

	assert.True(t, m.Success)
	assert.True(t, m.IsCompleteMatch)
	assert.Equal(t, "abc", m.NearestPrefix)
}

func TestPrefix(t *testing.T) {
	i := NewTrie()
	i.Add("aa")
	i.Add("aabb")

	m := i.Find("aa")

	assert.True(t, m.Success)
	assert.True(t, m.IsCompleteMatch)
	assert.Equal(t, "aa", m.NearestPrefix)

	m = i.Find("aab")

	assert.True(t, m.Success)
	assert.False(t, m.IsCompleteMatch)
	assert.Equal(t, "aab", m.NearestPrefix)

	m = i.Find("aabb")

	assert.True(t, m.Success)
	assert.True(t, m.IsCompleteMatch)
	assert.Equal(t, "aabb", m.NearestPrefix)

	m = i.Find("ab")

	assert.False(t, m.Success)
	assert.False(t, m.IsCompleteMatch)
	assert.Equal(t, "a", m.NearestPrefix)
}

func TestUnsuccessfulMatch(t *testing.T) {
	i := NewTrie()

	i.Add("abc")

	m := i.Find("def")

	assert.False(t, m.Success)
	assert.False(t, m.IsCompleteMatch)
	assert.Equal(t, "", m.NearestPrefix)
}

func TestUnicodeEntries(t *testing.T) {
	i := NewTrie()
	i.Add("😄🍓💩👠")

	m := i.Find("😄🍓")

	assert.True(t, m.Success)
	assert.False(t, m.IsCompleteMatch)
	assert.Equal(t, "😄🍓", m.NearestPrefix)

	m = i.Find("😄🍓💩👠")

	assert.True(t, m.Success)
	assert.True(t, m.IsCompleteMatch)
	assert.Equal(t, "😄🍓💩👠", m.NearestPrefix)

	m = i.Find("🍓💩")

	assert.False(t, m.Success)
	assert.False(t, m.IsCompleteMatch)
	assert.Equal(t, "", m.NearestPrefix)
}
<|endoftext|>


<commit_before>// Package bootstrap uses Terraform to remove bootstrap resources.
package bootstrap

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

	"github.com/openshift/installer/pkg/asset/cluster"
	"github.com/openshift/installer/pkg/terraform"
	"github.com/pkg/errors"
)

// Destroy uses Terraform to remove bootstrap resources.
func Destroy(dir string) (err error) {
	metadata, err := cluster.LoadMetadata(dir)
	if err != nil {
		return err
	}

	platform := metadata.Platform()
	if platform == "" {
		return errors.New("no platform configured in metadata")
	}

	copyNames := []string{terraform.StateFileName, cluster.TfVarsFileName}

	if platform == "libvirt" {
		err = ioutil.WriteFile(filepath.Join(dir, "disable-bootstrap.auto.tfvars"), []byte(`{
  "bootstrap_dns": false
}
`), 0666)
		if err != nil {
			return err
		}
		copyNames = append(copyNames, "disable-bootstrap.auto.tfvars")
	}

	tempDir, err := ioutil.TempDir("", "openshift-install-")
	if err != nil {
		return errors.Wrap(err, "failed to create temporary directory for Terraform execution")
	}
	defer os.RemoveAll(tempDir)

	for _, filename := range copyNames {
		err = copy(filepath.Join(dir, filename), filepath.Join(tempDir, filename))
		if err != nil {
			return errors.Wrapf(err, "failed to copy %s to the temporary directory", filename)
		}
	}

	if platform == "libvirt" {
		_, err = terraform.Apply(tempDir, platform)
		if err != nil {
			return errors.Wrap(err, "Terraform apply")
		}
	}

	err = terraform.Destroy(tempDir, platform, "-target=module.bootstrap")
	if err != nil {
		return errors.Wrap(err, "Terraform destroy")
	}

	tempStateFilePath := filepath.Join(dir, terraform.StateFileName+".new")
	err = copy(filepath.Join(tempDir, terraform.StateFileName), tempStateFilePath)
	if err != nil {
		return errors.Wrapf(err, "failed to copy %s from the temporary directory", terraform.StateFileName)
	}
	return os.Rename(tempStateFilePath, filepath.Join(dir, terraform.StateFileName))
}

func copy(from string, to string) error {
	data, err := ioutil.ReadFile(from)
	if err != nil {
		return err
	}

	return ioutil.WriteFile(to, data, 0666)
}
<commit_msg>destroy/bootstrap: explicit pass `disable-bootstrap.tfvars` for libvirt<commit_after>// Package bootstrap uses Terraform to remove bootstrap resources.
package bootstrap

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

	"github.com/openshift/installer/pkg/asset/cluster"
	"github.com/openshift/installer/pkg/terraform"
	"github.com/pkg/errors"
)

// Destroy uses Terraform to remove bootstrap resources.
func Destroy(dir string) (err error) {
	metadata, err := cluster.LoadMetadata(dir)
	if err != nil {
		return err
	}

	platform := metadata.Platform()
	if platform == "" {
		return errors.New("no platform configured in metadata")
	}

	copyNames := []string{terraform.StateFileName, cluster.TfVarsFileName}

	if platform == "libvirt" {
		err = ioutil.WriteFile(filepath.Join(dir, "disable-bootstrap.tfvars"), []byte(`{
  "bootstrap_dns": false
}
`), 0666)
		if err != nil {
			return err
		}
		copyNames = append(copyNames, "disable-bootstrap.tfvars")
	}

	tempDir, err := ioutil.TempDir("", "openshift-install-")
	if err != nil {
		return errors.Wrap(err, "failed to create temporary directory for Terraform execution")
	}
	defer os.RemoveAll(tempDir)

	for _, filename := range copyNames {
		err = copy(filepath.Join(dir, filename), filepath.Join(tempDir, filename))
		if err != nil {
			return errors.Wrapf(err, "failed to copy %s to the temporary directory", filename)
		}
	}

	if platform == "libvirt" {
		_, err = terraform.Apply(tempDir, platform, fmt.Sprintf("-var-file=%s", filepath.Join(tempDir, "disable-bootstrap.tfvars")))
		if err != nil {
			return errors.Wrap(err, "Terraform apply")
		}
	}

	err = terraform.Destroy(tempDir, platform, "-target=module.bootstrap")
	if err != nil {
		return errors.Wrap(err, "Terraform destroy")
	}

	tempStateFilePath := filepath.Join(dir, terraform.StateFileName+".new")
	err = copy(filepath.Join(tempDir, terraform.StateFileName), tempStateFilePath)
	if err != nil {
		return errors.Wrapf(err, "failed to copy %s from the temporary directory", terraform.StateFileName)
	}
	return os.Rename(tempStateFilePath, filepath.Join(dir, terraform.StateFileName))
}

func copy(from string, to string) error {
	data, err := ioutil.ReadFile(from)
	if err != nil {
		return err
	}

	return ioutil.WriteFile(to, data, 0666)
}
<|endoftext|>


<commit_before>package mocks

import "github.com/intelsdi-x/athena/pkg/snap"
import "github.com/stretchr/testify/mock"

import "github.com/intelsdi-x/athena/pkg/executor"

type SessionLauncher struct {
	mock.Mock
}

// LaunchSession provides a mock function with given fields: _a0, _a1
func (_m *SessionLauncher) LaunchSession(_a0 executor.TaskInfo, _a1 string) (snap.SessionHandle, error) {
	ret := _m.Called(_a0, _a1)

	var r0 snap.SessionHandle
	if rf, ok := ret.Get(0).(func(executor.TaskInfo, string) snap.SessionHandle); ok {
		r0 = rf(_a0, _a1)
	} else {
		r0 = ret.Get(0).(snap.SessionHandle)
	}

	var r1 error
	if rf, ok := ret.Get(1).(func(executor.TaskInfo, string) error); ok {
		r1 = rf(_a0, _a1)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}
<commit_msg>Split: mock lint fixes<commit_after>package mocks

import "github.com/intelsdi-x/athena/pkg/snap"
import "github.com/stretchr/testify/mock"

import "github.com/intelsdi-x/athena/pkg/executor"

// SessionLauncher ...
type SessionLauncher struct {
	mock.Mock
}

// LaunchSession provides a mock function with given fields: _a0, _a1
func (_m *SessionLauncher) LaunchSession(_a0 executor.TaskInfo, _a1 string) (snap.SessionHandle, error) {
	ret := _m.Called(_a0, _a1)

	var r0 snap.SessionHandle
	if rf, ok := ret.Get(0).(func(executor.TaskInfo, string) snap.SessionHandle); ok {
		r0 = rf(_a0, _a1)
	} else {
		r0 = ret.Get(0).(snap.SessionHandle)
	}

	var r1 error
	if rf, ok := ret.Get(1).(func(executor.TaskInfo, string) error); ok {
		r1 = rf(_a0, _a1)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}
<|endoftext|>


<commit_before>// Copyright 2013 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.

// +build plan9

package runtime

// Polls for ready network connections.
// Returns list of goroutines that become runnable.
func netpoll(block bool) (gp *g) {
	// Implementation for platforms that do not support
	// integrated network poller.
	return
}
<commit_msg>runtime: define netpollinited on Plan 9<commit_after>// Copyright 2013 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.

// +build plan9

package runtime

// Polls for ready network connections.
// Returns list of goroutines that become runnable.
func netpoll(block bool) (gp *g) {
	// Implementation for platforms that do not support
	// integrated network poller.
	return
}

func netpollinited() bool {
	return false
}
<|endoftext|>