<commit_before>package sse

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

const (
	allowedContentType = "text/event-stream"
)

var (
	// ErrContentType error indicates the content-type header is not accepted
	ErrContentType = errors.New("eventsource: the content type of the stream is not allowed")

	// ErrUnauthorized error indicates an authorization error of the connection request
	ErrUnauthorized = errors.New("eventsource: connection is unauthorized")
)

// Function for modifying the http connection request.
type RequestModifier func(r *http.Request)

type (
	// EventSource connects and processes events from an HTTP server-sent events stream.
	EventSource struct {
		url              string
		requestModifiers []RequestModifier
		lastEventID      string
		d                *Decoder
		resp             *http.Response
		closed           bool
		closedMutex      *sync.RWMutex
		out              chan *MessageEvent
		readyState       chan Status
	}
)

// NewEventSource connects and returns an EventSource.
func NewEventSource(url string, requestModifiers ...RequestModifier) (*EventSource, error) {
	es := &EventSource{
		d:           nil,
		url:         url,
		out:         make(chan *MessageEvent),
		readyState:  make(chan Status, 128),
		closedMutex: new(sync.RWMutex),
	}
	es.requestModifiers = append(es.requestModifiers, requestModifiers...)
	return es, es.connect()
}

// connect does a connection attempt, if the operation fails, attempt reconnecting
// according to the spec.
func (es *EventSource) connect() (err error) {
	err = es.connectOnce()
	if err != nil {
		es.Close(err)
	}
	return
}

// reconnect to the stream several until the operation succeeds or the conditions
// to retry no longer hold true.
func (es *EventSource) reconnect() (err error) {
	for es.mustReconnect(err) {
		time.Sleep(time.Duration(es.d.Retry()) * time.Millisecond)
		err = es.connectOnce()
	}
	if err != nil {
		es.Close(err)
	}
	return
}

// Attempts to connect and updates internal status depending on the outcome.
func (es *EventSource) connectOnce() (err error) {
	es.readyState <- Status{Connecting, nil}
	es.resp, err = es.doHTTPConnect()
	if err != nil {
		return
	}
	es.readyState <- Status{Open, nil}
	es.d = NewDecoder(es.resp.Body)
	go es.consume()
	return
}

func (es *EventSource) doHTTPConnect() (*http.Response, error) {
	// Prepare request
	req, err := http.NewRequest("GET", es.url, nil)
	if err != nil {
		return nil, err
	}

	// apply request modifiers
	for _, requestModifier := range es.requestModifiers {
		requestModifier(req)
	}

	req.Header.Set("Accept", allowedContentType)
	req.Header.Set("Cache-Control", "no-store")
	if es.lastEventID != "" {
		req.Header.Set("Last-Event-ID", es.lastEventID)
	}

	// Check response
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return resp, err
	}

	if resp.StatusCode == 401 {
		return resp, ErrUnauthorized
	}

	if resp.Header.Get("Content-Type") != allowedContentType {
		return resp, ErrContentType
	}
	return resp, nil
}

func WithBasicAuth(username, password string) RequestModifier {
	return func(r *http.Request) {
		r.SetBasicAuth(username, password)
	}
}

func WithBearerTokenAuth(token string) RequestModifier {
	return func(r *http.Request) {
		r.Header.Add("Authorization", "Bearer "+token)
	}
}

// Method consume() must be called once connect() succeeds.
// It parses the input reader and assigns the event output channel accordingly.
func (es *EventSource) consume() {
	for {
		ev, err := es.d.Decode()
		if err != nil {
			if es.mustReconnect(err) {
				es.reconnect()
			} else {
				es.Close(err)
			}
			return
		}
		es.lastEventID = ev.LastEventID
		es.out <- ev
	}
}

// Clients will reconnect if the connection is closed;
// a client can be told to stop reconnecting using the HTTP 204 No Content response code.
func (es *EventSource) mustReconnect(err error) bool {
	es.closedMutex.RLock()
	defer es.closedMutex.RUnlock()
	if es.closed {
		return false
	}
	switch err {
	case ErrContentType:
		return false
	case io.ErrUnexpectedEOF:
		return true
	}
	if es.resp != nil && es.resp.StatusCode == http.StatusNoContent {
		return false
	}
	return true
}

// URL returns the event source URL.
func (es *EventSource) URL() string {
	return es.url
}

// MessageEvents returns a channel of received events.
func (es *EventSource) MessageEvents() <-chan *MessageEvent {
	return es.out
}

// ReadyState exposes a channel with updates on the ready state
// of the event source.
// It must be consumed together with MessageEvents.
func (es *EventSource) ReadyState() <-chan Status {
	return es.readyState
}

// Close the event source. Once closed, the event source cannot be re-used again.
func (es *EventSource) Close(err error) {
	es.closedMutex.Lock()
	defer es.closedMutex.Unlock()
	if es.closed {
		return
	}
	es.readyState <- Status{Closing, err}
	es.closed = true

	if es.resp != nil {
		es.resp.Body.Close()
	}

	close(es.out)
	es.readyState <- Status{Closed, err}
}
<commit_msg>improve content-type check<commit_after>package sse

import (
	"errors"
	"io"
	"net/http"
	"strings"
	"sync"
	"time"
)

const (
	allowedContentType = "text/event-stream"
)

var (
	// ErrContentType error indicates the content-type header is not accepted
	ErrContentType = errors.New("eventsource: the content type of the stream is not allowed")

	// ErrUnauthorized error indicates an authorization error of the connection request
	ErrUnauthorized = errors.New("eventsource: connection is unauthorized")
)

// Function for modifying the http connection request.
type RequestModifier func(r *http.Request)

type (
	// EventSource connects and processes events from an HTTP server-sent events stream.
	EventSource struct {
		url              string
		requestModifiers []RequestModifier
		lastEventID      string
		d                *Decoder
		resp             *http.Response
		closed           bool
		closedMutex      *sync.RWMutex
		out              chan *MessageEvent
		readyState       chan Status
	}
)

// NewEventSource connects and returns an EventSource.
func NewEventSource(url string, requestModifiers ...RequestModifier) (*EventSource, error) {
	es := &EventSource{
		d:           nil,
		url:         url,
		out:         make(chan *MessageEvent),
		readyState:  make(chan Status, 128),
		closedMutex: new(sync.RWMutex),
	}
	es.requestModifiers = append(es.requestModifiers, requestModifiers...)
	return es, es.connect()
}

// connect does a connection attempt, if the operation fails, attempt reconnecting
// according to the spec.
func (es *EventSource) connect() (err error) {
	err = es.connectOnce()
	if err != nil {
		es.Close(err)
	}
	return
}

// reconnect to the stream several until the operation succeeds or the conditions
// to retry no longer hold true.
func (es *EventSource) reconnect() (err error) {
	for es.mustReconnect(err) {
		time.Sleep(time.Duration(es.d.Retry()) * time.Millisecond)
		err = es.connectOnce()
	}
	if err != nil {
		es.Close(err)
	}
	return
}

// Attempts to connect and updates internal status depending on the outcome.
func (es *EventSource) connectOnce() (err error) {
	es.readyState <- Status{Connecting, nil}
	es.resp, err = es.doHTTPConnect()
	if err != nil {
		return
	}
	es.readyState <- Status{Open, nil}
	es.d = NewDecoder(es.resp.Body)
	go es.consume()
	return
}

func (es *EventSource) doHTTPConnect() (*http.Response, error) {
	// Prepare request
	req, err := http.NewRequest("GET", es.url, nil)
	if err != nil {
		return nil, err
	}

	// apply request modifiers
	for _, requestModifier := range es.requestModifiers {
		requestModifier(req)
	}

	req.Header.Set("Accept", allowedContentType)
	req.Header.Set("Cache-Control", "no-store")
	if es.lastEventID != "" {
		req.Header.Set("Last-Event-ID", es.lastEventID)
	}

	// Check response
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return resp, err
	}

	if resp.StatusCode == 401 {
		return resp, ErrUnauthorized
	}

	if !strings.Contains(resp.Header.Get("Content-Type"), allowedContentType) {
		return resp, ErrContentType
	}
	return resp, nil
}

func WithBasicAuth(username, password string) RequestModifier {
	return func(r *http.Request) {
		r.SetBasicAuth(username, password)
	}
}

func WithBearerTokenAuth(token string) RequestModifier {
	return func(r *http.Request) {
		r.Header.Add("Authorization", "Bearer "+token)
	}
}

// Method consume() must be called once connect() succeeds.
// It parses the input reader and assigns the event output channel accordingly.
func (es *EventSource) consume() {
	for {
		ev, err := es.d.Decode()
		if err != nil {
			if es.mustReconnect(err) {
				es.reconnect()
			} else {
				es.Close(err)
			}
			return
		}
		es.lastEventID = ev.LastEventID
		es.out <- ev
	}
}

// Clients will reconnect if the connection is closed;
// a client can be told to stop reconnecting using the HTTP 204 No Content response code.
func (es *EventSource) mustReconnect(err error) bool {
	es.closedMutex.RLock()
	defer es.closedMutex.RUnlock()
	if es.closed {
		return false
	}
	switch err {
	case ErrContentType:
		return false
	case io.ErrUnexpectedEOF:
		return true
	}
	if es.resp != nil && es.resp.StatusCode == http.StatusNoContent {
		return false
	}
	return true
}

// URL returns the event source URL.
func (es *EventSource) URL() string {
	return es.url
}

// MessageEvents returns a channel of received events.
func (es *EventSource) MessageEvents() <-chan *MessageEvent {
	return es.out
}

// ReadyState exposes a channel with updates on the ready state
// of the event source.
// It must be consumed together with MessageEvents.
func (es *EventSource) ReadyState() <-chan Status {
	return es.readyState
}

// Close the event source. Once closed, the event source cannot be re-used again.
func (es *EventSource) Close(err error) {
	es.closedMutex.Lock()
	defer es.closedMutex.Unlock()
	if es.closed {
		return
	}
	es.readyState <- Status{Closing, err}
	es.closed = true

	if es.resp != nil {
		es.resp.Body.Close()
	}

	close(es.out)
	es.readyState <- Status{Closed, err}
}
<|endoftext|>


<commit_before>package robustly
// Package robustly provides code to handle infrequent panics.

import (
	"bytes"
	"fmt"
	"runtime/debug"
	"time"
	"github.com/VividCortex/moving_average"
)

func Run(function func(), options map[string]int) int {
	// Set config options
	rateLimit := options["rateLimit"]
	timeout := options["timeout"]

	// We use a moving average to compute the rate of errors per second.
	avg := moving_average.NewMovingAverage(float64(timeout))
	before := time.Now()
	var startAboveLimit time.Time
	var belowLimit bool = true
	var beforeTimeout = true
	var totalPanics = 0
	var oktorun bool = true

	for oktorun {
		fmt.Println("running function resiliently, panic rate %f since %s",
								avg.Value(),
								startAboveLimit,
								)

		// Run the provided code and catch errors.
		func() {
			defer func() {
				localErr := recover()
				if localErr == nil {
					oktorun = false // The call to f() exited normally.
					return
				}

				totalPanics++
				after := time.Now()
				duration := after.Sub(before).Seconds()
				if duration > 0 {
					rate := 1.0 / duration
					avg.Add(rate)

					// Figure out whether we're above the rate limit and for how long
					if avg.Value() > float64(rateLimit) {
						if belowLimit {
							startAboveLimit = after
						}
						beforeTimeout =
							after.Before(startAboveLimit.Add(time.Second * time.Duration(timeout)))
						belowLimit = false
					} else {
						belowLimit = true
					}
				}
				before = after

				if !belowLimit && !beforeTimeout {
					panic(fmt.Sprintf("giving up after %d errors at %.2f/sec since %s",
						totalPanics, avg.Value(), startAboveLimit))
				}

				var buf bytes.Buffer
				fmt.Fprintf(&buf, "%v\n", localErr)
				buf.Write(debug.Stack())
				fmt.Println(buf.String())
			}()
			function()
			return
		}()

	}
	return totalPanics
}
<commit_msg>String interpolation in output messages<commit_after>package robustly
// Package robustly provides code to handle infrequent panics.

import (
	"bytes"
	"fmt"
	"runtime/debug"
	"time"
	"github.com/VividCortex/moving_average"
)

func Run(function func(), options map[string]int) int {
	// Set config options
	rateLimit := options["rateLimit"]
	timeout := options["timeout"]

	// We use a moving average to compute the rate of errors per second.
	avg := moving_average.NewMovingAverage(float64(timeout))
	before := time.Now()
	var startAboveLimit time.Time
	var belowLimit bool = true
	var beforeTimeout = true
	var totalPanics = 0
	var oktorun bool = true

	for oktorun {
		fmt.Printf("running function resiliently, panic rate %f since %s",
								avg.Value(),
								startAboveLimit,
								)

		// Run the provided code and catch errors.
		func() {
			defer func() {
				localErr := recover()
				if localErr == nil {
					oktorun = false // The call to f() exited normally.
					return
				}

				totalPanics++
				after := time.Now()
				duration := after.Sub(before).Seconds()
				if duration > 0 {
					rate := 1.0 / duration
					avg.Add(rate)

					// Figure out whether we're above the rate limit and for how long
					if avg.Value() > float64(rateLimit) {
						if belowLimit {
							startAboveLimit = after
						}
						beforeTimeout =
							after.Before(startAboveLimit.Add(time.Second * time.Duration(timeout)))
						belowLimit = false
					} else {
						belowLimit = true
					}
				}
				before = after

				if !belowLimit && !beforeTimeout {
					panic(fmt.Sprintf("giving up after %d errors at %.2f/sec since %s",
						totalPanics, avg.Value(), startAboveLimit))
				}

				var buf bytes.Buffer
				fmt.Fprintf(&buf, "%v\n", localErr)
				buf.Write(debug.Stack())
				fmt.Printf(buf.String())
			}()
			function()
			return
		}()

	}
	return totalPanics
}
<|endoftext|>


