<commit_before>/*
 *    Copyright (C) 2014 Christian Muehlhaeuser
 *
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU Affero General Public License as published
 *    by the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *    Authors:
 *      Christian Muehlhaeuser <muesli@gmail.com>
 */

// beehive's central module system.
package bees

import (
	"log"
	"sync"
)

// Interface which all modules need to implement
type BeeInterface interface {
	// Name of the module
	Name() string
	// Namespace of the module
	Namespace() string
	// Description of the module
	Description() string

	// Activates the module
	Run(eventChannel chan Event)
	// Stop the module
	Stop()

	WaitGroup() *sync.WaitGroup

	// Handles an action
	Action(action Action) []Placeholder
}

// Base-struct to be embedded by bee implementations
type Bee struct {
	BeeName        string
	BeeNamespace   string
	BeeDescription string

	SigChan   chan bool
	waitGroup *sync.WaitGroup
}

// An instance of a bee
type BeeInstance struct {
	Name        string
	Class       string
	Description string
	Options     []BeeOption
}

// An Event
type Event struct {
	Bee     string
	Name    string
	Options []Placeholder
}

// An Action
type Action struct {
	Bee     string
	Name    string
	Options []Placeholder
}

// A Filter
type Filter struct {
	Name    string
	Options []FilterOption
}

// A Placeholder used by ins & outs of a module.
type Placeholder struct {
	Name  string
	Type  string
	Value interface{}
}

var (
	eventsIn                                  = make(chan Event)
	bees      map[string]*BeeInterface        = make(map[string]*BeeInterface)
	factories map[string]*BeeFactoryInterface = make(map[string]*BeeFactoryInterface)
	chains    []Chain
)

// Handles incoming events and executes matching Chains.
func handleEvents() {
	for {
		event, ok := <-eventsIn
		if !ok {
			log.Println()
			log.Println("Stopped event handler!")
			break
		}

		log.Println()
		log.Println("Event received:", event.Bee, "/", event.Name, "-", GetEventDescriptor(&event).Description)
		for _, v := range event.Options {
			log.Println("\tOptions:", v)
		}

		go func() {
			defer func() {
				if e := recover(); e != nil {
					log.Println("Fatal chain event:", e)
				}
			}()

			execChains(&event)
		}()
	}
}

// Bees need to call this method to register themselves
func RegisterBee(bee BeeInterface) {
	log.Println("Worker bee ready:", bee.Name(), "-", bee.Description())

	bees[bee.Name()] = &bee
}

// Returns module with this name
func GetBee(identifier string) *BeeInterface {
	bee, ok := bees[identifier]
	if ok {
		return bee
	}

	return nil
}

// Starts a bee and recovers from panics
func startBee(bee *BeeInterface, fatals int) {
	if fatals >= 3 {
		log.Println("Terminating evil bee", (*bee).Name(), "after", fatals, "failed tries!")
		return
	}

	defer func(bee *BeeInterface) {
		if e := recover(); e != nil {
			log.Println("Fatal bee event:", e, fatals)
			startBee(bee, fatals+1)
		}
	}(bee)

	defer (*bee).WaitGroup().Done()
	(*bee).Run(eventsIn)
}

// Starts all registered bees
func StartBees(beeList []BeeInstance) {
	eventsIn = make(chan Event)
	go handleEvents()

	for _, bee := range beeList {
		factory := GetFactory(bee.Class)
		if factory == nil {
			panic("Unknown bee-class in config file: " + bee.Class)
		}
		mod := (*factory).New(bee.Name, bee.Description, bee.Options)
		RegisterBee(mod)
	}

	for _, m := range bees {
		go func(mod *BeeInterface) {
			startBee(mod, 0)
		}(m)
	}
}

// Stops all bees gracefully
func StopBees() {
	for _, bee := range bees {
		log.Println("Stopping bee:", (*bee).Name())
		(*bee).Stop()
	}

	close(eventsIn)
	bees = make(map[string]*BeeInterface)
}

// Stops all running bees and restarts a new set of bees
func RestartBees(bees []BeeInstance) {
	StopBees()
	StartBees(bees)
}

// Returns a new bee and sets up sig-channel & waitGroup
func NewBee(name, factoryName, description string) Bee {
	b := Bee{
		BeeName:        name,
		BeeNamespace:   factoryName,
		BeeDescription: description,
		SigChan:        make(chan bool),
		waitGroup:      &sync.WaitGroup{},
	}
	b.waitGroup.Add(1)

	return b
}

// Getter for chains
func Chains() []Chain {
	return chains
}

// Setter for chains
func SetChains(cs []Chain) {
	chains = cs
}

func init() {
	log.Println("Waking the bees...")
}
<commit_msg>Rename module to bee in comments.<commit_after>/*
 *    Copyright (C) 2014 Christian Muehlhaeuser
 *
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU Affero General Public License as published
 *    by the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *    Authors:
 *      Christian Muehlhaeuser <muesli@gmail.com>
 */

// beehive's central module system.
package bees

import (
	"log"
	"sync"
)

// Interface which all bees need to implement
type BeeInterface interface {
	// Name of the bee
	Name() string
	// Namespace of the bee
	Namespace() string
	// Description of the bee
	Description() string

	// Activates the bee
	Run(eventChannel chan Event)
	// Stop the bee
	Stop()

	WaitGroup() *sync.WaitGroup

	// Handles an action
	Action(action Action) []Placeholder
}

// Base-struct to be embedded by bee implementations
type Bee struct {
	BeeName        string
	BeeNamespace   string
	BeeDescription string

	SigChan   chan bool
	waitGroup *sync.WaitGroup
}

// An instance of a bee
type BeeInstance struct {
	Name        string
	Class       string
	Description string
	Options     []BeeOption
}

// An Event
type Event struct {
	Bee     string
	Name    string
	Options []Placeholder
}

// An Action
type Action struct {
	Bee     string
	Name    string
	Options []Placeholder
}

// A Filter
type Filter struct {
	Name    string
	Options []FilterOption
}

// A Placeholder used by ins & outs of a bee.
type Placeholder struct {
	Name  string
	Type  string
	Value interface{}
}

var (
	eventsIn                                  = make(chan Event)
	bees      map[string]*BeeInterface        = make(map[string]*BeeInterface)
	factories map[string]*BeeFactoryInterface = make(map[string]*BeeFactoryInterface)
	chains    []Chain
)

// Handles incoming events and executes matching Chains.
func handleEvents() {
	for {
		event, ok := <-eventsIn
		if !ok {
			log.Println()
			log.Println("Stopped event handler!")
			break
		}

		log.Println()
		log.Println("Event received:", event.Bee, "/", event.Name, "-", GetEventDescriptor(&event).Description)
		for _, v := range event.Options {
			log.Println("\tOptions:", v)
		}

		go func() {
			defer func() {
				if e := recover(); e != nil {
					log.Println("Fatal chain event:", e)
				}
			}()

			execChains(&event)
		}()
	}
}

// Bees need to call this method to register themselves
func RegisterBee(bee BeeInterface) {
	log.Println("Worker bee ready:", bee.Name(), "-", bee.Description())

	bees[bee.Name()] = &bee
}

// Returns bee with this name
func GetBee(identifier string) *BeeInterface {
	bee, ok := bees[identifier]
	if ok {
		return bee
	}

	return nil
}

// Starts a bee and recovers from panics
func startBee(bee *BeeInterface, fatals int) {
	if fatals >= 3 {
		log.Println("Terminating evil bee", (*bee).Name(), "after", fatals, "failed tries!")
		return
	}

	defer func(bee *BeeInterface) {
		if e := recover(); e != nil {
			log.Println("Fatal bee event:", e, fatals)
			startBee(bee, fatals+1)
		}
	}(bee)

	defer (*bee).WaitGroup().Done()
	(*bee).Run(eventsIn)
}

// Starts all registered bees
func StartBees(beeList []BeeInstance) {
	eventsIn = make(chan Event)
	go handleEvents()

	for _, bee := range beeList {
		factory := GetFactory(bee.Class)
		if factory == nil {
			panic("Unknown bee-class in config file: " + bee.Class)
		}
		mod := (*factory).New(bee.Name, bee.Description, bee.Options)
		RegisterBee(mod)
	}

	for _, m := range bees {
		go func(mod *BeeInterface) {
			startBee(mod, 0)
		}(m)
	}
}

// Stops all bees gracefully
func StopBees() {
	for _, bee := range bees {
		log.Println("Stopping bee:", (*bee).Name())
		(*bee).Stop()
	}

	close(eventsIn)
	bees = make(map[string]*BeeInterface)
}

// Stops all running bees and restarts a new set of bees
func RestartBees(bees []BeeInstance) {
	StopBees()
	StartBees(bees)
}

// Returns a new bee and sets up sig-channel & waitGroup
func NewBee(name, factoryName, description string) Bee {
	b := Bee{
		BeeName:        name,
		BeeNamespace:   factoryName,
		BeeDescription: description,
		SigChan:        make(chan bool),
		waitGroup:      &sync.WaitGroup{},
	}
	b.waitGroup.Add(1)

	return b
}

// Getter for chains
func Chains() []Chain {
	return chains
}

// Setter for chains
func SetChains(cs []Chain) {
	chains = cs
}

func init() {
	log.Println("Waking the bees...")
}
<|endoftext|>


<commit_before>package docker

import (
	"context"
	"sync"

	"github.com/docker/docker/api/types/events"
)

//SourceType is a representation of the sources types that might emit Docker events
type SourceType string

//ContainerSource for events emitted by Docker containers
var ContainerSource = SourceType("container")

//DaemonSource for events emitted by the Docker daemon
var DaemonSource = SourceType("daemon")

//ImageSource for events emitted by Docker images
var ImageSource = SourceType("image")

//NetworkSource for events emitted by Docker networks
var NetworkSource = SourceType("network")

//PluginSource for events emitted by Docker plugins
var PluginSource = SourceType("plugin")

//VolumeSource for events emitted by Docker volumes
var VolumeSource = SourceType("volume")

//ServiceSource for events emitted by Docker services
var ServiceSource = SourceType("service")

//NodeSource for events emitted by Docker nodes
var NodeSource = SourceType("node")

//SecretSource for events emitted by Docker secrets
var SecretSource = SourceType("secret")

//CallbackRegistry d
type CallbackRegistry interface {
	Register(actor SourceType, callback EventCallback)
}

//GlobalRegistry is a globally available CallbackRegistry
var GlobalRegistry CallbackRegistry

//callbackNotifier should be registered to receive events from Docker
var callbackNotifier EventCallback

func init() {
	r := &registry{actions: make(map[SourceType][]EventCallback)}
	GlobalRegistry = r
	callbackNotifier = notifyCallbacks(r)
}

type registry struct {
	actions map[SourceType][]EventCallback
	sync.RWMutex
}

//Register registers the interest of the given callback on messages from the given source
func (r *registry) Register(source SourceType, callback EventCallback) {
	r.Lock()
	defer r.Unlock()

	r.actions[source] = append(r.actions[source], callback)
}

func notifyCallbacks(r *registry) EventCallback {
	return func(ctx context.Context, message events.Message) error {
		r.RLock()
		defer r.RUnlock()
		actor := SourceType(message.Type)
		for _, callback := range r.actions[actor] {
			select {
			case <-ctx.Done():
				return ctx.Err()
			default:
				go callback(ctx, message)
			}
		}
		return nil
	}
}
<commit_msg>Minor<commit_after>package docker

import (
	"context"
	"sync"

	"github.com/docker/docker/api/types/events"
)

//SourceType is a representation of the sources types that might emit Docker events
type SourceType string

const (
	//ContainerSource for events emitted by Docker containers
	ContainerSource = SourceType("container")

	//DaemonSource for events emitted by the Docker daemon
	DaemonSource = SourceType("daemon")

	//ImageSource for events emitted by Docker images
	ImageSource = SourceType("image")

	//NetworkSource for events emitted by Docker networks
	NetworkSource = SourceType("network")

	//PluginSource for events emitted by Docker plugins
	PluginSource = SourceType("plugin")

	//VolumeSource for events emitted by Docker volumes
	VolumeSource = SourceType("volume")

	//ServiceSource for events emitted by Docker services
	ServiceSource = SourceType("service")

	//NodeSource for events emitted by Docker nodes
	NodeSource = SourceType("node")

	//SecretSource for events emitted by Docker secrets
	SecretSource = SourceType("secret")
)

//CallbackRegistry d
type CallbackRegistry interface {
	Register(actor SourceType, callback EventCallback)
}

//GlobalRegistry is a globally available CallbackRegistry
var GlobalRegistry CallbackRegistry

//callbackNotifier should be registered to receive events from Docker
var callbackNotifier EventCallback

func init() {
	r := &registry{actions: make(map[SourceType][]EventCallback)}
	GlobalRegistry = r
	callbackNotifier = notifyCallbacks(r)
}

type registry struct {
	actions map[SourceType][]EventCallback
	sync.RWMutex
}

//Register registers the interest of the given callback on messages from the given source
func (r *registry) Register(source SourceType, callback EventCallback) {
	r.Lock()
	defer r.Unlock()

	r.actions[source] = append(r.actions[source], callback)
}

