<commit_before>package rpc

import (
	"fmt"
	"io"
	"net"
	"sync"
)

type WrapErrorFunc func(error) interface{}

type Transporter interface {
	// IsConnected returns false when incoming packets have
	// finished processing.
	//
	// TODO: Use a better name.
	IsConnected() bool

	registerProtocol(p Protocol) error

	getDispatcher() (dispatcher, error)
	getReceiver() (receiver, error)

	// receiveFrames starts processing incoming frames in a
	// background goroutine, if it's not already happening.
	// Returns the result of done(), for convenience.
	receiveFrames() <-chan struct{}

	// Returns a channel that's closed when incoming frames have
	// finished processing, either due to an error or the
	// underlying connection being closed. Successive calls to
	// done() return the same value.
	done() <-chan struct{}

	// err returns a non-nil error value after done() is closed.
	// After done() is closed, successive calls to err return the
	// same value.
	err() error

	// Close closes the transport and releases resources.
	Close()
}

var _ Transporter = (*transport)(nil)

type transport struct {
	c          net.Conn
	enc        *framedMsgpackEncoder
	dispatcher dispatcher
	receiver   receiver
	packetizer *packetizer
	protocols  *protocolHandler
	calls      *callContainer
	log        LogInterface
	closeOnce  sync.Once
	startOnce  sync.Once
	stopCh     chan struct{}

	// Filled in right before stopCh is closed.
	stopErr error
}

func NewTransport(c net.Conn, l LogFactory, wef WrapErrorFunc, maxFrameLength int32) Transporter {
	if maxFrameLength <= 0 {
		panic(fmt.Sprintf("maxFrameLength must be positive: got %d", maxFrameLength))
	}

	if l == nil {
		l = NewSimpleLogFactory(nil, nil)
	}
	log := l.NewLog(c.RemoteAddr())

	ret := &transport{
		c:         c,
		log:       log,
		stopCh:    make(chan struct{}),
		protocols: newProtocolHandler(wef),
		calls:     newCallContainer(),
	}
	enc := newFramedMsgpackEncoder(maxFrameLength, c)
	ret.enc = enc
	ret.dispatcher = newDispatch(enc, ret.calls, log)
	ret.receiver = newReceiveHandler(enc, ret.protocols, log)
	ret.packetizer = newPacketizer(maxFrameLength, c, ret.protocols, ret.calls, log)
	return ret
}

func (t *transport) Close() {
	t.closeOnce.Do(func() {
		// Since the receiver might require the transport, we have to
		// close it before terminating our loops
		close(t.stopCh)
		t.dispatcher.Close()
		<-t.receiver.Close()

		// First inform the encoder that it should close
		encoderClosed := t.enc.Close()
		// Unblock any remaining writes
		t.c.Close()
		// Wait for the encoder to finish handling the now unblocked writes
		<-encoderClosed
	})
}

func (t *transport) IsConnected() bool {
	select {
	case <-t.stopCh:
		return false
	default:
		return true
	}
}

func (t *transport) receiveFrames() <-chan struct{} {
	t.startOnce.Do(func() {
		go t.receiveFramesLoop()
	})
	return t.stopCh
}

func (t *transport) done() <-chan struct{} {
	return t.stopCh
}

func (t *transport) err() error {
	select {
	case <-t.stopCh:
		return t.stopErr
	default:
		return nil
	}
}

func (t *transport) receiveFramesLoop() {
	// Packetize: do work
	var err error
	for shouldContinue(err) {
		var rpc rpcMessage
		if rpc, err = t.packetizer.NextFrame(); shouldReceive(rpc) {
			t.receiver.Receive(rpc)
		}
	}

	// Log packetizer completion
	t.log.TransportError(err)

	// This must happen before stopCh is closed to have a correct
	// ordering.
	t.stopErr = err

	t.Close()
}

func (t *transport) getDispatcher() (dispatcher, error) {
	if !t.IsConnected() {
		return nil, io.EOF
	}
	return t.dispatcher, nil
}

func (t *transport) getReceiver() (receiver, error) {
	if !t.IsConnected() {
		return nil, io.EOF
	}
	return t.receiver, nil
}

func (t *transport) registerProtocol(p Protocol) error {
	return t.protocols.registerProtocol(p)
}

func shouldContinue(err error) bool {
	err = unboxRPCError(err)
	switch err.(type) {
	case nil:
		return true
	case CallNotFoundError:
		return true
	case MethodNotFoundError:
		return true
	case ProtocolNotFoundError:
		return true
	default:
		return false
	}
}