<commit_before>package rtm

import (
	"regexp"
	"strings"

	"github.com/firba1/slack"

	"github.com/gorilla/websocket"
)

type Conn struct {
	conn           *websocket.Conn
	messageCounter int
	userChanges    chan<- slack.User
	infoRequests   chan<- userInfoRequest
	cancel         chan struct{}
}

func (c *Conn) Close() error {
	close(c.cancel)
	return c.conn.Close()
}

type sendMessage struct {
	ID      int    `json:"id"`
	Type    string `json:"type"`
	Channel string `json:"channel"`
	Text    string `json:"text"`
}

func (c *Conn) SendMessage(text, channel string) error {
	c.messageCounter++
	msg := sendMessage{
		ID:      c.messageCounter,
		Type:    "message",
		Channel: channel,
		Text:    text,
	}
	return c.conn.WriteJSON(msg)
}

/*
NextEvent blocks until the next Event is sent and then returns it to the caller.
*/
func (c *Conn) NextEvent() Event {
	rawEvent := make(map[string]interface{})
	c.conn.ReadJSON(&rawEvent)
	return toEvent(rawEvent)
}

var escapeRegex = regexp.MustCompile("<(.*?)>")

var escapeTypePostprocessors = map[int]func(string) string{
	userEscape:    func(s string) string { return "@" + s },
	channelEscape: func(s string) string { return "#" + s },
}

/*
UnescapeMessage takes in the escape string text of a message and returns a new string that appears as it would to a user.

UnescapeMessage does so by parsing escape sequences according to <https://api.slack.com/docs/formatting> and substituting the appropriate user-facing junk (e.g. <@UABC123> would become @firba1, assuming there's a user named firba1 with the user ID UABC123).
*/
func (c Conn) UnescapeMessage(message string) string {
	return c.UnescapeMessagePostprocess(message, func(s string, i int) string { return s })
}

func (c Conn) UnescapeMessagePostprocess(
	message string,
	postprocessor func(userString string, escapeType int) string,
) string {
	message = escapeRegex.ReplaceAllStringFunc(message, func(match string) string {
		unescapedMatch, escapeType := replaceEscapeHelper(c, match)
		postprocess := escapeTypePostprocessors[escapeType]
		if postprocess != nil {
			unescapedMatch = postprocess(unescapedMatch)
		}
		return unescapedMatch
	})

	// finally replace all html entity escapes
	message = strings.Replace(message, "&", "&", -1)
	message = strings.Replace(message, "<", "<", -1)
	message = strings.Replace(message, ">", ">", -1)
	return message
}

func replaceEscapeHelper(c Conn, match string) (unescape string, escapeType int) {
	// remove < and > from each end
	fullEscape := match[1 : len(match)-1]

	// check for display string
	escapeParts := strings.Split(fullEscape, "|")

	// this is a case we don't recognize, just return the original match and treat it as a link (the default)
	if len(escapeParts) > 2 || len(escapeParts) <= 0 {
		unescape = match
		escapeType = linkEscape
		return
	}

	escape := escapeParts[0]
	escapeType = parseEscapeType(escape)

	// if we have an alias, just return that
	if len(escapeParts) == 2 {
		unescape = escapeParts[1]
		return
	}

	// since there's no alias, now it's time for idenitifier lookup
	escapeType = parseEscapeType(escape)

	switch escapeType {
	case userEscape:
		// user link
		user := c.UserInfo(escape[1:])
		// if user is zero value, this will just be empty string, which we handle later
		unescape = user.Profile.DisplayName
	}

	// if we couldn't unescape properly, just return the original match text, make it a linkEscape type to prevent post processing
	if unescape == "" {
		escapeType = linkEscape
		unescape = match
	}
	return
}

const (
	linkEscape = iota
	userEscape
	channelEscape
	commandEscape
)

/*
parseEscapeType is a convience function for getting an easily comparable type from an escape sequence (e.g. "@U123A56BC" for users "#C789D10EF" for channels, etc)
*/
func parseEscapeType(escapeString string) int {
	switch {
	case escapeString[0:2] == "@U":
		return userEscape
	case escapeString[0:2] == "#C":
		return channelEscape
	case escapeString[0] == '!':
		return commandEscape
	default:
		// as per the docs, anything we can't recognize like this is a link
		return linkEscape
	}
}
<commit_msg>use postprocessor on match<commit_after>package rtm

import (
	"regexp"
	"strings"

	"github.com/firba1/slack"

	"github.com/gorilla/websocket"
)

type Conn struct {
	conn           *websocket.Conn
	messageCounter int
	userChanges    chan<- slack.User
	infoRequests   chan<- userInfoRequest
	cancel         chan struct{}
}

func (c *Conn) Close() error {
	close(c.cancel)
	return c.conn.Close()
}

type sendMessage struct {
	ID      int    `json:"id"`
	Type    string `json:"type"`
	Channel string `json:"channel"`
	Text    string `json:"text"`
}

func (c *Conn) SendMessage(text, channel string) error {
	c.messageCounter++
	msg := sendMessage{
		ID:      c.messageCounter,
		Type:    "message",
		Channel: channel,
		Text:    text,
	}
	return c.conn.WriteJSON(msg)
}

/*
NextEvent blocks until the next Event is sent and then returns it to the caller.
*/
func (c *Conn) NextEvent() Event {
	rawEvent := make(map[string]interface{})
	c.conn.ReadJSON(&rawEvent)
	return toEvent(rawEvent)
}

var escapeRegex = regexp.MustCompile("<(.*?)>")

var escapeTypePostprocessors = map[int]func(string) string{
	userEscape:    func(s string) string { return "@" + s },
	channelEscape: func(s string) string { return "#" + s },
}

/*
UnescapeMessage takes in the escape string text of a message and returns a new string that appears as it would to a user.

UnescapeMessage does so by parsing escape sequences according to <https://api.slack.com/docs/formatting> and substituting the appropriate user-facing junk (e.g. <@UABC123> would become @firba1, assuming there's a user named firba1 with the user ID UABC123).
*/
func (c Conn) UnescapeMessage(message string) string {
	return c.UnescapeMessagePostprocess(message, func(s string, i int) string { return s })
}

func (c Conn) UnescapeMessagePostprocess(
	message string,
	postprocessor func(userString string, escapeType int) string,
) string {
	message = escapeRegex.ReplaceAllStringFunc(message, func(match string) string {
		unescapedMatch, escapeType := replaceEscapeHelper(c, match)
		postprocess := escapeTypePostprocessors[escapeType]
		if postprocess != nil {
			unescapedMatch = postprocess(unescapedMatch)
		}
		return postprocessor(unescapedMatch, escapeType)
	})

	// finally replace all html entity escapes
	message = strings.Replace(message, "&", "&", -1)
	message = strings.Replace(message, "<", "<", -1)
	message = strings.Replace(message, ">", ">", -1)
	return message
}

func replaceEscapeHelper(c Conn, match string) (unescape string, escapeType int) {
	// remove < and > from each end
	fullEscape := match[1 : len(match)-1]

	// check for display string
	escapeParts := strings.Split(fullEscape, "|")

	// this is a case we don't recognize, just return the original match and treat it as a link (the default)
	if len(escapeParts) > 2 || len(escapeParts) <= 0 {
		unescape = match
		escapeType = linkEscape
		return
	}

	escape := escapeParts[0]
	escapeType = parseEscapeType(escape)

	// if we have an alias, just return that
	if len(escapeParts) == 2 {
		unescape = escapeParts[1]
		return
	}

	// since there's no alias, now it's time for idenitifier lookup
	escapeType = parseEscapeType(escape)

	switch escapeType {
	case userEscape:
		// user link
		user := c.UserInfo(escape[1:])
		// if user is zero value, this will just be empty string, which we handle later
		unescape = user.Profile.DisplayName
	}

	// if we couldn't unescape properly, just return the original match text, make it a linkEscape type to prevent post processing
	if unescape == "" {
		escapeType = linkEscape
		unescape = match
	}
	return
}

const (
	linkEscape = iota
	userEscape
	channelEscape
	commandEscape
)

/*
parseEscapeType is a convience function for getting an easily comparable type from an escape sequence (e.g. "@U123A56BC" for users "#C789D10EF" for channels, etc)
*/
func parseEscapeType(escapeString string) int {
	switch {
	case escapeString[0:2] == "@U":
		return userEscape
	case escapeString[0:2] == "#C":
		return channelEscape
	case escapeString[0] == '!':
		return commandEscape
	default:
		// as per the docs, anything we can't recognize like this is a link
		return linkEscape
	}
}
<|endoftext|>


<commit_before>package jsonprovider

import (
	"encoding/json"
	"testing"

	"github.com/google/go-cmp/cmp"
	"github.com/zclconf/go-cty/cty"

	"github.com/hashicorp/terraform/addrs"
	"github.com/hashicorp/terraform/configs/configschema"
	"github.com/hashicorp/terraform/terraform"
)

func TestMarshalProvider(t *testing.T) {
	tests := []struct {
		Input *terraform.ProviderSchema
		Want  *Provider
	}{
		{
			nil,
			&Provider{},
		},
		{
			testProvider(),
			&Provider{
				Provider: &schema{
					Block: &block{
						Attributes: map[string]*attribute{
							"region": {
								AttributeType:   json.RawMessage(`"string"`),
								Required:        true,
								DescriptionKind: "plain",
							},
						},
						DescriptionKind: "plain",
					},
				},
				ResourceSchemas: map[string]*schema{
					"test_instance": {
						Version: 42,
						Block: &block{
							Attributes: map[string]*attribute{
								"id": {
									AttributeType:   json.RawMessage(`"string"`),
									Optional:        true,
									Computed:        true,
									DescriptionKind: "plain",
								},
								"ami": {
									AttributeType:   json.RawMessage(`"string"`),
									Optional:        true,
									DescriptionKind: "plain",
								},
							},
							BlockTypes: map[string]*blockType{
								"network_interface": {
									Block: &block{
										Attributes: map[string]*attribute{
											"device_index": {
												AttributeType:   json.RawMessage(`"string"`),
												Optional:        true,
												DescriptionKind: "plain",
											},
											"description": {
												AttributeType:   json.RawMessage(`"string"`),
												Optional:        true,
												DescriptionKind: "plain",
											},
										},
										DescriptionKind: "plain",
									},
									NestingMode: "list",
								},
							},
							DescriptionKind: "plain",
						},
					},
				},
				DataSourceSchemas: map[string]*schema{
					"test_data_source": {
						Version: 3,
						Block: &block{
							Attributes: map[string]*attribute{
								"id": {
									AttributeType:   json.RawMessage(`"string"`),
									Optional:        true,
									Computed:        true,
									DescriptionKind: "plain",
								},
								"ami": {
									AttributeType:   json.RawMessage(`"string"`),
									Optional:        true,
									DescriptionKind: "plain",
								},
							},
							BlockTypes: map[string]*blockType{
								"network_interface": {
									Block: &block{
										Attributes: map[string]*attribute{
											"device_index": {
												AttributeType:   json.RawMessage(`"string"`),
												Optional:        true,
												DescriptionKind: "plain",
											},
											"description": {
												AttributeType:   json.RawMessage(`"string"`),
												Optional:        true,
												DescriptionKind: "plain",
											},
										},
										DescriptionKind: "plain",
									},
									NestingMode: "list",
								},
							},
							DescriptionKind: "plain",
						},
					},
				},
			},
		},
	}

	for _, test := range tests {
		got := marshalProvider(test.Input)
		if !cmp.Equal(got, test.Want) {
			t.Fatalf("wrong result:\n %v\n", cmp.Diff(got, test.Want))
		}
	}
}

func testProviders() *terraform.Schemas {
	return &terraform.Schemas{
		Providers: map[addrs.Provider]*terraform.ProviderSchema{
			addrs.NewDefaultProvider("test"): testProvider(),
		},
	}
}