func notifyCallbacks(r *registry) EventCallback {
	return func(ctx context.Context, message events.Message) error {
		r.RLock()
		defer r.RUnlock()
		actor := SourceType(message.Type)
		for _, callback := range r.actions[actor] {
			select {
			case <-ctx.Done():
				return ctx.Err()
			default:
				go callback(ctx, message)
			}
		}
		return nil
	}
}
<|endoftext|>


<commit_before>/*
Package rawSocket provides traffic sniffier using RAW sockets.

Capture traffic from socket using RAW_SOCKET's
http://en.wikipedia.org/wiki/Raw_socket

RAW_SOCKET allow you listen for traffic on any port (e.g. sniffing) because they operate on IP level.

Ports is TCP feature, same as flow control, reliable transmission and etc.

This package implements own TCP layer: TCP packets is parsed using tcp_packet.go, and flow control is managed by tcp_message.go
*/
package rawSocket

import (
	"bytes"
	"encoding/binary"
	"log"
	"net"
	"runtime/debug"
	"strconv"
	"strings"
	"time"
)

// Listener handle traffic capture
type Listener struct {
	// buffer of TCPMessages waiting to be send
	messages map[string]*TCPMessage

	// Expect: 100-continue request is send in 2 tcp messages
	// We store ACK aliases to merge this packets together
	ackAliases map[uint32]uint32
	// To get ACK of second message we need to compute its Seq and wait for them message
	seqWithData map[uint32]uint32

	respAliases map[uint32]*request

	// Messages ready to be send to client
	packetsChan chan *TCPPacket

	// Messages ready to be send to client
	messagesChan chan *TCPMessage

	addr string // IP to listen
	port uint16 // Port to listen

	messageExpire time.Duration

	captureResponse bool

	conn net.PacketConn
	quit chan bool
}

type request struct {
	start time.Time
	ack   uint32
}

// NewListener creates and initializes new Listener object
func NewListener(addr string, port string, expire time.Duration, captureResponse bool) (l *Listener) {
	l = &Listener{captureResponse: captureResponse}

	l.packetsChan = make(chan *TCPPacket, 10000)
	l.messagesChan = make(chan *TCPMessage, 10000)
	l.quit = make(chan bool)

	l.messages = make(map[string]*TCPMessage)
	l.ackAliases = make(map[uint32]uint32)
	l.seqWithData = make(map[uint32]uint32)
	l.respAliases = make(map[uint32]*request)

	l.addr = addr
	_port, _ := strconv.Atoi(port)
	l.port = uint16(_port)

	if expire.Nanoseconds() == 0 {
		expire = 2000 * time.Millisecond
	}

	l.messageExpire = expire

	go l.listen()
	go l.readRAWSocket()

	return
}

func (t *Listener) listen() {
	gcTicker := time.Tick(t.messageExpire / 2)

	for {
		select {
		case <-t.quit:
			t.conn.Close()
			return
		// We need to use channels to process each packet to avoid data races
		case packet := <-t.packetsChan:
			t.processTCPPacket(packet)

		case <- gcTicker:
			now := time.Now()

			for _, message := range t.messages {
				if now.Sub(message.Start) >= t.messageExpire {
					t.dispatchMessage(message)
				}
			}
		}
	}
}

func (t *Listener) dispatchMessage(message *TCPMessage) {
	delete(t.ackAliases, message.Ack)
	delete(t.messages, message.ID)

	if !message.IsIncoming {
		delete(t.respAliases, message.Ack)

		// Do not track responses which have no associated requests
		if message.RequestAck == 0 {
			return
		}
	}
	t.messagesChan <- message
}

func (t *Listener) readRAWSocket() {
	conn, e := net.ListenPacket("ip4:tcp", t.addr)
	t.conn = conn

	if e != nil {
		log.Fatal(e)
	}

	defer t.conn.Close()

	buf := make([]byte, 64*1024) // 64kb

	for {
		// Note: ReadFrom receive messages without IP header
		n, addr, err := t.conn.ReadFrom(buf)

		if err != nil {
			if strings.HasSuffix(err.Error(), "closed network connection") {
				return
			} else {
				log.Println("Raw listener error:", err)
				continue
			}
		}

		if n > 0 {
			if t.isValidPacket(buf[:n]) {
				newBuf := make([]byte, n)
				copy(newBuf, buf[:n])

				go func(newBuf []byte) {
					t.packetsChan <- ParseTCPPacket(addr, newBuf)
				}(newBuf)
			}
		}
	}
}

func (t *Listener) isValidPacket(buf []byte) bool {
	// To avoid full packet parsing every time, we manually parsing values needed for packet filtering
	// http://en.wikipedia.org/wiki/Transmission_Control_Protocol
	destPort := binary.BigEndian.Uint16(buf[2:4])
	srcPort := binary.BigEndian.Uint16(buf[0:2])

	// Because RAW_SOCKET can't be bound to port, we have to control it by ourself
	if destPort == t.port || (t.captureResponse && srcPort == t.port) {
		// Get the 'data offset' (size of the TCP header in 32-bit words)
		dataOffset := (buf[12] & 0xF0) >> 4

		// We need only packets with data inside
		// Check that the buffer is larger than the size of the TCP header
		if len(buf) > int(dataOffset*4) {
			// We should create new buffer because go slices is pointers. So buffer data shoud be immutable.
			return true
		}
	}

	return false
}

var bExpect100ContinueCheck = []byte("Expect: 100-continue")
var bPOST = []byte("POST")

// Trying to add packet to existing message or creating new message
//
// For TCP message unique id is Acknowledgment number (see tcp_packet.go)
func (t *Listener) processTCPPacket(packet *TCPPacket) {
	// Don't exit on panic
	defer func() {
		if r := recover(); r != nil {
			log.Println("PANIC: pkg:", r, string(debug.Stack()))
		}
	}()

	var message *TCPMessage

	isIncoming := packet.DestPort == t.port

	if parentAck, ok := t.seqWithData[packet.Seq]; ok {
		t.ackAliases[packet.Ack] = parentAck
		delete(t.seqWithData, packet.Seq)
	}

	if alias, ok := t.ackAliases[packet.Ack]; ok {
		packet.Ack = alias
	}

	var responseRequest *request

	if t.captureResponse && !isIncoming {
		responseRequest, _ = t.respAliases[packet.Ack]
	}

	mID := packet.Addr.String() + strconv.Itoa(int(packet.DestPort)) + strconv.Itoa(int(packet.Ack))

	message, ok := t.messages[mID]

	if !ok {
		message = NewTCPMessage(mID, packet.Ack, isIncoming)
		t.messages[mID] = message

		if !isIncoming && responseRequest != nil {
			message.RequestStart = responseRequest.start
			message.RequestAck = responseRequest.ack
		}
	}

	// Handling Expect: 100-continue requests
	if bytes.Equal(packet.Data[0:4], bPOST) {
		// reading last 20 bytes (not counting CRLF): last header value (if no body presented)
		if bytes.Equal(packet.Data[len(packet.Data)-24:len(packet.Data)-4], bExpect100ContinueCheck) {
			t.seqWithData[packet.Seq+uint32(len(packet.Data))] = packet.Ack

			// Removing `Expect: 100-continue` header
			packet.Data = append(packet.Data[:len(packet.Data)-24], packet.Data[len(packet.Data)-2:]...)
		}
	}

	if t.captureResponse && isIncoming {
		// If message have multiple packets, delete previous alias
		if len(message.packets) > 0 {
			delete(t.respAliases, message.ResponseAck)
		}

		responseAck := packet.Seq + uint32(len(packet.Data))
		t.respAliases[responseAck] = &request{message.Start, message.Ack}
		message.ResponseAck = responseAck
	}

	// Adding packet to message
	message.AddPacket(packet)

	// If message contains only single packet immediately dispatch it
	if !message.IsMultipart() {
		t.dispatchMessage(message)
	}
}

// Receive TCP messages from the listener channel
func (t *Listener) Receive() *TCPMessage {
	return <-t.messagesChan
}

func (t *Listener) Close() {
	close(t.quit)
	t.conn.Close()
	return
}
<commit_msg>Add more debug<commit_after>/*
Package rawSocket provides traffic sniffier using RAW sockets.

Capture traffic from socket using RAW_SOCKET's
http://en.wikipedia.org/wiki/Raw_socket

RAW_SOCKET allow you listen for traffic on any port (e.g. sniffing) because they operate on IP level.

Ports is TCP feature, same as flow control, reliable transmission and etc.

This package implements own TCP layer: TCP packets is parsed using tcp_packet.go, and flow control is managed by tcp_message.go
*/
package rawSocket

import (
	"bytes"
	"encoding/binary"
	"log"
	"net"
	"runtime/debug"
	"strconv"
	"strings"
	"time"
)

// Listener handle traffic capture
type Listener struct {
	// buffer of TCPMessages waiting to be send
	messages map[string]*TCPMessage

	// Expect: 100-continue request is send in 2 tcp messages
	// We store ACK aliases to merge this packets together
	ackAliases map[uint32]uint32
	// To get ACK of second message we need to compute its Seq and wait for them message
	seqWithData map[uint32]uint32

	respAliases map[uint32]*request

	// Messages ready to be send to client
	packetsChan chan *TCPPacket

	// Messages ready to be send to client
	messagesChan chan *TCPMessage

	addr string // IP to listen
	port uint16 // Port to listen

	messageExpire time.Duration

	captureResponse bool

	conn net.PacketConn
	quit chan bool
}

type request struct {
	start time.Time
	ack   uint32
}

// NewListener creates and initializes new Listener object
func NewListener(addr string, port string, expire time.Duration, captureResponse bool) (l *Listener) {
	l = &Listener{captureResponse: captureResponse}

	l.packetsChan = make(chan *TCPPacket, 10000)
	l.messagesChan = make(chan *TCPMessage, 10000)
	l.quit = make(chan bool)

	l.messages = make(map[string]*TCPMessage)
	l.ackAliases = make(map[uint32]uint32)
	l.seqWithData = make(map[uint32]uint32)
	l.respAliases = make(map[uint32]*request)

	l.addr = addr
	_port, _ := strconv.Atoi(port)
	l.port = uint16(_port)

	if expire.Nanoseconds() == 0 {
		expire = 2000 * time.Millisecond
	}

	l.messageExpire = expire

	go l.listen()
	go l.readRAWSocket()

	return
}

func (t *Listener) listen() {
	gcTicker := time.Tick(t.messageExpire / 2)

	for {
		select {
		case <-t.quit:
			t.conn.Close()
			return
		// We need to use channels to process each packet to avoid data races
		case packet := <-t.packetsChan:
			t.processTCPPacket(packet)

		case <- gcTicker:
			now := time.Now()

			for _, message := range t.messages {
				if now.Sub(message.Start) >= t.messageExpire {
					t.dispatchMessage(message)
				}
			}
		}
	}
}

func (t *Listener) dispatchMessage(message *TCPMessage) {
	delete(t.ackAliases, message.Ack)
	delete(t.messages, message.ID)

	if !message.IsIncoming {
		delete(t.respAliases, message.Ack)

		// Do not track responses which have no associated requests
		if message.RequestAck == 0 {
			return
		}
	}
	t.messagesChan <- message
}

func (t *Listener) readRAWSocket() {
	conn, e := net.ListenPacket("ip4:tcp", t.addr)
	t.conn = conn

	if e != nil {
		log.Fatal(e)
	}

	defer t.conn.Close()

	buf := make([]byte, 64*1024) // 64kb

	for {
		// Note: ReadFrom receive messages without IP header
		n, addr, err := t.conn.ReadFrom(buf)

		if err != nil {
			if strings.HasSuffix(err.Error(), "closed network connection") {
				return
			} else {
				log.Println("Raw listener error:", err)
				continue
			}
		}

		if n > 0 {
			if t.isValidPacket(buf[:n]) {
				newBuf := make([]byte, n)
				copy(newBuf, buf[:n])

				go func(newBuf []byte) {
					t.packetsChan <- ParseTCPPacket(addr, newBuf)
				}(newBuf)
			}
		}
	}
}

func (t *Listener) isValidPacket(buf []byte) bool {
	// To avoid full packet parsing every time, we manually parsing values needed for packet filtering
	// http://en.wikipedia.org/wiki/Transmission_Control_Protocol
	destPort := binary.BigEndian.Uint16(buf[2:4])
	srcPort := binary.BigEndian.Uint16(buf[0:2])

	// Because RAW_SOCKET can't be bound to port, we have to control it by ourself
	if destPort == t.port || (t.captureResponse && srcPort == t.port) {
		// Get the 'data offset' (size of the TCP header in 32-bit words)
		dataOffset := (buf[12] & 0xF0) >> 4

		// We need only packets with data inside
		// Check that the buffer is larger than the size of the TCP header
		if len(buf) > int(dataOffset*4) {
			// We should create new buffer because go slices is pointers. So buffer data shoud be immutable.
			return true
		}
	}

	return false
}

var bExpect100ContinueCheck = []byte("Expect: 100-continue")
var bPOST = []byte("POST")