func shouldReceive(rpc rpcMessage) bool {
	if rpc == nil {
		return false
	}
	switch rpc.Err().(type) {
	case nil:
		return true
	case MethodNotFoundError:
		return true
	case ProtocolNotFoundError:
		return true
	default:
		return false
	}
}
<commit_msg>Add a DefaultMaxFrameLength constant and use it (#158)<commit_after>package rpc

import (
	"io"
	"net"
	"sync"
)

type WrapErrorFunc func(error) interface{}

type Transporter interface {
	// IsConnected returns false when incoming packets have
	// finished processing.
	//
	// TODO: Use a better name.
	IsConnected() bool

	registerProtocol(p Protocol) error

	getDispatcher() (dispatcher, error)
	getReceiver() (receiver, error)

	// receiveFrames starts processing incoming frames in a
	// background goroutine, if it's not already happening.
	// Returns the result of done(), for convenience.
	receiveFrames() <-chan struct{}

	// Returns a channel that's closed when incoming frames have
	// finished processing, either due to an error or the
	// underlying connection being closed. Successive calls to
	// done() return the same value.
	done() <-chan struct{}

	// err returns a non-nil error value after done() is closed.
	// After done() is closed, successive calls to err return the
	// same value.
	err() error

	// Close closes the transport and releases resources.
	Close()
}

var _ Transporter = (*transport)(nil)

type transport struct {
	c          net.Conn
	enc        *framedMsgpackEncoder
	dispatcher dispatcher
	receiver   receiver
	packetizer *packetizer
	protocols  *protocolHandler
	calls      *callContainer
	log        LogInterface
	closeOnce  sync.Once
	startOnce  sync.Once
	stopCh     chan struct{}

	// Filled in right before stopCh is closed.
	stopErr error
}

// DefaultMaxFrameLength (100 MiB) is the default value for the
// maxFrameLength in NewTransporter.
const DefaultMaxFrameLength = 100 * 1024 * 1024

// NewTransporter creates a new Transporter from the given connection
// and parameters. If maxFrameLength is not positive, it is set to
// DefaultMaxFrameLength. Both sides of a connection should use the
// same number for maxFrameLength.
func NewTransport(c net.Conn, l LogFactory, wef WrapErrorFunc, maxFrameLength int32) Transporter {
	if maxFrameLength <= 0 {
		maxFrameLength = DefaultMaxFrameLength
	}

	if l == nil {
		l = NewSimpleLogFactory(nil, nil)
	}
	log := l.NewLog(c.RemoteAddr())

	ret := &transport{
		c:         c,
		log:       log,
		stopCh:    make(chan struct{}),
		protocols: newProtocolHandler(wef),
		calls:     newCallContainer(),
	}
	enc := newFramedMsgpackEncoder(maxFrameLength, c)
	ret.enc = enc
	ret.dispatcher = newDispatch(enc, ret.calls, log)
	ret.receiver = newReceiveHandler(enc, ret.protocols, log)
	ret.packetizer = newPacketizer(maxFrameLength, c, ret.protocols, ret.calls, log)
	return ret
}

func (t *transport) Close() {
	t.closeOnce.Do(func() {
		// Since the receiver might require the transport, we have to
		// close it before terminating our loops
		close(t.stopCh)
		t.dispatcher.Close()
		<-t.receiver.Close()

		// First inform the encoder that it should close
		encoderClosed := t.enc.Close()
		// Unblock any remaining writes
		t.c.Close()
		// Wait for the encoder to finish handling the now unblocked writes
		<-encoderClosed
	})
}

func (t *transport) IsConnected() bool {
	select {
	case <-t.stopCh:
		return false
	default:
		return true
	}
}

func (t *transport) receiveFrames() <-chan struct{} {
	t.startOnce.Do(func() {
		go t.receiveFramesLoop()
	})
	return t.stopCh
}

func (t *transport) done() <-chan struct{} {
	return t.stopCh
}

func (t *transport) err() error {
	select {
	case <-t.stopCh:
		return t.stopErr
	default:
		return nil
	}
}

func (t *transport) receiveFramesLoop() {
	// Packetize: do work
	var err error
	for shouldContinue(err) {
		var rpc rpcMessage
		if rpc, err = t.packetizer.NextFrame(); shouldReceive(rpc) {
			t.receiver.Receive(rpc)
		}
	}

	// Log packetizer completion
	t.log.TransportError(err)

	// This must happen before stopCh is closed to have a correct
	// ordering.
	t.stopErr = err

	t.Close()
}

func (t *transport) getDispatcher() (dispatcher, error) {
	if !t.IsConnected() {
		return nil, io.EOF
	}
	return t.dispatcher, nil
}

func (t *transport) getReceiver() (receiver, error) {
	if !t.IsConnected() {
		return nil, io.EOF
	}
	return t.receiver, nil
}

func (t *transport) registerProtocol(p Protocol) error {
	return t.protocols.registerProtocol(p)
}

func shouldContinue(err error) bool {
	err = unboxRPCError(err)
	switch err.(type) {
	case nil:
		return true
	case CallNotFoundError:
		return true
	case MethodNotFoundError:
		return true
	case ProtocolNotFoundError:
		return true
	default:
		return false
	}
}

func shouldReceive(rpc rpcMessage) bool {
	if rpc == nil {
		return false
	}
	switch rpc.Err().(type) {
	case nil:
		return true
	case MethodNotFoundError:
		return true
	case ProtocolNotFoundError:
		return true
	default:
		return false
	}
}
<|endoftext|>


<commit_before>package rpc

import (
	"fmt"
	"io"
	"net"
	"sync"
)

type WrapErrorFunc func(error) interface{}

type Transporter interface {
	// IsConnected returns false when incoming packets have
	// finished processing.
	//
	// TODO: Use a better name.
	IsConnected() bool

	registerProtocol(p Protocol) error

	getDispatcher() (dispatcher, error)
	getReceiver() (receiver, error)

	// receiveFrames starts processing incoming frames in a
	// background goroutine, if it's not already happening.
	// Returns the result of done(), for convenience.
	receiveFrames() <-chan struct{}

	// Returns a channel that's closed when incoming frames have
	// finished processing, either due to an error or the
	// underlying connection being closed. Successive calls to
	// done() return the same value.
	done() <-chan struct{}

	// err returns a non-nil error value after done() is closed.
	// After done() is closed, successive calls to err return the
	// same value.
	err() error

	// Close closes the transport and releases resources.
	Close()
}

var _ Transporter = (*transport)(nil)

type transport struct {
	c          net.Conn
	enc        *framedMsgpackEncoder
	dispatcher dispatcher
	receiver   receiver
	packetizer *packetizer
	protocols  *protocolHandler
	calls      *callContainer
	log        LogInterface
	closeOnce  sync.Once
	startOnce  sync.Once
	stopCh     chan struct{}

	// Filled in right before stopCh is closed.
	stopErr error
}

// DefaultMaxFrameLength (100 MiB) is a reasonable default value for
// the maxFrameLength parameter in NewTransporter.
const DefaultMaxFrameLength = 100 * 1024 * 1024

// NewTransporter creates a new Transporter from the given connection
// and parameters. Both sides of a connection should use the same
// number for maxFrameLength.
func NewTransport(c net.Conn, l LogFactory, wef WrapErrorFunc, maxFrameLength int32) Transporter {
	if maxFrameLength <= 0 {
		panic(fmt.Sprintf("maxFrameLength must be positive: got %d", maxFrameLength))
	}

	if l == nil {
		l = NewSimpleLogFactory(nil, nil)
	}
	log := l.NewLog(c.RemoteAddr())

	ret := &transport{
		c:         c,
		log:       log,
		stopCh:    make(chan struct{}),
		protocols: newProtocolHandler(wef),
		calls:     newCallContainer(),
	}
	enc := newFramedMsgpackEncoder(maxFrameLength, c)
	ret.enc = enc
	ret.dispatcher = newDispatch(enc, ret.calls, log)
	ret.receiver = newReceiveHandler(enc, ret.protocols, log)
	ret.packetizer = newPacketizer(maxFrameLength, c, ret.protocols, ret.calls, log)
	return ret
}

func (t *transport) Close() {
	t.closeOnce.Do(func() {
		// Since the receiver might require the transport, we have to
		// close it before terminating our loops
		close(t.stopCh)
		t.dispatcher.Close()
		<-t.receiver.Close()

		// First inform the encoder that it should close
		encoderClosed := t.enc.Close()
		// Unblock any remaining writes
		t.c.Close()
		// Wait for the encoder to finish handling the now unblocked writes
		<-encoderClosed
	})
}

func (t *transport) IsConnected() bool {
	select {
	case <-t.stopCh:
		return false
	default:
		return true
	}
}

func (t *transport) receiveFrames() <-chan struct{} {
	t.startOnce.Do(func() {
		go t.receiveFramesLoop()
	})
	return t.stopCh
}

func (t *transport) done() <-chan struct{} {
	return t.stopCh
}

func (t *transport) err() error {
	select {
	case <-t.stopCh:
		return t.stopErr
	default:
		return nil
	}
}

func (t *transport) receiveFramesLoop() {
	// Packetize: do work
	var err error
	for shouldContinue(err) {
		var rpc rpcMessage
		if rpc, err = t.packetizer.NextFrame(); shouldReceive(rpc) {
			rerr := t.receiver.Receive(rpc)
			if err == nil {
				err = rerr
			}
		}
	}

	// Log packetizer completion
	t.log.TransportError(err)

	// This must happen before stopCh is closed to have a correct
	// ordering.
	t.stopErr = err

	t.Close()
}

func (t *transport) getDispatcher() (dispatcher, error) {
	if !t.IsConnected() {
		return nil, io.EOF
	}
	return t.dispatcher, nil
}

func (t *transport) getReceiver() (receiver, error) {
	if !t.IsConnected() {
		return nil, io.EOF
	}
	return t.receiver, nil
}

func (t *transport) registerProtocol(p Protocol) error {
	return t.protocols.registerProtocol(p)
}

func shouldContinue(err error) bool {
	err = unboxRPCError(err)
	switch err.(type) {
	case nil:
		return true
	case CallNotFoundError:
		return true
	case MethodNotFoundError:
		return true
	case ProtocolNotFoundError:
		return true
	default:
		return false
	}
}

func shouldReceive(rpc rpcMessage) bool {
	if rpc == nil {
		return false
	}
	switch rpc.Err().(type) {
	case nil:
		return true
	case MethodNotFoundError:
		return true
	case ProtocolNotFoundError:
		return true
	default:
		return false
	}
}
<commit_msg>log instead<commit_after>package rpc

import (
	"fmt"
	"io"
	"net"
	"sync"
)

type WrapErrorFunc func(error) interface{}

type Transporter interface {
	// IsConnected returns false when incoming packets have
	// finished processing.
	//
	// TODO: Use a better name.
	IsConnected() bool

	registerProtocol(p Protocol) error

	getDispatcher() (dispatcher, error)
	getReceiver() (receiver, error)

	// receiveFrames starts processing incoming frames in a
	// background goroutine, if it's not already happening.
	// Returns the result of done(), for convenience.
	receiveFrames() <-chan struct{}

	// Returns a channel that's closed when incoming frames have
	// finished processing, either due to an error or the
	// underlying connection being closed. Successive calls to
	// done() return the same value.
	done() <-chan struct{}

	// err returns a non-nil error value after done() is closed.
	// After done() is closed, successive calls to err return the
	// same value.
	err() error

	// Close closes the transport and releases resources.
	Close()
}

var _ Transporter = (*transport)(nil)

type transport struct {
	c          net.Conn
	enc        *framedMsgpackEncoder
	dispatcher dispatcher
	receiver   receiver
	packetizer *packetizer
	protocols  *protocolHandler
	calls      *callContainer
	log        LogInterface
	closeOnce  sync.Once
	startOnce  sync.Once
	stopCh     chan struct{}

	// Filled in right before stopCh is closed.
	stopErr error
}

// DefaultMaxFrameLength (100 MiB) is a reasonable default value for
// the maxFrameLength parameter in NewTransporter.
const DefaultMaxFrameLength = 100 * 1024 * 1024

// NewTransporter creates a new Transporter from the given connection
// and parameters. Both sides of a connection should use the same
// number for maxFrameLength.
func NewTransport(c net.Conn, l LogFactory, wef WrapErrorFunc, maxFrameLength int32) Transporter {
	if maxFrameLength <= 0 {
		panic(fmt.Sprintf("maxFrameLength must be positive: got %d", maxFrameLength))
	}

	if l == nil {
		l = NewSimpleLogFactory(nil, nil)
	}
	log := l.NewLog(c.RemoteAddr())

	ret := &transport{
		c:         c,
		log:       log,
		stopCh:    make(chan struct{}),
		protocols: newProtocolHandler(wef),
		calls:     newCallContainer(),
	}
	enc := newFramedMsgpackEncoder(maxFrameLength, c)
	ret.enc = enc
	ret.dispatcher = newDispatch(enc, ret.calls, log)
	ret.receiver = newReceiveHandler(enc, ret.protocols, log)
	ret.packetizer = newPacketizer(maxFrameLength, c, ret.protocols, ret.calls, log)
	return ret
}

func (t *transport) Close() {
	t.closeOnce.Do(func() {
		// Since the receiver might require the transport, we have to
		// close it before terminating our loops
		close(t.stopCh)
		t.dispatcher.Close()
		<-t.receiver.Close()

		// First inform the encoder that it should close
		encoderClosed := t.enc.Close()
		// Unblock any remaining writes
		t.c.Close()
		// Wait for the encoder to finish handling the now unblocked writes
		<-encoderClosed
	})
}

func (t *transport) IsConnected() bool {
	select {
	case <-t.stopCh:
		return false
	default:
		return true
	}
}

func (t *transport) receiveFrames() <-chan struct{} {
	t.startOnce.Do(func() {
		go t.receiveFramesLoop()
	})
	return t.stopCh
}

func (t *transport) done() <-chan struct{} {
	return t.stopCh
}

func (t *transport) err() error {
	select {
	case <-t.stopCh:
		return t.stopErr
	default:
		return nil
	}
}

func (t *transport) receiveFramesLoop() {
	// Packetize: do work
	var err error
	for shouldContinue(err) {
		var rpc rpcMessage
		if rpc, err = t.packetizer.NextFrame(); shouldReceive(rpc) {
			if rerr := t.receiver.Receive(rpc); rerr != nil {
				t.log.Info("error on Receive: %v", rerr)
			}
		}
	}

	// Log packetizer completion
	t.log.TransportError(err)

	// This must happen before stopCh is closed to have a correct
	// ordering.
	t.stopErr = err

	t.Close()
}

func (t *transport) getDispatcher() (dispatcher, error) {
	if !t.IsConnected() {
		return nil, io.EOF
	}
	return t.dispatcher, nil
}

func (t *transport) getReceiver() (receiver, error) {
	if !t.IsConnected() {
		return nil, io.EOF
	}
	return t.receiver, nil
}

func (t *transport) registerProtocol(p Protocol) error {
	return t.protocols.registerProtocol(p)
}

func shouldContinue(err error) bool {
	err = unboxRPCError(err)
	switch err.(type) {
	case nil:
		return true
	case CallNotFoundError:
		return true
	case MethodNotFoundError:
		return true
	case ProtocolNotFoundError:
		return true
	default:
		return false
	}
}

func shouldReceive(rpc rpcMessage) bool {
	if rpc == nil {
		return false
	}
	switch rpc.Err().(type) {
	case nil:
		return true
	case MethodNotFoundError:
		return true
	case ProtocolNotFoundError:
		return true
	default:
		return false
	}
}
<|endoftext|>


<commit_before>package Gate

import (
	"Gate/NetSession"
)

type Messager interface {
	GetSession() *NetSession.NetSession
}

type Hander interface {
	Action()
	GetMessage() *Messager
}

type MessageManager struct {
	Handers  [int]interface{}
	Messages [int]interface{}
}

func NewMessagePool() {
	var ret = &MessageManager{}
	return ret
}

func (manager *MessageManager) register(id int, handler *Hander, message *Messager) {
	manager.Handers[id] = handler
	manager.Messages[id] = message
}

func (manager *MessageManager) CreateHandler(id int) *Hander {
	var ret = &Hander{}
	return ret
}

func (manager *MessageManager) CreateMessage(id int) *Messager {
	var ret = &Messager{}
	return ret
}
<commit_msg>modify MessageManager. use reflect manage Handers and Messages<commit_after>package Gate

import (
	"Gate/NetSession"
	"reflect"
)

type Messager interface {
	GetSession() *NetSession.NetSession
}

type Hander interface {
	Action()
	GetMessage() *Messager
}

type MessageManager struct {
	Handers  map[int]reflect.Type
	Messages map[int]reflect.Type
}

func NewMessagePool() {
	var ret = &MessageManager{
		Handers:   make(map[int]reflect.Type),
		Messagers: make(map[int]reflect.Type),
	}
	return ret
}

func (manager *MessageManager) register(id int, handlerType reflect.Type, messageType reflect.Type) {
	manager.Handers[id] = handlerType
	manager.Messages[id] = messageType
}

func (manager *MessageManager) CreateHandler(id int) *Hander {
	var t = manager.Handers[id]
	if t == nil {
		//error
	}

	var ret = &reflect.New(t)
	return ret
}

func (manager *MessageManager) CreateMessage(id int) *Messager {
	var t = manager.Handers[id]
	if t == nil {
		//error
	}
	return &reflect.New(t)
}
<|endoftext|>


<commit_before>package fife

//

import (
  "testing"
  "fmt"
)

func TestConfig(t *testing.T){
  workers := 3
  cfg := make_config(t, workers)
  //check workers and fife
  for _, w := range(cfg.workers) {
    if w == nil {
      t.Fatalf("worker not created by config")
    }
  }
  if cfg.fife == nil {
    t.Fatalf("fife not created by config")
  }
  fmt.Println("...passed")
}

/*
Set up some tables, add some data to them, run an rpc call between workers
*/
func TestSetup(t *testing.T){
  cfg := make_config(t, 2) //config with 2 workers
  if len(cfg.workers) != 2 {
    t.Fatalf("unexpected number of workers")
  }
  //shared kernel func between workers
  kernMap := map[string]KernelFunction{"hello":kernel_simple}

  //init workers
  for i, w := range(cfg.workers){
    table := MakeTable(Accumulator{}, Partitioner{}, w, "pasta")
    w.Setup(kernMap, []Table{*table})
    fmt.Println(w)
    //now, add some data

  }
}

func TestRPCs(t *testing.T){

}

func kernel_simple(args []interface{}, tables map[string]Table){
  fmt.Println("hello, world")
}
<commit_msg>Compile error, whoops<commit_after>package fife

//

import (
  "testing"
  "fmt"
)

func TestConfig(t *testing.T){
  workers := 3
  cfg := make_config(t, workers)
  //check workers and fife
  for _, w := range(cfg.workers) {
    if w == nil {
      t.Fatalf("worker not created by config")
    }
  }
  if cfg.fife == nil {
    t.Fatalf("fife not created by config")
  }
  fmt.Println("...passed")
}

/*
Set up some tables, add some data to them, run an rpc call between workers
*/
func TestSetup(t *testing.T){
  cfg := make_config(t, 2) //config with 2 workers
  if len(cfg.workers) != 2 {
    t.Fatalf("unexpected number of workers")
  }
  //shared kernel func between workers
  kernMap := map[string]KernelFunction{"hello":kernel_simple}

  //init workers
  for _, w := range(cfg.workers){
    table := MakeTable(Accumulator{}, Partitioner{}, w, "pasta")
    w.Setup(kernMap, []Table{*table})
    fmt.Println(w)
    //now, add some data

  }
}

func TestRPCs(t *testing.T){

}

func kernel_simple(args []interface{}, tables map[string]Table){
  fmt.Println("hello, world")
}
<|endoftext|>


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

package oglemock_test

import (
	"reflect"
	"testing"

	. "github.com/jacobsa/oglematchers"
	"github.com/jacobsa/oglemock"
	. "github.com/jacobsa/ogletest"
)

func TestSaveArg(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////
// Boilerplate
////////////////////////////////////////////////////////////

type SaveArgTest struct {
}

func init() { RegisterTestSuite(&SaveArgTest{}) }

////////////////////////////////////////////////////////////
// Test functions
////////////////////////////////////////////////////////////

func (t *SaveArgTest) FunctionHasNoArguments() {
	const index = 0
	var dst int
	f := func() (int, string) { return 0, "" }

	err := oglemock.SaveArg(index, &dst).SetSignature(reflect.TypeOf(f))
	ExpectThat(err, Error(HasSubstr("index 0")))
	ExpectThat(err, Error(HasSubstr("out of range")))
	ExpectThat(err, Error(HasSubstr("func() (int, string)")))
}

func (t *SaveArgTest) ArgumentIndexOutOfRange() {
	const index = 2
	var dst int
	f := func(a int, b int) {}

	err := oglemock.SaveArg(index, &dst).SetSignature(reflect.TypeOf(f))
	ExpectThat(err, Error(HasSubstr("index 2")))
	ExpectThat(err, Error(HasSubstr("out of range")))
	ExpectThat(err, Error(HasSubstr("func(int, int)")))
}

func (t *SaveArgTest) DestinationIsLiteralNil() {
	const index = 0
	f := func(a int, b int) {}

	err := oglemock.SaveArg(index, nil).SetSignature(reflect.TypeOf(f))
	ExpectThat(err, Error(HasSubstr("pointer")))
	ExpectThat(err, Error(HasSubstr("<nil>")))
}

func (t *SaveArgTest) DestinationIsNotAPointer() {
	AssertFalse(true, "TODO")
}

func (t *SaveArgTest) DestinationIsNilPointer() {
	AssertFalse(true, "TODO")
}

func (t *SaveArgTest) DestinationNotAssignable() {
	AssertFalse(true, "TODO")
}

func (t *SaveArgTest) ExactTypeMatch() {
	AssertFalse(true, "TODO")
}

func (t *SaveArgTest) AssignableTypeMatch() {
	AssertFalse(true, "TODO")
}
<commit_msg>SaveArgTest.DestinationIsNilPointer<commit_after>// Copyright 2015 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.

package oglemock_test

import (
	"reflect"
	"testing"

	. "github.com/jacobsa/oglematchers"
	"github.com/jacobsa/oglemock"
	. "github.com/jacobsa/ogletest"
)

func TestSaveArg(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////
// Boilerplate
////////////////////////////////////////////////////////////

type SaveArgTest struct {
}

func init() { RegisterTestSuite(&SaveArgTest{}) }

////////////////////////////////////////////////////////////
// Test functions
////////////////////////////////////////////////////////////

func (t *SaveArgTest) FunctionHasNoArguments() {
	const index = 0
	var dst int
	f := func() (int, string) { return 0, "" }

	err := oglemock.SaveArg(index, &dst).SetSignature(reflect.TypeOf(f))
	ExpectThat(err, Error(HasSubstr("index 0")))
	ExpectThat(err, Error(HasSubstr("out of range")))
	ExpectThat(err, Error(HasSubstr("func() (int, string)")))
}

func (t *SaveArgTest) ArgumentIndexOutOfRange() {
	const index = 2
	var dst int
	f := func(a int, b int) {}

	err := oglemock.SaveArg(index, &dst).SetSignature(reflect.TypeOf(f))
	ExpectThat(err, Error(HasSubstr("index 2")))
	ExpectThat(err, Error(HasSubstr("out of range")))
	ExpectThat(err, Error(HasSubstr("func(int, int)")))
}

func (t *SaveArgTest) DestinationIsLiteralNil() {
	const index = 0
	f := func(a int, b int) {}

	err := oglemock.SaveArg(index, nil).SetSignature(reflect.TypeOf(f))
	ExpectThat(err, Error(HasSubstr("pointer")))
	ExpectThat(err, Error(HasSubstr("<nil>")))
}

func (t *SaveArgTest) DestinationIsNotAPointer() {
	const index = 0
	f := func(a int, b int) {}

	err := oglemock.SaveArg(index, uint(17)).SetSignature(reflect.TypeOf(f))
	ExpectThat(err, Error(HasSubstr("pointer")))
	ExpectThat(err, Error(HasSubstr("uint")))
}

func (t *SaveArgTest) DestinationIsNilPointer() {
	const index = 2
	var dst *int
	f := func(a int, b int) {}

	err := oglemock.SaveArg(index, dst).SetSignature(reflect.TypeOf(f))
	ExpectThat(err, Error(HasSubstr("pointer")))
	ExpectThat(err, Error(HasSubstr("non-nil")))
}

func (t *SaveArgTest) DestinationNotAssignable() {
	AssertFalse(true, "TODO")
}

func (t *SaveArgTest) ExactTypeMatch() {
	AssertFalse(true, "TODO")
}

func (t *SaveArgTest) AssignableTypeMatch() {
	AssertFalse(true, "TODO")
}
<|endoftext|>


<commit_before>package main

import (
    "fmt"
    "io/ioutil"
	"log"
    "os"
    "strconv"
	"syscall"

    "github.com/tsuru/config"
    "github.com/dchest/uniuri"
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
	_ "github.com/mattn/go-sqlite3"
    _ "github.com/go-sql-driver/mysql"
    _ "github.com/lib/pq"
)

type LMVFile struct {
	Id        int64      `json:"-"`
	Size      int64      `bson:"size"         json:"size"         binding:"required"`
	Name      string     `bson:"name"         json:"name"         binding:"required"`
	Algorithm string     `bson:"algorithm"    json:"algorithm"    binding:"required"`
	Chunks    []LMVChunk `bson:"chunks"       json:"chunks"       binding:"required"`
	Tar       bool       `bson:"tar"          json:"tar"`
	Token     string     `bson:"token"        json:"token"`
}

type LMVChunk struct {
	Id        int64  `json:"-"`
	LMVFileId int64  `json:"-"`
	Hash      string `bson:"hash"         json:"hash"         binding:"required"`
	Size      int64  `bson:"size"         json:"size"         binding:"required"`
	Index     int    `bson:"index"        json:"index"        binding:"required"`
}

type Configuration struct {
    Web     struct {
        Address     string
    }
    System  struct {
        Pid         bool
    }
    Tokens  struct {
    	Pool        []byte
    	Length      int
    }
    Database struct {
        Type        string
        Source      string
    }
}

func GenerateToken(conf Configuration) string {

    return uniuri.NewLenChars(conf.Tokens.Length, conf.Tokens.Pool)

}

func processConfig() Configuration {

    conf := Configuration{}

    if _, err := os.Stat("lmv-tracker.yml"); err == nil {
        config.ReadConfigFile("lmv-tracker.yml")
    } else {
    	if _, err := os.Stat("/etc/lmv-tracker.yml"); err == nil {
    		config.ReadConfigFile("/etc/lmv-tracker.yml")
    	}
    }

    address, _ := config.GetString("web:address")
    conf.Web.Address = address

    pid, _ := config.GetBool("system:pid")
    conf.System.Pid = pid

    token_pool, _ := config.GetString("tokens:pool")
    conf.Tokens.Pool = []byte(token_pool)

    fmt.Println(conf.Tokens.Pool)

    token_length, _ := config.GetInt("tokens:length")
    conf.Tokens.Length = token_length

    database_type, _ := config.GetString("database:type")
    conf.Database.Type = database_type

    database_source, _ := config.GetString("database:source")
    conf.Database.Source = database_source

    return conf
}

func main() {

    conf := processConfig()

	if conf.System.Pid {
		ioutil.WriteFile("lmv-tracker.pid", []byte(strconv.Itoa(syscall.Getpid())), 0644)
	}

	db, err := gorm.Open(conf.Database.Type, conf.Database.Source)

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

	db.DB()
	db.DB().Ping()

	db.CreateTable(LMVFile{})
	db.CreateTable(LMVChunk{})

	r := gin.Default()

	r.GET("/files/", func(gc *gin.Context) {
		var lmvfiles []LMVFile
		var response []LMVFile

		db.Find(&lmvfiles)

		for _, file := range lmvfiles {

			var chunks []LMVChunk

			db.Where(&LMVChunk{LMVFileId: file.Id}).Find(&chunks)

			file.Chunks = chunks

			response = append(response, file)
		}

		gc.JSON(200, response)
	})

	r.GET("/files/:token/", func(gc *gin.Context) {

		token := gc.Params.ByName("token")
		var lmv_file LMVFile
		var response LMVFile

		db.Where(&LMVFile{Token: token}).First(&lmv_file)

		if lmv_file.Name != "" {

			var chunks []LMVChunk

			db.Where(&LMVChunk{LMVFileId: lmv_file.Id}).Find(&chunks)

			response = lmv_file
			response.Chunks = chunks

			gc.JSON(200, response)

		} else {

			gc.JSON(404, nil)

		}

	})

	r.POST("/files/", func(gc *gin.Context) {

		token := GenerateToken(conf)
		var lmv_file LMVFile

		gc.Bind(&lmv_file)

		for {

			var testFile = LMVFile{}
			db.Where(&LMVFile{Token: token}).First(&testFile)

			if testFile.Name != "" {

				token = GenerateToken(conf)

			} else {

				break

			}

		}

		lmv_file.Token = token

		db.Create(&lmv_file)

		gc.JSON(200, map[string]interface{}{"token": token})

	})

	r.GET("/ping/", func(c *gin.Context) {
		c.String(200, "pong")
	})

	r.Run(conf.Web.Address)

}
<commit_msg>Check the user's home directory for a config after checking the current directory<commit_after>package main

import (
    "fmt"
    "io/ioutil"
	"log"
    "os"
    "os/user"
    "strconv"
	"syscall"

    "github.com/tsuru/config"
    "github.com/dchest/uniuri"
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
	_ "github.com/mattn/go-sqlite3"
    _ "github.com/go-sql-driver/mysql"
    _ "github.com/lib/pq"
)

type LMVFile struct {
	Id        int64      `json:"-"`
	Size      int64      `bson:"size"         json:"size"         binding:"required"`
	Name      string     `bson:"name"         json:"name"         binding:"required"`
	Algorithm string     `bson:"algorithm"    json:"algorithm"    binding:"required"`
	Chunks    []LMVChunk `bson:"chunks"       json:"chunks"       binding:"required"`
	Tar       bool       `bson:"tar"          json:"tar"`
	Token     string     `bson:"token"        json:"token"`
}

type LMVChunk struct {
	Id        int64  `json:"-"`
	LMVFileId int64  `json:"-"`
	Hash      string `bson:"hash"         json:"hash"         binding:"required"`
	Size      int64  `bson:"size"         json:"size"         binding:"required"`
	Index     int    `bson:"index"        json:"index"        binding:"required"`
}

type Configuration struct {
    Web     struct {
        Address     string
    }
    System  struct {
        Pid         bool
    }
    Tokens  struct {
    	Pool        []byte
    	Length      int
    }
    Database struct {
        Type        string
        Source      string
    }
}

func GenerateToken(conf Configuration) string {

    return uniuri.NewLenChars(conf.Tokens.Length, conf.Tokens.Pool)

}

func processConfig() Configuration {

    conf := Configuration{}

    if _, err := os.Stat("lmv-tracker.yml"); err == nil {
        config.ReadConfigFile("lmv-tracker.yml")
    } else {
        usr, err := user.Current()

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

        if _, err := os.Stat(usr.HomeDir+"/lmv-tracker.yml"); err == nil {
            config.ReadConfigFile(usr.HomeDir+"/lmv-tracker.yml")
        } else {
            if _, err := os.Stat("/etc/lmv-tracker.yml"); err == nil {
        		config.ReadConfigFile("/etc/lmv-tracker.yml")
    	    }
    	}
    }

    address, _ := config.GetString("web:address")
    conf.Web.Address = address

    pid, _ := config.GetBool("system:pid")
    conf.System.Pid = pid

    token_pool, _ := config.GetString("tokens:pool")
    conf.Tokens.Pool = []byte(token_pool)

    fmt.Println(conf.Tokens.Pool)

    token_length, _ := config.GetInt("tokens:length")
    conf.Tokens.Length = token_length

    database_type, _ := config.GetString("database:type")
    conf.Database.Type = database_type

    database_source, _ := config.GetString("database:source")
    conf.Database.Source = database_source

    return conf
}

func main() {

    conf := processConfig()

	if conf.System.Pid {
		ioutil.WriteFile("lmv-tracker.pid", []byte(strconv.Itoa(syscall.Getpid())), 0644)
	}

	db, err := gorm.Open(conf.Database.Type, conf.Database.Source)

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

	db.DB()
	db.DB().Ping()

	db.CreateTable(LMVFile{})
	db.CreateTable(LMVChunk{})

	r := gin.Default()

	r.GET("/files/", func(gc *gin.Context) {
		var lmvfiles []LMVFile
		var response []LMVFile

		db.Find(&lmvfiles)

		for _, file := range lmvfiles {

			var chunks []LMVChunk

			db.Where(&LMVChunk{LMVFileId: file.Id}).Find(&chunks)

			file.Chunks = chunks

			response = append(response, file)
		}

		gc.JSON(200, response)
	})

	r.GET("/files/:token/", func(gc *gin.Context) {

		token := gc.Params.ByName("token")
		var lmv_file LMVFile
		var response LMVFile

		db.Where(&LMVFile{Token: token}).First(&lmv_file)

		if lmv_file.Name != "" {

			var chunks []LMVChunk

			db.Where(&LMVChunk{LMVFileId: lmv_file.Id}).Find(&chunks)

			response = lmv_file
			response.Chunks = chunks

			gc.JSON(200, response)

		} else {

			gc.JSON(404, nil)

		}

	})

	r.POST("/files/", func(gc *gin.Context) {

		token := GenerateToken(conf)
		var lmv_file LMVFile

		gc.Bind(&lmv_file)

		for {

			var testFile = LMVFile{}
			db.Where(&LMVFile{Token: token}).First(&testFile)

			if testFile.Name != "" {

				token = GenerateToken(conf)

			} else {

				break

			}

		}

		lmv_file.Token = token

		db.Create(&lmv_file)

		gc.JSON(200, map[string]interface{}{"token": token})

	})

	r.GET("/ping/", func(c *gin.Context) {
		c.String(200, "pong")
	})

	r.Run(conf.Web.Address)

}
<|endoftext|>


<commit_before>package swift

import (
	"errors"
	"strconv"
	"time"
	"webup/backr"

	"github.com/ncw/swift"
)

func Get(query string, settings backr.SwiftSettings) ([]backr.UploadedArchiveInfo, error) {
	items := []backr.UploadedArchiveInfo{}

	// get a swift connection
	c, err := getSwiftConnection(settings)
	if err != nil {
		return items, backr.UploadedArchiveError{IsFatal: true, Err: err}
	}

	// fetch all backups with the name starting with the term passed as param
	objects, err := c.ObjectsAll(settings.ContainerName, &swift.ObjectsOpts{
		Prefix: query,
	})
	if err != nil {
		return items, backr.UploadedArchiveError{IsFatal: true, Err: err}
	}

	if len(objects) == 0 {
		return items, backr.UploadedArchiveError{IsFatal: false, Err: errors.New("No project or backup found.")}
	}

	// fetch the headers for the Account (allowing to get the key for temp urls)
	_, headers, accountErr := c.Account()

	results := make(chan backr.UploadedArchiveInfo)

	for _, obj := range objects {

		go func(obj swift.Object) {
			// prepare info for this backup
			info := backr.UploadedArchiveInfo{
				Name: obj.Name,
			}

			// get the expire time
			_, objHeaders, objErr := c.Object(settings.ContainerName, obj.Name)
			if objErr == nil {
				if deleteAt, ok := objHeaders["X-Delete-At"]; ok {
					timestamp, _ := strconv.ParseInt(deleteAt, 10, 64)
					expire := time.Unix(timestamp, 0)
					info.Expire = expire
				}
			}

			// generate a temp url for download
			if accountErr == nil {
				info.URL = c.ObjectTempUrl(settings.ContainerName, obj.Name, headers["X-Account-Meta-Temp-Url-Key"], "GET", time.Now().Add(2*time.Minute))
			}

			results <- info

		}(obj)
	}

	for i := 0; i < len(objects); i++ {
		info := <-results
		items = append(items, info)
	}

	return items, nil
}
<commit_msg>Increase temp URL validity<commit_after>package swift

import (
	"errors"
	"strconv"
	"time"
	"webup/backr"

	"github.com/ncw/swift"
)

func Get(query string, settings backr.SwiftSettings) ([]backr.UploadedArchiveInfo, error) {
	items := []backr.UploadedArchiveInfo{}

	// get a swift connection
	c, err := getSwiftConnection(settings)
	if err != nil {
		return items, backr.UploadedArchiveError{IsFatal: true, Err: err}
	}

	// fetch all backups with the name starting with the term passed as param
	objects, err := c.ObjectsAll(settings.ContainerName, &swift.ObjectsOpts{
		Prefix: query,
	})
	if err != nil {
		return items, backr.UploadedArchiveError{IsFatal: true, Err: err}
	}

	if len(objects) == 0 {
		return items, backr.UploadedArchiveError{IsFatal: false, Err: errors.New("No project or backup found.")}
	}

	// fetch the headers for the Account (allowing to get the key for temp urls)
	_, headers, accountErr := c.Account()

	results := make(chan backr.UploadedArchiveInfo)

	for _, obj := range objects {

		go func(obj swift.Object) {
			// prepare info for this backup
			info := backr.UploadedArchiveInfo{
				Name: obj.Name,
			}

			// get the expire time
			_, objHeaders, objErr := c.Object(settings.ContainerName, obj.Name)
			if objErr == nil {
				if deleteAt, ok := objHeaders["X-Delete-At"]; ok {
					timestamp, _ := strconv.ParseInt(deleteAt, 10, 64)
					expire := time.Unix(timestamp, 0)
					info.Expire = expire
				}
			}

			// generate a temp url for download
			if accountErr == nil {
				info.URL = c.ObjectTempUrl(settings.ContainerName, obj.Name, headers["X-Account-Meta-Temp-Url-Key"], "GET", time.Now().Add(10*time.Minute))
			}

			results <- info

		}(obj)
	}

	for i := 0; i < len(objects); i++ {
		info := <-results
		items = append(items, info)
	}

	return items, nil
}
<|endoftext|>


<commit_before>package scamp

import (
	"errors"
	"net"
	"crypto/tls"
	"crypto/rand"
	"crypto/rsa"
	"encoding/base64"
	// "encoding/json"
	"fmt"
	"bytes"
	"io/ioutil"
	"time"

	"sync"
	"sync/atomic"
)

// Two minute timeout on clients
var msgTimeout = time.Second * 120

type ServiceActionFunc func(*Message, *Client)
type ServiceAction struct {
	callback ServiceActionFunc
	crudTags string
	version  int
}

type Service struct {
	serviceSpec   string
	sector        string
	name          string
	humanName     string

	listener      net.Listener
	listenerIP    net.IP
	listenerPort  int

	actions       map[string]*ServiceAction
	isRunning     bool

	clientsM      sync.Mutex
	clients       []*Client

	// requests      ClientChan

	cert          tls.Certificate
	pemCert       []byte // just a copy of what was read off disk at tls cert load time

	// stats
	statsCloseChan chan bool
	connectionsAccepted uint64
}

func NewService(sector string, serviceSpec string, humanName string) (serv *Service, err error){
	if len(humanName) > 18 {
		err = fmt.Errorf("name `%s` is too long, must be less than 18 bytes", humanName)
		return
	}

	serv = new(Service)
	serv.sector = sector
	serv.serviceSpec = serviceSpec
	serv.humanName = humanName
	serv.generateRandomName()

	serv.actions = make(map[string]*ServiceAction)

	crtPath := defaultConfig.ServiceCertPath(serv.humanName)
	keyPath := defaultConfig.ServiceKeyPath(serv.humanName)

	if crtPath == nil || keyPath == nil {
		err = fmt.Errorf( "could not find valid crt/key pair for service %s (`%s`,`%s`)", serv.humanName, crtPath, keyPath )
		return
	}

	// Load keypair for tls socket library to use
	serv.cert, err = tls.LoadX509KeyPair( string(crtPath), string(keyPath) )
	if err != nil {
		return
	}

	// Load cert in to memory for announce packet writing
	serv.pemCert, err = ioutil.ReadFile(string(crtPath))
	if err != nil {
		return
	}
	serv.pemCert = bytes.TrimSpace(serv.pemCert)

	// Finally, get ready for incoming requests
	err = serv.listen()
	if err != nil {
		return
	}

	serv.statsCloseChan = make(chan bool)
	// go PrintStatsLoop(serv, time.Duration(15)*time.Second, serv.statsCloseChan)

	Trace.Printf("done initializing service")

	return
}

// TODO: port discovery and interface/IP discovery should happen here
// important to set values so announce packets are correct
func (serv *Service)listen() (err error) {
	config := &tls.Config{
		Certificates: []tls.Certificate{ serv.cert },
	}

	Info.Printf("starting service on %s", serv.serviceSpec)
	serv.listener,err = tls.Listen("tcp", serv.serviceSpec, config)
	if err != nil {
		return err
	}
	addr := serv.listener.Addr()
	Info.Printf("service now listening to %s", addr.String())

  // TODO: get listenerIP to return 127.0.0.1 or something other than '::'/nil
  // serv.listenerIP = serv.listener.Addr().(*net.TCPAddr).IP
  serv.listenerIP, err = IPForAnnouncePacket()
  Trace.Printf("serv.listenerIP: `%s`", serv.listenerIP)

  if err != nil {
  	return
  }

	serv.listenerPort = serv.listener.Addr().(*net.TCPAddr).Port

	return
}

func (serv *Service)Register(name string, callback ServiceActionFunc) (err error) {
	if serv.isRunning {
		err = errors.New("cannot register handlers while server is running")
		return
	}

	serv.actions[name] = &ServiceAction {
		callback: callback,
		version: 1,
	}
	return
}

func (serv *Service)Run() {

	forLoop:
	for {
		netConn,err := serv.listener.Accept()
		if err != nil {
			Info.Printf("exiting service service Run(): `%s`", err)
			break forLoop
		}
		Trace.Printf("accepted new connection...")

		var tlsConn (*tls.Conn) = (netConn).(*tls.Conn)
		if tlsConn == nil {
			Error.Fatalf("could not create tlsConn")
			break forLoop
		}

		conn := NewConnection(tlsConn,"service")
		client := NewClient(conn)

		serv.clientsM.Lock()
		serv.clients = append(serv.clients, client)
		serv.clientsM.Unlock()

		go serv.Handle(client)

		atomic.AddUint64(&serv.connectionsAccepted, 1)
	}

	Info.Printf("closing all registered objects")

	serv.clientsM.Lock()
	defer serv.clientsM.Unlock()
	for _,client := range serv.clients {
		client.Close()
	}

	serv.statsCloseChan <- true
}

func (serv *Service)Handle(client *Client) {
	var action *ServiceAction

	HandlerLoop:
	for {
		select {
		case msg,ok := <-client.Incoming():
			if !ok {
				break HandlerLoop
			}
			action = serv.actions[msg.Action]

			if action != nil{
				// yay
				action.callback(msg, client)
			} else {
				Error.Printf("do not know how to handle action `%s`", msg.Action)

				reply := NewMessage()
		    reply.SetMessageType(MESSAGE_TYPE_REPLY)
		    reply.SetEnvelope(ENVELOPE_JSON)
		    reply.SetRequestId(msg.RequestId)
		    reply.Write([]byte(`{"error": "no such action"`))
				_,err := client.Send(reply)
				if err != nil {
					client.Close()
					break HandlerLoop
				}

			}
		case <- time.After(msgTimeout):
			Error.Printf("timeout... dying!")
			break HandlerLoop
		}
	}

	client.Close()
	serv.RemoveClient(client)

	Trace.Printf("done handling client")

}

func (serv *Service)RemoveClient(client *Client) (err error){
	serv.clientsM.Lock()
	defer serv.clientsM.Unlock()

	index := -1
	for i,entry := range serv.clients {
		if client == entry {
			index = i
			break
		}
	}

	if index == -1 {
		Error.Printf("tried removing client that wasn't being tracked")
		return fmt.Errorf("unknown client") // TODO can I get the client's IP?
	}

	client.Close()
	serv.clients = append(serv.clients[:index], serv.clients[index+1:]...)

	return nil
}

func (serv *Service)Stop(){
	// Sometimes we Stop() before service after service has been init but before it is started
	// The usual case is a bad config in another plugin
	if serv.listener != nil {
		serv.listener.Close()
	}
}

func (serv *Service)MarshalText() (b []byte, err error){
	var buf bytes.Buffer

	serviceProxy := ServiceAsServiceProxy(serv)

	classRecord,err := serviceProxy.MarshalJSON()//json.Marshal(&serviceProxy) //Marshal is mangling service actions
	if err != nil {
		return
	}
	sig, err := SignSHA256(classRecord, serv.cert.PrivateKey.(*rsa.PrivateKey))
	if err != nil {
		return
	}
	sigParts := stringToRows(sig, 76)

	buf.Write(classRecord)
	buf.WriteString("\n\n")
	buf.Write(serv.pemCert)
	buf.WriteString("\n\n")
	// buf.WriteString(sig)
	// buf.WriteString("\n\n")
	for _,part := range sigParts {
		buf.WriteString(part)
		buf.WriteString("\n")
	}
	buf.WriteString("\n")

	b = buf.Bytes()
	return
}

func stringToRows(input string, rowlen int) (output []string) {
	output = make([]string,0)

	if len(input) <= 76 {
		output = append(output, input)
	} else {
		substr := input[:]
		var row string
		var done bool = false
		for {
			if len(substr) > 76 {
				row = substr[0:76]
				substr = substr[76:]
			} else {
				row = substr[:]
				done = true
			}
			output = append(output,row)
			if done {
				break
			}
		}
	}

	return
}

func (serv *Service)generateRandomName() {
	randBytes := make([]byte, 18, 18)
	read,err := rand.Read(randBytes)
	if err != nil {
		err = fmt.Errorf("could not generate all rand bytes needed. only read %d of 18", read)
		return
	}
	base64RandBytes := base64.StdEncoding.EncodeToString(randBytes)

	var buffer bytes.Buffer
	buffer.WriteString(serv.humanName)
	buffer.WriteString("-")
	buffer.WriteString(base64RandBytes[0:])
	serv.name = string(buffer.Bytes())
}
<commit_msg>updated timeout message to include action and requestID<commit_after>package scamp

import (
	"errors"
	"net"
	"crypto/tls"
	"crypto/rand"
	"crypto/rsa"
	"encoding/base64"
	// "encoding/json"
	"fmt"
	"bytes"
	"io/ioutil"
	"time"

	"sync"
	"sync/atomic"
)

// Two minute timeout on clients
var msgTimeout = time.Second * 120

type ServiceActionFunc func(*Message, *Client)
type ServiceAction struct {
	callback ServiceActionFunc
	crudTags string
	version  int
}

type Service struct {
	serviceSpec   string
	sector        string
	name          string
	humanName     string

	listener      net.Listener
	listenerIP    net.IP
	listenerPort  int

	actions       map[string]*ServiceAction
	isRunning     bool

	clientsM      sync.Mutex
	clients       []*Client

	// requests      ClientChan

	cert          tls.Certificate
	pemCert       []byte // just a copy of what was read off disk at tls cert load time

	// stats
	statsCloseChan chan bool
	connectionsAccepted uint64
}

func NewService(sector string, serviceSpec string, humanName string) (serv *Service, err error){
	if len(humanName) > 18 {
		err = fmt.Errorf("name `%s` is too long, must be less than 18 bytes", humanName)
		return
	}

	serv = new(Service)
	serv.sector = sector
	serv.serviceSpec = serviceSpec
	serv.humanName = humanName
	serv.generateRandomName()

	serv.actions = make(map[string]*ServiceAction)

	crtPath := defaultConfig.ServiceCertPath(serv.humanName)
	keyPath := defaultConfig.ServiceKeyPath(serv.humanName)

	if crtPath == nil || keyPath == nil {
		err = fmt.Errorf( "could not find valid crt/key pair for service %s (`%s`,`%s`)", serv.humanName, crtPath, keyPath )
		return
	}

	// Load keypair for tls socket library to use
	serv.cert, err = tls.LoadX509KeyPair( string(crtPath), string(keyPath) )
	if err != nil {
		return
	}

	// Load cert in to memory for announce packet writing
	serv.pemCert, err = ioutil.ReadFile(string(crtPath))
	if err != nil {
		return
	}
	serv.pemCert = bytes.TrimSpace(serv.pemCert)

	// Finally, get ready for incoming requests
	err = serv.listen()
	if err != nil {
		return
	}

	serv.statsCloseChan = make(chan bool)
	// go PrintStatsLoop(serv, time.Duration(15)*time.Second, serv.statsCloseChan)

	Trace.Printf("done initializing service")

	return
}

// TODO: port discovery and interface/IP discovery should happen here
// important to set values so announce packets are correct
func (serv *Service)listen() (err error) {
	config := &tls.Config{
		Certificates: []tls.Certificate{ serv.cert },
	}

	Info.Printf("starting service on %s", serv.serviceSpec)
	serv.listener,err = tls.Listen("tcp", serv.serviceSpec, config)
	if err != nil {
		return err
	}
	addr := serv.listener.Addr()
	Info.Printf("service now listening to %s", addr.String())

  // TODO: get listenerIP to return 127.0.0.1 or something other than '::'/nil
  // serv.listenerIP = serv.listener.Addr().(*net.TCPAddr).IP
  serv.listenerIP, err = IPForAnnouncePacket()
  Trace.Printf("serv.listenerIP: `%s`", serv.listenerIP)

  if err != nil {
  	return
  }

	serv.listenerPort = serv.listener.Addr().(*net.TCPAddr).Port

	return
}

func (serv *Service)Register(name string, callback ServiceActionFunc) (err error) {
	if serv.isRunning {
		err = errors.New("cannot register handlers while server is running")
		return
	}

	serv.actions[name] = &ServiceAction {
		callback: callback,
		version: 1,
	}
	return
}

func (serv *Service)Run() {

	forLoop:
	for {
		netConn,err := serv.listener.Accept()
		if err != nil {
			Info.Printf("exiting service service Run(): `%s`", err)
			break forLoop
		}
		Trace.Printf("accepted new connection...")

		var tlsConn (*tls.Conn) = (netConn).(*tls.Conn)
		if tlsConn == nil {
			Error.Fatalf("could not create tlsConn")
			break forLoop
		}

		conn := NewConnection(tlsConn,"service")
		client := NewClient(conn)

		serv.clientsM.Lock()
		serv.clients = append(serv.clients, client)
		serv.clientsM.Unlock()

		go serv.Handle(client)

		atomic.AddUint64(&serv.connectionsAccepted, 1)
	}

	Info.Printf("closing all registered objects")

	serv.clientsM.Lock()
	defer serv.clientsM.Unlock()
	for _,client := range serv.clients {
		client.Close()
	}

	serv.statsCloseChan <- true
}

func (serv *Service)Handle(client *Client) {
	var action *ServiceAction

	HandlerLoop:
	for {
		select {
		case msg,ok := <-client.Incoming():
			if !ok {
				break HandlerLoop
			}
			action = serv.actions[msg.Action]

			if action != nil{
				// yay
				action.callback(msg, client)
			} else {
				Error.Printf("do not know how to handle action `%s`", msg.Action)

				reply := NewMessage()
		    reply.SetMessageType(MESSAGE_TYPE_REPLY)
		    reply.SetEnvelope(ENVELOPE_JSON)
		    reply.SetRequestId(msg.RequestId)
		    reply.Write([]byte(`{"error": "no such action"}`))
				_,err := client.Send(reply)
				if err != nil {
					client.Close()
					break HandlerLoop
				}

			}
		case <- time.After(msgTimeout):
            reqIDString := strconv.Itoa(msg.RequestId)
			Error.Printf("\n%s - %s timeout... dying!", msg.Action, reqIDString) //TODO: include msg ID or # so that we can debug
			break HandlerLoop
		}
	}

	client.Close()
	serv.RemoveClient(client)

	Trace.Printf("done handling client")

}

func (serv *Service)RemoveClient(client *Client) (err error){
	serv.clientsM.Lock()
	defer serv.clientsM.Unlock()

	index := -1
	for i,entry := range serv.clients {
		if client == entry {
			index = i
			break
		}
	}

	if index == -1 {
		Error.Printf("tried removing client that wasn't being tracked")
		return fmt.Errorf("unknown client") // TODO can I get the client's IP?
	}

	client.Close()
	serv.clients = append(serv.clients[:index], serv.clients[index+1:]...)

	return nil
}

func (serv *Service)Stop(){
	// Sometimes we Stop() before service after service has been init but before it is started
	// The usual case is a bad config in another plugin
	if serv.listener != nil {
		serv.listener.Close()
	}
}

func (serv *Service)MarshalText() (b []byte, err error){
	var buf bytes.Buffer

	serviceProxy := ServiceAsServiceProxy(serv)

	classRecord,err := serviceProxy.MarshalJSON()//json.Marshal(&serviceProxy) //Marshal is mangling service actions
	if err != nil {
		return
	}
	sig, err := SignSHA256(classRecord, serv.cert.PrivateKey.(*rsa.PrivateKey))
	if err != nil {
		return
	}
	sigParts := stringToRows(sig, 76)

	buf.Write(classRecord)
	buf.WriteString("\n\n")
	buf.Write(serv.pemCert)
	buf.WriteString("\n\n")
	// buf.WriteString(sig)
	// buf.WriteString("\n\n")
	for _,part := range sigParts {
		buf.WriteString(part)
		buf.WriteString("\n")
	}
	buf.WriteString("\n")

	b = buf.Bytes()
	return
}

func stringToRows(input string, rowlen int) (output []string) {
	output = make([]string,0)

	if len(input) <= 76 {
		output = append(output, input)
	} else {
		substr := input[:]
		var row string
		var done bool = false
		for {
			if len(substr) > 76 {
				row = substr[0:76]
				substr = substr[76:]
			} else {
				row = substr[:]
				done = true
			}
			output = append(output,row)
			if done {
				break
			}
		}
	}

	return
}

func (serv *Service)generateRandomName() {
	randBytes := make([]byte, 18, 18)
	read,err := rand.Read(randBytes)
	if err != nil {
		err = fmt.Errorf("could not generate all rand bytes needed. only read %d of 18", read)
		return
	}
	base64RandBytes := base64.StdEncoding.EncodeToString(randBytes)

	var buffer bytes.Buffer
	buffer.WriteString(serv.humanName)
	buffer.WriteString("-")
	buffer.WriteString(base64RandBytes[0:])
	serv.name = string(buffer.Bytes())
}
<|endoftext|>


<commit_before>package schema

import (
	"strings"

	"github.com/acsellers/inflections"
	"github.com/drone/sqlgen/parse"
)

func Load(tree *parse.Node) *Table {
	table := new(Table)

	// local map of indexes, used for quick
	// lookups and de-duping.
	indexs := map[string]*Index{}

	// pluralizes the table name and then
	// formats in snake case.
	table.Name = inflections.Underscore(tree.Type)
	table.Name = inflections.Pluralize(table.Name)

	// each edge node in the tree is a column
	// in the table. Convert each edge node to
	// a Field structure.
	for _, node := range tree.Edges() {

		field := new(Field)

		// Lookup the SQL column type
		// TODO: move this to a function
		t, ok := parse.Types[node.Type]
		if ok {
			tt, ok := types[t]
			if !ok {
				tt = BLOB
			}
			field.Type = tt
		} else {
			field.Type = BLOB
		}

		// substitute tag variables
		if node.Tags != nil {

			if node.Tags.Skip {
				continue
			}

			// default ID and int64 to primary key
			// with auto-increment
			if node.Name == "ID" && node.Kind == parse.Int64 {
				node.Tags.Primary = true
				node.Tags.Auto = true
			}

			field.Auto = node.Tags.Auto
			field.Primary = node.Tags.Primary
			field.Size = node.Tags.Size

			if node.Tags.Primary {
				table.Primary = append(table.Primary, field)
			}

			if node.Tags.Index != "" {
				index, ok := indexs[node.Tags.Index]
				if !ok {
					index = new(Index)
					index.Name = node.Tags.Index
					indexs[index.Name] = index
					table.Index = append(table.Index, index)
				}
				index.Fields = append(index.Fields, field)
			}

			if node.Tags.Unique != "" {
				index, ok := indexs[node.Tags.Index]
				if !ok {
					index = new(Index)
					index.Name = node.Tags.Unique
					index.Unique = true
					indexs[index.Name] = index
					table.Index = append(table.Index, index)
				}
				index.Fields = append(index.Fields, field)
			}

			if node.Tags.Type != "" {
				t, ok := sqlTypes[node.Tags.Type]
				if ok {
					field.Type = t
				}
			}
		}

		// get the full path name
		path := node.Path()
		var parts []string
		for _, part := range path {
			if part.Tags != nil && part.Tags.Name != "" {
				parts = append(parts, part.Tags.Name)
				continue
			}

			parts = append(parts, part.Name)
		}
		field.Name = strings.Join(parts, "_")
		field.Name = inflections.Underscore(field.Name)

		table.Fields = append(table.Fields, field)
	}

	return table
}

// convert Go types to SQL types.
var types = map[uint8]int{
	parse.Bool:       BOOLEAN,
	parse.Int:        INTEGER,
	parse.Int8:       INTEGER,
	parse.Int16:      INTEGER,
	parse.Int32:      INTEGER,
	parse.Int64:      INTEGER,
	parse.Uint:       INTEGER,
	parse.Uint8:      INTEGER,
	parse.Uint16:     INTEGER,
	parse.Uint32:     INTEGER,
	parse.Uint64:     INTEGER,
	parse.Float32:    INTEGER,
	parse.Float64:    INTEGER,
	parse.Complex64:  INTEGER,
	parse.Complex128: INTEGER,
	parse.Interface:  BLOB,
	parse.Bytes:      BLOB,
	parse.String:     VARCHAR,
	parse.Map:        BLOB,
	parse.Slice:      BLOB,
}

var sqlTypes = map[string]int{
	"text":     VARCHAR,
	"varchar":  VARCHAR,
	"varchar2": VARCHAR,
	"number":   INTEGER,
	"integer":  INTEGER,
	"int":      INTEGER,
	"blob":     BLOB,
	"bytea":    BLOB,
}
<commit_msg>omit table name from field names<commit_after>package schema

import (
	"strings"

	"github.com/acsellers/inflections"
	"github.com/drone/sqlgen/parse"
)

func Load(tree *parse.Node) *Table {
	table := new(Table)

	// local map of indexes, used for quick
	// lookups and de-duping.
	indexs := map[string]*Index{}

	// pluralizes the table name and then
	// formats in snake case.
	table.Name = inflections.Underscore(tree.Type)
	table.Name = inflections.Pluralize(table.Name)

	// each edge node in the tree is a column
	// in the table. Convert each edge node to
	// a Field structure.
	for _, node := range tree.Edges() {

		field := new(Field)

		// Lookup the SQL column type
		// TODO: move this to a function
		t, ok := parse.Types[node.Type]
		if ok {
			tt, ok := types[t]
			if !ok {
				tt = BLOB
			}
			field.Type = tt
		} else {
			field.Type = BLOB
		}

		// substitute tag variables
		if node.Tags != nil {

			if node.Tags.Skip {
				continue
			}

			// default ID and int64 to primary key
			// with auto-increment
			if node.Name == "ID" && node.Kind == parse.Int64 {
				node.Tags.Primary = true
				node.Tags.Auto = true
			}

			field.Auto = node.Tags.Auto
			field.Primary = node.Tags.Primary
			field.Size = node.Tags.Size

			if node.Tags.Primary {
				table.Primary = append(table.Primary, field)
			}

			if node.Tags.Index != "" {
				index, ok := indexs[node.Tags.Index]
				if !ok {
					index = new(Index)
					index.Name = node.Tags.Index
					indexs[index.Name] = index
					table.Index = append(table.Index, index)
				}
				index.Fields = append(index.Fields, field)
			}

			if node.Tags.Unique != "" {
				index, ok := indexs[node.Tags.Index]
				if !ok {
					index = new(Index)
					index.Name = node.Tags.Unique
					index.Unique = true
					indexs[index.Name] = index
					table.Index = append(table.Index, index)
				}
				index.Fields = append(index.Fields, field)
			}

			if node.Tags.Type != "" {
				t, ok := sqlTypes[node.Tags.Type]
				if ok {
					field.Type = t
				}
			}
		}

		// get the full path name
		// omit table name
		path := node.Path()[1:]
		var parts []string
		for _, part := range path {
			if part.Tags != nil && part.Tags.Name != "" {
				parts = append(parts, part.Tags.Name)
				continue
			}

			parts = append(parts, part.Name)
		}
		field.Name = strings.Join(parts, "_")
		field.Name = inflections.Underscore(field.Name)

		table.Fields = append(table.Fields, field)
	}

	return table
}

// convert Go types to SQL types.
var types = map[uint8]int{
	parse.Bool:       BOOLEAN,
	parse.Int:        INTEGER,
	parse.Int8:       INTEGER,
	parse.Int16:      INTEGER,
	parse.Int32:      INTEGER,
	parse.Int64:      INTEGER,
	parse.Uint:       INTEGER,
	parse.Uint8:      INTEGER,
	parse.Uint16:     INTEGER,
	parse.Uint32:     INTEGER,
	parse.Uint64:     INTEGER,
	parse.Float32:    INTEGER,
	parse.Float64:    INTEGER,
	parse.Complex64:  INTEGER,
	parse.Complex128: INTEGER,
	parse.Interface:  BLOB,
	parse.Bytes:      BLOB,
	parse.String:     VARCHAR,
	parse.Map:        BLOB,
	parse.Slice:      BLOB,
}

var sqlTypes = map[string]int{
	"text":     VARCHAR,
	"varchar":  VARCHAR,
	"varchar2": VARCHAR,
	"number":   INTEGER,
	"integer":  INTEGER,
	"int":      INTEGER,
	"blob":     BLOB,
	"bytea":    BLOB,
}
<|endoftext|>


<commit_before>// vagrant implements the packer.PostProcessor interface and adds a
// post-processor that turns artifacts of known builders into Vagrant
// boxes.
package vagrant

import (
	"compress/flate"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"text/template"

	"github.com/mitchellh/packer/common"
	"github.com/mitchellh/packer/packer"
)

var builtins = map[string]string{
	"mitchellh.amazonebs":       "aws",
	"mitchellh.amazon.instance": "aws",
	"mitchellh.virtualbox":      "virtualbox",
	"mitchellh.vmware":          "vmware",
	"pearkes.digitalocean":      "digitalocean",
}

type Config struct {
	common.PackerConfig `mapstructure:",squash"`

	Include             []string `mapstructure:"include"`
	OutputPath          string   `mapstructure:"output"`
	VagrantfileTemplate string   `mapstructure:"vagrantfile_template"`
	CompressionLevel    int      `mapstructure:"compression_level"`

	tpl *packer.ConfigTemplate
}

// OutputPathTemplate is the structure that is availalable within the
// OutputPath variables.
type OutputPathTemplate struct {
	ArtifactId string
	BuildName  string
	Provider   string
}

type PostProcessor struct {
	config Config
}

type VagrantfileTemplate struct {
	ProviderVagrantfile string
	CustomVagrantfile   string
}

func (p *PostProcessor) Configure(raws ...interface{}) error {
	md, err := common.DecodeConfig(&p.config, raws...)
	if err != nil {
		return err
	}

	p.config.tpl, err = packer.NewConfigTemplate()
	if err != nil {
		return err
	}
	p.config.tpl.UserVars = p.config.PackerUserVars

	// Defaults
	if p.config.OutputPath == "" {
		p.config.OutputPath = "packer_{{ .BuildName }}_{{.Provider}}.box"
	}

	found := false
	for _, k := range md.Keys {
		if k == "compression_level" {
			found = true
			break
		}
	}

	if !found {
		p.config.CompressionLevel = flate.DefaultCompression
	}

	// Accumulate any errors
	errs := common.CheckUnusedConfig(md)

	validates := map[string]*string{
		"output":               &p.config.OutputPath,
		"vagrantfile_template": &p.config.VagrantfileTemplate,
	}

	for n, ptr := range validates {
		if err := p.config.tpl.Validate(*ptr); err != nil {
			errs = packer.MultiErrorAppend(
				errs, fmt.Errorf("Error parsing %s: %s", n, err))
		}
	}

	if errs != nil && len(errs.Errors) > 0 {
		return errs
	}

	return nil
}

func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) {
	name, ok := builtins[artifact.BuilderId()]
	if !ok {
		return nil, false, fmt.Errorf(
			"Unknown artifact type, can't build box: %s", artifact.BuilderId())
	}

	provider := providerForName(name)
	if provider == nil {
		// This shouldn't happen since we hard code all of these ourselves
		panic(fmt.Sprintf("bad provider name: %s", name))
	}

	ui.Say(fmt.Sprintf("Creating Vagrant box for '%s' provider", name))

	outputPath, err := p.config.tpl.Process(p.config.OutputPath, &OutputPathTemplate{
		ArtifactId: artifact.Id(),
		BuildName:  p.config.PackerBuildName,
		Provider:   name,
	})
	if err != nil {
		return nil, false, err
	}

	// Create a temporary directory for us to build the contents of the box in
	dir, err := ioutil.TempDir("", "packer")
	if err != nil {
		return nil, false, err
	}
	defer os.RemoveAll(dir)

	// Copy all of the includes files into the temporary directory
	for _, src := range p.config.Include {
		ui.Message(fmt.Sprintf("Copying from include: %s", src))
		dst := filepath.Join(dir, filepath.Base(src))
		if err := CopyContents(dst, src); err != nil {
			err = fmt.Errorf("Error copying include file: %s\n\n%s", src, err)
			return nil, false, err
		}
	}

	// Run the provider processing step
	vagrantfile, metadata, err := provider.Process(ui, artifact, dir)
	if err != nil {
		return nil, false, err
	}

	// Write the metadata we got
	if err := WriteMetadata(dir, metadata); err != nil {
		return nil, false, err
	}

	// Write our Vagrantfile
	var customVagrantfile string
	if p.config.VagrantfileTemplate != "" {
		ui.Message(fmt.Sprintf(
			"Using custom Vagrantfile: %s", p.config.VagrantfileTemplate))
		customBytes, err := ioutil.ReadFile(p.config.VagrantfileTemplate)
		if err != nil {
			return nil, false, err
		}

		customVagrantfile = string(customBytes)
	}

	f, err := os.Create(filepath.Join(dir, "Vagrantfile"))
	if err != nil {
		return nil, false, err
	}

	t := template.Must(template.New("root").Parse(boxVagrantfileContents))
	err = t.Execute(f, &VagrantfileTemplate{
		ProviderVagrantfile: vagrantfile,
		CustomVagrantfile:   customVagrantfile,
	})
	f.Close()
	if err != nil {
		return nil, false, err
	}

	// Create the box
	if err := DirToBox(outputPath, dir, ui, p.config.CompressionLevel); err != nil {
		return nil, false, err
	}

	return nil, false, nil
}

func providerForName(name string) Provider {
	switch name {
	case "virtualbox":
		return new(VBoxProvider)
	default:
		return nil
	}
}

const boxVagrantfileContents string = `
# The contents below were provided by the Packer Vagrant post-processor
{{ .ProviderVagrantfile }}

# The contents below (if any) are custom contents provided by the
# Packer template during image build.
{{ .CustomVagrantfile }}
`
<commit_msg>post-procssor/vagrant: don't export some things<commit_after>// vagrant implements the packer.PostProcessor interface and adds a
// post-processor that turns artifacts of known builders into Vagrant
// boxes.
package vagrant

import (
	"compress/flate"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"text/template"

	"github.com/mitchellh/packer/common"
	"github.com/mitchellh/packer/packer"
)

var builtins = map[string]string{
	"mitchellh.amazonebs":       "aws",
	"mitchellh.amazon.instance": "aws",
	"mitchellh.virtualbox":      "virtualbox",
	"mitchellh.vmware":          "vmware",
	"pearkes.digitalocean":      "digitalocean",
}

type Config struct {
	common.PackerConfig `mapstructure:",squash"`

	Include             []string `mapstructure:"include"`
	OutputPath          string   `mapstructure:"output"`
	VagrantfileTemplate string   `mapstructure:"vagrantfile_template"`
	CompressionLevel    int      `mapstructure:"compression_level"`

	tpl *packer.ConfigTemplate
}

type PostProcessor struct {
	config Config
}

func (p *PostProcessor) Configure(raws ...interface{}) error {
	md, err := common.DecodeConfig(&p.config, raws...)
	if err != nil {
		return err
	}

	p.config.tpl, err = packer.NewConfigTemplate()
	if err != nil {
		return err
	}
	p.config.tpl.UserVars = p.config.PackerUserVars

	// Defaults
	if p.config.OutputPath == "" {
		p.config.OutputPath = "packer_{{ .BuildName }}_{{.Provider}}.box"
	}

	found := false
	for _, k := range md.Keys {
		if k == "compression_level" {
			found = true
			break
		}
	}

	if !found {
		p.config.CompressionLevel = flate.DefaultCompression
	}

	// Accumulate any errors
	errs := common.CheckUnusedConfig(md)

	validates := map[string]*string{
		"output":               &p.config.OutputPath,
		"vagrantfile_template": &p.config.VagrantfileTemplate,
	}

	for n, ptr := range validates {
		if err := p.config.tpl.Validate(*ptr); err != nil {
			errs = packer.MultiErrorAppend(
				errs, fmt.Errorf("Error parsing %s: %s", n, err))
		}
	}

	if errs != nil && len(errs.Errors) > 0 {
		return errs
	}

	return nil
}

func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) {
	name, ok := builtins[artifact.BuilderId()]
	if !ok {
		return nil, false, fmt.Errorf(
			"Unknown artifact type, can't build box: %s", artifact.BuilderId())
	}

	provider := providerForName(name)
	if provider == nil {
		// This shouldn't happen since we hard code all of these ourselves
		panic(fmt.Sprintf("bad provider name: %s", name))
	}

	ui.Say(fmt.Sprintf("Creating Vagrant box for '%s' provider", name))

	outputPath, err := p.config.tpl.Process(p.config.OutputPath, &outputPathTemplate{
		ArtifactId: artifact.Id(),
		BuildName:  p.config.PackerBuildName,
		Provider:   name,
	})
	if err != nil {
		return nil, false, err
	}

	// Create a temporary directory for us to build the contents of the box in
	dir, err := ioutil.TempDir("", "packer")
	if err != nil {
		return nil, false, err
	}
	defer os.RemoveAll(dir)

	// Copy all of the includes files into the temporary directory
	for _, src := range p.config.Include {
		ui.Message(fmt.Sprintf("Copying from include: %s", src))
		dst := filepath.Join(dir, filepath.Base(src))
		if err := CopyContents(dst, src); err != nil {
			err = fmt.Errorf("Error copying include file: %s\n\n%s", src, err)
			return nil, false, err
		}
	}

	// Run the provider processing step
	vagrantfile, metadata, err := provider.Process(ui, artifact, dir)
	if err != nil {
		return nil, false, err
	}

	// Write the metadata we got
	if err := WriteMetadata(dir, metadata); err != nil {
		return nil, false, err
	}

	// Write our Vagrantfile
	var customVagrantfile string
	if p.config.VagrantfileTemplate != "" {
		ui.Message(fmt.Sprintf(
			"Using custom Vagrantfile: %s", p.config.VagrantfileTemplate))
		customBytes, err := ioutil.ReadFile(p.config.VagrantfileTemplate)
		if err != nil {
			return nil, false, err
		}

		customVagrantfile = string(customBytes)
	}

	f, err := os.Create(filepath.Join(dir, "Vagrantfile"))
	if err != nil {
		return nil, false, err
	}

	t := template.Must(template.New("root").Parse(boxVagrantfileContents))
	err = t.Execute(f, &vagrantfileTemplate{
		ProviderVagrantfile: vagrantfile,
		CustomVagrantfile:   customVagrantfile,
	})
	f.Close()
	if err != nil {
		return nil, false, err
	}

	// Create the box
	if err := DirToBox(outputPath, dir, ui, p.config.CompressionLevel); err != nil {
		return nil, false, err
	}

	return nil, false, nil
}

func providerForName(name string) Provider {
	switch name {
	case "virtualbox":
		return new(VBoxProvider)
	default:
		return nil
	}
}

// OutputPathTemplate is the structure that is availalable within the
// OutputPath variables.
type outputPathTemplate struct {
	ArtifactId string
	BuildName  string
	Provider   string
}

type vagrantfileTemplate struct {
	ProviderVagrantfile string
	CustomVagrantfile   string
}

const boxVagrantfileContents string = `
# The contents below were provided by the Packer Vagrant post-processor
{{ .ProviderVagrantfile }}

# The contents below (if any) are custom contents provided by the
# Packer template during image build.
{{ .CustomVagrantfile }}
`
<|endoftext|>


<commit_before>package models

import (
	"appengine"
	"appengine/datastore"
	"time"
)

const confTimeFormat = "15:04"
const confDateFormat = "2006-1-2"

//Config stores central configuration in Datastore.
//There is always only one Config record in Datastore.
type Config struct {
	StandardOn     time.Time
	StandardOff    time.Time
	OverrideOn     bool
	OverrideOff    bool
	UpdateInterval int
}

//GetKey returns key of the Datastore Config record.
func (c Config) GetKey(ctx appengine.Context) (k *datastore.Key, err error) {
	k, err = datastore.NewQuery("Config").KeysOnly().Run(ctx).Next(nil)
	return
}

//SaveConfig saves data provided into the Config record.
func (c Config) SaveConfig(ctx appengine.Context) (err error) {
	var key *datastore.Key
	key, err = c.GetKey(ctx)
	if err == datastore.Done {
		key = datastore.NewIncompleteKey(ctx, "Config", nil)
	} else if err != nil {
		return
	}

	c.StandardOn = normalizeTime(standardOn)
	c.StandardOff = normalizeTime(standardOff)

	_, err = datastore.Put(ctx, key, c)
	if err != nil {
		return
	}

	DeleteQueryTimesFor(Config{}, ctx)
	return
}

//GetConfig fetches the Config record from Datastore and
//returns its data.
func GetConfig(ctx appengine.Context) (c Config, err error) {
	var conf Config
	_, err = datastore.NewQuery("Config").Run(ctx).Next(&c)
	if err != nil {
		return
	}
	return
}

type TimeConfig struct {
	Date time.Time
	On   time.Time
	Off  time.Time
	Key  datastore.Key `datastore:"-"`
}

func NewTimeConfig(date, on, off time.Time) (tc TimeConfig) {
	tc = new(TimeConfig)
	tc.Date = date
	tc.Off = off
	tc.On = on
	return
}

func MakeTimeConfig(date, on, off time.Time, c appengine.Context) (tc TimeConfig, err error) {
	tc = NewTimeConfig(date, on, off)
	err = tc.Save()
	return
}

func (tc *TimeConfig) Save(c appengine.Context) (err error) {
	var k *datastore.Key
	if tc.Key == nil {
		confKey, err := Config{}.GetKey(c)
		if err != nil {
			return
		}

		k, err = datastore.NewIncompleteKey(c, "TimeConfig", confKey)
		if err != nil {
			return
		}
		tc.Key = k.Encode()
	} else {
		k, err = datastore.DecodeKey(tc.Key)
		if err != nil {
			return
		}
	}
	_, err = datastore.Put(c, k, tc)
	return
}

func normalizeDate(t time.Time) time.Time {
	return time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, Tz)
}