func testProvider() *terraform.ProviderSchema {
	return &terraform.ProviderSchema{
		Provider: &configschema.Block{
			Attributes: map[string]*configschema.Attribute{
				"region": {Type: cty.String, Required: true},
			},
		},
		ResourceTypes: map[string]*configschema.Block{
			"test_instance": {
				Attributes: map[string]*configschema.Attribute{
					"id":  {Type: cty.String, Optional: true, Computed: true},
					"ami": {Type: cty.String, Optional: true},
				},
				BlockTypes: map[string]*configschema.NestedBlock{
					"network_interface": {
						Nesting: configschema.NestingList,
						Block: configschema.Block{
							Attributes: map[string]*configschema.Attribute{
								"device_index": {Type: cty.String, Optional: true},
								"description":  {Type: cty.String, Optional: true},
							},
						},
					},
				},
			},
		},
		DataSources: map[string]*configschema.Block{
			"test_data_source": {
				Attributes: map[string]*configschema.Attribute{
					"id":  {Type: cty.String, Optional: true, Computed: true},
					"ami": {Type: cty.String, Optional: true},
				},
				BlockTypes: map[string]*configschema.NestedBlock{
					"network_interface": {
						Nesting: configschema.NestingList,
						Block: configschema.Block{
							Attributes: map[string]*configschema.Attribute{
								"device_index": {Type: cty.String, Optional: true},
								"description":  {Type: cty.String, Optional: true},
							},
						},
					},
				},
			},
		},

		ResourceTypeSchemaVersions: map[string]uint64{
			"test_instance":    42,
			"test_data_source": 3,
		},
	}
}
<commit_msg>command/jsonprovider: staticcheck<commit_after>package jsonprovider

import (
	"encoding/json"
	"testing"

	"github.com/google/go-cmp/cmp"
	"github.com/zclconf/go-cty/cty"

	"github.com/hashicorp/terraform/configs/configschema"
	"github.com/hashicorp/terraform/terraform"
)

func TestMarshalProvider(t *testing.T) {
	tests := []struct {
		Input *terraform.ProviderSchema
		Want  *Provider
	}{
		{
			nil,
			&Provider{},
		},
		{
			testProvider(),
			&Provider{
				Provider: &schema{
					Block: &block{
						Attributes: map[string]*attribute{
							"region": {
								AttributeType:   json.RawMessage(`"string"`),
								Required:        true,
								DescriptionKind: "plain",
							},
						},
						DescriptionKind: "plain",
					},
				},
				ResourceSchemas: map[string]*schema{
					"test_instance": {
						Version: 42,
						Block: &block{
							Attributes: map[string]*attribute{
								"id": {
									AttributeType:   json.RawMessage(`"string"`),
									Optional:        true,
									Computed:        true,
									DescriptionKind: "plain",
								},
								"ami": {
									AttributeType:   json.RawMessage(`"string"`),
									Optional:        true,
									DescriptionKind: "plain",
								},
							},
							BlockTypes: map[string]*blockType{
								"network_interface": {
									Block: &block{
										Attributes: map[string]*attribute{
											"device_index": {
												AttributeType:   json.RawMessage(`"string"`),
												Optional:        true,
												DescriptionKind: "plain",
											},
											"description": {
												AttributeType:   json.RawMessage(`"string"`),
												Optional:        true,
												DescriptionKind: "plain",
											},
										},
										DescriptionKind: "plain",
									},
									NestingMode: "list",
								},
							},
							DescriptionKind: "plain",
						},
					},
				},
				DataSourceSchemas: map[string]*schema{
					"test_data_source": {
						Version: 3,
						Block: &block{
							Attributes: map[string]*attribute{
								"id": {
									AttributeType:   json.RawMessage(`"string"`),
									Optional:        true,
									Computed:        true,
									DescriptionKind: "plain",
								},
								"ami": {
									AttributeType:   json.RawMessage(`"string"`),
									Optional:        true,
									DescriptionKind: "plain",
								},
							},
							BlockTypes: map[string]*blockType{
								"network_interface": {
									Block: &block{
										Attributes: map[string]*attribute{
											"device_index": {
												AttributeType:   json.RawMessage(`"string"`),
												Optional:        true,
												DescriptionKind: "plain",
											},
											"description": {
												AttributeType:   json.RawMessage(`"string"`),
												Optional:        true,
												DescriptionKind: "plain",
											},
										},
										DescriptionKind: "plain",
									},
									NestingMode: "list",
								},
							},
							DescriptionKind: "plain",
						},
					},
				},
			},
		},
	}

	for _, test := range tests {
		got := marshalProvider(test.Input)
		if !cmp.Equal(got, test.Want) {
			t.Fatalf("wrong result:\n %v\n", cmp.Diff(got, test.Want))
		}
	}
}

func testProvider() *terraform.ProviderSchema {
	return &terraform.ProviderSchema{
		Provider: &configschema.Block{
			Attributes: map[string]*configschema.Attribute{
				"region": {Type: cty.String, Required: true},
			},
		},
		ResourceTypes: map[string]*configschema.Block{
			"test_instance": {
				Attributes: map[string]*configschema.Attribute{
					"id":  {Type: cty.String, Optional: true, Computed: true},
					"ami": {Type: cty.String, Optional: true},
				},
				BlockTypes: map[string]*configschema.NestedBlock{
					"network_interface": {
						Nesting: configschema.NestingList,
						Block: configschema.Block{
							Attributes: map[string]*configschema.Attribute{
								"device_index": {Type: cty.String, Optional: true},
								"description":  {Type: cty.String, Optional: true},
							},
						},
					},
				},
			},
		},
		DataSources: map[string]*configschema.Block{
			"test_data_source": {
				Attributes: map[string]*configschema.Attribute{
					"id":  {Type: cty.String, Optional: true, Computed: true},
					"ami": {Type: cty.String, Optional: true},
				},
				BlockTypes: map[string]*configschema.NestedBlock{
					"network_interface": {
						Nesting: configschema.NestingList,
						Block: configschema.Block{
							Attributes: map[string]*configschema.Attribute{
								"device_index": {Type: cty.String, Optional: true},
								"description":  {Type: cty.String, Optional: true},
							},
						},
					},
				},
			},
		},

		ResourceTypeSchemaVersions: map[string]uint64{
			"test_instance":    42,
			"test_data_source": 3,
		},
	}
}
<|endoftext|>


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

package hello_test

import (
	"fmt"

	"v.io/x/ref/envvar"
	"v.io/x/ref/lib/security"
	_ "v.io/x/ref/profiles"
	"v.io/x/ref/test/testutil"
	"v.io/x/ref/test/v23tests"
)

//go:generate v23 test generate

func init() {
	envvar.ClearCredentials()
}

// setupCredentials makes a bunch of credentials directories.
// Note that I do this myself instead of allowing the test framework
// to do it because I really want to use the agentd binary, not
// the agent that is locally hosted inside v23Tests.T.
// This is important for regression tests where we want to test against
// old agent binaries.
func setupCredentials(i *v23tests.T, names ...string) (map[string]string, error) {
	idp := testutil.NewIDProvider("root")
	out := make(map[string]string, len(names))
	for _, name := range names {
		dir := i.NewTempDir("")
		p, err := security.CreatePersistentPrincipal(dir, nil)
		if err != nil {
			return nil, err
		}
		if err := idp.Bless(p, name); err != nil {
			return nil, err
		}
		out[name] = fmt.Sprintf("%s=%s", envvar.Credentials, dir)
	}
	return out, nil
}

func V23TestHelloDirect(i *v23tests.T) {
	creds, err := setupCredentials(i, "helloclient", "helloserver")
	if err != nil {
		i.Fatalf("Could not create credentials: %v", err)
	}
	clientbin := i.BuildGoPkg("v.io/x/ref/examples/hello/helloclient")
	serverbin := i.BuildGoPkg("v.io/x/ref/examples/hello/helloserver")
	server := serverbin.WithEnv(creds["helloserver"]).Start()
	name := server.ExpectVar("SERVER_NAME")
	clientbin.WithEnv(creds["helloclient"]).Run("--name", name)
}

func V23TestHelloAgentd(i *v23tests.T) {
	creds, err := setupCredentials(i, "helloclient", "helloserver")
	if err != nil {
		i.Fatalf("Could not create credentials: %v", err)
	}
	agentdbin := i.BuildGoPkg("v.io/x/ref/services/agent/agentd")
	serverbin := i.BuildGoPkg("v.io/x/ref/examples/hello/helloserver")
	clientbin := i.BuildGoPkg("v.io/x/ref/examples/hello/helloclient")
	server := agentdbin.WithEnv(creds["helloserver"]).Start(serverbin.Path())
	name := server.ExpectVar("SERVER_NAME")
	agentdbin.WithEnv(creds["helloclient"]).Run(clientbin.Path(), "--name", name)
}

func V23TestHelloMounttabled(i *v23tests.T) {
	creds, err := setupCredentials(i, "helloclient", "helloserver", "mounttabled")
	if err != nil {
		i.Fatalf("Could not create credentials: %v", err)
	}
	agentdbin := i.BuildGoPkg("v.io/x/ref/services/agent/agentd")
	mounttabledbin := i.BuildGoPkg("v.io/x/ref/services/mounttable/mounttabled")
	serverbin := i.BuildGoPkg("v.io/x/ref/examples/hello/helloserver")
	clientbin := i.BuildGoPkg("v.io/x/ref/examples/hello/helloclient")
	name := "hello"
	mounttabled := agentdbin.WithEnv(creds["mounttabled"]).Start(mounttabledbin.Path(),
		"--v23.tcp.address", "127.0.0.1:0")
	mt := fmt.Sprintf("%s=%s", envvar.NamespacePrefix, mounttabled.ExpectVar("NAME"))
	agentdbin.WithEnv(creds["helloserver"], mt).Start(serverbin.Path(), "--name", name)
	agentdbin.WithEnv(creds["helloclient"], mt).Run(clientbin.Path(), "--name", name)
}

func V23TestHelloProxy(i *v23tests.T) {
	// Skipping this test for older binaries because of incompatibility in
	// the proxyd commandline flags.
	i.SkipInRegressionBefore("2015-04-25")

	creds, err := setupCredentials(i, "helloclient", "helloserver",
		"mounttabled", "proxyd")
	if err != nil {
		i.Fatalf("Could not create credentials: %v", err)
	}
	agentdbin := i.BuildGoPkg("v.io/x/ref/services/agent/agentd")
	mounttabledbin := i.BuildGoPkg("v.io/x/ref/services/mounttable/mounttabled")
	proxydbin := i.BuildGoPkg("v.io/x/ref/services/proxy/proxyd")
	serverbin := i.BuildGoPkg("v.io/x/ref/examples/hello/helloserver")
	clientbin := i.BuildGoPkg("v.io/x/ref/examples/hello/helloclient")
	proxyname := "proxy"
	name := "hello"
	mounttabled := agentdbin.WithEnv(creds["mounttabled"]).Start(mounttabledbin.Path(),
		"--v23.tcp.address", "127.0.0.1:0")
	mt := fmt.Sprintf("%s=%s", envvar.NamespacePrefix, mounttabled.ExpectVar("NAME"))
	agentdbin.WithEnv(creds["proxyd"], mt).Start(proxydbin.Path(),
		"--name", proxyname, "--v23.tcp.address", "127.0.0.1:0",
		"--access-list", "{\"In\":[\"root\"]}")
	server := agentdbin.WithEnv(creds["helloserver"], mt).Start(serverbin.Path(),
		"--name", name, "--v23.proxy", proxyname, "--v23.tcp.address", "")
	// Prove that we're listening on a proxy.
	if sn := server.ExpectVar("SERVER_NAME"); sn != "proxy" {
		i.Fatalf("helloserver not listening through proxy: %s.", sn)
	}
	agentdbin.WithEnv(creds["helloclient"], mt).Run(clientbin.Path(), "--name", name)
}
<commit_msg>hello:  Add timeouts for the hello regression tests.<commit_after>// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package hello_test

import (
	"fmt"
	"os"
	"strings"
	"time"

	"v.io/x/ref/envvar"
	"v.io/x/ref/lib/security"
	_ "v.io/x/ref/profiles"
	"v.io/x/ref/test/modules"
	"v.io/x/ref/test/testutil"
	"v.io/x/ref/test/v23tests"
)

//go:generate v23 test generate

func init() {
	envvar.ClearCredentials()
	// Unset all the namespace variables too.
	for _, ev := range os.Environ() {
		p := strings.SplitN(ev, "=", 2)
		if len(p) != 2 {
			continue
		}
		key := p[0]
		if strings.HasPrefix(key, envvar.NamespacePrefix) {
			os.Unsetenv(key)
		}
	}
}

var opts = modules.StartOpts{
	StartTimeout:    20 * time.Second,
	ShutdownTimeout: 20 * time.Second,
	ExpectTimeout:   20 * time.Second,
	ExecProtocol:    false,
	External:        true,
}

// setupCredentials makes a bunch of credentials directories.
// Note that I do this myself instead of allowing the test framework
// to do it because I really want to use the agentd binary, not
// the agent that is locally hosted inside v23Tests.T.
// This is important for regression tests where we want to test against
// old agent binaries.
func setupCredentials(i *v23tests.T, names ...string) (map[string]string, error) {
	idp := testutil.NewIDProvider("root")
	out := make(map[string]string, len(names))
	for _, name := range names {
		dir := i.NewTempDir("")
		p, err := security.CreatePersistentPrincipal(dir, nil)
		if err != nil {
			return nil, err
		}
		if err := idp.Bless(p, name); err != nil {
			return nil, err
		}
		out[name] = fmt.Sprintf("%s=%s", envvar.Credentials, dir)
	}
	return out, nil
}