// Trying to add packet to existing message or creating new message
//
// For TCP message unique id is Acknowledgment number (see tcp_packet.go)
func (t *Listener) processTCPPacket(packet *TCPPacket) {
	// Don't exit on panic
	defer func() {
		if r := recover(); r != nil {
			log.Println("PANIC: pkg:", r, packet, string(debug.Stack()))
		}
	}()

	var message *TCPMessage

	isIncoming := packet.DestPort == t.port

	if parentAck, ok := t.seqWithData[packet.Seq]; ok {
		t.ackAliases[packet.Ack] = parentAck
		delete(t.seqWithData, packet.Seq)
	}

	if alias, ok := t.ackAliases[packet.Ack]; ok {
		packet.Ack = alias
	}

	var responseRequest *request

	if t.captureResponse && !isIncoming {
		responseRequest, _ = t.respAliases[packet.Ack]
	}

	mID := packet.Addr.String() + strconv.Itoa(int(packet.DestPort)) + strconv.Itoa(int(packet.Ack))

	message, ok := t.messages[mID]

	if !ok {
		message = NewTCPMessage(mID, packet.Ack, isIncoming)
		t.messages[mID] = message

		if !isIncoming && responseRequest != nil {
			message.RequestStart = responseRequest.start
			message.RequestAck = responseRequest.ack
		}
	}

	// Handling Expect: 100-continue requests
	if bytes.Equal(packet.Data[0:4], bPOST) {
		// reading last 20 bytes (not counting CRLF): last header value (if no body presented)
		if bytes.Equal(packet.Data[len(packet.Data)-24:len(packet.Data)-4], bExpect100ContinueCheck) {
			t.seqWithData[packet.Seq+uint32(len(packet.Data))] = packet.Ack

			// Removing `Expect: 100-continue` header
			packet.Data = append(packet.Data[:len(packet.Data)-24], packet.Data[len(packet.Data)-2:]...)
		}
	}

	if t.captureResponse && isIncoming {
		// If message have multiple packets, delete previous alias
		if len(message.packets) > 0 {
			delete(t.respAliases, message.ResponseAck)
		}

		responseAck := packet.Seq + uint32(len(packet.Data))
		t.respAliases[responseAck] = &request{message.Start, message.Ack}
		message.ResponseAck = responseAck
	}

	// Adding packet to message
	message.AddPacket(packet)

	// If message contains only single packet immediately dispatch it
	if !message.IsMultipart() {
		t.dispatchMessage(message)
	}
}

// Receive TCP messages from the listener channel
func (t *Listener) Receive() *TCPMessage {
	return <-t.messagesChan
}

func (t *Listener) Close() {
	close(t.quit)
	t.conn.Close()
	return
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Company 0, LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package account

import (
	"io/ioutil"
	"path/filepath"
	"testing"
	"time"

	"github.com/companyzero/zkc/zkidentity"
)

var (
	a *Account
)

func init() {
	root, err := ioutil.TempDir("", "zkserver")
	if err != nil {
		panic(err)
	}
	a, err = New(root)
	if err != nil {
		panic(err)
	}
}

func TestCreate(t *testing.T) {
	t.Logf("tmpdir: %v", a.root)
	pi := zkidentity.PublicIdentity{}
	err := a.Create(pi, false)
	if err != nil {
		t.Fatal(err)
	}
}

func TestDeliver(t *testing.T) {
	to := zkidentity.PublicIdentity{}
	from := zkidentity.PublicIdentity{}
	from.Identity[0] = 1
	from.Identity[31] = 32

	// 0
	id, err := a.Deliver(to.Identity, from.Identity, []byte("payload0"))
	if err != nil {
		t.Fatal(err)
	}
	err = a.Delete(to.Identity, filepath.Base(id))
	if err != nil {
		t.Fatal(err)
	}

	// 1
	id, err = a.Deliver(to.Identity, from.Identity, []byte("payload1"))
	if err != nil {
		t.Fatal(err)
	}
	err = a.Delete(to.Identity, filepath.Base(id))
	if err != nil {
		t.Fatal(err)
	}

	// 1
	id, err = a.Deliver(to.Identity, from.Identity, []byte("payload2"))
	if err != nil {
		t.Fatal(err)
	}
	err = a.Delete(to.Identity, filepath.Base(id))
	if err != nil {
		t.Fatal(err)
	}
}

func TestDeleteDoesntExist(t *testing.T) {
	to := zkidentity.PublicIdentity{}
	err := a.Delete(to.Identity, "moo")
	if err == nil {
		t.Fatal("file should have not existed")
	}
}

func TestNotify(t *testing.T) {
	to := zkidentity.PublicIdentity{}
	from := zkidentity.PublicIdentity{}
	from.Identity[0] = 1
	from.Identity[31] = 32

	c1 := make(chan *Notification, 1)
	err := a.Online(from.Identity, c1)
	if err != nil {
		t.Fatalf("from: %v", err)
	}

	c2 := make(chan *Notification, 1)
	err = a.Online(to.Identity, c2)
	if err != nil {
		t.Fatalf("to: %v", err)
	}

	wait := make(chan bool)
	go func() {
		c1r := false
		c2r := false
		for {
			select {
			case n := <-c1:
				t.Logf("c1: %x -> %x", n.From, n.To)
				c1r = true
			case n := <-c2:
				t.Logf("c2: %x -> %x", n.From, n.To)
				c2r = true
			}

			if c1r && c2r {
				wait <- true
				return
			}
		}
	}()

	// deliver message
	id, err := a.Deliver(to.Identity, from.Identity, []byte("payload0"))
	if err != nil {
		t.Fatal(err)
	}

	select {
	case <-wait:
	case <-time.After(3 * time.Second):
		t.Fatalf("timeout")
	}

	// test offline
	a.Offline(from.Identity)
	a.Offline(to.Identity)

	err = a.Delete(to.Identity, filepath.Base(id))
	if err != nil {
		t.Fatal(err)
	}
}
<commit_msg>Fix tests that were racing. (#4)<commit_after>// Copyright (c) 2016 Company 0, LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package account

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

	"github.com/companyzero/zkc/zkidentity"
)

func newAccount(t *testing.T) (*Account, error) {
	root, err := ioutil.TempDir("", "zkserver")
	if err != nil {
		return nil, err
	}
	t.Logf("tmpdir: %v", root)
	return New(root)
}

func TestCreate(t *testing.T) {
	a, err := newAccount(t)
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(a.root)

	pi := zkidentity.PublicIdentity{}
	err = a.Create(pi, false)
	if err != nil {
		t.Fatal(err)
	}
}

func TestDeliver(t *testing.T) {
	a, err := newAccount(t)
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(a.root)

	to := zkidentity.PublicIdentity{}
	from := zkidentity.PublicIdentity{}
	from.Identity[0] = 1
	from.Identity[31] = 32

	err = a.Create(to, false)
	if err != nil {
		t.Fatal(err)
	}
	err = a.Create(from, false)
	if err != nil {
		t.Fatal(err)
	}

	// 0
	id, err := a.Deliver(to.Identity, from.Identity, []byte("payload0"))
	if err != nil {
		t.Fatal(err)
	}
	err = a.Delete(to.Identity, filepath.Base(id))
	if err != nil {
		t.Fatal(err)
	}

	// 1
	id, err = a.Deliver(to.Identity, from.Identity, []byte("payload1"))
	if err != nil {
		t.Fatal(err)
	}
	err = a.Delete(to.Identity, filepath.Base(id))
	if err != nil {
		t.Fatal(err)
	}

	// 1
	id, err = a.Deliver(to.Identity, from.Identity, []byte("payload2"))
	if err != nil {
		t.Fatal(err)
	}
	err = a.Delete(to.Identity, filepath.Base(id))
	if err != nil {
		t.Fatal(err)
	}
}

func TestDeleteDoesntExist(t *testing.T) {
	a, err := newAccount(t)
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(a.root)

	to := zkidentity.PublicIdentity{}
	err = a.Delete(to.Identity, "moo")
	if err == nil {
		t.Fatal("file should have not existed")
	}
}

func TestNotify(t *testing.T) {
	a, err := newAccount(t)
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(a.root)

	to := zkidentity.PublicIdentity{}
	from := zkidentity.PublicIdentity{}
	from.Identity[0] = 1
	from.Identity[31] = 32

	err = a.Create(to, false)
	if err != nil {
		t.Fatal(err)
	}
	err = a.Create(from, false)
	if err != nil {
		t.Fatal(err)
	}

	c1 := make(chan *Notification, 1)
	c2 := make(chan *Notification, 1)

	var wg sync.WaitGroup
	wg.Add(2)
	go func() {
		c1r := false
		c2r := false
		for {
			select {
			case n, ok := <-c1:
				if !ok {
					return
				}
				c1r = true
				t.Logf("c1: %x -> %x", n.From, n.To)
				wg.Add(-1)
			case n, ok := <-c2:
				if !ok {
					return
				}
				c2r = true
				t.Logf("c2: %x -> %x", n.From, n.To)
				wg.Add(-1)
			}
			if c1r && c2r {
				return
			}
		}
	}()

	err = a.Online(from.Identity, c1)
	if err != nil {
		t.Fatalf("from: %v", err)
	}

	err = a.Online(to.Identity, c2)
	if err != nil {
		t.Fatalf("to: %v", err)
	}

	// deliver message
	id, err := a.Deliver(to.Identity, from.Identity, []byte("payload0"))
	if err != nil {
		t.Fatal(err)
	}
	id2, err := a.Deliver(from.Identity, to.Identity, []byte("payload1"))
	if err != nil {
		t.Fatal(err)
	}

	wg.Wait()

	// test offline
	a.Offline(from.Identity)
	a.Offline(to.Identity)

	err = a.Delete(to.Identity, filepath.Base(id))
	if err != nil {
		t.Fatal(err)
	}

	err = a.Delete(from.Identity, filepath.Base(id2))
	if err != nil {
		t.Fatal(err)
	}
}
<|endoftext|>


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

// createmock is used to generate source code for mock versions of interfaces
// from installed packages.
package main

import (
	"errors"
	"flag"
	"fmt"
	"go/build"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path"
	"regexp"
	"text/template"

	// Ensure that the generate package, which is used by the generated code, is
	// installed by goinstall.
	_ "github.com/jacobsa/oglemock/generate"
)

// A template for generated code that is used to print the result.
const tmplStr = `
{{$inputPkg := .InputPkg}}
{{$outputPkg := .OutputPkg}}

package main

import (
	{{range $identifier, $import := .Imports}}
		{{$identifier}} "{{$import}}"
	{{end}}
)

func getTypeForPtr(ptr interface{}) reflect.Type {
	return reflect.TypeOf(ptr).Elem()
}

func main() {
	// Reduce noise in logging output.
	log.SetFlags(0)

	interfaces := []reflect.Type{
		{{range $typeName := .TypeNames}}
			getTypeForPtr((*{{base $inputPkg}}.{{$typeName}})(nil)),
		{{end}}
	}

	err := generate.GenerateMockSource(os.Stdout, "{{$outputPkg}}", interfaces)
	if err != nil {
		log.Fatalf("Error generating mock source: %v", err)
	}
}
`

// A map from import identifier to package to use that identifier for,
// containing elements for each import needed by the generated code.
type importMap map[string]string

type tmplArg struct {
	InputPkg  string
	OutputPkg string

	// Imports needed by the generated code.
	Imports importMap

	// Types to be mocked, relative to their package's name.
	TypeNames []string
}

var unknownPackageRegexp = regexp.MustCompile(
	`tool\.go:\d+:\d+: import "([^"]+)": cannot find package`)

var undefinedInterfaceRegexp = regexp.MustCompile(`tool\.go:\d+: undefined: [\pL_0-9]+\.([\pL_0-9]+)`)

// Does the 'go build' output indicate that a package wasn't found? If so,
// return the name of the package.
func findUnknownPackage(output []byte) *string {
	if match := unknownPackageRegexp.FindSubmatch(output); match != nil {
		res := string(match[1])
		return &res
	}

	return nil
}

// Does the 'go build' output indicate that an interface wasn't found? If so,
// return the name of the interface.
func findUndefinedInterface(output []byte) *string {
	if match := undefinedInterfaceRegexp.FindSubmatch(output); match != nil {
		res := string(match[1])
		return &res
	}

	return nil
}

// Split out from main so that deferred calls are executed even in the event of
// an error.
func run() error {
	// Reduce noise in logging output.
	log.SetFlags(0)

	// Check the command-line arguments.
	flag.Parse()

	cmdLineArgs := flag.Args()
	if len(cmdLineArgs) < 2 {
		return errors.New("Usage: createmock [package] [interface ...]")
	}

	// Create a temporary directory inside of $GOPATH to hold generated code.
	buildPkg, err := build.Import("github.com/jacobsa/oglemock", "", build.FindOnly)
	if err != nil {
		return errors.New(fmt.Sprintf("Couldn't find oglemock in $GOPATH: %v", err))
	}

	tmpDir, err := ioutil.TempDir(buildPkg.SrcRoot, "tmp-createmock-")
	if err != nil {
		return errors.New(fmt.Sprintf("Creating temp dir: %v", err))
	}

	defer os.RemoveAll(tmpDir)

	// Create a file to hold generated code.
	codeFile, err := os.Create(path.Join(tmpDir, "tool.go"))
	if err != nil {
		return errors.New(fmt.Sprintf("Couldn't create a file to hold code: %v", err))
	}

	// Create an appropriate path for the built binary.
	binaryPath := path.Join(tmpDir, "tool")

	// Create an appropriate template argument.
	var arg tmplArg
	arg.InputPkg = cmdLineArgs[0]
	arg.OutputPkg = "mock_" + path.Base(arg.InputPkg)
	arg.TypeNames = cmdLineArgs[1:]

	arg.Imports = make(importMap)
	arg.Imports[path.Base(arg.InputPkg)] = arg.InputPkg
	arg.Imports["generate"] = "github.com/jacobsa/oglemock/generate"
	arg.Imports["log"] = "log"
	arg.Imports["os"] = "os"
	arg.Imports["reflect"] = "reflect"

	// Execute the template to generate code that will itself generate the mock
	// code. Write the code to the temp file.
	tmpl := template.Must(
		template.New("code").Funcs(
			template.FuncMap{
				"base": path.Base,
			}).Parse(tmplStr))
	if err := tmpl.Execute(codeFile, arg); err != nil {
		return errors.New(fmt.Sprintf("Error executing template: %v", err))
	}

	codeFile.Close()

	// Attempt to build the code.
	cmd := exec.Command("go", "build", "-o", binaryPath)
	cmd.Dir = tmpDir
	buildOutput, err := cmd.CombinedOutput()

	if err != nil {
		// Did the compilation fail due to the user-specified package not being found?
		if pkg := findUnknownPackage(buildOutput); pkg != nil && *pkg == arg.InputPkg {
			return errors.New(fmt.Sprintf("Unknown package: %s", *pkg))
		}

		// Did the compilation fail due to an unknown interface?
		if in := findUndefinedInterface(buildOutput); in != nil {
			return errors.New(fmt.Sprintf("Unknown interface: %s", *in))
		}

		// Otherwise return a generic error.
		return errors.New(fmt.Sprintf(
			"%s\n\nError building generated code:\n\n"+
				"    %v\n\nPlease report this oglemock bug.",
			buildOutput,
			err))
	}

	// Run the binary.
	cmd = exec.Command(binaryPath)
	binaryOutput, err := cmd.CombinedOutput()

	if err != nil {
		return errors.New(fmt.Sprintf(
			"%s\n\nError running generated code:\n\n"+
				"    %v\n\n Please report this oglemock bug.",
			binaryOutput,
			err))
	}

	// Copy its output.
	_, err = os.Stdout.Write(binaryOutput)
	if err != nil {
		return errors.New(fmt.Sprintf("Error copying binary output: %v", err))
	}

	return nil
}

func main() {
	if err := run(); err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}
}
<commit_msg>Fixed 'go build' scraper for Go 1.1.<commit_after>// Copyright 2012 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// createmock is used to generate source code for mock versions of interfaces
// from installed packages.
package main