func normalizeTime(t time.Time) time.Time {
	return time.Date(0, 0, 0, t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), Tz)
}
<commit_msg>Changed complete override settings<commit_after>package models

import (
	"appengine"
	"appengine/datastore"
	"time"
)

const (
	ConfTimeFormat = "15:04"
	ConfDateFormat = "2006-1-2"
	OverrideOn     = 1
	OverrideOff    = -1
	NoOverride     = 0
)

//Config stores central configuration in Datastore.
//There is always only one Config record in Datastore.
type Config struct {
	StandardOn     time.Time
	StandardOff    time.Time
	OverrideState  int8
	UpdateInterval int
}

//GetKey returns key of the Datastore Config record.
func (c Config) GetKey(ctx appengine.Context) (k *datastore.Key, err error) {
	k, err = datastore.NewQuery("Config").KeysOnly().Run(ctx).Next(nil)
	return
}

//SaveConfig saves data provided into the Config record.
func (c Config) SaveConfig(ctx appengine.Context) (err error) {
	var key *datastore.Key
	key, err = c.GetKey(ctx)
	if err == datastore.Done {
		key = datastore.NewIncompleteKey(ctx, "Config", nil)
	} else if err != nil {
		return
	}

	c.StandardOn = normalizeTime(standardOn)
	c.StandardOff = normalizeTime(standardOff)

	_, err = datastore.Put(ctx, key, c)
	if err != nil {
		return
	}

	DeleteQueryTimesFor(Config{}, ctx)
	return
}