func V23TestHelloDirect(i *v23tests.T) {
	creds, err := setupCredentials(i, "helloclient", "helloserver")
	if err != nil {
		i.Fatalf("Could not create credentials: %v", err)
	}
	clientbin := i.BuildGoPkg("v.io/x/ref/examples/hello/helloclient")
	serverbin := i.BuildGoPkg("v.io/x/ref/examples/hello/helloserver")
	server := serverbin.WithStartOpts(opts).WithEnv(creds["helloserver"]).Start()
	name := server.ExpectVar("SERVER_NAME")

	clientbin.WithEnv(creds["helloclient"]).WithStartOpts(opts).Run("--name", name)
}

func V23TestHelloAgentd(i *v23tests.T) {
	creds, err := setupCredentials(i, "helloclient", "helloserver")
	if err != nil {
		i.Fatalf("Could not create credentials: %v", err)
	}
	agentdbin := i.BuildGoPkg("v.io/x/ref/services/agent/agentd").WithStartOpts(opts)
	serverbin := i.BuildGoPkg("v.io/x/ref/examples/hello/helloserver")
	clientbin := i.BuildGoPkg("v.io/x/ref/examples/hello/helloclient")
	server := agentdbin.WithEnv(creds["helloserver"]).Start(serverbin.Path())
	name := server.ExpectVar("SERVER_NAME")
	agentdbin.WithEnv(creds["helloclient"]).Run(clientbin.Path(), "--name", name)
}

func V23TestHelloMounttabled(i *v23tests.T) {
	creds, err := setupCredentials(i, "helloclient", "helloserver", "mounttabled")
	if err != nil {
		i.Fatalf("Could not create credentials: %v", err)
	}
	agentdbin := i.BuildGoPkg("v.io/x/ref/services/agent/agentd").WithStartOpts(opts)
	mounttabledbin := i.BuildGoPkg("v.io/x/ref/services/mounttable/mounttabled")
	serverbin := i.BuildGoPkg("v.io/x/ref/examples/hello/helloserver")
	clientbin := i.BuildGoPkg("v.io/x/ref/examples/hello/helloclient")
	name := "hello"
	mounttabled := agentdbin.WithEnv(creds["mounttabled"]).Start(mounttabledbin.Path(),
		"--v23.tcp.address", "127.0.0.1:0")
	mt := fmt.Sprintf("%s=%s", envvar.NamespacePrefix, mounttabled.ExpectVar("NAME"))
	agentdbin.WithEnv(creds["helloserver"], mt).Start(serverbin.Path(), "--name", name)
	agentdbin.WithEnv(creds["helloclient"], mt).Run(clientbin.Path(), "--name", name)
}

func V23TestHelloProxy(i *v23tests.T) {
	// Skipping this test for older binaries because of incompatibility in
	// the proxyd commandline flags.
	i.SkipInRegressionBefore("2015-04-25")

	creds, err := setupCredentials(i, "helloclient", "helloserver",
		"mounttabled", "proxyd")
	if err != nil {
		i.Fatalf("Could not create credentials: %v", err)
	}
	agentdbin := i.BuildGoPkg("v.io/x/ref/services/agent/agentd").WithStartOpts(opts)
	mounttabledbin := i.BuildGoPkg("v.io/x/ref/services/mounttable/mounttabled")
	proxydbin := i.BuildGoPkg("v.io/x/ref/services/proxy/proxyd")
	serverbin := i.BuildGoPkg("v.io/x/ref/examples/hello/helloserver")
	clientbin := i.BuildGoPkg("v.io/x/ref/examples/hello/helloclient")
	proxyname := "proxy"
	name := "hello"
	mounttabled := agentdbin.WithEnv(creds["mounttabled"]).Start(mounttabledbin.Path(),
		"--v23.tcp.address", "127.0.0.1:0")
	mt := fmt.Sprintf("%s=%s", envvar.NamespacePrefix, mounttabled.ExpectVar("NAME"))
	agentdbin.WithEnv(creds["proxyd"], mt).Start(proxydbin.Path(),
		"--name", proxyname, "--v23.tcp.address", "127.0.0.1:0",
		"--access-list", "{\"In\":[\"root\"]}")
	server := agentdbin.WithEnv(creds["helloserver"], mt).Start(serverbin.Path(),
		"--name", name, "--v23.proxy", proxyname, "--v23.tcp.address", "")
	// Prove that we're listening on a proxy.
	if sn := server.ExpectVar("SERVER_NAME"); sn != "proxy" {
		i.Fatalf("helloserver not listening through proxy: %s.", sn)
	}
	agentdbin.WithEnv(creds["helloclient"], mt).Run(clientbin.Path(), "--name", name)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/fujiwara/fluent-agent-hydra/hydra"
	"log"
	"os"
	"os/signal"
	"runtime/pprof"
	"syscall"
)

var (
	version     string
	buildDate   string
	trapSignals = []os.Signal{
		syscall.SIGHUP,
		syscall.SIGINT,
		syscall.SIGTERM,
		syscall.SIGQUIT}
)

func main() {
	var (
		configFile  string
		help        bool
		fieldName   string
		monitorAddr string
		showVersion bool
	)
	flag.StringVar(&configFile, "c", "", "configuration file path")
	flag.BoolVar(&help, "h", false, "show help message")
	flag.BoolVar(&help, "help", false, "show help message")
	flag.StringVar(&fieldName, "f", hydra.DefaultFieldName, "fieldname of fluentd log message attribute (DEFAULT: message)")
	flag.StringVar(&monitorAddr, "monitor", "", "monitor HTTP server address")
	flag.BoolVar(&showVersion, "v", false, "show version")
	flag.BoolVar(&showVersion, "version", false, "show version")
	flag.Parse()

	if showVersion {
		fmt.Println("version:", version)
		fmt.Println("build:", buildDate)
		os.Exit(0)
	}
	if help {
		usage()
	}
	if pprofile := os.Getenv("PPROF"); pprofile != "" {
		f, err := os.Create(pprofile)
		if err != nil {
			log.Fatal("[error] Can't create profiling stat file.", err)
		}
		log.Println("[info] StartCPUProfile() stat file", f.Name())
		pprof.StartCPUProfile(f)
	}

	done := make(chan os.Signal, 1)
	signal.Notify(done, trapSignals...)
	if configFile != "" {
		config, err := hydra.ReadConfig(configFile)
		if err != nil {
			log.Println("Can't load config", err)
			os.Exit(2)
		}
		run(config)
	} else if args := flag.Args(); len(args) >= 3 {
		config := hydra.NewConfigByArgs(args, fieldName, monitorAddr)
		run(config)
	} else {
		usage()
	}
	sig := <-done
	log.Println("[info] SIGNAL", sig, "exit.")
	pprof.StopCPUProfile()
	os.Exit(0)
}

func usage() {
	fmt.Println("Usage of fluent-agent-hydra")
	fmt.Println("")
	fmt.Println("  fluent-agent-hydra -c config.toml")
	fmt.Println("  fluent-agent-hydra [options] TAG TARGET_FILE PRIMARY_SERVER SECONDARY_SERVER")
	fmt.Println("")
	flag.PrintDefaults()
	os.Exit(1)
}

func run(config *hydra.Config) {
	messageCh, monitorCh := hydra.NewChannel()

	// start monitor server
	monitor, err := hydra.NewMonitor(config, monitorCh)
	if err != nil {
		log.Println("[error] Couldn't start monitor server.", err)
	} else {
		go monitor.Run()
	}

	// start out_forward
	outForward, err := hydra.NewOutForward(config.Servers, messageCh, monitorCh)
	if err != nil {
		log.Println("[error]", err)
	} else {
		go outForward.Run()
	}

	// start watcher && in_tail
	if len(config.Logs) > 0 {
		watcher, err := hydra.NewWatcher()
		if err != nil {
			log.Println("[error]", err)
		}
		for _, configLogfile := range config.Logs {
			tail, err := hydra.NewInTail(configLogfile, watcher, messageCh, monitorCh)
			if err != nil {
				log.Println("[error]", err)
			} else {
				go tail.Run()
			}
		}
		go watcher.Run()
	}

	// start in_forward
	if config.Receiver != nil {
		inForward, err := hydra.NewInForward(config.Receiver, messageCh, monitorCh)
		if err != nil {
			log.Println("[error]", err)
		} else {
			go inForward.Run()
		}
	}
}
<commit_msg>output a warning message if GOMAXPROCS=1 and using receiver.<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/fujiwara/fluent-agent-hydra/hydra"
	"log"
	"os"
	"os/signal"
	"runtime"
	"runtime/pprof"
	"syscall"
)

var (
	version     string
	buildDate   string
	trapSignals = []os.Signal{
		syscall.SIGHUP,
		syscall.SIGINT,
		syscall.SIGTERM,
		syscall.SIGQUIT}
)

func main() {
	var (
		configFile  string
		help        bool
		fieldName   string
		monitorAddr string
		showVersion bool
	)
	flag.StringVar(&configFile, "c", "", "configuration file path")
	flag.BoolVar(&help, "h", false, "show help message")
	flag.BoolVar(&help, "help", false, "show help message")
	flag.StringVar(&fieldName, "f", hydra.DefaultFieldName, "fieldname of fluentd log message attribute (DEFAULT: message)")
	flag.StringVar(&monitorAddr, "monitor", "", "monitor HTTP server address")
	flag.BoolVar(&showVersion, "v", false, "show version")
	flag.BoolVar(&showVersion, "version", false, "show version")
	flag.Parse()

	if showVersion {
		fmt.Println("version:", version)
		fmt.Println("build:", buildDate)
		os.Exit(0)
	}
	if help {
		usage()
	}
	if pprofile := os.Getenv("PPROF"); pprofile != "" {
		f, err := os.Create(pprofile)
		if err != nil {
			log.Fatal("[error] Can't create profiling stat file.", err)
		}
		log.Println("[info] StartCPUProfile() stat file", f.Name())
		pprof.StartCPUProfile(f)
	}

	done := make(chan os.Signal, 1)
	signal.Notify(done, trapSignals...)
	if configFile != "" {
		config, err := hydra.ReadConfig(configFile)
		if err != nil {
			log.Println("Can't load config", err)
			os.Exit(2)
		}
		run(config)
	} else if args := flag.Args(); len(args) >= 3 {
		config := hydra.NewConfigByArgs(args, fieldName, monitorAddr)
		run(config)
	} else {
		usage()
	}
	sig := <-done
	log.Println("[info] SIGNAL", sig, "exit.")
	pprof.StopCPUProfile()
	os.Exit(0)
}

func usage() {
	fmt.Println("Usage of fluent-agent-hydra")
	fmt.Println("")
	fmt.Println("  fluent-agent-hydra -c config.toml")
	fmt.Println("  fluent-agent-hydra [options] TAG TARGET_FILE PRIMARY_SERVER SECONDARY_SERVER")
	fmt.Println("")
	flag.PrintDefaults()
	os.Exit(1)
}

func run(config *hydra.Config) {
	messageCh, monitorCh := hydra.NewChannel()

	// start monitor server
	monitor, err := hydra.NewMonitor(config, monitorCh)
	if err != nil {
		log.Println("[error] Couldn't start monitor server.", err)
	} else {
		go monitor.Run()
	}

	// start out_forward
	outForward, err := hydra.NewOutForward(config.Servers, messageCh, monitorCh)
	if err != nil {
		log.Println("[error]", err)
	} else {
		go outForward.Run()
	}

	// start watcher && in_tail
	if len(config.Logs) > 0 {
		watcher, err := hydra.NewWatcher()
		if err != nil {
			log.Println("[error]", err)
		}
		for _, configLogfile := range config.Logs {
			tail, err := hydra.NewInTail(configLogfile, watcher, messageCh, monitorCh)
			if err != nil {
				log.Println("[error]", err)
			} else {
				go tail.Run()
			}
		}
		go watcher.Run()
	}

	// start in_forward
	if config.Receiver != nil {
		if runtime.GOMAXPROCS(0) < 2 {
			log.Println("[warning] When using Receiver, recommend to set GOMAXPROCS >= 2.")
		}
		inForward, err := hydra.NewInForward(config.Receiver, messageCh, monitorCh)
		if err != nil {
			log.Println("[error]", err)
		} else {
			go inForward.Run()
		}
	}
}
<|endoftext|>


<commit_before>package cmd

import (
	"fmt"
	"log"
	"os"
	"os/user"
	"path"

	"github.com/pkg/errors"
	"github.com/spf13/cobra"

	"nimona.io/go/api"
	"nimona.io/go/dht"
	"nimona.io/go/net"
	"nimona.io/go/peers"
	"nimona.io/go/storage"
	"nimona.io/go/telemetry"
)

var (
	daemonConfigPath     string
	daemonPort           int
	daemonAPIPort        int
	daemonEnableRelaying bool
	daemonEnableMetrics  bool

	bootstrapAddresses = []string{
		"tcp:andromeda.nimona.io:21013",
		// "tcp:borealis.nimona.io:21013",
		// "tcp:cassiopeia.nimona.io:21013",
		// "tcp:draco.nimona.io:21013",
		// "tcp:eridanus.nimona.io:21013",
		// "tcp:fornax.nimona.io:21013",
		// "tcp:gemini.nimona.io:21013",
		// "tcp:hydra.nimona.io:21013",
		// "tcp:indus.nimona.io:21013",
		// "tcp:lacerta.nimona.io:21013",
		// "tcp:mensa.nimona.io:21013",
		// "tcp:norma.nimona.io:21013",
		// "tcp:orion.nimona.io:21013",
		// "tcp:pyxis.nimona.io:21013",
		// "tcp:stats.nimona.io:21013",
	}
)