import (
	"errors"
	"flag"
	"fmt"
	"go/build"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path"
	"regexp"
	"text/template"

	// Ensure that the generate package, which is used by the generated code, is
	// installed by goinstall.
	_ "github.com/jacobsa/oglemock/generate"
)

// A template for generated code that is used to print the result.
const tmplStr = `
{{$inputPkg := .InputPkg}}
{{$outputPkg := .OutputPkg}}

package main

import (
	{{range $identifier, $import := .Imports}}
		{{$identifier}} "{{$import}}"
	{{end}}
)

func getTypeForPtr(ptr interface{}) reflect.Type {
	return reflect.TypeOf(ptr).Elem()
}

func main() {
	// Reduce noise in logging output.
	log.SetFlags(0)

	interfaces := []reflect.Type{
		{{range $typeName := .TypeNames}}
			getTypeForPtr((*{{base $inputPkg}}.{{$typeName}})(nil)),
		{{end}}
	}

	err := generate.GenerateMockSource(os.Stdout, "{{$outputPkg}}", interfaces)
	if err != nil {
		log.Fatalf("Error generating mock source: %v", err)
	}
}
`

// A map from import identifier to package to use that identifier for,
// containing elements for each import needed by the generated code.
type importMap map[string]string

type tmplArg struct {
	InputPkg  string
	OutputPkg string

	// Imports needed by the generated code.
	Imports importMap

	// Types to be mocked, relative to their package's name.
	TypeNames []string
}

var unknownPackageRegexp = regexp.MustCompile(
	`tool\.go:\d+:\d+: cannot find package "([^"]+)"`)

var undefinedInterfaceRegexp = regexp.MustCompile(`tool\.go:\d+: undefined: [\pL_0-9]+\.([\pL_0-9]+)`)

// Does the 'go build' output indicate that a package wasn't found? If so,
// return the name of the package.
func findUnknownPackage(output []byte) *string {
	if match := unknownPackageRegexp.FindSubmatch(output); match != nil {
		res := string(match[1])
		return &res
	}

	return nil
}

// Does the 'go build' output indicate that an interface wasn't found? If so,
// return the name of the interface.
func findUndefinedInterface(output []byte) *string {
	if match := undefinedInterfaceRegexp.FindSubmatch(output); match != nil {
		res := string(match[1])
		return &res
	}

	return nil
}

// Split out from main so that deferred calls are executed even in the event of
// an error.
func run() error {
	// Reduce noise in logging output.
	log.SetFlags(0)

	// Check the command-line arguments.
	flag.Parse()

	cmdLineArgs := flag.Args()
	if len(cmdLineArgs) < 2 {
		return errors.New("Usage: createmock [package] [interface ...]")
	}

	// Create a temporary directory inside of $GOPATH to hold generated code.
	buildPkg, err := build.Import("github.com/jacobsa/oglemock", "", build.FindOnly)
	if err != nil {
		return errors.New(fmt.Sprintf("Couldn't find oglemock in $GOPATH: %v", err))
	}

	tmpDir, err := ioutil.TempDir(buildPkg.SrcRoot, "tmp-createmock-")
	if err != nil {
		return errors.New(fmt.Sprintf("Creating temp dir: %v", err))
	}

	defer os.RemoveAll(tmpDir)

	// Create a file to hold generated code.
	codeFile, err := os.Create(path.Join(tmpDir, "tool.go"))
	if err != nil {
		return errors.New(fmt.Sprintf("Couldn't create a file to hold code: %v", err))
	}

	// Create an appropriate path for the built binary.
	binaryPath := path.Join(tmpDir, "tool")

	// Create an appropriate template argument.
	var arg tmplArg
	arg.InputPkg = cmdLineArgs[0]
	arg.OutputPkg = "mock_" + path.Base(arg.InputPkg)
	arg.TypeNames = cmdLineArgs[1:]

	arg.Imports = make(importMap)
	arg.Imports[path.Base(arg.InputPkg)] = arg.InputPkg
	arg.Imports["generate"] = "github.com/jacobsa/oglemock/generate"
	arg.Imports["log"] = "log"
	arg.Imports["os"] = "os"
	arg.Imports["reflect"] = "reflect"

	// Execute the template to generate code that will itself generate the mock
	// code. Write the code to the temp file.
	tmpl := template.Must(
		template.New("code").Funcs(
			template.FuncMap{
				"base": path.Base,
			}).Parse(tmplStr))
	if err := tmpl.Execute(codeFile, arg); err != nil {
		return errors.New(fmt.Sprintf("Error executing template: %v", err))
	}

	codeFile.Close()

	// Attempt to build the code.
	cmd := exec.Command("go", "build", "-o", binaryPath)
	cmd.Dir = tmpDir
	buildOutput, err := cmd.CombinedOutput()

	if err != nil {
		// Did the compilation fail due to the user-specified package not being found?
		if pkg := findUnknownPackage(buildOutput); pkg != nil && *pkg == arg.InputPkg {
			return errors.New(fmt.Sprintf("Unknown package: %s", *pkg))
		}

		// Did the compilation fail due to an unknown interface?
		if in := findUndefinedInterface(buildOutput); in != nil {
			return errors.New(fmt.Sprintf("Unknown interface: %s", *in))
		}

		// Otherwise return a generic error.
		return errors.New(fmt.Sprintf(
			"%s\n\nError building generated code:\n\n"+
				"    %v\n\nPlease report this oglemock bug.",
			buildOutput,
			err))
	}

	// Run the binary.
	cmd = exec.Command(binaryPath)
	binaryOutput, err := cmd.CombinedOutput()

	if err != nil {
		return errors.New(fmt.Sprintf(
			"%s\n\nError running generated code:\n\n"+
				"    %v\n\n Please report this oglemock bug.",
			binaryOutput,
			err))
	}

	// Copy its output.
	_, err = os.Stdout.Write(binaryOutput)
	if err != nil {
		return errors.New(fmt.Sprintf("Error copying binary output: %v", err))
	}

	return nil
}