//GetConfig fetches the Config record from Datastore and
//returns its data.
func GetConfig(ctx appengine.Context) (c Config, err error) {
	var conf Config
	_, err = datastore.NewQuery("Config").Run(ctx).Next(&c)
	if err != nil {
		return
	}
	return
}

type TimeConfig struct {
	Date time.Time
	On   time.Time
	Off  time.Time
	Key  datastore.Key `datastore:"-"`
}

func NewTimeConfig(date, on, off time.Time) (tc TimeConfig) {
	tc = new(TimeConfig)
	tc.Date = date
	tc.Off = off
	tc.On = on
	return
}

func MakeTimeConfig(date, on, off time.Time, c appengine.Context) (tc TimeConfig, err error) {
	tc = NewTimeConfig(date, on, off)
	err = tc.Save()
	return
}

func (tc *TimeConfig) Save(c appengine.Context) (err error) {
	var k *datastore.Key
	if tc.Key == nil {
		confKey, err := Config{}.GetKey(c)
		if err != nil {
			return
		}

		k, err = datastore.NewIncompleteKey(c, "TimeConfig", confKey)
		if err != nil {
			return
		}
		tc.Key = k.Encode()
	} else {
		k, err = datastore.DecodeKey(tc.Key)
		if err != nil {
			return
		}
	}
	_, err = datastore.Put(c, k, tc)
	return
}