// daemonStartCmd represents the daemon command
var daemonStartCmd = &cobra.Command{
	Use:   "start",
	Short: "Start a peer as a daemon",
	Long:  "",
	RunE: func(cmd *cobra.Command, args []string) error {
		if daemonConfigPath == "" {
			usr, _ := user.Current()
			daemonConfigPath = path.Join(usr.HomeDir, ".nimona")
		}

		if err := os.MkdirAll(daemonConfigPath, 0777); err != nil {
			return errors.Wrap(err, "could not create config dir")
		}

		addressBook, err := peers.NewAddressBook(daemonConfigPath)
		if err != nil {
			return errors.Wrap(err, "could not load key")
		}

		addressBook.LocalHostname = announceHostname

		if daemonEnableRelaying {
			addressBook.AddLocalPeerRelay(bootstrapAddresses...)
		}

		storagePath := path.Join(daemonConfigPath, "storage")
		dpr := storage.NewDiskStorage(storagePath)
		n, _ := net.NewExchange(addressBook, dpr, fmt.Sprintf("0.0.0.0:%d", daemonPort))
		dht, _ := dht.NewDHT(n, addressBook, bootstrapAddresses)
		telemetry.NewTelemetry(n, addressBook.GetLocalPeerKey(), "tcp:stats.nimona.io:21013")

		n.RegisterDiscoverer(dht)

		peerAddress := fmt.Sprintf("0.0.0.0:%d", daemonAPIPort)
		apiAddress := fmt.Sprintf("http://localhost:%d", daemonAPIPort)

		log.Println("Started daemon.")
		log.Println("* Peer key:", addressBook.GetLocalPeerInfo().Thumbprint())
		peerAddresses := addressBook.GetLocalPeerAddresses()
		if len(peerAddresses) > 0 {
			log.Println("* Peer addresses:")
			for _, addr := range addressBook.GetLocalPeerAddresses() {
				log.Println("  *", addr)
			}
		}
		log.Println("* HTTP API address:", apiAddress)

		api := api.New(addressBook, dht, n, dpr)
		err = api.Serve(peerAddress)
		return errors.Wrap(err, "http server stopped")
	},
}

func init() {
	daemon.AddCommand(daemonStartCmd)

	daemonStartCmd.PersistentFlags().IntVar(
		&daemonPort,
		"port",
		0,
		"peer port",
	)

	daemonStartCmd.PersistentFlags().IntVar(
		&daemonAPIPort,
		"api-port",
		8030,
		"api port",
	)

	daemonStartCmd.PersistentFlags().BoolVar(
		&daemonEnableRelaying,
		"relay",
		true,
		"enable relaying through bootstrap peers",
	)

	daemonStartCmd.PersistentFlags().BoolVar(
		&daemonEnableMetrics,
		"metrics",
		false,
		"enable sending anonymous metrics",
	)

	daemonStartCmd.PersistentFlags().StringSliceVar(
		&bootstrapAddresses,
		"bootstraps",
		bootstrapAddresses,
		"bootstrap addresses",
	)
}
<commit_msg>Make daemon start more verbose<commit_after>package cmd

import (
	"fmt"
	"os"
	"os/user"
	"path"

	"github.com/pkg/errors"
	"github.com/spf13/cobra"

	"nimona.io/go/api"
	"nimona.io/go/dht"
	"nimona.io/go/net"
	"nimona.io/go/peers"
	"nimona.io/go/storage"
	"nimona.io/go/telemetry"
)

var (
	daemonConfigPath     string
	daemonPort           int
	daemonAPIPort        int
	daemonEnableRelaying bool
	daemonEnableMetrics  bool

	bootstrapAddresses = []string{
		"tcp:andromeda.nimona.io:21013",
		// "tcp:borealis.nimona.io:21013",
		// "tcp:cassiopeia.nimona.io:21013",
		// "tcp:draco.nimona.io:21013",
		// "tcp:eridanus.nimona.io:21013",
		// "tcp:fornax.nimona.io:21013",
		// "tcp:gemini.nimona.io:21013",
		// "tcp:hydra.nimona.io:21013",
		// "tcp:indus.nimona.io:21013",
		// "tcp:lacerta.nimona.io:21013",
		// "tcp:mensa.nimona.io:21013",
		// "tcp:norma.nimona.io:21013",
		// "tcp:orion.nimona.io:21013",
		// "tcp:pyxis.nimona.io:21013",
		// "tcp:stats.nimona.io:21013",
	}
)

// daemonStartCmd represents the daemon command
var daemonStartCmd = &cobra.Command{
	Use:   "start",
	Short: "Start a peer as a daemon",
	Long:  "",
	RunE: func(cmd *cobra.Command, args []string) error {
		if daemonConfigPath == "" {
			usr, _ := user.Current()
			daemonConfigPath = path.Join(usr.HomeDir, ".nimona")
		}

		if err := os.MkdirAll(daemonConfigPath, 0777); err != nil {
			return errors.Wrap(err, "could not create config dir")
		}

		addressBook, err := peers.NewAddressBook(daemonConfigPath)
		if err != nil {
			return errors.Wrap(err, "could not load key")
		}

		if len(bootstrapAddresses) > 0 {
			cmd.Println("Adding bootstrap nodes")
			for _, v := range bootstrapAddresses {
				cmd.Println("  *", v)
			}
		} else {
			cmd.Println("No bootstrap nodes provided")
		}

		addressBook.LocalHostname = announceHostname

		if daemonEnableRelaying {
			if len(bootstrapAddresses) > 0 {
				cmd.Println("Relaying enabled, using bootstrap nodes")
				addressBook.AddLocalPeerRelay(bootstrapAddresses...)
			} else {
				cmd.Println("Relaying not enabled, no bootstrap nodes provided")
			}
		} else {
			cmd.Println("Relaying not enabled")
		}

		storagePath := path.Join(daemonConfigPath, "storage")
		dpr := storage.NewDiskStorage(storagePath)
		n, _ := net.NewExchange(addressBook, dpr, fmt.Sprintf("0.0.0.0:%d", daemonPort))
		dht, _ := dht.NewDHT(n, addressBook, bootstrapAddresses)
		telemetry.NewTelemetry(n, addressBook.GetLocalPeerKey(), "tcp:stats.nimona.io:21013")

		n.RegisterDiscoverer(dht)

		peerAddress := fmt.Sprintf("0.0.0.0:%d", daemonAPIPort)
		apiAddress := fmt.Sprintf("http://localhost:%d", daemonAPIPort)

		cmd.Println("Started daemon")
		cmd.Println("* Peer keys:\n  *", addressBook.GetLocalPeerInfo().Thumbprint())
		peerAddresses := addressBook.GetLocalPeerAddresses()
		cmd.Println("* Peer addresses:")
		if len(peerAddresses) > 0 {
			for _, addr := range addressBook.GetLocalPeerAddresses() {
				cmd.Println("  *", addr)
			}
		} else {
			cmd.Println("  * No addresses available")
		}
		cmd.Println("* HTTP API address:\n  *", apiAddress)

		api := api.New(addressBook, dht, n, dpr)
		err = api.Serve(peerAddress)
		return errors.Wrap(err, "http server stopped")
	},
}

func init() {
	daemon.AddCommand(daemonStartCmd)

	daemonStartCmd.PersistentFlags().IntVar(
		&daemonPort,
		"port",
		0,
		"peer port",
	)

	daemonStartCmd.PersistentFlags().IntVar(
		&daemonAPIPort,
		"api-port",
		8030,
		"api port",
	)

	daemonStartCmd.PersistentFlags().BoolVar(
		&daemonEnableRelaying,
		"relay",
		true,
		"enable relaying through bootstrap peers",
	)

	daemonStartCmd.PersistentFlags().BoolVar(
		&daemonEnableMetrics,
		"metrics",
		false,
		"enable sending anonymous metrics",
	)

	daemonStartCmd.PersistentFlags().StringSliceVar(
		&bootstrapAddresses,
		"bootstraps",
		bootstrapAddresses,
		"bootstrap addresses",
	)
}
<|endoftext|>


<commit_before>
package main

import (
	"fmt"
	"strings"
	"strconv"
	"errors"
	"encoding/json"
	"github.com/hyperledger/fabric/core/chaincode/shim"
)

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

type Employee struct {
	Name string `json:"name"`
	EmployeeId int `json:"employeeId"`
	Project string `json:"project"`
}

type Customer struct {
	Name string `json:"name"`
	CustomerId int `json:"customerId"`
}
type Project struct {
	Name string `json:"name"`
	ProjectId int `json:"projectId"`
	CustomerOf string `json:"customerOf"`
}

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte,error) {
    fmt.Println("Init is running " + function)
    return nil,nil
}

func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte,error) {

    fmt.Println("Invoke is running " + function)

    if function =="initEmployee"{
		return t.initEmployee(stub,args)
	}else if function =="getEmployee"{
		return t.getEmployee(stub,args)
	}else if function =="initCustomer"{
		return t.initCustomer(stub,args)
	}else if function =="getCustomer"{
		return t.getCustomer(stub,args)
	}else if function =="initProject"{
		return t.initProject(stub,args)
	}else if function =="getProject"{
		return t.getProject(stub,args)
	}
	return nil,errors.New("Received unknown function invocation")
}

func (t *SimpleChaincode) initProject(stub shim.ChaincodeStubInterface, args []string) ([]byte,error){

	if len(args) != 3 {
		return nil,errors.New("Incorrect number of arguments. Expecting 3")
	}
	// ==== Input sanitation ====
	fmt.Println("- start initProject")
	if len(args[0]) <= 0 {
		return nil,errors.New("1st argument must be a non-empty string")
	}
	if len(args[1]) <= 0 {
		return nil,errors.New("2nd argument must be a non-empty string")
	}
	if len(args[2]) <= 0 {
		return nil,errors.New("3rd argument must be a non-empty string")
	}

	projectName := args[0]
	customerOf := strings.ToLower(args[2])
	projectId, err := strconv.Atoi(args[1])
	projectIdAsString := args[1]
	if err != nil {
		return nil,errors.New("2nd argument must be a numeric string")
	}

	projectAsBytes, err := stub.GetState(projectIdAsString)
	if err != nil {
		return nil,err
	} else if projectAsBytes != nil {
		fmt.Println("This project already exists: " + projectIdAsString)
		return nil, errors.New("This project already exists "+projectIdAsString)
	}

	project:= Project{projectName,projectId,customerOf}

	projectJSONasBytes, err := json.Marshal(project)

	if err != nil {
		return nil,err
	}
	err = stub.PutState(projectIdAsString, projectJSONasBytes)

	if err != nil {
		return nil,err
	}

	// composite key creation for searching projects according to customer
	/*
	indexName := "customerOf"
	customerOfIndexKey, err := stub.CreateCompositeKey(indexName, []string{customerOf, projectIdAsString})
	if err != nil {
		return nil,err
	}

	value := []byte{0x00}
	stub.PutState(customerOfIndexKey, value)
    */
	fmt.Println("- end initProject")
	return nil,nil
}

func (t *SimpleChaincode) getProject(stub shim.ChaincodeStubInterface, args []string) ([]byte,error){
	if len(args) !=1{
		return nil,errors.New("Incorrect number of arguments. Expecting 1")
	}
	projectId := args[0]
	project, err := stub.GetState(projectId)
	if err != nil {
		return nil,err
	}

	return project,nil
}

func (t *SimpleChaincode) getCustomer(stub shim.ChaincodeStubInterface, args []string) ([]byte,error){
	if len(args) !=1{
		return nil,errors.New("Incorrect number of arguments. Expecting 1")
	}
	customerId := args[0]
	customer, err := stub.GetState(customerId)
	if err != nil {
		return nil,err
	}

	return customer,nil
}

func (t *SimpleChaincode) initCustomer(stub shim.ChaincodeStubInterface,args []string) ([]byte,error) {
		if len(args) != 2{
			return nil,errors.New("Incorrect number of arguments. Expecting 2")
		}
			// ==== Input sanitation ====
		fmt.Println("- start initCustomer")
		if len(args[0]) <= 0 {
			return nil,errors.New("1st argument must be a non-empty string")
		}
		if len(args[1]) <= 0 {
			return nil,errors.New("2nd argument must be a non-empty string")
		}

		customerName := args[0]
		customerId, err := strconv.Atoi(args[1])
		customerIdAsString := args[1]
		if err != nil {
			return nil,errors.New("2nd argument must be a numeric string")
		}
		customerAsBytes, err := stub.GetState(customerIdAsString)
		if err != nil {
			 return nil,err
		} else if customerAsBytes != nil {
			fmt.Println("This customer already exists: " + customerIdAsString)
			return nil,errors.New("This customer already exists: "+customerIdAsString)
		}

		customer:= Customer{customerName,customerId}

		customerJSONasBytes, err := json.Marshal(customer)

		if err != nil {
			return nil,err
		}
		err = stub.PutState(customerIdAsString, customerJSONasBytes)

		if err != nil {
			return nil,err
		}

		fmt.Println("- end initCustomer")
		return nil,nil
}