func main() {
	if err := run(); err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package servers

import (
	"net/http"
	"os"
	"os/exec"
	"time"

	"github.com/cloudfoundry-incubator/notifications/application"
)

type Notifications struct {
	cmd *exec.Cmd
	env application.Environment
}

func NewNotifications() Notifications {
	env := application.NewEnvironment()
	cmd := exec.Cmd{
		Path: env.RootPath + "/bin/notifications",
		Dir:  env.RootPath,
		//Stdout: os.Stdout, // Uncomment to get server output for debugging
		//Stderr: os.Stderr,
	}

	return Notifications{
		cmd: &cmd,
		env: env,
	}
}

func (s Notifications) Compile() {
	path, err := exec.LookPath("go")
	if err != nil {
		panic(err)
	}

	cmd := exec.Cmd{
		Path:   path,
		Args:   []string{"go", "build", "-o", "bin/notifications", "main.go"},
		Dir:    s.env.RootPath,
		Stdout: os.Stdout,
		Stderr: os.Stderr,
	}
	err = cmd.Run()
	if err != nil {
		panic(err)
	}
}

func (s Notifications) Destroy() {
	err := os.Remove(s.env.RootPath + "/bin/notifications")
	if err != nil {
		panic(err)
	}
}

func (s Notifications) Boot() {
	err := s.cmd.Start()
	if err != nil {
		panic(err)
	}
	s.Ping()
}

func (s Notifications) Ping() {
	timer := time.After(0 * time.Second)
	timeout := time.After(10 * time.Second)
	for {
		select {
		case <-timeout:
			panic("Failed to boot!")
		case <-timer:
			_, err := http.Get("http://localhost:" + s.env.Port + "/info")
			if err == nil {
				return
			}

			timer = time.After(1 * time.Second)
		}
	}
}

func (s Notifications) Close() {
	err := s.cmd.Process.Kill()
	if err != nil {
		panic(err)
	}
}

func (s Notifications) RootPath() string {
	return "http://localhost:" + s.env.Port
}

func (s Notifications) SpacesPath(space string) string {
	return s.RootPath() + "/spaces/" + space
}

func (s Notifications) OrganizationsPath(organization string) string {
	return s.RootPath() + "/organizations/" + organization
}

func (s Notifications) EveryonePath() string {
	return s.RootPath() + "/everyone"
}

func (s Notifications) ScopesPath(scope string) string {
	return s.RootPath() + "/uaa_scopes/" + scope
}

func (s Notifications) UsersPath(user string) string {
	return s.RootPath() + "/users/" + user
}

func (s Notifications) EmailPath() string {
	return s.RootPath() + "/emails"
}

func (s Notifications) NotificationsPath() string {
	return s.RootPath() + "/notifications"
}

func (s Notifications) RegistrationPath() string {
	return s.RootPath() + "/registration"
}

func (s Notifications) UserPreferencesPath() string {
	return s.RootPath() + "/user_preferences"
}

func (s Notifications) SpecificUserPreferencesPath(userGUID string) string {
	return s.RootPath() + "/user_preferences/" + userGUID
}

func (s Notifications) DefaultTemplatePath() string {
	return s.RootPath() + "/default_template"
}

func (s Notifications) TemplatesBasePath() string {
	return s.RootPath() + "/templates"
}

func (s Notifications) TemplatePath(templateID string) string {
	return s.RootPath() + "/templates/" + templateID
}

func (s Notifications) DeprecatedTemplatePath(templateName string) string {
	return s.RootPath() + "/deprecated_templates/" + templateName
}

func (s Notifications) ClientsTemplatePath(clientID string) string {
	return s.RootPath() + "/clients/" + clientID + "/template"
}

func (s Notifications) ClientsNotificationsTemplatePath(clientID, notificationID string) string {
	return s.RootPath() + "/clients/" + clientID + "/notifications/" + notificationID + "/template"
}
<commit_msg>Toggles acceptance test suite server output using TRACE env var<commit_after>package servers

import (
	"net/http"
	"os"
	"os/exec"
	"time"

	"github.com/cloudfoundry-incubator/notifications/application"
)

type Notifications struct {
	cmd *exec.Cmd
	env application.Environment
}

func NewNotifications() Notifications {
	env := application.NewEnvironment()
	cmd := exec.Cmd{
		Path: env.RootPath + "/bin/notifications",
		Dir:  env.RootPath,
	}
	if os.Getenv("TRACE") != "" {
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
	}

	return Notifications{
		cmd: &cmd,
		env: env,
	}
}

func (s Notifications) Compile() {
	path, err := exec.LookPath("go")
	if err != nil {
		panic(err)
	}

	cmd := exec.Cmd{
		Path:   path,
		Args:   []string{"go", "build", "-o", "bin/notifications", "main.go"},
		Dir:    s.env.RootPath,
		Stdout: os.Stdout,
		Stderr: os.Stderr,
	}
	err = cmd.Run()
	if err != nil {
		panic(err)
	}
}

func (s Notifications) Destroy() {
	err := os.Remove(s.env.RootPath + "/bin/notifications")
	if err != nil {
		panic(err)
	}
}

func (s Notifications) Boot() {
	err := s.cmd.Start()
	if err != nil {
		panic(err)
	}
	s.Ping()
}

func (s Notifications) Ping() {
	timer := time.After(0 * time.Second)
	timeout := time.After(10 * time.Second)
	for {
		select {
		case <-timeout:
			panic("Failed to boot!")
		case <-timer:
			_, err := http.Get("http://localhost:" + s.env.Port + "/info")
			if err == nil {
				return
			}

			timer = time.After(1 * time.Second)
		}
	}
}

func (s Notifications) Close() {
	err := s.cmd.Process.Kill()
	if err != nil {
		panic(err)
	}
}

func (s Notifications) RootPath() string {
	return "http://localhost:" + s.env.Port
}

func (s Notifications) SpacesPath(space string) string {
	return s.RootPath() + "/spaces/" + space
}

func (s Notifications) OrganizationsPath(organization string) string {
	return s.RootPath() + "/organizations/" + organization
}

func (s Notifications) EveryonePath() string {
	return s.RootPath() + "/everyone"
}

func (s Notifications) ScopesPath(scope string) string {
	return s.RootPath() + "/uaa_scopes/" + scope
}

func (s Notifications) UsersPath(user string) string {
	return s.RootPath() + "/users/" + user
}

func (s Notifications) EmailPath() string {
	return s.RootPath() + "/emails"
}

func (s Notifications) NotificationsPath() string {
	return s.RootPath() + "/notifications"
}

func (s Notifications) RegistrationPath() string {
	return s.RootPath() + "/registration"
}

func (s Notifications) UserPreferencesPath() string {
	return s.RootPath() + "/user_preferences"
}

func (s Notifications) SpecificUserPreferencesPath(userGUID string) string {
	return s.RootPath() + "/user_preferences/" + userGUID
}

func (s Notifications) DefaultTemplatePath() string {
	return s.RootPath() + "/default_template"
}

func (s Notifications) TemplatesBasePath() string {
	return s.RootPath() + "/templates"
}

func (s Notifications) TemplatePath(templateID string) string {
	return s.RootPath() + "/templates/" + templateID
}

func (s Notifications) DeprecatedTemplatePath(templateName string) string {
	return s.RootPath() + "/deprecated_templates/" + templateName
}

func (s Notifications) ClientsTemplatePath(clientID string) string {
	return s.RootPath() + "/clients/" + clientID + "/template"
}

func (s Notifications) ClientsNotificationsTemplatePath(clientID, notificationID string) string {
	return s.RootPath() + "/clients/" + clientID + "/notifications/" + notificationID + "/template"
}
<|endoftext|>


<commit_before>package vlog

import (
	"fmt"
	"reflect"
	"sync/atomic"

	"github.com/cosmosnicolaou/llog"
)

// LogCall logs that its caller has been called given the arguments
// passed to it.  It returns a function that is supposed to be called
// when the caller returns, logging the caller’s return along with the
// arguments it is provided with.
// File name and line number of the call site and a randomly generated
// invocation identifier is logged automatically.  The path through which
// the caller function returns will be logged automatically too.
//
// The canonical way to use LogCall is along the lines of the following:
//
//     func Function(a Type1, b Type2) ReturnType {
//         defer vlog.LogCall(a, b)()
//         // ... function body ...
//         return retVal
//     }
//
// To log the return value as the function returns, the following
// pattern should be used.  Note that pointers to the output
// variables should be passed to the returning function, not the
// variables themselves:
//
//     func Function(a Type1, b Type2) (r ReturnType) {
//         defer vlog.LogCall(a, b)(&r)
//         // ... function body ...
//         return computeReturnValue()
//     }
//
// Note that when using this pattern, you do not need to actually
// assign anything to the named return variable explicitly.  A regular
// return statement would automatically do the proper return variable
// assignments.
//
// The log injector tool will automatically insert a LogCall invocation
// into all implementations of the public API it runs, unless a Valid
// Log Construct is found.  A Valid Log Construct is defined as of the
// following at the beginning of the function body (i.e. should not be
// preceded by any non-whitespace or non-comment tokens):
//     1. defer vlog.LogCall(optional arguments)(optional pointers to return values)
//     2. defer vlog.LogCallf(argsFormat, optional arguments)(returnValuesFormat, optional pointers to return values)
//     3. // nologcall
//
// The comment "// nologcall" is used to silence the static analysis
// and not warn about the lack of a LogCall or LogCallf statement within
// a function.  It also prevents the log injector to inject a LogCall
// invocation in a function.  It is used as follows:
//
//     func FunctionWithoutLogging(args ...interface{}) {
//         // nologcall
//         // ... function body ...
//     }
//
func LogCall(v ...interface{}) func(...interface{}) {
	invocationId := newInvocationIdentifier()
	if len(v) > 0 {
		Log.log.Printf(llog.InfoLog, "call[%s]: args:%v", invocationId, v)
	} else {
		Log.log.Printf(llog.InfoLog, "call[%s]", invocationId)
	}
	return func(v ...interface{}) {
		if len(v) > 0 {
			Log.log.Printf(llog.InfoLog, "return[%s]: %v", invocationId, derefSlice(v))
		} else {
			Log.log.Printf(llog.InfoLog, "return[%s]", invocationId)
		}
	}
}

// LogCallf behaves identically to LogCall, except it lets the caller to
// customize the log messages via format specifiers, like the following:
//
//     func Function(a Type1, b Type2) (r, t ReturnType) {
//         defer vlog.LogCallf("a: %v, b: %v", a, b)("(r,t)=(%v,%v)", &r, &t)
//         // ... function body ...
//         return finalR, finalT
//     }
//
func LogCallf(format string, v ...interface{}) func(string, ...interface{}) {
	invocationId := newInvocationIdentifier()
	Log.log.Printf(llog.InfoLog, "call[%s]: %s", invocationId, fmt.Sprintf(format, v...))
	return func(format string, v ...interface{}) {
		Log.log.Printf(llog.InfoLog, "return[%s]: %v", invocationId, fmt.Sprintf(format, derefSlice(v)...))
	}
}

func derefSlice(slice []interface{}) []interface{} {
	o := make([]interface{}, 0, len(slice))
	for _, x := range slice {
		o = append(o, reflect.Indirect(reflect.ValueOf(x)).Interface())
	}
	return o
}

var invocationCounter uint64 = 0

func newInvocationIdentifier() string {
	const (
		charSet    = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"
		charSetLen = uint64(len(charSet))
	)
	r := []byte{'@'}
	for n := atomic.AddUint64(&invocationCounter, 1); n > 0; n /= charSetLen {
		r = append(r, charSet[n%charSetLen])
	}
	return string(r)
}
<commit_msg>veyron2/vlog: Improved documentation for the public API logging functions<commit_after>package vlog

import (
	"fmt"
	"reflect"
	"sync/atomic"

	"github.com/cosmosnicolaou/llog"
)

// LogCall logs that its caller has been called given the arguments
// passed to it.  It returns a function that is supposed to be called
// when the caller returns, logging the caller’s return along with the
// arguments it is provided with.
// File name and line number of the call site and a randomly generated
// invocation identifier is logged automatically.  The path through which
// the caller function returns will be logged automatically too.
//
// The canonical way to use LogCall is along the lines of the following:
//
//     func Function(a Type1, b Type2) ReturnType {
//         defer vlog.LogCall(a, b)()
//         // ... function body ...
//         return retVal
//     }
//
// To log the return value as the function returns, the following
// pattern should be used.  Note that pointers to the output
// variables should be passed to the returning function, not the
// variables themselves:
//
//     func Function(a Type1, b Type2) (r ReturnType) {
//         defer vlog.LogCall(a, b)(&r)
//         // ... function body ...
//         return computeReturnValue()
//     }
//
// Note that when using this pattern, you do not need to actually
// assign anything to the named return variable explicitly.  A regular
// return statement would automatically do the proper return variable
// assignments.
//
// The log injector tool will automatically insert a LogCall invocation
// into all implementations of the public API it runs, unless a Valid
// Log Construct is found.  A Valid Log Construct is defined as one of
// the following at the beginning of the function body (i.e. should not
// be preceded by any non-whitespace or non-comment tokens):
//     1. defer vlog.LogCall(optional arguments)(optional pointers to return values)
//     2. defer vlog.LogCallf(argsFormat, optional arguments)(returnValuesFormat, optional pointers to return values)
//     3. // nologcall
//
// The comment "// nologcall" serves as a hint to log injection and
// checking tools to exclude the function from their consideration.
// It is used as follows:
//
//     func FunctionWithoutLogging(args ...interface{}) {
//         // nologcall
//         // ... function body ...
//     }
//
func LogCall(v ...interface{}) func(...interface{}) {
	invocationId := newInvocationIdentifier()
	if len(v) > 0 {
		Log.log.Printf(llog.InfoLog, "call[%s]: args:%v", invocationId, v)
	} else {
		Log.log.Printf(llog.InfoLog, "call[%s]", invocationId)
	}
	return func(v ...interface{}) {
		if len(v) > 0 {
			Log.log.Printf(llog.InfoLog, "return[%s]: %v", invocationId, derefSlice(v))
		} else {
			Log.log.Printf(llog.InfoLog, "return[%s]", invocationId)
		}
	}
}

// LogCallf behaves identically to LogCall, except it lets the caller to
// customize the log messages via format specifiers, like the following:
//
//     func Function(a Type1, b Type2) (r, t ReturnType) {
//         defer vlog.LogCallf("a: %v, b: %v", a, b)("(r,t)=(%v,%v)", &r, &t)
//         // ... function body ...
//         return finalR, finalT
//     }
//
func LogCallf(format string, v ...interface{}) func(string, ...interface{}) {
	invocationId := newInvocationIdentifier()
	Log.log.Printf(llog.InfoLog, "call[%s]: %s", invocationId, fmt.Sprintf(format, v...))
	return func(format string, v ...interface{}) {
		Log.log.Printf(llog.InfoLog, "return[%s]: %v", invocationId, fmt.Sprintf(format, derefSlice(v)...))
	}
}

func derefSlice(slice []interface{}) []interface{} {
	o := make([]interface{}, 0, len(slice))
	for _, x := range slice {
		o = append(o, reflect.Indirect(reflect.ValueOf(x)).Interface())
	}
	return o
}

var invocationCounter uint64 = 0

// newInvocationIdentifier generates a unique identifier for a method invocation
// to make it easier to match up log lines for the entry and exit of a function
// when looking at a log transcript.
func newInvocationIdentifier() string {
	const (
		charSet    = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"
		charSetLen = uint64(len(charSet))
	)
	r := []byte{'@'}
	for n := atomic.AddUint64(&invocationCounter, 1); n > 0; n /= charSetLen {
		r = append(r, charSet[n%charSetLen])
	}
	return string(r)
}
<|endoftext|>


<commit_before>package vlog

import (
	"fmt"
	"reflect"
	"sync/atomic"

	"github.com/cosmosnicolaou/llog"
)

// LogCall logs that its caller has been called given the arguments
// passed to it.  It returns a function that is supposed to be called
// when the caller returns, logging the caller’s return along with the
// arguments it is provided with.
// File name and line number of the call site and a randomly generated
// invocation identifier is logged automatically.  The path through which
// the caller function returns will be logged automatically too.
//
// The canonical way to use LogCall is along the lines of the following:
//
//     func Function(a Type1, b Type2) ReturnType {
//         defer vlog.LogCall(a, b)()
//         // ... function body ...
//         return retVal
//     }
//
// To log the return value as the function returns, the following
// pattern should be used.  Note that pointers to the output
// variables should be passed to the returning function, not the
// variables themselves:
//
//     func Function(a Type1, b Type2) (r ReturnType) {
//         defer vlog.LogCall(a, b)(&r)
//         // ... function body ...
//         return computeReturnValue()
//     }
//
// Note that when using this pattern, you do not need to actually
// assign anything to the named return variable explicitly.  A regular
// return statement would automatically do the proper return variable
// assignments.
//
// The log injector tool will automatically insert a LogCall invocation
// into all implementations of the public API it runs, unless a Valid
// Log Construct is found.  A Valid Log Construct is defined as one of
// the following at the beginning of the function body (i.e. should not
// be preceded by any non-whitespace or non-comment tokens):
//     1. defer vlog.LogCall(optional arguments)(optional pointers to return values)
//     2. defer vlog.LogCallf(argsFormat, optional arguments)(returnValuesFormat, optional pointers to return values)
//     3. // nologcall
//
// The comment "// nologcall" serves as a hint to log injection and
// checking tools to exclude the function from their consideration.
// It is used as follows:
//
//     func FunctionWithoutLogging(args ...interface{}) {
//         // nologcall
//         // ... function body ...
//     }
//
func LogCall(v ...interface{}) func(...interface{}) {
	invocationId := newInvocationIdentifier()
	if len(v) > 0 {
		Log.log.Printf(llog.InfoLog, "call[%s]: args:%v", invocationId, v)
	} else {
		Log.log.Printf(llog.InfoLog, "call[%s]", invocationId)
	}
	return func(v ...interface{}) {
		if len(v) > 0 {
			Log.log.Printf(llog.InfoLog, "return[%s]: %v", invocationId, derefSlice(v))
		} else {
			Log.log.Printf(llog.InfoLog, "return[%s]", invocationId)
		}
	}
}

// LogCallf behaves identically to LogCall, except it lets the caller to
// customize the log messages via format specifiers, like the following:
//
//     func Function(a Type1, b Type2) (r, t ReturnType) {
//         defer vlog.LogCallf("a: %v, b: %v", a, b)("(r,t)=(%v,%v)", &r, &t)
//         // ... function body ...
//         return finalR, finalT
//     }
//
func LogCallf(format string, v ...interface{}) func(string, ...interface{}) {
	invocationId := newInvocationIdentifier()
	Log.log.Printf(llog.InfoLog, "call[%s]: %s", invocationId, fmt.Sprintf(format, v...))
	return func(format string, v ...interface{}) {
		Log.log.Printf(llog.InfoLog, "return[%s]: %v", invocationId, fmt.Sprintf(format, derefSlice(v)...))
	}
}

func derefSlice(slice []interface{}) []interface{} {
	o := make([]interface{}, 0, len(slice))
	for _, x := range slice {
		o = append(o, reflect.Indirect(reflect.ValueOf(x)).Interface())
	}
	return o
}

var invocationCounter uint64 = 0

// newInvocationIdentifier generates a unique identifier for a method invocation
// to make it easier to match up log lines for the entry and exit of a function
// when looking at a log transcript.
func newInvocationIdentifier() string {
	const (
		charSet    = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"
		charSetLen = uint64(len(charSet))
	)
	r := []byte{'@'}
	for n := atomic.AddUint64(&invocationCounter, 1); n > 0; n /= charSetLen {
		r = append(r, charSet[n%charSetLen])
	}
	return string(r)
}
<commit_msg>veyron2/vlog: LogCall only at V(3)<commit_after>package vlog

import (
	"fmt"
	"reflect"
	"sync/atomic"

	"github.com/cosmosnicolaou/llog"
)

// logCallLogLevel is the log level beyond which calls are logged.
const logCallLogLevel = 3

// LogCall logs that its caller has been called given the arguments
// passed to it.  It returns a function that is supposed to be called
// when the caller returns, logging the caller’s return along with the
// arguments it is provided with.
// File name and line number of the call site and a randomly generated
// invocation identifier is logged automatically.  The path through which
// the caller function returns will be logged automatically too.
//
// The canonical way to use LogCall is along the lines of the following:
//
//     func Function(a Type1, b Type2) ReturnType {
//         defer vlog.LogCall(a, b)()
//         // ... function body ...
//         return retVal
//     }
//
// To log the return value as the function returns, the following
// pattern should be used.  Note that pointers to the output
// variables should be passed to the returning function, not the
// variables themselves:
//
//     func Function(a Type1, b Type2) (r ReturnType) {
//         defer vlog.LogCall(a, b)(&r)
//         // ... function body ...
//         return computeReturnValue()
//     }
//
// Note that when using this pattern, you do not need to actually
// assign anything to the named return variable explicitly.  A regular
// return statement would automatically do the proper return variable
// assignments.
//
// The log injector tool will automatically insert a LogCall invocation
// into all implementations of the public API it runs, unless a Valid
// Log Construct is found.  A Valid Log Construct is defined as one of
// the following at the beginning of the function body (i.e. should not
// be preceded by any non-whitespace or non-comment tokens):
//     1. defer vlog.LogCall(optional arguments)(optional pointers to return values)
//     2. defer vlog.LogCallf(argsFormat, optional arguments)(returnValuesFormat, optional pointers to return values)
//     3. // nologcall
//
// The comment "// nologcall" serves as a hint to log injection and
// checking tools to exclude the function from their consideration.
// It is used as follows:
//
//     func FunctionWithoutLogging(args ...interface{}) {
//         // nologcall
//         // ... function body ...
//     }
//
func LogCall(v ...interface{}) func(...interface{}) {
	if !V(logCallLogLevel) {
		return func(...interface{}) {}
	}
	invocationId := newInvocationIdentifier()
	if len(v) > 0 {
		Log.log.Printf(llog.InfoLog, "call[%s]: args:%v", invocationId, v)
	} else {
		Log.log.Printf(llog.InfoLog, "call[%s]", invocationId)
	}
	return func(v ...interface{}) {
		if len(v) > 0 {
			Log.log.Printf(llog.InfoLog, "return[%s]: %v", invocationId, derefSlice(v))
		} else {
			Log.log.Printf(llog.InfoLog, "return[%s]", invocationId)
		}
	}
}

// LogCallf behaves identically to LogCall, except it lets the caller to
// customize the log messages via format specifiers, like the following:
//
//     func Function(a Type1, b Type2) (r, t ReturnType) {
//         defer vlog.LogCallf("a: %v, b: %v", a, b)("(r,t)=(%v,%v)", &r, &t)
//         // ... function body ...
//         return finalR, finalT
//     }
//
func LogCallf(format string, v ...interface{}) func(string, ...interface{}) {
	if !V(logCallLogLevel) {
		return func(string, ...interface{}) {}
	}
	invocationId := newInvocationIdentifier()
	Log.log.Printf(llog.InfoLog, "call[%s]: %s", invocationId, fmt.Sprintf(format, v...))
	return func(format string, v ...interface{}) {
		Log.log.Printf(llog.InfoLog, "return[%s]: %v", invocationId, fmt.Sprintf(format, derefSlice(v)...))
	}
}

func derefSlice(slice []interface{}) []interface{} {
	o := make([]interface{}, 0, len(slice))
	for _, x := range slice {
		o = append(o, reflect.Indirect(reflect.ValueOf(x)).Interface())
	}
	return o
}

var invocationCounter uint64 = 0

// newInvocationIdentifier generates a unique identifier for a method invocation
// to make it easier to match up log lines for the entry and exit of a function
// when looking at a log transcript.
func newInvocationIdentifier() string {
	const (
		charSet    = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"
		charSetLen = uint64(len(charSet))
	)
	r := []byte{'@'}
	for n := atomic.AddUint64(&invocationCounter, 1); n > 0; n /= charSetLen {
		r = append(r, charSet[n%charSetLen])
	}
	return string(r)
}
<|endoftext|>


<commit_before>package plugins

import (
	"../../seabird"

	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"net/url"

	"github.com/thoj/go-ircevent"
)

// Basic structures from https://github.com/mlbright/forecast/blob/master/v2/forecast.go
// TODO: cleanup
type DataPoint struct {
	Time                   float64
	Summary                string
	Icon                   string
	SunriseTime            float64
	SunsetTime             float64
	PrecipIntensity        float64
	PrecipIntensityMax     float64
	PrecipIntensityMaxTime float64
	PrecipProbability      float64
	PrecipType             string
	PrecipAccumulation     float64
	Temperature            float64
	TemperatureMin         float64
	TemperatureMinTime     float64
	TemperatureMax         float64
	TemperatureMaxTime     float64
	DewPoint               float64
	WindSpeed              float64
	WindBearing            float64
	CloudCover             float64
	Humidity               float64
	Pressure               float64
	Visibility             float64
	Ozone                  float64
}

type DataBlock struct {
	Summary string
	Icon    string
	Data    []DataPoint
}

type alert struct {
	Title   string
	Expires float64
	URI     string
}

type Flags struct {
	DarkSkyUnavailable string
	DarkSkyStations    []string
	DataPointStations  []string
	ISDStations        []string
	LAMPStations       []string
	METARStations      []string
	METNOLicense       string
	Sources            []string
	Units              string
}

type ForecastResponse struct {
	Latitude  float64
	Longitude float64
	Timezone  string
	Offset    float64
	Currently DataPoint
	Minutely  DataBlock
	Hourly    DataBlock
	Daily     DataBlock
	Alerts    []alert
	Flags     Flags
	APICalls  int
}

// Grabs a lat and lon from a location
type LocationResponse struct {
	Results []struct {
		Address  string `json:"formatted_address"`
		Geometry struct {
			Location struct {
				Lat float64 `json:"lat"`
				Lon float64 `json:"lng"`
			} `json:"location"`
		} `json:"geometry"`
	} `json:"results"`
	Status string `json:"status"`
}

func (p *ForecastPlugin) locationQuery(name string) (*LocationResponse, error) {
	v := url.Values{}
	v.Set("address", name)
	v.Set("sensor", "false")

	u, _ := url.Parse("http://maps.googleapis.com/maps/api/geocode/json")
	u.RawQuery = v.Encode()

	r, err := http.Get(u.String())
	if err != nil {
		return nil, err
	}

	loc := LocationResponse{}
	dec := json.NewDecoder(r.Body)
	defer r.Body.Close()
	dec.Decode(&loc)

	if len(loc.Results) == 0 {
		return nil, errors.New("No location results found")
	} else if len(loc.Results) > 1 {
		// TODO: display results
		return nil, errors.New("More than 1 result")
	}

	return &loc, nil
}

func (p *ForecastPlugin) forecastQuery(m string) (*ForecastResponse, *LocationResponse, error) {
	if m == "" {
		return nil, nil, errors.New("Empty query string")
	}

	loc, err := p.locationQuery(m)
	if err != nil {
		return nil, nil, err
	}

	link := fmt.Sprintf("https://api.forecast.io/forecast/%s/%.4f,%.4f",
		p.Key,
		loc.Results[0].Geometry.Location.Lat,
		loc.Results[0].Geometry.Location.Lon)

	r, err := http.Get(link)
	if err != nil {
		return nil, nil, err
	}

	f := ForecastResponse{}
	dec := json.NewDecoder(r.Body)
	defer r.Body.Close()
	dec.Decode(&f)

	return &f, loc, nil
}

type ForecastPlugin struct {
	Bot *seabird.Bot
	Key string
}

func init() {
	seabird.RegisterPlugin("forecast", NewForecastPlugin)
}

func NewForecastPlugin(b *seabird.Bot, c json.RawMessage) {
	p := &ForecastPlugin{Bot: b}

	err := json.Unmarshal(c, &p.Key)
	if err != nil {
		fmt.Println(err)
	}

	b.RegisterFunction("fforecast", p.ForecastDaily)
	b.RegisterFunction("fweather", p.ForecastCurrent)
}

func (p *ForecastPlugin) ForecastDaily(e *irc.Event) {
	f, l, err := p.forecastQuery(e.Message())
	if err != nil {
		p.Bot.MentionReply(e, "%s", err.Error())
		return
	}

	p.Bot.MentionReply(e, "7 day forecast for %s.", l.Results[0].Address)
	for _, block := range f.Daily.Data {
		p.Bot.MentionReply(e,
			"High %.2f, Low %.2f, %s",
			block.TemperatureMax,
			block.TemperatureMin,
			block.Summary)
	}
}

func (p *ForecastPlugin) ForecastCurrent(e *irc.Event) {
	f, l, err := p.forecastQuery(e.Message())
	if err != nil {
		p.Bot.MentionReply(e, "%s", err.Error())
		return
	}

	p.Bot.MentionReply(e,
		"%s. Currently %.1f. %s.",
		l.Results[0].Address,
		f.Currently.Temperature,
		f.Currently.Summary)
}
<commit_msg>Add humidity to fweather info<commit_after>package plugins

import (
	"../../seabird"

	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"net/url"

	"github.com/thoj/go-ircevent"
)

// Basic structures from https://github.com/mlbright/forecast/blob/master/v2/forecast.go
// TODO: cleanup
type DataPoint struct {
	Time                   float64
	Summary                string
	Icon                   string
	SunriseTime            float64
	SunsetTime             float64
	PrecipIntensity        float64
	PrecipIntensityMax     float64
	PrecipIntensityMaxTime float64
	PrecipProbability      float64
	PrecipType             string
	PrecipAccumulation     float64
	Temperature            float64
	TemperatureMin         float64
	TemperatureMinTime     float64
	TemperatureMax         float64
	TemperatureMaxTime     float64
	DewPoint               float64
	WindSpeed              float64
	WindBearing            float64
	CloudCover             float64
	Humidity               float64
	Pressure               float64
	Visibility             float64
	Ozone                  float64
}

type DataBlock struct {
	Summary string
	Icon    string
	Data    []DataPoint
}

type alert struct {
	Title   string
	Expires float64
	URI     string
}

type Flags struct {
	DarkSkyUnavailable string
	DarkSkyStations    []string
	DataPointStations  []string
	ISDStations        []string
	LAMPStations       []string
	METARStations      []string
	METNOLicense       string
	Sources            []string
	Units              string
}

type ForecastResponse struct {
	Latitude  float64
	Longitude float64
	Timezone  string
	Offset    float64
	Currently DataPoint
	Minutely  DataBlock
	Hourly    DataBlock
	Daily     DataBlock
	Alerts    []alert
	Flags     Flags
	APICalls  int
}

// Grabs a lat and lon from a location
type LocationResponse struct {
	Results []struct {
		Address  string `json:"formatted_address"`
		Geometry struct {
			Location struct {
				Lat float64 `json:"lat"`
				Lon float64 `json:"lng"`
			} `json:"location"`
		} `json:"geometry"`
	} `json:"results"`
	Status string `json:"status"`
}

func (p *ForecastPlugin) locationQuery(name string) (*LocationResponse, error) {
	v := url.Values{}
	v.Set("address", name)
	v.Set("sensor", "false")

	u, _ := url.Parse("http://maps.googleapis.com/maps/api/geocode/json")
	u.RawQuery = v.Encode()

	r, err := http.Get(u.String())
	if err != nil {
		return nil, err
	}

	loc := LocationResponse{}
	dec := json.NewDecoder(r.Body)
	defer r.Body.Close()
	dec.Decode(&loc)

	if len(loc.Results) == 0 {
		return nil, errors.New("No location results found")
	} else if len(loc.Results) > 1 {
		// TODO: display results
		return nil, errors.New("More than 1 result")
	}

	return &loc, nil
}

func (p *ForecastPlugin) forecastQuery(m string) (*ForecastResponse, *LocationResponse, error) {
	if m == "" {
		return nil, nil, errors.New("Empty query string")
	}

	loc, err := p.locationQuery(m)
	if err != nil {
		return nil, nil, err
	}

	link := fmt.Sprintf("https://api.forecast.io/forecast/%s/%.4f,%.4f",
		p.Key,
		loc.Results[0].Geometry.Location.Lat,
		loc.Results[0].Geometry.Location.Lon)

	r, err := http.Get(link)
	if err != nil {
		return nil, nil, err
	}

	f := ForecastResponse{}
	dec := json.NewDecoder(r.Body)
	defer r.Body.Close()
	dec.Decode(&f)

	return &f, loc, nil
}

type ForecastPlugin struct {
	Bot *seabird.Bot
	Key string
}

func init() {
	seabird.RegisterPlugin("forecast", NewForecastPlugin)
}

func NewForecastPlugin(b *seabird.Bot, c json.RawMessage) {
	p := &ForecastPlugin{Bot: b}

	err := json.Unmarshal(c, &p.Key)
	if err != nil {
		fmt.Println(err)
	}

	b.RegisterFunction("fforecast", p.ForecastDaily)
	b.RegisterFunction("fweather", p.ForecastCurrent)
}

func (p *ForecastPlugin) ForecastDaily(e *irc.Event) {
	f, l, err := p.forecastQuery(e.Message())
	if err != nil {
		p.Bot.MentionReply(e, "%s", err.Error())
		return
	}

	p.Bot.MentionReply(e, "7 day forecast for %s.", l.Results[0].Address)
	for _, block := range f.Daily.Data {
		p.Bot.MentionReply(e,
			"High %.2f, Low %.2f, %s, %.f%% Humidity",
			block.TemperatureMax,
			block.TemperatureMin,
			block.Summary,
			block.Humidity)
	}
}

func (p *ForecastPlugin) ForecastCurrent(e *irc.Event) {
	f, l, err := p.forecastQuery(e.Message())
	if err != nil {
		p.Bot.MentionReply(e, "%s", err.Error())
		return
	}

	p.Bot.MentionReply(e,
		"%s. Currently %.1f. %s. %.f%% Humidity",
		l.Results[0].Address,
		f.Currently.Temperature,
		f.Currently.Summary,
		f.Currently.Humidity)
}
<|endoftext|>


<commit_before>package commons

import (
	"bufio"
	"fmt"
	"io"
	"path/filepath"
	"regexp"
)

var hl7SplitToken = regexp.MustCompile("(\\r(\\n|\\x1c)+(\\n\\r)?MSH\\||$)")
var hl7FindStartToken = regexp.MustCompile("(MSH\\||$)")

const scanBufferSize = 10 * 1024 * 1024

// GetHl7Files finds all hl7 files in the current directory and returns the file names as a slice of strings
func GetHl7Files() (matches []string, err error) {
	pattern := "*.hl7"
	fileCnt := 0
	fmt.Println("")
	if matches, err = filepath.Glob(pattern); err == nil {
		for fileCnt, _ = range matches {
			fileCnt++
			if fileCnt == 1 || fileCnt%1000 == 0 {
				fmt.Printf("\rfound %v", fileCnt)
			}
		}
	}
	if fileCnt != 1 && fileCnt%1000 != 0 {
		fmt.Printf("\rfound %v", fileCnt)
	}
	fmt.Println("")
	return matches, err
}

// CrLfSplit implements a split function to deal with hl7 messages in a file, terminated by cr/lf and an optional second lf
func crLfSplit(data []byte, atEOF bool) (advance int, token []byte, err error) {
	if atEOF && len(data) == 0 { // end of file
	} else {
		loc := hl7SplitToken.FindIndex(data) // found record delimiter
		if loc != nil || atEOF {
			nextLoc := hl7FindStartToken.FindIndex(data[1:])
			return nextLoc[0] + 1, data[0:loc[0]], nil
		}
	}
	return advance, token, err // no cr/lf found, either the end or get bigger data and look again
}

func NewBufScanner(r io.Reader) *bufio.Scanner {
	b := bufio.NewScanner(r)
	buf := make([]byte, scanBufferSize)
	b.Buffer(buf, scanBufferSize)
	b.Split(crLfSplit)
	return b
}
<commit_msg>fix: made hl7 record seperator more specific in the hopes of fixing some issues<commit_after>package commons

import (
	"bufio"
	"fmt"
	"io"
	"path/filepath"
	"regexp"
)

var hl7SplitToken = regexp.MustCompile("(\\r(\\n|\\x1c)+(\\n\\r)?MSH\\|\\^\\~\\\\\\&\\||$)")
var hl7FindStartToken = regexp.MustCompile("(MSH\\|\\^\\~\\\\\\&\\||$)")

const scanBufferSize = 10 * 1024 * 1024

// GetHl7Files finds all hl7 files in the current directory and returns the file names as a slice of strings
func GetHl7Files() (matches []string, err error) {
	pattern := "*.hl7"
	fileCnt := 0
	fmt.Println("")
	if matches, err = filepath.Glob(pattern); err == nil {
		for fileCnt, _ = range matches {
			fileCnt++
			if fileCnt == 1 || fileCnt%1000 == 0 {
				fmt.Printf("\rfound %v", fileCnt)
			}
		}
	}
	if fileCnt != 1 && fileCnt%1000 != 0 {
		fmt.Printf("\rfound %v", fileCnt)
	}
	fmt.Println("")
	return matches, err
}

// CrLfSplit implements a split function to deal with hl7 messages in a file, terminated by cr/lf and an optional second lf
func crLfSplit(data []byte, atEOF bool) (advance int, token []byte, err error) {
	if atEOF && len(data) == 0 { // end of file
	} else {
		loc := hl7SplitToken.FindIndex(data) // found record delimiter
		if loc != nil || atEOF {
			nextLoc := hl7FindStartToken.FindIndex(data[1:])
			return nextLoc[0] + 1, data[0:loc[0]], nil
		}
	}
	return advance, token, err // no cr/lf found, either the end or get bigger data and look again
}

func NewBufScanner(r io.Reader) *bufio.Scanner {
	b := bufio.NewScanner(r)
	buf := make([]byte, scanBufferSize)
	b.Buffer(buf, scanBufferSize)
	b.Split(crLfSplit)
	return b
}
<|endoftext|>


<commit_before>package goenocean

import (
	"bytes"
	"encoding/binary"
	"io"
	"time"

	log "github.com/cihub/seelog"
	"github.com/tarm/goserial"
)

type Encoder interface {
	Encode() []byte
}

func Serial(send chan Encoder, recv chan Packet) {
	c := &serial.Config{Name: "/dev/ttyUSB0", Baud: 57600}
	s, err := serial.OpenPort(c)
	if err != nil {
		log.Critical(err)
	}

	response := make(chan Packet, 100)
	go readPackets(s, func(data []byte) {
		reciever(data, recv, response)
	})

	go sender(s, send, response)
}

func sender(data io.Writer, send chan Encoder, response chan Packet) {

	for p := range send {
		gotResponse := make(chan struct{})
		go waitForResponse(gotResponse, response)
		_, err := data.Write(p.Encode())
		//Dont send next until we have a response from the last one
		<-gotResponse
		if err != nil {
			log.Critical(err)
		}
	}
}

func waitForResponse(weGotResponse chan struct{}, response chan Packet) {
	select {
	case p := <-response:
		log.Debugf("We got response after send: % x\n", p.Encode())
		if !bytes.Equal(p.Data(), []byte{0}) {
			log.Errorf("We got RESPONSE error after send: % x\n", p.Encode())
		}
		weGotResponse <- struct{}{}
		return
	case <-time.After(time.Second * 2):
		log.Error("We got TIMOUT after send")
		weGotResponse <- struct{}{}
		return
	}

}

func reciever(data []byte, recv chan Packet, resp chan Packet) {
	p, err := Decode(data)
	log.Debugf("%#v\n", p)
	log.Debugf("%#v\n", p.Header())
	log.Debugf("Data: %#v\n", p.Data())
	if err != nil {
		log.Error("Decode failed :", err)
		return
	}
	if p.PacketType() == PacketTypeResponse {
		resp <- p
	}
	recv <- p
}

func readPackets(rd io.Reader, f func([]byte)) {

	buf := make([]byte, 1)
	var rawPacket []byte
	state := 0
	var length int

	for {
		readLen, err := rd.Read(buf)
		if err != nil {
			if err == io.EOF {
				return
			}
			log.Error("ERROR reading:", err)
			continue
		}

		log.Debugf("% x ", buf)

		if readLen > 0 && buf[0] == 0x55 && state == 0 {
			rawPacket = []byte{}
			state = 1
		}

		rawPacket = append(rawPacket, buf...)

		switch state {
		case 1: //header
			if len(rawPacket) > 5 {
				length = int(binary.BigEndian.Uint16(rawPacket[1:3]))
				state = 2
			}

		case 2: // the rest!
			if len(rawPacket) > 5+length+int(rawPacket[3]) {
				state = 3
			}

		case 3: //data crc
			state = 0
			f(rawPacket)
		}

	}

}
<commit_msg>dont block when telling sender we have a response<commit_after>package goenocean

import (
	"bytes"
	"encoding/binary"
	"io"
	"time"

	log "github.com/cihub/seelog"
	"github.com/tarm/goserial"
)

type Encoder interface {
	Encode() []byte
}

func Serial(send chan Encoder, recv chan Packet) {
	c := &serial.Config{Name: "/dev/ttyUSB0", Baud: 57600}
	s, err := serial.OpenPort(c)
	if err != nil {
		log.Critical(err)
	}

	response := make(chan Packet, 100)
	go readPackets(s, func(data []byte) {
		reciever(data, recv, response)
	})

	go sender(s, send, response)
}

func sender(data io.Writer, send chan Encoder, response chan Packet) {

	for p := range send {
		gotResponse := make(chan struct{})
		go waitForResponse(gotResponse, response)
		_, err := data.Write(p.Encode())
		//Dont send next until we have a response from the last one
		<-gotResponse
		if err != nil {
			log.Critical(err)
		}
	}
}

func waitForResponse(weGotResponse chan struct{}, response chan Packet) {
	select {
	case p := <-response:
		log.Debugf("We got response after send: % x\n", p.Encode())
		if !bytes.Equal(p.Data(), []byte{0}) {
			log.Errorf("We got RESPONSE error after send: % x\n", p.Encode())
		}
		weGotResponse <- struct{}{}
		return
	case <-time.After(time.Second * 2):
		log.Error("We got TIMOUT after send")
		weGotResponse <- struct{}{}
		return
	}

}

func reciever(data []byte, recv chan Packet, resp chan Packet) {
	p, err := Decode(data)
	log.Debugf("%#v\n", p)
	log.Debugf("%#v\n", p.Header())
	log.Debugf("Data: %#v\n", p.Data())
	if err != nil {
		log.Error("Decode failed :", err)
		return
	}
	if p.PacketType() == PacketTypeResponse {
		select { // Nonblocking send just in case
		case resp <- p:
		default:
		}
	}
	recv <- p
}

func readPackets(rd io.Reader, f func([]byte)) {

	buf := make([]byte, 1)
	var rawPacket []byte
	state := 0
	var length int

	for {
		readLen, err := rd.Read(buf)
		if err != nil {
			if err == io.EOF {
				return
			}
			log.Error("ERROR reading:", err)
			continue
		}

		log.Debugf("% x ", buf)

		if readLen > 0 && buf[0] == 0x55 && state == 0 {
			rawPacket = []byte{}
			state = 1
		}

		rawPacket = append(rawPacket, buf...)

		switch state {
		case 1: //header
			if len(rawPacket) > 5 {
				length = int(binary.BigEndian.Uint16(rawPacket[1:3]))
				state = 2
			}

		case 2: // the rest!
			if len(rawPacket) > 5+length+int(rawPacket[3]) {
				state = 3
			}

		case 3: //data crc
			state = 0
			f(rawPacket)
		}

	}

}
<|endoftext|>


<commit_before>package region

import (
    "github.com/johnny-morrice/godelbrot/base"
    "github.com/johnny-morrice/godelbrot/draw"
)

type MockRenderApplication struct {
    base.MockRenderApplication
    draw.MockContextProvider
    MockRegionProvider
}

type MockRegionProvider struct {
    TRegionConfig bool
    TRegionNumericsFactory bool

    RegConfig RegionConfig
    RegionFactory *MockFactory
}

func (mock *MockRegionProvider) RegionConfig() RegionConfig {
    mock.TRegionConfig = true
    return mock.RegConfig
}

func (mock *MockRegionProvider) RegionNumericsFactory() RegionNumericsFactory {
    mock.TRegionNumericsFactory = true
    return mock.RegionFactory
}

type MockFactory struct {
    TBuild bool
    Numerics *MockNumerics
}

func (mock *MockFactory) Build() RegionNumerics {
    mock.TBuild = true
    return mock.Numerics
}<commit_msg>Use abstract factory<commit_after>package region

import (
    "github.com/johnny-morrice/godelbrot/base"
    "github.com/johnny-morrice/godelbrot/draw"
)

type MockRenderApplication struct {
    base.MockRenderApplication
    draw.MockContextProvider
    MockRegionProvider
}

type MockRegionProvider struct {
    TRegionConfig bool
    TRegionNumericsFactory bool

    RegConfig RegionConfig
    RegionFactory RegionNumericsFactory
}

func (mock *MockRegionProvider) RegionConfig() RegionConfig {
    mock.TRegionConfig = true
    return mock.RegConfig
}

func (mock *MockRegionProvider) RegionNumericsFactory() RegionNumericsFactory {
    mock.TRegionNumericsFactory = true
    return mock.RegionFactory
}

type MockFactory struct {
    TBuild bool
    Numerics *MockNumerics
}

func (mock *MockFactory) Build() RegionNumerics {
    mock.TBuild = true
    return mock.Numerics
}<|endoftext|>


<commit_before>package special

import (
	"testing"

	"github.com/ready-steady/assert"
	"github.com/ready-steady/probability"
	"github.com/ready-steady/probability/uniform"
)

func TestIncBeta(t *testing.T) {
	p, q := 2.0, 3.0
	logBeta := LogBeta(p, q)

	points := []float64{
		0.00, 0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45, 0.50,
		0.55, 0.60, 0.65, 0.70, 0.75, 0.80, 0.85, 0.90, 0.95, 1.00,
	}

	values := []float64{
		0.000000000000000e+00,
		1.401875000000000e-02,
		5.230000000000002e-02,
		1.095187500000000e-01,
		1.807999999999999e-01,
		2.617187500000001e-01,
		3.483000000000000e-01,
		4.370187500000001e-01,
		5.248000000000003e-01,
		6.090187500000001e-01,
		6.875000000000000e-01,
		7.585187500000001e-01,
		8.208000000000000e-01,
		8.735187499999999e-01,
		9.163000000000000e-01,
		9.492187500000000e-01,
		9.728000000000000e-01,
		9.880187500000001e-01,
		9.963000000000000e-01,
		9.995187500000000e-01,
		1.000000000000000e+00,
	}

	actual := make([]float64, len(points))

	for i := range points {
		actual[i] = IncBeta(points[i], p, q, logBeta)
	}
	assert.EqualWithin(actual, values, 1e-15, t)

	p, q = 0.1, 0.2
	logBeta = LogBeta(p, q)

	values = []float64{
		0.000000000000000e+00,
		5.095391215346399e-01,
		5.482400859052436e-01,
		5.732625733722232e-01,
		5.925346573554778e-01,
		6.086596697678208e-01,
		6.228433547203172e-01,
		6.357578563479236e-01,
		6.478288604374864e-01,
		6.593557133297501e-01,
		6.705707961028990e-01,
		6.816739425887479e-01,
		6.928567823206671e-01,
		7.043251807250750e-01,
		7.163269829958610e-01,
		7.291961263917867e-01,
		7.434379555965913e-01,
		7.599272566076309e-01,
		7.804880320024465e-01,
		8.104335200313719e-01,
		1.000000000000000e+00,
	}

	for i := range points {
		actual[i] = IncBeta(points[i], p, q, logBeta)
	}
	assert.EqualWithin(actual, values, 2e-15, t)
}

func TestInvIncBeta(t *testing.T) {
	p, q := 1.0, 2.0
	logBeta := LogBeta(p, q)

	points := []float64{
		0.00, 0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45, 0.50,
		0.55, 0.60, 0.65, 0.70, 0.75, 0.80, 0.85, 0.90, 0.95, 1.00,
	}

	values := []float64{
		0.000000000000000e+00,
		0.025320565519104e+00,
		0.051316701949486e+00,
		0.078045554270711e+00,
		0.105572809000084e+00,
		0.133974596215561e+00,
		0.163339973465924e+00,
		0.193774225170145e+00,
		0.225403330758517e+00,
		0.258380151290432e+00,
		0.292893218813452e+00,
		0.329179606750063e+00,
		0.367544467966324e+00,
		0.408392021690038e+00,
		0.452277442494834e+00,
		0.500000000000000e+00,
		0.552786404500042e+00,
		0.612701665379257e+00,
		0.683772233983162e+00,
		0.776393202250021e+00,
		1.000000000000000e+00,
	}

	actual := make([]float64, len(points))

	for i := range points {
		actual[i] = InvIncBeta(points[i], p, q, logBeta)
	}
	assert.EqualWithin(actual, values, 2e-15, t)

	p, q = 0.2, 0.3
	logBeta = LogBeta(p, q)

	values = []float64{
		0.000000000000000e+00,
		2.793072851850660e-06,
		8.937381711316164e-05,
		6.784491773826951e-04,
		2.855345858289119e-03,
		8.684107512129325e-03,
		2.144658503798324e-02,
		4.568556852983932e-02,
		8.683942933344659e-02,
		1.502095712585510e-01,
		2.391350361479824e-01,
		3.527066234122371e-01,
		4.840600731467657e-01,
		6.206841200371190e-01,
		7.474718280552188e-01,
		8.514539745840592e-01,
		9.257428898178934e-01,
		9.707021084050310e-01,
		9.923134416335146e-01,
		9.992341305241808e-01,
		1.000000000000000e+00,
	}

	for i := range points {
		actual[i] = InvIncBeta(points[i], p, q, logBeta)
	}
	assert.EqualWithin(actual, values, 1e-14, t)
}

func BenchmarkIncBeta(b *testing.B) {
	p, q := 0.5, 1.5
	logBeta := LogBeta(p, q)
	points := probability.Sample(uniform.New(0, 1), 1000)

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		for _, x := range points {
			IncBeta(x, p, q, logBeta)
		}
	}
}