func normalizeDate(t time.Time) time.Time {
	return time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, Tz)
}

func normalizeTime(t time.Time) time.Time {
	return time.Date(0, 0, 0, t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), Tz)
}
<|endoftext|>


<commit_before>/*
	Port of https://github.com/coreos/locksmith/blob/master/lock/etcd.go
	from etcd to Consul
*/

package lock

import (
	"encoding/json"
	"errors"
	api "github.com/armon/consul-api"
)

var (
	CheckAndSetFailedErr = errors.New("Someone else modified the semaphore")
)

// ConsulLockClient is a wrapper around the consul-api client
// that provides simple primitives to operate on a named semaphore
// stored as a Consul KV.
type ConsulLockClient struct {
	Path   string
	client *api.Client
}

func NewConsulLockClient(apiClient *api.Client) (client *ConsulLockClient, err error) {
	client = &ConsulLockClient{client: apiClient}
	err = nil
	return
}

func (c *ConsulLockClient) SetPath(path string) error {
	c.Path = path
	return nil
}

func (c *ConsulLockClient) Init() (err error) {
	if c.Path == "" {
		return errors.New("cannot initialize semaphore without a path")
	}

	sem := newSemaphore()
	b, err := json.Marshal(sem)
	if err != nil {
		return err
	}

	kv := c.client.KV()

	pair, _, err := kv.Get(c.Path, nil)
	if err != nil {
		return err
	}

	if pair == nil {
		p := &api.KVPair{Key: c.Path, Value: b}
		_, err := kv.Put(p, nil)
		if err != nil {
			return err
		}
	}
	return nil
}