func (t *SimpleChaincode) initEmployee(stub shim.ChaincodeStubInterface, args []string) ([]byte,error){

	if len(args) != 3 {
		return nil,errors.New("Incorrect number of arguments. Expecting 3")
	}
	// ==== Input sanitation ====
	fmt.Println("- start initEmployee")
	if len(args[0]) <= 0 {
		return nil,errors.New("1st argument must be a non-empty string")
	}
	if len(args[1]) <= 0 {
		return nil,errors.New("2nd argument must be a non-empty string")
	}
	if len(args[2]) <= 0 {
		return nil,errors.New("3rd argument must be a non-empty string")
	}

	employeeName := args[0]
	project := strings.ToLower(args[2])
	employeeId, err := strconv.Atoi(args[1])
	employeeIdAsString := args[1]
	if err != nil {
		return nil,errors.New("2nd argument must be a numeric string")
	}

	employeeAsBytes, err := stub.GetState(employeeIdAsString)
	if err != nil {
		return nil,err
	} else if employeeAsBytes != nil {
		fmt.Println("This employee already exists: " + employeeIdAsString)
		return nil,errors.New("This employee already exists: "+employeeIdAsString)
	}

	employee:= Employee{employeeName,employeeId,project}
	fmt.Println(employee)
	employeeJSONasBytes, err := json.Marshal(employee)
	fmt.Println(employeeJSONasBytes)
	if err != nil {
		return nil,err
	}
	err = stub.PutState(employeeIdAsString, employeeJSONasBytes)

	if err != nil {
		return nil,err
	}
	employee_temp,_ := stub.GetState(employeeIdAsString)
	fmt.Println(employee_temp)
	// composite key to get employees by project

	/*
	indexName := "project"
	projectIndexKey, err := stub.CreateCompositeKey(indexName, []string{project, employeeIdAsString})
	if err != nil {
		return nil,err
	}

	value := []byte{0x00}
	stub.PutState(projectIndexKey, value)
	*/
	fmt.Println("- end initEmployee")
	return nil,nil
}

func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte,error) {
    fmt.Println("Query is running " + function)

    if function =="getEmployee"{
		return t.getEmployee(stub,args)
	}else if function =="getCustomer"{
		return t.getCustomer(stub,args)
	}else if function =="getProject"{
		return t.getProject(stub,args)
	}

	return nil,errors.New("Received unknown function query")
}

func (t *SimpleChaincode) getEmployee(stub shim.ChaincodeStubInterface, args []string) ([]byte,error){
	fmt.Printf("getEmployee called")
	if len(args) !=1{
		return nil,errors.New("Incorrect number of arguments. Expecting 1")
	}
	employeeId := args[0]
	employee, err := stub.GetState(employeeId)
	fmt.Println(employee)
	if err != nil {
		return nil,err
	}

	return employee,nil
}

func main() {
    	err := shim.Start(new(SimpleChaincode))
    if err != nil {
        fmt.Printf("Error starting Simple chaincode: %s", err)
    }
}
<commit_msg>changes in project<commit_after>
package main

import (
	"fmt"
	"strings"
	"strconv"
	"errors"
	"encoding/json"
	"github.com/hyperledger/fabric/core/chaincode/shim"
)

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

type Employee struct {
	Name string `json:"name"`
	EmployeeId int `json:"employeeId"`
	Project string `json:"project"`
}

type Customer struct {
	Name string `json:"name"`
	CustomerId int `json:"customerId"`
}
type Project struct {
	Name string `json:"name"`
	ProjectId int `json:"projectId"`
	CustomerOf string `json:"customerOf"`
	StartTime string `json:"startDate"`
	EndTime string `json:"endDate"`
}

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte,error) {
    fmt.Println("Init is running " + function)
    return nil,nil
}

func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte,error) {

    fmt.Println("Invoke is running " + function)

    if function =="initEmployee"{
		return t.initEmployee(stub,args)
	}else if function =="getEmployee"{
		return t.getEmployee(stub,args)
	}else if function =="initCustomer"{
		return t.initCustomer(stub,args)
	}else if function =="getCustomer"{
		return t.getCustomer(stub,args)
	}else if function =="initProject"{
		return t.initProject(stub,args)
	}else if function =="getProject"{
		return t.getProject(stub,args)
	}
	return nil,errors.New("Received unknown function invocation")
}

func (t *SimpleChaincode) initProject(stub shim.ChaincodeStubInterface, args []string) ([]byte,error){

	if len(args) != 3 {
		return nil,errors.New("Incorrect number of arguments. Expecting 3")
	}
	// ==== Input sanitation ====
	fmt.Println("- start initProject")
	if len(args[0]) <= 0 {
		return nil,errors.New("1st argument must be a non-empty string")
	}
	if len(args[1]) <= 0 {
		return nil,errors.New("2nd argument must be a non-empty string")
	}
	if len(args[2]) <= 0 {
		return nil,errors.New("3rd argument must be a non-empty string")
	}
	if len(args[3]) <= 0 {
		return nil,errors.New("4th argument must be a non-empty string")
	}
	if len(args[4]) <= 0 {
		return nil,errors.New("5th argument must be a non-empty string")
	}

	projectName := args[0]
	customerOf := strings.ToLower(args[2])
	projectId, err := strconv.Atoi(args[1])
	projectIdAsString := args[1]
	startDate:= args[3]
	endDate:= args[4]
	if err != nil {
		return nil,errors.New("2nd argument must be a numeric string")
	}

	projectAsBytes, err := stub.GetState(projectIdAsString)
	if err != nil {
		return nil,err
	} else if projectAsBytes != nil {
		fmt.Println("This project already exists: " + projectIdAsString)
		return nil, errors.New("This project already exists "+projectIdAsString)
	}

	project:= Project{projectName,projectId,customerOf,startDate,endDate}

	projectJSONasBytes, err := json.Marshal(project)

	if err != nil {
		return nil,err
	}
	err = stub.PutState(projectIdAsString, projectJSONasBytes)

	if err != nil {
		return nil,err
	}

	// composite key creation for searching projects according to customer
	/*
	indexName := "customerOf"
	customerOfIndexKey, err := stub.CreateCompositeKey(indexName, []string{customerOf, projectIdAsString})
	if err != nil {
		return nil,err
	}

	value := []byte{0x00}
	stub.PutState(customerOfIndexKey, value)
    */
	fmt.Println("- end initProject")
	return nil,nil
}

func (t *SimpleChaincode) getProject(stub shim.ChaincodeStubInterface, args []string) ([]byte,error){
	if len(args) !=1{
		return nil,errors.New("Incorrect number of arguments. Expecting 1")
	}
	projectId := args[0]
	project, err := stub.GetState(projectId)
	if err != nil {
		return nil,err
	}

	return project,nil
}

func (t *SimpleChaincode) getCustomer(stub shim.ChaincodeStubInterface, args []string) ([]byte,error){
	if len(args) !=1{
		return nil,errors.New("Incorrect number of arguments. Expecting 1")
	}
	customerId := args[0]
	customer, err := stub.GetState(customerId)
	if err != nil {
		return nil,err
	}

	return customer,nil
}

func (t *SimpleChaincode) initCustomer(stub shim.ChaincodeStubInterface,args []string) ([]byte,error) {
		if len(args) != 2{
			return nil,errors.New("Incorrect number of arguments. Expecting 2")
		}
			// ==== Input sanitation ====
		fmt.Println("- start initCustomer")
		if len(args[0]) <= 0 {
			return nil,errors.New("1st argument must be a non-empty string")
		}
		if len(args[1]) <= 0 {
			return nil,errors.New("2nd argument must be a non-empty string")
		}

		customerName := args[0]
		customerId, err := strconv.Atoi(args[1])
		customerIdAsString := args[1]
		if err != nil {
			return nil,errors.New("2nd argument must be a numeric string")
		}
		customerAsBytes, err := stub.GetState(customerIdAsString)
		if err != nil {
			 return nil,err
		} else if customerAsBytes != nil {
			fmt.Println("This customer already exists: " + customerIdAsString)
			return nil,errors.New("This customer already exists: "+customerIdAsString)
		}

		customer:= Customer{customerName,customerId}

		customerJSONasBytes, err := json.Marshal(customer)

		if err != nil {
			return nil,err
		}
		err = stub.PutState(customerIdAsString, customerJSONasBytes)

		if err != nil {
			return nil,err
		}

		fmt.Println("- end initCustomer")
		return nil,nil
}

func (t *SimpleChaincode) initEmployee(stub shim.ChaincodeStubInterface, args []string) ([]byte,error){

	if len(args) != 3 {
		return nil,errors.New("Incorrect number of arguments. Expecting 3")
	}
	// ==== Input sanitation ====
	fmt.Println("- start initEmployee")
	if len(args[0]) <= 0 {
		return nil,errors.New("1st argument must be a non-empty string")
	}
	if len(args[1]) <= 0 {
		return nil,errors.New("2nd argument must be a non-empty string")
	}
	if len(args[2]) <= 0 {
		return nil,errors.New("3rd argument must be a non-empty string")
	}

	employeeName := args[0]
	project := strings.ToLower(args[2])
	employeeId, err := strconv.Atoi(args[1])
	employeeIdAsString := args[1]
	if err != nil {
		return nil,errors.New("2nd argument must be a numeric string")
	}

	employeeAsBytes, err := stub.GetState(employeeIdAsString)
	if err != nil {
		return nil,err
	} else if employeeAsBytes != nil {
		fmt.Println("This employee already exists: " + employeeIdAsString)
		return nil,errors.New("This employee already exists: "+employeeIdAsString)
	}

	employee:= Employee{employeeName,employeeId,project}
	fmt.Println(employee)
	employeeJSONasBytes, err := json.Marshal(employee)
	fmt.Println(employeeJSONasBytes)
	if err != nil {
		return nil,err
	}
	err = stub.PutState(employeeIdAsString, employeeJSONasBytes)

	if err != nil {
		return nil,err
	}
	employee_temp,_ := stub.GetState(employeeIdAsString)
	fmt.Println(employee_temp)
	// composite key to get employees by project

	/*
	indexName := "project"
	projectIndexKey, err := stub.CreateCompositeKey(indexName, []string{project, employeeIdAsString})
	if err != nil {
		return nil,err
	}

	value := []byte{0x00}
	stub.PutState(projectIndexKey, value)
	*/
	fmt.Println("- end initEmployee")
	return nil,nil
}

func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte,error) {
    fmt.Println("Query is running " + function)

    if function =="getEmployee"{
		return t.getEmployee(stub,args)
	}else if function =="getCustomer"{
		return t.getCustomer(stub,args)
	}else if function =="getProject"{
		return t.getProject(stub,args)
	}

	return nil,errors.New("Received unknown function query")
}

func (t *SimpleChaincode) getEmployee(stub shim.ChaincodeStubInterface, args []string) ([]byte,error){
	fmt.Printf("getEmployee called")
	if len(args) !=1{
		return nil,errors.New("Incorrect number of arguments. Expecting 1")
	}
	employeeId := args[0]
	employee, err := stub.GetState(employeeId)
	fmt.Println(employee)
	if err != nil {
		return nil,err
	}

	return employee,nil
}

func main() {
    	err := shim.Start(new(SimpleChaincode))
    if err != nil {
        fmt.Printf("Error starting Simple chaincode: %s", err)
    }
}
<|endoftext|>