func BenchmarkInvIncBeta(b *testing.B) {
	p, q := 0.5, 1.5
	logBeta := LogBeta(p, q)
	points := probability.Sample(uniform.New(0, 1), 1000)

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		for _, α := range points {
			InvIncBeta(α, p, q, logBeta)
		}
	}
}
<commit_msg>Update the usage of probability.Sample<commit_after>package special

import (
	"testing"

	"github.com/ready-steady/assert"
	"github.com/ready-steady/probability"
	"github.com/ready-steady/probability/generator"
	"github.com/ready-steady/probability/uniform"
)

func TestIncBeta(t *testing.T) {
	p, q := 2.0, 3.0
	logBeta := LogBeta(p, q)

	points := []float64{
		0.00, 0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45, 0.50,
		0.55, 0.60, 0.65, 0.70, 0.75, 0.80, 0.85, 0.90, 0.95, 1.00,
	}

	values := []float64{
		0.000000000000000e+00,
		1.401875000000000e-02,
		5.230000000000002e-02,
		1.095187500000000e-01,
		1.807999999999999e-01,
		2.617187500000001e-01,
		3.483000000000000e-01,
		4.370187500000001e-01,
		5.248000000000003e-01,
		6.090187500000001e-01,
		6.875000000000000e-01,
		7.585187500000001e-01,
		8.208000000000000e-01,
		8.735187499999999e-01,
		9.163000000000000e-01,
		9.492187500000000e-01,
		9.728000000000000e-01,
		9.880187500000001e-01,
		9.963000000000000e-01,
		9.995187500000000e-01,
		1.000000000000000e+00,
	}

	actual := make([]float64, len(points))

	for i := range points {
		actual[i] = IncBeta(points[i], p, q, logBeta)
	}
	assert.EqualWithin(actual, values, 1e-15, t)

	p, q = 0.1, 0.2
	logBeta = LogBeta(p, q)

	values = []float64{
		0.000000000000000e+00,
		5.095391215346399e-01,
		5.482400859052436e-01,
		5.732625733722232e-01,
		5.925346573554778e-01,
		6.086596697678208e-01,
		6.228433547203172e-01,
		6.357578563479236e-01,
		6.478288604374864e-01,
		6.593557133297501e-01,
		6.705707961028990e-01,
		6.816739425887479e-01,
		6.928567823206671e-01,
		7.043251807250750e-01,
		7.163269829958610e-01,
		7.291961263917867e-01,
		7.434379555965913e-01,
		7.599272566076309e-01,
		7.804880320024465e-01,
		8.104335200313719e-01,
		1.000000000000000e+00,
	}

	for i := range points {
		actual[i] = IncBeta(points[i], p, q, logBeta)
	}
	assert.EqualWithin(actual, values, 2e-15, t)
}