func (c *ConsulLockClient) Get() (sem *Semaphore, err error) {
	kv := c.client.KV()
	pair, _, err := kv.Get(c.Path, nil)
	if err != nil {
		return nil, err
	}

	sem = &Semaphore{}
	err = json.Unmarshal([]byte(pair.Value), sem)
	if err != nil {
		return nil, err
	}

	sem.Index = pair.ModifyIndex

	return sem, nil
}

func (c *ConsulLockClient) Set(sem *Semaphore) (err error) {
	if sem == nil {
		return errors.New("cannot set nil semaphore")
	}
	b, err := json.Marshal(sem)
	if err != nil {
		return err
	}

	pair := &api.KVPair{Key: c.Path, Value: b}
	pair.ModifyIndex = sem.Index

	kv := c.client.KV()

	written, _, err := kv.CAS(pair, nil)
	if err != nil {
		return err
	}

	if written != true {
		return CheckAndSetFailedErr
	}

	return nil
}

func (c *ConsulLockClient) Watch(sem *Semaphore) (changed bool, err error) {
	// naive first pass, doesn't stop anything
	return true, nil
}
<commit_msg>Sketch of how to proceed.<commit_after>/*
	Port of https://github.com/coreos/locksmith/blob/master/lock/etcd.go
	from etcd to Consul
*/