<commit_before>/*
Copyright 2017 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
	"log"
	"net/http"
	"os/exec"
	"strings"

	"github.com/spf13/pflag"

	api "k8s.io/client-go/pkg/api/v1"

	nginxconfig "k8s.io/ingress/controllers/nginx/pkg/config"
	"k8s.io/ingress/core/pkg/ingress"
	"k8s.io/ingress/core/pkg/ingress/controller"
	"k8s.io/ingress/core/pkg/ingress/defaults"
)

func main() {
	dc := newDummyController()
	ic := controller.NewIngressController(dc)
	defer func() {
		log.Printf("Shutting down ingress controller...")
		ic.Stop()
	}()
	ic.Start()
}

func newDummyController() ingress.Controller {
	return &DummyController{}
}

type DummyController struct{}

func (dc DummyController) SetConfig(cfgMap *api.ConfigMap) {
	log.Printf("Config map %+v", cfgMap)
}

func (dc DummyController) Reload(data []byte) ([]byte, bool, error) {
	out, err := exec.Command("echo", string(data)).CombinedOutput()
	if err != nil {
		return out, false, err
	}
	log.Printf("Reloaded new config %s", out)
	return out, true, err
}

func (dc DummyController) Test(file string) *exec.Cmd {
	return exec.Command("echo", file)
}

func (dc DummyController) OnUpdate(updatePayload ingress.Configuration) ([]byte, error) {
	log.Printf("Received OnUpdate notification")
	for _, b := range updatePayload.Backends {
		eps := []string{}
		for _, e := range b.Endpoints {
			eps = append(eps, e.Address)
		}
		log.Printf("%v: %v", b.Name, strings.Join(eps, ", "))
	}
	return []byte(`<string containing a configuration file>`), nil
}

func (dc DummyController) BackendDefaults() defaults.Backend {
	// Just adopt nginx's default backend config
	return nginxconfig.NewDefault().Backend
}

func (n DummyController) Name() string {
	return "dummy Controller"
}

func (n DummyController) Check(_ *http.Request) error {
	return nil
}

func (dc DummyController) Info() *ingress.BackendInfo {
	return &ingress.BackendInfo{
		Name:       "dummy",
		Release:    "0.0.0",
		Build:      "git-00000000",
		Repository: "git://foo.bar.com",
	}
}

func (n DummyController) ConfigureFlags(*pflag.FlagSet) {
}

func (n DummyController) OverrideFlags(*pflag.FlagSet) {
}

func (n DummyController) SetListers(lister ingress.StoreLister) {

}

func (n DummyController) DefaultIngressClass() string {
	return "dummy"
}
<commit_msg><commit_after>/*
Copyright 2017 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
	"log"
	"net/http"
	"os/exec"
	"strings"

	"github.com/spf13/pflag"

	api "k8s.io/client-go/pkg/api/v1"

	nginxconfig "k8s.io/ingress/controllers/nginx/pkg/config"
	"k8s.io/ingress/core/pkg/ingress"
	"k8s.io/ingress/core/pkg/ingress/controller"
	"k8s.io/ingress/core/pkg/ingress/defaults"
)

func main() {
	dc := newDummyController()
	ic := controller.NewIngressController(dc)
	defer func() {
		log.Printf("Shutting down ingress controller...")
		ic.Stop()
	}()
	ic.Start()
}

func newDummyController() ingress.Controller {
	return &DummyController{}
}

type DummyController struct{}

func (dc DummyController) SetConfig(cfgMap *api.ConfigMap) {
	log.Printf("Config map %+v", cfgMap)
}

func (dc DummyController) Test(file string) *exec.Cmd {
	return exec.Command("echo", file)
}

func (dc DummyController) OnUpdate(updatePayload ingress.Configuration) error {
	log.Printf("Received OnUpdate notification")
	for _, b := range updatePayload.Backends {
		eps := []string{}
		for _, e := range b.Endpoints {
			eps = append(eps, e.Address)
		}
		log.Printf("%v: %v", b.Name, strings.Join(eps, ", "))
	}

	log.Printf("Reloaded new config")
	return nil
}

func (dc DummyController) BackendDefaults() defaults.Backend {
	// Just adopt nginx's default backend config
	return nginxconfig.NewDefault().Backend
}

func (n DummyController) Name() string {
	return "dummy Controller"
}

func (n DummyController) Check(_ *http.Request) error {
	return nil
}

func (dc DummyController) Info() *ingress.BackendInfo {
	return &ingress.BackendInfo{
		Name:       "dummy",
		Release:    "0.0.0",
		Build:      "git-00000000",
		Repository: "git://foo.bar.com",
	}
}

func (n DummyController) ConfigureFlags(*pflag.FlagSet) {
}

func (n DummyController) OverrideFlags(*pflag.FlagSet) {
}

func (n DummyController) SetListers(lister ingress.StoreLister) {

}

func (n DummyController) DefaultIngressClass() string {
	return "dummy"
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/hmac"
	"crypto/rand"
	"crypto/sha256"
	"database/sql"
	"encoding/hex"
	"log"
	"net/http"
	"text/template"

	"github.com/zenazn/goji"
	"github.com/zenazn/goji/web"

	_ "github.com/mattn/go-sqlite3"
)

type TemplateContext struct {
	Alias string
	Addr  string
}

var db *sql.DB

var cookie_secret = make([]byte, 16)

func set_cookie(user_id string, w http.ResponseWriter) {
	mac := hmac.New(sha256.New, cookie_secret)
	mac.Write([]byte(user_id))

	cookie := &http.Cookie{
		Name:     "user_id",
		Value:    hex.EncodeToString(mac.Sum(nil)) + user_id,
		MaxAge:   60 * 5,
		Path:     "/",
		HttpOnly: true,
		// Secure:   true,
	}

	http.SetCookie(w, cookie)
}

func read_cookie(r *http.Request) string {
	cookie, err := r.Cookie("user_id")
	if err != nil {
		return ""
	}

	mac := hmac.New(sha256.New, cookie_secret)
	mac.Write([]byte(cookie.Value[sha256.Size*2:]))

	if !hmac.Equal([]byte(hex.EncodeToString(mac.Sum(nil))),
		[]byte(cookie.Value[:sha256.Size*2])) {
		return ""
	}

	return cookie.Value[sha256.Size*2:]
}

func get_form(c web.C, w http.ResponseWriter, r *http.Request) {
	user_id := read_cookie(r)

	t, _ := template.ParseFiles("form.html")
	context := &TemplateContext{
		Alias: user_id,
		Addr:  "$ADDR",
	}
	t.Execute(w, context)
}

func post_form(c web.C, w http.ResponseWriter, r *http.Request) {
	err := r.ParseForm()
	if err != nil {
		log.Println("Could not parse form params")
		http.Error(w, http.StatusText(400), 400)
		return
	}

	log.Println(r.PostForm.Get("alias"))
	log.Println(r.PostForm.Get("addr"))
	http.Redirect(w, r, "/", 303)
}

func main() {
	_, err := rand.Read(cookie_secret)
	if err != nil {
		log.Fatal(err)
	}

	load_oauth()

	db, err = sql.Open("sqlite3", "./alum.db")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	_, err = db.Exec(`
        CREATE TABLE IF NOT EXISTS "ALIASES" (
        "user_id" TEXT PRIMARY KEY NOT NULL,
        "alias" TEXT UNIQUE NOT NULL,
        "addr" TEXT NOT NULL
        );`)
	if err != nil {
		log.Fatal(err)
	}

	goji.Get("/", get_form)
	goji.Post("/", post_form)
	goji.Serve()
}
<commit_msg>create new aliases<commit_after>package main

import (
	"crypto/hmac"
	"crypto/rand"
	"crypto/sha256"
	"database/sql"
	"encoding/hex"
	"io/ioutil"
	"log"
	"net/http"
	"text/template"

	"github.com/zenazn/goji"
	"github.com/zenazn/goji/web"

	_ "github.com/mattn/go-sqlite3"
)

type TemplateContext struct {
	Alias string
	Addr  string
}

var db *sql.DB

var cookie_secret = make([]byte, 16)

func set_cookie(user_id string, w http.ResponseWriter) {
	mac := hmac.New(sha256.New, cookie_secret)
	mac.Write([]byte(user_id))

	cookie := &http.Cookie{
		Name:     "user_id",
		Value:    hex.EncodeToString(mac.Sum(nil)) + user_id,
		MaxAge:   60 * 5,
		Path:     "/",
		HttpOnly: true,
		// Secure:   true,
	}

	http.SetCookie(w, cookie)
}

func read_cookie(r *http.Request) string {
	cookie, err := r.Cookie("user_id")
	if err != nil {
		return ""
	}

	mac := hmac.New(sha256.New, cookie_secret)
	mac.Write([]byte(cookie.Value[sha256.Size*2:]))

	if !hmac.Equal([]byte(hex.EncodeToString(mac.Sum(nil))),
		[]byte(cookie.Value[:sha256.Size*2])) {
		return ""
	}

	return cookie.Value[sha256.Size*2:]
}

func get_form(c web.C, w http.ResponseWriter, r *http.Request) {
	user_id := read_cookie(r)

	t, _ := template.ParseFiles("form.html")
	context := &TemplateContext{
		Alias: user_id,
		Addr:  "$ADDR",
	}
	t.Execute(w, context)
}

func post_form(c web.C, w http.ResponseWriter, r *http.Request) {
	user_id := read_cookie(r)

	err := r.ParseForm()
	if err != nil {
		log.Println("Could not parse form params")
		http.Error(w, http.StatusText(400), 400)
		return
	}

	alias := r.PostForm.Get("alias")
	addr := r.PostForm.Get("addr")

	_, err = db.Exec(`DELETE FROM "ALIASES" WHERE user_id = ?`, user_id)
	if err != nil {
		log.Println(err)
		http.Error(w, http.StatusText(500), 500)
		return
	}

	_, err = db.Exec(`INSERT INTO "ALIASES" (user_id, alias, addr)
					  VALUES (?, ?, ?)`, user_id, alias, addr)
	if err != nil {
		log.Println(err)
		file, err := ioutil.ReadFile("./error.html")
		if err != nil {
			log.Println(err)
			http.Error(w, http.StatusText(500), 500)
			return
		}
		w.Write(file)
		return
	}

	http.Redirect(w, r, "/", 303)
}

func main() {
	_, err := rand.Read(cookie_secret)
	if err != nil {
		log.Fatal(err)
	}

	load_oauth()

	db, err = sql.Open("sqlite3", "./alum.db")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	_, err = db.Exec(`
        CREATE TABLE IF NOT EXISTS "ALIASES" (
        "user_id" TEXT PRIMARY KEY NOT NULL,
        "alias" TEXT UNIQUE NOT NULL,
        "addr" TEXT NOT NULL
        );`)
	if err != nil {
		log.Fatal(err)
	}

	goji.Get("/", get_form)
	goji.Post("/", post_form)
	goji.Serve()
}
<|endoftext|>


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

// +build docker_test

package client

import (
	"bytes"
	"io"
	"sync"
	"testing"
	"time"

	"github.com/katzenpost/client/config"
	"github.com/katzenpost/client/constants"
	"github.com/katzenpost/core/crypto/rand"
	"github.com/katzenpost/core/utils"
	"github.com/stretchr/testify/require"
)

func TestDockerClientConnectShutdown(t *testing.T) {
	require := require.New(t)

	cfg, err := config.LoadFile("testdata/client.toml")
	require.NoError(err)

	cfg, linkKey := AutoRegisterRandomClient(cfg)
	client, err := New(cfg)
	require.NoError(err)

	session, err := client.NewSession(linkKey)
	require.NoError(err)

	<-session.EventSink

	client.Shutdown()
	client.Wait()
}

func TestDockerClientBlockingSendReceive(t *testing.T) {
	require := require.New(t)

	cfg, err := config.LoadFile("testdata/client.toml")
	require.NoError(err)

	cfg, linkKey := AutoRegisterRandomClient(cfg)
	client, err := New(cfg)
	require.NoError(err)

	session, err := client.NewSession(linkKey)
	require.NoError(err)

	desc, err := session.GetService("loop")
	require.NoError(err)

	reply, err := session.BlockingSendUnreliableMessage(desc.Name, desc.Provider, []byte("hello"))
	require.NoError(err)
	require.True(utils.CtIsZero(reply))

	client.Shutdown()
	client.Wait()
}

func TestDockerClientBlockingSendReceiveWithDecoyTraffic(t *testing.T) {
	require := require.New(t)

	cfg, err := config.LoadFile("testdata/client.toml")
	require.NoError(err)

	cfg, linkKey := AutoRegisterRandomClient(cfg)
	cfg.Debug.DisableDecoyTraffic = false
	client, err := New(cfg)
	require.NoError(err)

	session, err := client.NewSession(linkKey)
	require.NoError(err)

	desc, err := session.GetService("loop")
	require.NoError(err)

	reply, err := session.BlockingSendUnreliableMessage(desc.Name, desc.Provider, []byte("hello"))
	require.NoError(err)
	require.True(utils.CtIsZero(reply))

	client.Shutdown()
	client.Wait()
}

func TestDockerClientAsyncSendReceive(t *testing.T) {
	require := require.New(t)

	cfg, err := config.LoadFile("testdata/client.toml")
	require.NoError(err)

	cfg, linkKey := AutoRegisterRandomClient(cfg)
	client, err := New(cfg)
	require.NoError(err)

	clientSession, err := client.NewSession(linkKey)
	require.NoError(err)

	desc, err := clientSession.GetService("loop")
	require.NoError(err)

	msgID, err := clientSession.SendUnreliableMessage(desc.Name, desc.Provider, []byte("hello"))
	require.NoError(err)
	t.Logf("sent message ID %x", msgID)

	var wg sync.WaitGroup
	wg.Add(2)
	go func() {
		for eventRaw := range clientSession.EventSink {
			switch event := eventRaw.(type) {
			case *MessageSentEvent:
				if bytes.Equal(msgID[:], event.MessageID[:]) {
					require.NoError(event.Err)
					wg.Done()
				}
			case *MessageReplyEvent:
				if bytes.Equal(msgID[:], event.MessageID[:]) {
					require.NoError(event.Err)
					require.True(utils.CtIsZero(event.Payload))
					wg.Done()
					return
				}
			default:
				continue
			}
		}
	}()
	wg.Wait()

	client.Shutdown()
	client.Wait()
}

func TestDockerClientAsyncSendReceiveWithDecoyTraffic(t *testing.T) {
	require := require.New(t)

	cfg, err := config.LoadFile("testdata/client.toml")
	require.NoError(err)

	cfg, linkKey := AutoRegisterRandomClient(cfg)
	cfg.Debug.DisableDecoyTraffic = false
	client, err := New(cfg)
	require.NoError(err)

	clientSession, err := client.NewSession(linkKey)
	require.NoError(err)

	desc, err := clientSession.GetService("loop")
	require.NoError(err)

	msgID, err := clientSession.SendUnreliableMessage(desc.Name, desc.Provider, []byte("hello"))
	require.NoError(err)
	t.Logf("sent message ID %x", msgID)

	var wg sync.WaitGroup
	wg.Add(2)
	go func() {
		for eventRaw := range clientSession.EventSink {
			switch event := eventRaw.(type) {
			case *MessageSentEvent:
				if bytes.Equal(msgID[:], event.MessageID[:]) {
					require.NoError(event.Err)
					wg.Done()
				}
			case *MessageReplyEvent:
				if bytes.Equal(msgID[:], event.MessageID[:]) {
					require.NoError(event.Err)
					require.True(utils.CtIsZero(event.Payload))
					wg.Done()
					return
				}
			default:
				continue
			}
		}
	}()
	wg.Wait()

	client.Shutdown()
	client.Wait()
}

func TestDockerClientTestGarbageCollection(t *testing.T) {
	require := require.New(t)

	cfg, err := config.LoadFile("testdata/client.toml")
	require.NoError(err)

	cfg, linkKey := AutoRegisterRandomClient(cfg)
	client, err := New(cfg)
	require.NoError(err)

	clientSession, err := client.NewSession(linkKey)
	require.NoError(err)

	msgID := [constants.MessageIDLength]byte{}
	_, err = io.ReadFull(rand.Reader, msgID[:])
	var msg = Message{
		ID:         &msgID,
		IsBlocking: false,
		SentAt:     time.Now().AddDate(0, 0, -1),
		ReplyETA:   10 * time.Second,
	}
	clientSession.surbIDMap.Store(msgID, &msg)
	clientSession.garbageCollect()
	_, ok := clientSession.surbIDMap.Load(msgID)
	require.False(ok)

	client.Shutdown()
	client.Wait()
}

/*
WTF doesn't this work!?
func TestDockerClientTestIntegrationGarbageCollection(t *testing.T) {
	require := require.New(t)

	cfg, err := config.LoadFile("testdata/client.toml")
	require.NoError(err)

	cfg, linkKey := AutoRegisterRandomClient(cfg)
	client, err := New(cfg)
	require.NoError(err)

	clientSession, err := client.NewSession(linkKey)
	require.NoError(err)

	desc, err := clientSession.GetService("loop")
	require.NoError(err)

	// Send a message to a nonexistent service so that we don't get a reply and thus
	// retain an entry in the SURB ID Map which we must garbage collect.
	msgID, err := clientSession.SendUnreliableMessage("nonexistent", desc.Provider, []byte("hello"))
	require.NoError(err)
	t.Logf("sent message ID %x", msgID)

	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		for eventRaw := range clientSession.EventSink {
			switch event := eventRaw.(type) {
			case *MessageSentEvent:
				if bytes.Equal(msgID[:], event.MessageID[:]) {
					require.NoError(event.Err)

					_, ok := clientSession.surbIDMap.Load(msgID)
					require.True(ok)

					duration := time.Duration(event.ReplyETA + constants.RoundTripTimeSlop + (5 * time.Second))
					t.Logf("Sleeping for %s so that the SURB ID Map entry will get garbage collected.", duration)
					time.Sleep(duration)
					wg.Done()
					return
				}
			default:
				continue
			}
		}
	}()
	wg.Wait()

	clientSession.garbageCollect()
	_, ok := clientSession.surbIDMap.Load(msgID)
	require.False(ok)

	client.Shutdown()
	client.Wait()
}
*/
<commit_msg>Fix TestDockerClientTestIntegrationGarbageCollection<commit_after>// client_docker_test.go - optional client docker test
// Copyright (C) 2019  David Stainton.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