func TestInvIncBeta(t *testing.T) {
	p, q := 1.0, 2.0
	logBeta := LogBeta(p, q)

	points := []float64{
		0.00, 0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45, 0.50,
		0.55, 0.60, 0.65, 0.70, 0.75, 0.80, 0.85, 0.90, 0.95, 1.00,
	}

	values := []float64{
		0.000000000000000e+00,
		0.025320565519104e+00,
		0.051316701949486e+00,
		0.078045554270711e+00,
		0.105572809000084e+00,
		0.133974596215561e+00,
		0.163339973465924e+00,
		0.193774225170145e+00,
		0.225403330758517e+00,
		0.258380151290432e+00,
		0.292893218813452e+00,
		0.329179606750063e+00,
		0.367544467966324e+00,
		0.408392021690038e+00,
		0.452277442494834e+00,
		0.500000000000000e+00,
		0.552786404500042e+00,
		0.612701665379257e+00,
		0.683772233983162e+00,
		0.776393202250021e+00,
		1.000000000000000e+00,
	}

	actual := make([]float64, len(points))

	for i := range points {
		actual[i] = InvIncBeta(points[i], p, q, logBeta)
	}
	assert.EqualWithin(actual, values, 2e-15, t)

	p, q = 0.2, 0.3
	logBeta = LogBeta(p, q)

	values = []float64{
		0.000000000000000e+00,
		2.793072851850660e-06,
		8.937381711316164e-05,
		6.784491773826951e-04,
		2.855345858289119e-03,
		8.684107512129325e-03,
		2.144658503798324e-02,
		4.568556852983932e-02,
		8.683942933344659e-02,
		1.502095712585510e-01,
		2.391350361479824e-01,
		3.527066234122371e-01,
		4.840600731467657e-01,
		6.206841200371190e-01,
		7.474718280552188e-01,
		8.514539745840592e-01,
		9.257428898178934e-01,
		9.707021084050310e-01,
		9.923134416335146e-01,
		9.992341305241808e-01,
		1.000000000000000e+00,
	}

	for i := range points {
		actual[i] = InvIncBeta(points[i], p, q, logBeta)
	}
	assert.EqualWithin(actual, values, 1e-14, t)
}

func BenchmarkIncBeta(b *testing.B) {
	p, q := 0.5, 1.5
	logBeta := LogBeta(p, q)
	points := probability.Sample(uniform.New(0, 1), generator.New(0), 1000)

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		for _, x := range points {
			IncBeta(x, p, q, logBeta)
		}
	}
}

func BenchmarkInvIncBeta(b *testing.B) {
	p, q := 0.5, 1.5
	logBeta := LogBeta(p, q)
	points := probability.Sample(uniform.New(0, 1), generator.New(0), 1000)

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		for _, α := range points {
			InvIncBeta(α, p, q, logBeta)
		}
	}
}
<|endoftext|>


<commit_before>package main

const releaseVersion = "0.4.2"
<commit_msg>chore(release_version): bump to 0.4.3<commit_after>package main

const releaseVersion = "0.4.3"
<|endoftext|>