package lock

import (
	"encoding/json"
	"errors"
	api "github.com/armon/consul-api"
)

var (
	CheckAndSetFailedErr = errors.New("Someone else modified the semaphore")
)

// ConsulLockClient is a wrapper around the consul-api client
// that provides simple primitives to operate on a named semaphore
// stored as a Consul KV.
type ConsulLockClient struct {
	Path   string
	client *api.Client
}

func NewConsulLockClient(apiClient *api.Client) (client *ConsulLockClient, err error) {
	client = &ConsulLockClient{client: apiClient}
	err = nil
	return
}

func (c *ConsulLockClient) SetPath(path string) error {
	c.Path = path
	return nil
}

func (c *ConsulLockClient) Init() (err error) {
	if c.Path == "" {
		return errors.New("cannot initialize semaphore without a path")
	}

	sem := newSemaphore()
	b, err := json.Marshal(sem)
	if err != nil {
		return err
	}

	kv := c.client.KV()

	pair, _, err := kv.Get(c.Path, nil)
	if err != nil {
		return err
	}

	if pair == nil {
		p := &api.KVPair{Key: c.Path, Value: b}
		_, err := kv.Put(p, nil)
		if err != nil {
			return err
		}
	}
	return nil
}

func (c *ConsulLockClient) Get() (sem *Semaphore, err error) {
	kv := c.client.KV()
	pair, _, err := kv.Get(c.Path, nil)
	if err != nil {
		return nil, err
	}

	sem = &Semaphore{}
	err = json.Unmarshal([]byte(pair.Value), sem)
	if err != nil {
		return nil, err
	}

	sem.Index = pair.ModifyIndex

	return sem, nil
}

func (c *ConsulLockClient) Set(sem *Semaphore) (err error) {
	if sem == nil {
		return errors.New("cannot set nil semaphore")
	}
	b, err := json.Marshal(sem)
	if err != nil {
		return err
	}

	pair := &api.KVPair{Key: c.Path, Value: b}
	pair.ModifyIndex = sem.Index

	kv := c.client.KV()

	written, _, err := kv.CAS(pair, nil)
	if err != nil {
		return err
	}

	if written != true {
		return CheckAndSetFailedErr
	}

	return nil
}

func (c *ConsulLockClient) Watch(sem *Semaphore) (changed bool, err error) {
	// naive first pass, doesn't stop anything
	return true, nil
	/*
		kv := c.client.KV()
		qo := &api.QueryOptions{
			AllowStale:        false,
			RequireConsistent: true,
			WaitIndex:         sem.Index,
		}
		changed, meta, err := kv.Get(c.Path, qo)
		if err != nil {
			return false, err
		}
	*/
}
<|endoftext|>


<commit_before>package logger

import (
	"log"
	"net/rpc"

	"github.com/Senior-Design-May1601/projectmain/control"
)

type LogWriter struct {
	client *rpc.Client
    responseChan chan *rpc.Call
}

func NewLogger(prefix string, flag int) *log.Logger {
	client, err := rpc.DialHTTP("tcp", control.CONTROL_PORT_CORE)
	if err != nil {
		log.Fatal(err)
	}

	writer := &LogWriter{
        client: client,
        responseChan: make(chan *rpc.Call, 100)}

    go writer.handleResponses()

	return log.New(writer, prefix, flag)
}

func (x *LogWriter) Write(p []byte) (n int, err error) {
	var r int
	x.client.Go("LogManager.Log", p, &r, x.responseChan)
	return len(p), nil
}

func (x *LogWriter) handleResponses() {
    for response := range x.responseChan {
        if response.Error != nil {
            log.Fatal("Log manager error:", response.Error)
        }
    }
}
<commit_msg>go fmt<commit_after>package logger

import (
	"log"
	"net/rpc"

	"github.com/Senior-Design-May1601/projectmain/control"
)

type LogWriter struct {
	client       *rpc.Client
	responseChan chan *rpc.Call
}

func NewLogger(prefix string, flag int) *log.Logger {
	client, err := rpc.DialHTTP("tcp", control.CONTROL_PORT_CORE)
	if err != nil {
		log.Fatal(err)
	}

	writer := &LogWriter{
		client:       client,
		responseChan: make(chan *rpc.Call, 100)}

	go writer.handleResponses()

	return log.New(writer, prefix, flag)
}

func (x *LogWriter) Write(p []byte) (n int, err error) {
	var r int
	x.client.Go("LogManager.Log", p, &r, x.responseChan)
	return len(p), nil
}

func (x *LogWriter) handleResponses() {
	for response := range x.responseChan {
		if response.Error != nil {
			log.Fatal("Log manager error:", response.Error)
		}
	}
}
<|endoftext|>


<commit_before>// Copyright 2013 Carlos Brando. All rights reserved.
// Use of this source code is governed by a MIT license
// that can be found in the LICENSE file.

package main

import (
	"fmt"
	"os/exec"
	"regexp"
	"strings"

	"github.com/carlosbrando/lunchy/agents"
)

func (c *Command) status() error {
	cmd := exec.Command("launchctl", "list")

	out, err := cmd.Output()
	if err != nil {
		return err
	}

	output := strings.Split(string(out), "\n")

	agents, err := agents.Find(c.pattern)
	if err != nil {
		return err
	}

	for _, line := range output {
		for _, agent := range agents {
			matched, err := regexp.MatchString(agent.Name, line)
			if err != nil {
				return err
			}

			if matched {
				fmt.Println(line)
			}
		}
	}

	return nil
}
<commit_msg>Make it better than the original version.<commit_after>// Copyright 2013 Carlos Brando. All rights reserved.
// Use of this source code is governed by a MIT license
// that can be found in the LICENSE file.

package main

import (
	"fmt"
	"os/exec"
	"regexp"
	"strings"

	"github.com/carlosbrando/lunchy/agents"
)

var headerPrinted bool = false

// printHeader prints the header if it was not printed before.
func printHeader(header string) {
	if !headerPrinted {
		fmt.Println(header)
		headerPrinted = true
	}
}

func (c *Command) status() error {
	cmd := exec.Command("launchctl", "list")

	out, err := cmd.Output()
	if err != nil {
		return err
	}

	output := strings.Split(string(out), "\n")

	agents, err := agents.Find(c.pattern)
	if err != nil {
		return err
	}

	for _, line := range output {
		for _, agent := range agents {
			matched, err := regexp.MatchString(agent.Name, line)
			if err != nil {
				return err
			}

			if matched {
				printHeader(output[0])
				fmt.Println(line)
			}
		}
	}

	return nil
}
<|endoftext|>


<commit_before>package lunk

import (
	"bytes"
	"encoding/json"
	"reflect"
	"regexp"
	"testing"
	"time"
)

func TestJSONEventLoggerLog(t *testing.T) {
	ev := mockEvent{Example: "whee"}

	buf := bytes.NewBuffer(nil)
	logger := NewJSONEventLogger(buf)
	id := NewRootEventID()
	logger.Log(id, ev)

	var e Entry
	if err := json.Unmarshal(buf.Bytes(), &e); err != nil {
		t.Fatal(err)
	}

	if e.Schema != "example" {
		t.Errorf("Unexpected schema: %v", e.Schema)
	}

	if e.Root != id.Root {
		t.Errorf("Root was %v, but expected %v", e.Root, id.Root)
	}

	if e.ID != id.ID {
		t.Errorf("ID was %v, but expected %v", e.ID, id.ID)
	}

	if e.Parent != 0 {
		t.Errorf("Parent was %v, but expected %v", e.Parent, 0)
	}

	if time.Now().Sub(e.Time) > 5*time.Millisecond {
		t.Errorf("Unexpectedly old timestamp: %v", e.Time)
	}

	if e.Host == "" {
		t.Errorf("Blank hostname for meta data")
	}

	if e.PID == 0 {
		t.Errorf("Blank PID for meta data")
	}

	expected := map[string]string{
		"example": "whee",
	}
	actual := e.Properties
	if !reflect.DeepEqual(actual, expected) {
		t.Errorf("Properties were %+v, expected %+v", actual, expected)
	}
}

func TestTextLogger(t *testing.T) {
	ev := mockEvent{Example: "whee"}

	buf := bytes.NewBuffer(nil)
	logger := NewTextEventLogger(buf)
	id := EventID{
		Root:   100,
		Parent: 150,
		ID:     200,
	}
	logger.Log(id, ev)

	expected := regexp.MustCompile(
		`^time="[\d]{4}-[\d]{2}-[\d]{2}T[\d]{2}:[\d]{2}:[\d]{2}Z"` +
			` host="[^"]+"` +
			` pid="[\d]+"` +
			` deploy="[^"]*"` +
			` schema="example"` +
			` id="00000000000000c8"` +
			` root="0000000000000064"` +
			` parent="0000000000000096"` +
			` p:example="whee"` +
			`\n$`,
	)
	actual := buf.String()

	if !expected.MatchString(actual) {
		t.Errorf("Was `%s` but expected to match `%s`", actual, expected)
	}
}

func TestTextLoggerElidedParentID(t *testing.T) {
	ev := mockEvent{Example: "whee"}

	buf := bytes.NewBuffer(nil)
	logger := NewTextEventLogger(buf)
	id := EventID{
		Root: 100,
		ID:   200,
	}
	logger.Log(id, ev)

	expected := regexp.MustCompile(
		`^time="[\d]{4}-[\d]{2}-[\d]{2}T[\d]{2}:[\d]{2}:[\d]{2}Z"` +
			` host="[^"]+"` +
			` pid="[\d]+"` +
			` deploy="[^"]*"` +
			` schema="example"` +
			` id="00000000000000c8"` +
			` root="0000000000000064"` +
			` p:example="whee"` +
			`\n$`,
	)
	actual := buf.String()

	if !expected.MatchString(actual) {
		t.Errorf("Was `%s` but expected to match `%s`", actual, expected)
	}
}

type nullWriter struct{}

func (nullWriter) Write(a []byte) (int, error) {
	return len(a), nil
}

func BenchmarkJSONEventLogger(b *testing.B) {
	ev := mockEvent{Example: "whee"}
	logger := NewJSONEventLogger(nullWriter{})
	id := NewRootEventID()
	b.ReportAllocs()
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		logger.Log(id, ev)
	}
}
<commit_msg>Fix some test names and add a benchmark.<commit_after>package lunk

import (
	"bytes"
	"encoding/json"
	"reflect"
	"regexp"
	"testing"
	"time"
)