// +build docker_test

package client

import (
	"bytes"
	"io"
	"sync"
	"testing"
	"time"

	"github.com/katzenpost/client/config"
	"github.com/katzenpost/client/constants"
	"github.com/katzenpost/core/crypto/rand"
	sConstants "github.com/katzenpost/core/sphinx/constants"
	"github.com/katzenpost/core/utils"
	"github.com/stretchr/testify/require"
)

func TestDockerClientConnectShutdown(t *testing.T) {
	require := require.New(t)

	cfg, err := config.LoadFile("testdata/client.toml")
	require.NoError(err)

	cfg, linkKey := AutoRegisterRandomClient(cfg)
	client, err := New(cfg)
	require.NoError(err)

	session, err := client.NewSession(linkKey)
	require.NoError(err)

	<-session.EventSink

	client.Shutdown()
	client.Wait()
}

func TestDockerClientBlockingSendReceive(t *testing.T) {
	require := require.New(t)

	cfg, err := config.LoadFile("testdata/client.toml")
	require.NoError(err)

	cfg, linkKey := AutoRegisterRandomClient(cfg)
	client, err := New(cfg)
	require.NoError(err)

	session, err := client.NewSession(linkKey)
	require.NoError(err)

	desc, err := session.GetService("loop")
	require.NoError(err)

	reply, err := session.BlockingSendUnreliableMessage(desc.Name, desc.Provider, []byte("hello"))
	require.NoError(err)
	require.True(utils.CtIsZero(reply))

	client.Shutdown()
	client.Wait()
}

func TestDockerClientBlockingSendReceiveWithDecoyTraffic(t *testing.T) {
	require := require.New(t)

	cfg, err := config.LoadFile("testdata/client.toml")
	require.NoError(err)

	cfg, linkKey := AutoRegisterRandomClient(cfg)
	cfg.Debug.DisableDecoyTraffic = false
	client, err := New(cfg)
	require.NoError(err)

	session, err := client.NewSession(linkKey)
	require.NoError(err)

	desc, err := session.GetService("loop")
	require.NoError(err)

	reply, err := session.BlockingSendUnreliableMessage(desc.Name, desc.Provider, []byte("hello"))
	require.NoError(err)
	require.True(utils.CtIsZero(reply))

	client.Shutdown()
	client.Wait()
}

func TestDockerClientAsyncSendReceive(t *testing.T) {
	require := require.New(t)

	cfg, err := config.LoadFile("testdata/client.toml")
	require.NoError(err)

	cfg, linkKey := AutoRegisterRandomClient(cfg)
	client, err := New(cfg)
	require.NoError(err)

	clientSession, err := client.NewSession(linkKey)
	require.NoError(err)

	desc, err := clientSession.GetService("loop")
	require.NoError(err)

	msgID, err := clientSession.SendUnreliableMessage(desc.Name, desc.Provider, []byte("hello"))
	require.NoError(err)
	t.Logf("sent message ID %x", msgID)

	var wg sync.WaitGroup
	wg.Add(2)
	go func() {
		for eventRaw := range clientSession.EventSink {
			switch event := eventRaw.(type) {
			case *MessageSentEvent:
				if bytes.Equal(msgID[:], event.MessageID[:]) {
					require.NoError(event.Err)
					wg.Done()
				}
			case *MessageReplyEvent:
				if bytes.Equal(msgID[:], event.MessageID[:]) {
					require.NoError(event.Err)
					require.True(utils.CtIsZero(event.Payload))
					wg.Done()
					return
				}
			default:
				continue
			}
		}
	}()
	wg.Wait()

	client.Shutdown()
	client.Wait()
}

func TestDockerClientAsyncSendReceiveWithDecoyTraffic(t *testing.T) {
	require := require.New(t)

	cfg, err := config.LoadFile("testdata/client.toml")
	require.NoError(err)

	cfg, linkKey := AutoRegisterRandomClient(cfg)
	cfg.Debug.DisableDecoyTraffic = false
	client, err := New(cfg)
	require.NoError(err)

	clientSession, err := client.NewSession(linkKey)
	require.NoError(err)

	desc, err := clientSession.GetService("loop")
	require.NoError(err)

	msgID, err := clientSession.SendUnreliableMessage(desc.Name, desc.Provider, []byte("hello"))
	require.NoError(err)
	t.Logf("sent message ID %x", msgID)

	var wg sync.WaitGroup
	wg.Add(2)
	go func() {
		for eventRaw := range clientSession.EventSink {
			switch event := eventRaw.(type) {
			case *MessageSentEvent:
				if bytes.Equal(msgID[:], event.MessageID[:]) {
					require.NoError(event.Err)
					wg.Done()
				}
			case *MessageReplyEvent:
				if bytes.Equal(msgID[:], event.MessageID[:]) {
					require.NoError(event.Err)
					require.True(utils.CtIsZero(event.Payload))
					wg.Done()
					return
				}
			default:
				continue
			}
		}
	}()
	wg.Wait()

	client.Shutdown()
	client.Wait()
}

func TestDockerClientTestGarbageCollection(t *testing.T) {
	require := require.New(t)

	cfg, err := config.LoadFile("testdata/client.toml")
	require.NoError(err)

	cfg, linkKey := AutoRegisterRandomClient(cfg)
	client, err := New(cfg)
	require.NoError(err)

	clientSession, err := client.NewSession(linkKey)
	require.NoError(err)

	msgID := [constants.MessageIDLength]byte{}
	_, err = io.ReadFull(rand.Reader, msgID[:])
	var msg = Message{
		ID:         &msgID,
		IsBlocking: false,
		SentAt:     time.Now().AddDate(0, 0, -1),
		ReplyETA:   10 * time.Second,
	}
	// actually the key should be a SURB ID, but this works fine for the test
	clientSession.surbIDMap.Store(msgID, &msg)
	clientSession.garbageCollect()
	_, ok := clientSession.surbIDMap.Load(msgID)
	require.False(ok)

	client.Shutdown()
	client.Wait()
}

func TestDockerClientTestIntegrationGarbageCollection(t *testing.T) {
	require := require.New(t)

	cfg, err := config.LoadFile("testdata/client.toml")
	require.NoError(err)

	cfg, linkKey := AutoRegisterRandomClient(cfg)
	client, err := New(cfg)
	require.NoError(err)

	clientSession, err := client.NewSession(linkKey)
	require.NoError(err)

	desc, err := clientSession.GetService("loop")
	require.NoError(err)

	// Send a message to a nonexistent service so that we don't get a reply and thus
	// retain an entry in the SURB ID Map which we must garbage collect.
	msgID, err := clientSession.SendUnreliableMessage("nonexistent", desc.Provider, []byte("hello"))
	require.NoError(err)
	t.Logf("sent message ID %x", msgID)

	var surbID [sConstants.SURBIDLength]byte
	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		for eventRaw := range clientSession.EventSink {
			switch event := eventRaw.(type) {
			case *MessageSentEvent:
				if bytes.Equal(msgID[:], event.MessageID[:]) {
					require.NoError(event.Err)
					surbIDMapRange := func(rawSurbID, rawMessage interface{}) bool {
						surbID = rawSurbID.([sConstants.SURBIDLength]byte)
						return true
					}
					clientSession.surbIDMap.Range(surbIDMapRange)
					duration := time.Duration(event.ReplyETA + constants.RoundTripTimeSlop + (5 * time.Second))
					t.Logf("Sleeping for %s so that the SURB ID Map entry will get garbage collected.", duration)
					time.Sleep(duration)
					wg.Done()
					return
				}
			default:
				continue
			}
		}
	}()
	wg.Wait()

	clientSession.garbageCollect()
	_, ok := clientSession.surbIDMap.Load(surbID)
	require.False(ok)

	client.Shutdown()
	client.Wait()
}
<|endoftext|>


<commit_before><commit_msg>add emitter slice example<commit_after>package main

import (
	"fmt"

	"github.com/vladimirvivien/automi/collectors"
	"github.com/vladimirvivien/automi/stream"
)

type log map[string]string

func main() {

	data := []log{
		log{"Event": "request", "path": "/i/a", "Device": "00:11:51:AA", "Result": "accepted"},
		log{"Event": "response", "path": "/i/a/", "Device": "00:11:51:AA", "Result": "served"},
		log{"Event": "request", "path": "/i/b", "Device": "00:11:22:33", "Result": "accepted"},
		log{"Event": "response", "path": "/i/b", "Device": "00:11:22:33", "Result": "served"},
		log{"Event": "request", "path": "/i/c", "Device": "00:11:51:AA", "Result": "accepted"},
		log{"Event": "response", "path": "/i/c", "Device": "00:11:51:AA", "Result": "served"},
		log{"Event": "request", "path": "/i/d", "Device": "00:BB:22:DD", "Result": "accepted"},
		log{"Event": "response", "path": "/i/a", "Device": "00:BB:22:DD", "Result": "served"},
	}

	stream := stream.New(data)

	// Or, create stream with
	// stream := stream.New(emitter.Chan(ch))

	stream.Filter(func(e log) bool {
		return (e["Event"] == "response")
	})

	// sink result in a collector function which prints it
	stream.SinkTo(collectors.Func(func(data interface{}) error {
		e := data.(log)
		fmt.Println(e)
		return nil
	}))

	// open the stream
	if err := <-stream.Open(); err != nil {
		fmt.Println(err)
		return
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2014 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package btcwire

// These constants are deprecated as they do not follow the standard Go style
// guidelines and are only provided for backwards compatibility.  Use the
// InvType* constants instead.
const (
	InvVect_Error InvType = InvTypeError // DEPRECATED
	InvVect_Tx    InvType = InvTypeTx    // DEPRECATED
	InvVect_Block InvType = InvTypeBlock // DEPRECATED
)
<commit_msg>Remove deprecated InvType_* constants.<commit_after><|endoftext|>