func TestJSONEventLoggerLog(t *testing.T) {
	ev := mockEvent{Example: "whee"}

	buf := bytes.NewBuffer(nil)
	logger := NewJSONEventLogger(buf)
	id := NewRootEventID()
	logger.Log(id, ev)

	t.Log(buf.String())

	var e Entry
	if err := json.Unmarshal(buf.Bytes(), &e); err != nil {
		t.Fatal(err)
	}

	if e.Schema != "example" {
		t.Errorf("Unexpected schema: %v", e.Schema)
	}

	if e.Root != id.Root {
		t.Errorf("Root was %v, but expected %v", e.Root, id.Root)
	}

	if e.ID != id.ID {
		t.Errorf("ID was %v, but expected %v", e.ID, id.ID)
	}

	if e.Parent != 0 {
		t.Errorf("Parent was %v, but expected %v", e.Parent, 0)
	}

	if time.Now().Sub(e.Time) > 5*time.Millisecond {
		t.Errorf("Unexpectedly old timestamp: %v", e.Time)
	}

	if e.Host == "" {
		t.Errorf("Blank hostname for meta data")
	}

	if e.PID == 0 {
		t.Errorf("Blank PID for meta data")
	}

	expected := map[string]string{
		"example": "whee",
	}
	actual := e.Properties
	if !reflect.DeepEqual(actual, expected) {
		t.Errorf("Properties were %+v, expected %+v", actual, expected)
	}
}

func TestTextEventLoggerLog(t *testing.T) {
	ev := mockEvent{Example: "whee"}

	buf := bytes.NewBuffer(nil)
	logger := NewTextEventLogger(buf)
	id := EventID{
		Root:   100,
		Parent: 150,
		ID:     200,
	}
	logger.Log(id, ev)

	t.Log(buf.String())

	expected := regexp.MustCompile(
		`^time="[\d]{4}-[\d]{2}-[\d]{2}T[\d]{2}:[\d]{2}:[\d]{2}Z"` +
			` host="[^"]+"` +
			` pid="[\d]+"` +
			` deploy="[^"]*"` +
			` schema="example"` +
			` id="00000000000000c8"` +
			` root="0000000000000064"` +
			` parent="0000000000000096"` +
			` p:example="whee"` +
			`\n$`,
	)
	actual := buf.String()

	if !expected.MatchString(actual) {
		t.Errorf("Was `%s` but expected to match `%s`", actual, expected)
	}
}

func TestTextEventLoggerLogElidedParentID(t *testing.T) {
	ev := mockEvent{Example: "whee"}

	buf := bytes.NewBuffer(nil)
	logger := NewTextEventLogger(buf)
	id := EventID{
		Root: 100,
		ID:   200,
	}
	logger.Log(id, ev)

	expected := regexp.MustCompile(
		`^time="[\d]{4}-[\d]{2}-[\d]{2}T[\d]{2}:[\d]{2}:[\d]{2}Z"` +
			` host="[^"]+"` +
			` pid="[\d]+"` +
			` deploy="[^"]*"` +
			` schema="example"` +
			` id="00000000000000c8"` +
			` root="0000000000000064"` +
			` p:example="whee"` +
			`\n$`,
	)
	actual := buf.String()

	if !expected.MatchString(actual) {
		t.Errorf("Was `%s` but expected to match `%s`", actual, expected)
	}
}

type nullWriter struct{}

func (nullWriter) Write(a []byte) (int, error) {
	return len(a), nil
}

func BenchmarkJSONEventLogger(b *testing.B) {
	ev := mockEvent{Example: "whee"}
	logger := NewJSONEventLogger(nullWriter{})
	id := NewRootEventID()
	b.ReportAllocs()
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		logger.Log(id, ev)
	}
}

func BenchmarkTextEventLogger(b *testing.B) {
	ev := mockEvent{Example: "whee"}
	logger := NewTextEventLogger(nullWriter{})
	id := NewRootEventID()
	b.ReportAllocs()
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		logger.Log(id, ev)
	}
}
<|endoftext|>


<commit_before>package controllers

import (
	"github.com/piotrkowalczuk/gowik-tracker/models"
	"github.com/piotrkowalczuk/gowik-tracker/services"
	"labix.org/v2/mgo/bson"
	"net/http"
	"time"
)

type TrackController struct {
	BaseController
}

func (tc *TrackController) Get() {
	var err error

	w := tc.Ctx.ResponseWriter
	r := tc.Ctx.Request
	mongoDateNow := models.NewMongoDate(time.Now())
	domain := r.Header.Get("Origin")
	visitId := tc.GetString("v.id")
	var visit models.Visit

	page := models.Page{
		Title: tc.GetString("p.t"),
		Host:  tc.GetString("p.h"),
		Url:   tc.GetString("p.u"),
	}

	action := models.Action{
		Id:              bson.NewObjectId(),
		Referrer:        tc.GetString("r"),
		Page:            &page,
		CreatedAt:       mongoDateNow.DateTime,
		CreatedAtBucket: mongoDateNow.Bucket,
	}

	if len(visitId) == 0 {
		tc.log.Debug("New visit")

		plugins := models.Plugins{}
		plugins.Java, _ = tc.GetBool("b.p.j")

		window := models.Window{}
		window.Width, _ = tc.GetInt("b.w.w")
		window.Height, _ = tc.GetInt("b.w.h")

		browser := models.Browser{
			Name:         tc.GetString("b.n"),
			Version:      tc.GetString("b.v"),
			MajorVersion: tc.GetString("b.mv"),
			UserAgent:    r.UserAgent(),
			Platform:     tc.GetString("b.p"),
			Plugins:      plugins,
			Window:       window,
		}
		browser.Cookie, _ = tc.GetBool("b.c")
		browser.IsOnline, _ = tc.GetBool("b.io")

		os := models.OperatingSystem{
			Name:    tc.GetString("os.n"),
			Version: tc.GetString("os.v"),
		}

		screen := models.Screen{}
		screen.Width, _ = tc.GetInt("s.w")
		screen.Height, _ = tc.GetInt("s.h")

		device := models.Device{
			Name: tc.GetString("d.n"),
		}
		device.IsTablet, _ = tc.GetBool("d.it")
		device.IsPhone, _ = tc.GetBool("d.ip")
		device.IsMobile, _ = tc.GetBool("d.im")

		geoLocation, err := services.NewGeoLocation(r.RemoteAddr)
		location := models.Location{}
		if err == nil {
			location = *models.NewLocationFromGeoIP(geoLocation.Location)
		}

		visit = models.Visit{
			Id:                  bson.NewObjectId(),
			Referrer:            tc.GetString("r"),
			Language:            tc.GetString("lng"),
			Actions:             []*models.Action{&action},
			NbOfActions:         1,
			Location:            &location,
			Browser:             &browser,
			FirstPage:           &page,
			LastPage:            &page,
			OperatingSystem:     &os,
			Screen:              &screen,
			Device:              &device,
			CreatedAt:           mongoDateNow.DateTime,
			CreatedAtBucket:     mongoDateNow.Bucket,
			FirstActionAt:       mongoDateNow.DateTime,
			FirstActionAtBucket: mongoDateNow.Bucket,
			LastActionAt:        mongoDateNow.DateTime,
			LastActionAtBucket:  mongoDateNow.Bucket,
		}

		visitId = visit.Id.Hex()
		err = tc.MongoPool.Collection("visit").Insert(&visit)
		tc.abortIf(err, http.StatusInternalServerError)
	} else {
		tc.log.Debug("Existing visit #%s", visitId)

		err = tc.MongoPool.Collection("visit").UpdateId(
			bson.ObjectIdHex(visitId),
			bson.M{
				"$push": bson.M{"actions": action},
				"$inc":  bson.M{"nb_of_actions": 1},
				"$set": bson.M{
					"last_action_at":        mongoDateNow.DateTime,
					"last_action_at_bucket": mongoDateNow.Bucket,
					"last_page":             &page,
				},
			},
		)

		tc.abortIf(err, http.StatusInternalServerError)
	}

	w.Header().Set("Access-Control-Allow-Credentials", "true")
	w.Header().Set("Access-Control-Expose-Headers", "Gowik-Visit-Id")
	w.Header().Set("Access-Control-Allow-Origin", domain)
	w.Header().Set("Gowik-Visit-Id", visitId)
	http.ServeFile(w, r, "1x1.gif")
}
<commit_msg>SiteId added to tracking<commit_after>package controllers

import (
	"github.com/piotrkowalczuk/gowik-tracker/models"
	"github.com/piotrkowalczuk/gowik-tracker/services"
	"labix.org/v2/mgo/bson"
	"net/http"
	"time"
)

type TrackController struct {
	BaseController
}

func (tc *TrackController) Get() {
	var err error

	siteId, err := tc.GetInt("t.sid")
	tc.abortIf(err, http.StatusBadRequest)

	w := tc.Ctx.ResponseWriter
	r := tc.Ctx.Request
	mongoDateNow := models.NewMongoDate(time.Now())
	domain := r.Header.Get("Origin")
	visitId := tc.GetString("v.id")
	var visit models.Visit

	page := models.Page{
		Title: tc.GetString("p.t"),
		Host:  tc.GetString("p.h"),
		Url:   tc.GetString("p.u"),
	}

	action := models.Action{
		Id:              bson.NewObjectId(),
		Referrer:        tc.GetString("r"),
		Page:            &page,
		CreatedAt:       mongoDateNow.DateTime,
		CreatedAtBucket: mongoDateNow.Bucket,
	}

	if len(visitId) == 0 {
		tc.log.Debug("New visit")

		plugins := models.Plugins{}
		plugins.Java, _ = tc.GetBool("b.p.j")

		window := models.Window{}
		window.Width, _ = tc.GetInt("b.w.w")
		window.Height, _ = tc.GetInt("b.w.h")

		browser := models.Browser{
			Name:         tc.GetString("b.n"),
			Version:      tc.GetString("b.v"),
			MajorVersion: tc.GetString("b.mv"),
			UserAgent:    r.UserAgent(),
			Platform:     tc.GetString("b.p"),
			Plugins:      plugins,
			Window:       window,
		}
		browser.Cookie, _ = tc.GetBool("b.c")
		browser.IsOnline, _ = tc.GetBool("b.io")

		os := models.OperatingSystem{
			Name:    tc.GetString("os.n"),
			Version: tc.GetString("os.v"),
		}

		screen := models.Screen{}
		screen.Width, _ = tc.GetInt("s.w")
		screen.Height, _ = tc.GetInt("s.h")

		device := models.Device{
			Name: tc.GetString("d.n"),
		}
		device.IsTablet, _ = tc.GetBool("d.it")
		device.IsPhone, _ = tc.GetBool("d.ip")
		device.IsMobile, _ = tc.GetBool("d.im")

		geoLocation, err := services.NewGeoLocation(r.RemoteAddr)
		location := models.Location{}
		if err == nil {
			location = *models.NewLocationFromGeoIP(geoLocation.Location)
		}

		visit = models.Visit{
			Id:                  bson.NewObjectId(),
			Referrer:            tc.GetString("r"),
			Language:            tc.GetString("lng"),
			Actions:             []*models.Action{&action},
			NbOfActions:         1,
			SiteId:				 siteId,
			Location:            &location,
			Browser:             &browser,
			FirstPage:           &page,
			LastPage:            &page,
			OperatingSystem:     &os,
			Screen:              &screen,
			Device:              &device,
			CreatedAt:           mongoDateNow.DateTime,
			CreatedAtBucket:     mongoDateNow.Bucket,
			FirstActionAt:       mongoDateNow.DateTime,
			FirstActionAtBucket: mongoDateNow.Bucket,
			LastActionAt:        mongoDateNow.DateTime,
			LastActionAtBucket:  mongoDateNow.Bucket,
		}

		visitId = visit.Id.Hex()
		err = tc.MongoPool.Collection("visit").Insert(&visit)
		tc.abortIf(err, http.StatusInternalServerError)
	} else {
		tc.log.Debug("Existing visit #%s", visitId)

		err = tc.MongoPool.Collection("visit").UpdateId(
			bson.ObjectIdHex(visitId),
			bson.M{
				"$push": bson.M{"actions": action},
				"$inc":  bson.M{"nb_of_actions": 1},
				"$set": bson.M{
					"last_action_at":        mongoDateNow.DateTime,
					"last_action_at_bucket": mongoDateNow.Bucket,
					"last_page":             &page,
				},
			},
		)

		tc.abortIf(err, http.StatusInternalServerError)
	}

	w.Header().Set("Access-Control-Allow-Credentials", "true")
	w.Header().Set("Access-Control-Expose-Headers", "Gowik-Visit-Id")
	w.Header().Set("Access-Control-Allow-Origin", domain)
	w.Header().Set("Gowik-Visit-Id", visitId)
	http.ServeFile(w, r, "1x1.gif")
}
<|endoftext|>


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

// +build !windows,!darwin

package h5

/*
#cgo CFLAGS: -I/usr/include/hdf5/serial -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -D_FORTIFY_SOURCE=2 -g -O2 -Wformat -Werror=format-security
#cgo LDFLAGS: -L/usr/lib/x86_64-linux-gnu/hdf5/serial -lhdf5_hl -lhdf5 -Wl,-Bsymbolic-functions -Wl,-z,relro -lpthread -lsz -lz -ldl -lm -Wl,-rpath -Wl,/usr/lib/x86_64-linux-gnu/hdf5/serial
*/
import "C"

// NOTE: get flags with:
//
//   h5cc -show
<commit_msg>Remove -lsz flag in io/h5 compilation because Travis cannot find it<commit_after>// Copyright 2016 The Gosl Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build !windows,!darwin

package h5

/*
#cgo CFLAGS: -I/usr/include/hdf5/serial -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -D_FORTIFY_SOURCE=2 -g -O2 -Wformat -Werror=format-security
#cgo LDFLAGS: -L/usr/lib/x86_64-linux-gnu/hdf5/serial -lhdf5_hl -lhdf5 -Wl,-Bsymbolic-functions -Wl,-z,relro -lpthread -lz -ldl -lm -Wl,-rpath -Wl,/usr/lib/x86_64-linux-gnu/hdf5/serial
*/
import "C"

// NOTE: get flags with:
//
//   h5cc -show
<|endoftext|>