<commit_before>// chris 072815

package rebnf

import (
	"errors"
	"fmt"
	"io"
	"log"
	"unicode"

	mathrand "math/rand"
	"unicode/utf8"

	fixrand "chrispennello.com/go/util/fix/math/rand"
	"golang.org/x/exp/ebnf"
)

// ErrNoStart is returned by Random when the specified start production
// cannot be found in the grammar.
var ErrNoStart = errors.New("start production not found")

// Random generates random productions of the given grammar starting at
// the given start production, and writes them into the destination
// io.Writer.
func (c *Ctx) Random(dst io.Writer, grammar ebnf.Grammar, start string) error {
	prod, ok := grammar[start]
	if !ok {
		return ErrNoStart
	}
	return c.random(dst, grammar, prod.Expr, 0)
}

// IsCapital returns a boolean indicating whether or not the first rune
// of the given string is upper case.
func IsCapital(s string) bool {
	ch, _ := utf8.DecodeRuneInString(s)
	return unicode.IsUpper(ch)
}

// IsTerminal returns a boolean that indicates whether the given
// Expression is a terminal one.  Ranges and Tokens are unconditionally
// considered to be terminal, and Names are terminal iff they're
// capitalized.  Productions are not considered because Alternatives
// contain Names, and you have to loo up the production by name in the
// grammar--it's just not a use case handled by this library, but could
// be added easily if needed.
func IsTerminal(expr ebnf.Expression) bool {
	switch expr.(type) {
	case *ebnf.Name:
		name := expr.(*ebnf.Name)
		return !IsCapital(name.String)
	case *ebnf.Range:
		return true
	case *ebnf.Token:
		return true
	default:
		return false
	}
}

// findTerminals is like filter(IsTerminal, exprs).  It ranges over all
// of the given expressions and produces a new slice of expressions
// containing only those for which IsTerminal returns true.
func findTerminals(exprs []ebnf.Expression) []ebnf.Expression {
	r := make([]ebnf.Expression, 0, len(exprs))
	for _, expr := range exprs {
		if IsTerminal(expr) {
			r = append(r, expr)
		}
	}
	return r
}

// pad picks a random rune from the padding string specified by the
// context and writes it to the destination writer.
func (c *Ctx) pad(dst io.Writer) error {
	runes := []rune(c.padding)
	if len(runes) == 0 {
		return nil
	}
	r := runes[mathrand.Intn(len(runes))]
	_, err := io.WriteString(dst, string([]rune{r}))
	return err
}

func (c *Ctx) log(format string, a ...interface{}) {
	if !c.debug {
		return
	}
	// Logging errors ignored.
	log.Printf(format, a...)
}

// random is the inner, recursive implementation of Random.  It handles
// each of the ebnf.Expression implementations, outputting productions
// randomly to the destination writer.  It implements a recursion depth
// counter, and once the counter exceeds the limit, it favors producing
// terminals over non-terminals.  Note that this does not guarantee
// termination, however.  For example, the pathological grammar "S = S"
// will still loop forever.
func (c *Ctx) random(dst io.Writer, grammar ebnf.Grammar, expr ebnf.Expression, depth int) error {
	c.log("recursion depth %d\n", depth)
	c.log("%#v\n\n", expr)

	switch expr.(type) {
	// Choose a random alternative.
	case ebnf.Alternative:
		alt := expr.(ebnf.Alternative)
		var exprs []ebnf.Expression
		// If maximum recursion depth has been exceeded, attempt
		// to select from only terminal expressions.
		if depth > c.maxdepth {
			exprs = findTerminals(alt)
			c.log("alternative: found %d terminals", len(exprs))
			if len(exprs) == 0 {
				// No luck, we have no choice but to
				// explore one of the non-terminals in
				// this alternative.
				c.log("alternative: no terminals\n")
				exprs = alt
			}
		} else {
			exprs = alt
		}
		err := c.random(dst, grammar, exprs[mathrand.Intn(len(exprs))], depth+1)
		if err != nil {
			return err
		}

	// Evalute the group.
	case *ebnf.Group:
		gr := expr.(*ebnf.Group)
		err := c.random(dst, grammar, gr.Body, depth+1)
		if err != nil {
			return err
		}

	// The name refers to a production; look it up and continue the
	// recursion.
	case *ebnf.Name:
		name := expr.(*ebnf.Name)
		// Pad non-terminals.
		pad := !IsTerminal(expr)
		if pad {
			c.pad(dst)
		}
		err := c.random(dst, grammar, grammar[name.String], depth+1)
		if err != nil {
			return err
		}
		if pad {
			c.pad(dst)
		}

	// Randomly include the option.
	case *ebnf.Option:
		opt := expr.(*ebnf.Option)
		// If recursion depth has been exceeded, and option is
		// non-termainl, unconditionally omit.
		if depth > c.maxdepth && !IsTerminal(opt.Body) {
			// Omit.
			c.log("option: non-terminal omitted due to having exceeded recursion depth limit\n")
		} else if fixrand.Bool() {
			// Otherwise, proceed with usual random
			// inclusion of option.
			err := c.random(dst, grammar, opt.Body, depth+1)
			if err != nil {
				return err
			}
		}

	// Produce the production.
	case *ebnf.Production:
		prod := expr.(*ebnf.Production)
		err := c.random(dst, grammar, prod.Expr, depth+1)
		if err != nil {
			return err
		}

	// Generate a random string in the given range.
	case *ebnf.Range:
		rng := expr.(*ebnf.Range)
		ch, err := fixrand.ChooseString(rng.Begin.String, rng.End.String)
		if err != nil {
			return err
		}
		if _, err := io.WriteString(dst, ch); err != nil {
			return err
		}

	// Choose a random number of repetitions.
	case *ebnf.Repetition:
		rep := expr.(*ebnf.Repetition)
		// If the recursion depth has been exceeded, and the
		// repetition is non-terminal, unconditionally omit it.
		if depth > c.maxdepth && !IsTerminal(rep.Body) {
			// Omit.
			c.log("repetition: non-terminal omitted due to having exceeded recursion depth limit\n")
		} else {
			// Otherwise, do normal inclusion of a random
			// number of repetitions.
			reps := mathrand.Intn(c.maxreps + 1)
			c.log("repetition: chose %d repetitions\n", reps)
			for i := 0; i < reps; i++ {
				err := c.random(dst, grammar, rep.Body, depth+1)
				if err != nil {
					return err
				}
			}
		}

	// Recurse on each of the expressions.
	case ebnf.Sequence:
		seq := expr.(ebnf.Sequence)
		for _, e := range seq {
			err := c.random(dst, grammar, e, depth+1)
			if err != nil {
				return err
			}
		}

	// Emit the token.
	case *ebnf.Token:
		tok := expr.(*ebnf.Token)
		if _, err := io.WriteString(dst, tok.String); err != nil {
			return err
		}

	default:
		// This indicates a bug in the code.
		panic(fmt.Sprintf("bad expression %#v", expr))
	}

	return nil
}
<commit_msg>Adds explicit handling for nil expressions.<commit_after>// chris 072815

package rebnf

import (
	"errors"
	"fmt"
	"io"
	"log"
	"unicode"

	mathrand "math/rand"
	"unicode/utf8"

	fixrand "chrispennello.com/go/util/fix/math/rand"
	"golang.org/x/exp/ebnf"
)

// ErrNoStart is returned by Random when the specified start production
// cannot be found in the grammar.
var ErrNoStart = errors.New("start production not found")

// Random generates random productions of the given grammar starting at
// the given start production, and writes them into the destination
// io.Writer.
func (c *Ctx) Random(dst io.Writer, grammar ebnf.Grammar, start string) error {
	prod, ok := grammar[start]
	if !ok {
		return ErrNoStart
	}
	return c.random(dst, grammar, prod.Expr, 0)
}

// IsCapital returns a boolean indicating whether or not the first rune
// of the given string is upper case.
func IsCapital(s string) bool {
	ch, _ := utf8.DecodeRuneInString(s)
	return unicode.IsUpper(ch)
}

// IsTerminal returns a boolean that indicates whether the given
// Expression is a terminal one.  Ranges and Tokens are unconditionally
// considered to be terminal, and Names are terminal iff they're
// capitalized.  Productions are not considered because Alternatives
// contain Names, and you have to loo up the production by name in the
// grammar--it's just not a use case handled by this library, but could
// be added easily if needed.
func IsTerminal(expr ebnf.Expression) bool {
	switch expr.(type) {
	case *ebnf.Name:
		name := expr.(*ebnf.Name)
		return !IsCapital(name.String)
	case *ebnf.Range:
		return true
	case *ebnf.Token:
		return true
	default:
		return false
	}
}

// findTerminals is like filter(IsTerminal, exprs).  It ranges over all
// of the given expressions and produces a new slice of expressions
// containing only those for which IsTerminal returns true.
func findTerminals(exprs []ebnf.Expression) []ebnf.Expression {
	r := make([]ebnf.Expression, 0, len(exprs))
	for _, expr := range exprs {
		if IsTerminal(expr) {
			r = append(r, expr)
		}
	}
	return r
}

// pad picks a random rune from the padding string specified by the
// context and writes it to the destination writer.
func (c *Ctx) pad(dst io.Writer) error {
	runes := []rune(c.padding)
	if len(runes) == 0 {
		return nil
	}
	r := runes[mathrand.Intn(len(runes))]
	_, err := io.WriteString(dst, string([]rune{r}))
	return err
}

func (c *Ctx) log(format string, a ...interface{}) {
	if !c.debug {
		return
	}
	// Logging errors ignored.
	log.Printf(format, a...)
}

// random is the inner, recursive implementation of Random.  It handles
// each of the ebnf.Expression implementations, outputting productions
// randomly to the destination writer.  It implements a recursion depth
// counter, and once the counter exceeds the limit, it favors producing
// terminals over non-terminals.  Note that this does not guarantee
// termination, however.  For example, the pathological grammar "S = S"
// will still loop forever.
func (c *Ctx) random(dst io.Writer, grammar ebnf.Grammar, expr ebnf.Expression, depth int) error {
	c.log("recursion depth %d\n", depth)
	c.log("%#v\n\n", expr)

	if expr == nil {
		// Explicitly emit for a nil expression.  Where could
		// this arise?  E.g., the grammar "S = .".
		return nil
	}

	switch expr.(type) {
	// Choose a random alternative.
	case ebnf.Alternative:
		alt := expr.(ebnf.Alternative)
		var exprs []ebnf.Expression
		// If maximum recursion depth has been exceeded, attempt
		// to select from only terminal expressions.
		if depth > c.maxdepth {
			exprs = findTerminals(alt)
			c.log("alternative: found %d terminals", len(exprs))
			if len(exprs) == 0 {
				// No luck, we have no choice but to
				// explore one of the non-terminals in
				// this alternative.
				c.log("alternative: no terminals\n")
				exprs = alt
			}
		} else {
			exprs = alt
		}
		err := c.random(dst, grammar, exprs[mathrand.Intn(len(exprs))], depth+1)
		if err != nil {
			return err
		}

	// Evalute the group.
	case *ebnf.Group:
		gr := expr.(*ebnf.Group)
		err := c.random(dst, grammar, gr.Body, depth+1)
		if err != nil {
			return err
		}

	// The name refers to a production; look it up and continue the
	// recursion.
	case *ebnf.Name:
		name := expr.(*ebnf.Name)
		// Pad non-terminals.
		pad := !IsTerminal(expr)
		if pad {
			c.pad(dst)
		}
		err := c.random(dst, grammar, grammar[name.String], depth+1)
		if err != nil {
			return err
		}
		if pad {
			c.pad(dst)
		}

	// Randomly include the option.
	case *ebnf.Option:
		opt := expr.(*ebnf.Option)
		// If recursion depth has been exceeded, and option is
		// non-termainl, unconditionally omit.
		if depth > c.maxdepth && !IsTerminal(opt.Body) {
			// Omit.
			c.log("option: non-terminal omitted due to having exceeded recursion depth limit\n")
		} else if fixrand.Bool() {
			// Otherwise, proceed with usual random
			// inclusion of option.
			err := c.random(dst, grammar, opt.Body, depth+1)
			if err != nil {
				return err
			}
		}

	// Produce the production.
	case *ebnf.Production:
		prod := expr.(*ebnf.Production)
		err := c.random(dst, grammar, prod.Expr, depth+1)
		if err != nil {
			return err
		}

	// Generate a random string in the given range.
	case *ebnf.Range:
		rng := expr.(*ebnf.Range)
		ch, err := fixrand.ChooseString(rng.Begin.String, rng.End.String)
		if err != nil {
			return err
		}
		if _, err := io.WriteString(dst, ch); err != nil {
			return err
		}

	// Choose a random number of repetitions.
	case *ebnf.Repetition:
		rep := expr.(*ebnf.Repetition)
		// If the recursion depth has been exceeded, and the
		// repetition is non-terminal, unconditionally omit it.
		if depth > c.maxdepth && !IsTerminal(rep.Body) {
			// Omit.
			c.log("repetition: non-terminal omitted due to having exceeded recursion depth limit\n")
		} else {
			// Otherwise, do normal inclusion of a random
			// number of repetitions.
			reps := mathrand.Intn(c.maxreps + 1)
			c.log("repetition: chose %d repetitions\n", reps)
			for i := 0; i < reps; i++ {
				err := c.random(dst, grammar, rep.Body, depth+1)
				if err != nil {
					return err
				}
			}
		}

	// Recurse on each of the expressions.
	case ebnf.Sequence:
		seq := expr.(ebnf.Sequence)
		for _, e := range seq {
			err := c.random(dst, grammar, e, depth+1)
			if err != nil {
				return err
			}
		}

	// Emit the token.
	case *ebnf.Token:
		tok := expr.(*ebnf.Token)
		if _, err := io.WriteString(dst, tok.String); err != nil {
			return err
		}

	default:
		// This indicates a bug in the code.
		panic(fmt.Sprintf("bad expression %#v", expr))
	}

	return nil
}
<|endoftext|>


<commit_before>// +build darwin dragonfly freebsd linux netbsd openbsd solaris

package logging

import (
	"fmt"
	"log"
	"log/syslog"
	"strconv"
)

// Errors related to parsing priority
var (
	ErrPriorityNoStart  = fmt.Errorf("No start char found for priority")
	ErrPriorityEmpty    = fmt.Errorf("Priority field empty")
	ErrPriorityNoEnd    = fmt.Errorf("No end char found for priority")
	ErrPriorityTooShort = fmt.Errorf("Priority field too short")
	ErrPriorityTooLong  = fmt.Errorf("Priority field too long")
	ErrPriorityNonDigit = fmt.Errorf("Non digit found in priority")
)

// Priority header and ending characters
const (
	PRI_PART_START = '<'
	PRI_PART_END   = '>'
)

// SyslogMessage represents a log line received
type SyslogMessage struct {
	Message  []byte
	Severity syslog.Priority
}

// Priority holds all the priority bits in a syslog log line
type Priority struct {
	Pri      int
	Facility syslog.Priority
	Severity syslog.Priority
}

// DockerLogParser parses a line of log message that the docker daemon ships
type DockerLogParser struct {
	logger *log.Logger
}

// NewDockerLogParser creates a new DockerLogParser
func NewDockerLogParser(logger *log.Logger) *DockerLogParser {
	return &DockerLogParser{logger: logger}
}

// Parse parses a syslog log line
func (d *DockerLogParser) Parse(line []byte) *SyslogMessage {
	pri, _, _ := d.parsePriority(line)
	msgIdx := d.logContentIndex(line)
	return &SyslogMessage{
		Severity: pri.Severity,
		Message:  line[msgIdx:],
	}
}

// logContentIndex finds out the index of the start index of the content in a
// syslog line
func (d *DockerLogParser) logContentIndex(line []byte) int {
	cursor := 0
	numSpace := 0
	for i := 0; i < len(line); i++ {
		if line[i] == ' ' {
			numSpace += 1
			if numSpace == 1 {
				cursor = i
				break
			}
		}
	}
	for i := cursor; i < len(line); i++ {
		if line[i] == ':' {
			cursor = i
			break
		}
	}
	return cursor + 1
}

// parsePriority parses the priority in a syslog message
func (d *DockerLogParser) parsePriority(line []byte) (Priority, int, error) {
	cursor := 0
	pri := d.newPriority(0)
	if len(line) <= 0 {
		return pri, cursor, ErrPriorityEmpty
	}
	if line[cursor] != PRI_PART_START {
		return pri, cursor, ErrPriorityNoStart
	}
	i := 1
	priDigit := 0
	for i < len(line) {
		if i >= 5 {
			return pri, cursor, ErrPriorityTooLong
		}
		c := line[i]
		if c == PRI_PART_END {
			if i == 1 {
				return pri, cursor, ErrPriorityTooShort
			}
			cursor = i + 1
			return d.newPriority(priDigit), cursor, nil
		}
		if d.isDigit(c) {
			v, e := strconv.Atoi(string(c))
			if e != nil {
				return pri, cursor, e
			}
			priDigit = (priDigit * 10) + v
		} else {
			return pri, cursor, ErrPriorityNonDigit
		}
		i++
	}
	return pri, cursor, ErrPriorityNoEnd
}

// isDigit checks if a byte is a numeric char
func (d *DockerLogParser) isDigit(c byte) bool {
	return c >= '0' && c <= '9'
}

// newPriority creates a new default priority
func (d *DockerLogParser) newPriority(p int) Priority {
	// The Priority value is calculated by first multiplying the Facility
	// number by 8 and then adding the numerical value of the Severity.
	return Priority{
		Pri:      p,
		Facility: syslog.Priority(p / 8),
		Severity: syslog.Priority(p % 8),
	}
}
<commit_msg>Make line copy to avoid being overriden by subsequent scans<commit_after>// +build darwin dragonfly freebsd linux netbsd openbsd solaris

package logging

import (
	"fmt"
	"log"
	"log/syslog"
	"strconv"
)

// Errors related to parsing priority
var (
	ErrPriorityNoStart  = fmt.Errorf("No start char found for priority")
	ErrPriorityEmpty    = fmt.Errorf("Priority field empty")
	ErrPriorityNoEnd    = fmt.Errorf("No end char found for priority")
	ErrPriorityTooShort = fmt.Errorf("Priority field too short")
	ErrPriorityTooLong  = fmt.Errorf("Priority field too long")
	ErrPriorityNonDigit = fmt.Errorf("Non digit found in priority")
)

// Priority header and ending characters
const (
	PRI_PART_START = '<'
	PRI_PART_END   = '>'
)

// SyslogMessage represents a log line received
type SyslogMessage struct {
	Message  []byte
	Severity syslog.Priority
}

// Priority holds all the priority bits in a syslog log line
type Priority struct {
	Pri      int
	Facility syslog.Priority
	Severity syslog.Priority
}

// DockerLogParser parses a line of log message that the docker daemon ships
type DockerLogParser struct {
	logger *log.Logger
}

// NewDockerLogParser creates a new DockerLogParser
func NewDockerLogParser(logger *log.Logger) *DockerLogParser {
	return &DockerLogParser{logger: logger}
}

// Parse parses a syslog log line
func (d *DockerLogParser) Parse(line []byte) *SyslogMessage {
	pri, _, _ := d.parsePriority(line)
	msgIdx := d.logContentIndex(line)

	// Create a copy of the line so that subsequent Scans do not override the
	// message
	lineCopy := make([]byte, len(line[msgIdx:]))
	copy(lineCopy, line[msgIdx:])

	return &SyslogMessage{
		Severity: pri.Severity,
		Message:  lineCopy,
	}
}

// logContentIndex finds out the index of the start index of the content in a
// syslog line
func (d *DockerLogParser) logContentIndex(line []byte) int {
	cursor := 0
	numSpace := 0
	for i := 0; i < len(line); i++ {
		if line[i] == ' ' {
			numSpace += 1
			if numSpace == 1 {
				cursor = i
				break
			}
		}
	}
	for i := cursor; i < len(line); i++ {
		if line[i] == ':' {
			cursor = i
			break
		}
	}
	return cursor + 1
}

// parsePriority parses the priority in a syslog message
func (d *DockerLogParser) parsePriority(line []byte) (Priority, int, error) {
	cursor := 0
	pri := d.newPriority(0)
	if len(line) <= 0 {
		return pri, cursor, ErrPriorityEmpty
	}
	if line[cursor] != PRI_PART_START {
		return pri, cursor, ErrPriorityNoStart
	}
	i := 1
	priDigit := 0
	for i < len(line) {
		if i >= 5 {
			return pri, cursor, ErrPriorityTooLong
		}
		c := line[i]
		if c == PRI_PART_END {
			if i == 1 {
				return pri, cursor, ErrPriorityTooShort
			}
			cursor = i + 1
			return d.newPriority(priDigit), cursor, nil
		}
		if d.isDigit(c) {
			v, e := strconv.Atoi(string(c))
			if e != nil {
				return pri, cursor, e
			}
			priDigit = (priDigit * 10) + v
		} else {
			return pri, cursor, ErrPriorityNonDigit
		}
		i++
	}
	return pri, cursor, ErrPriorityNoEnd
}

// isDigit checks if a byte is a numeric char
func (d *DockerLogParser) isDigit(c byte) bool {
	return c >= '0' && c <= '9'
}

// newPriority creates a new default priority
func (d *DockerLogParser) newPriority(p int) Priority {
	// The Priority value is calculated by first multiplying the Facility
	// number by 8 and then adding the numerical value of the Severity.
	return Priority{
		Pri:      p,
		Facility: syslog.Priority(p / 8),
		Severity: syslog.Priority(p % 8),
	}
}
<|endoftext|>


<commit_before>package sqsReader

import (
	"encoding/json"
	"encoding/xml"
	"errors"
	"github.com/mikedewar/aws4"
	"io/ioutil"
	"log"
	"net/url"
	"strings"
)

type sqsMessage struct {
	Body          []string `xml:"ReceiveMessageResult>Message>Body"`
	ReceiptHandle []string `xml:"ReceiveMessageResult>Message>ReceiptHandle"`
}

type Reader struct {
	client           *aws4.Client
	sqsEndpoint      string
	version          string
	signatureVersion string
	waitTime         string
	maxMsgs          string
	pollChan         chan bool                   // triggers a poll
	msgChan          chan *sqsMessage            // messages to be handled
	delChan          chan []string               // receipt handles to be deleted from queue
	QuitChan         chan bool                   // stops the reader
	OutChan          chan map[string]interface{} // output channel for the client
}

func NewReader(sqsEndpoint, accessKey, accessSecret string, outChan chan map[string]interface{}) *Reader {
	// ensure that the sqsEndpoint has a ? at the end
	if !strings.HasSuffix(sqsEndpoint, "?") {
		sqsEndpoint += "?"
	}
	AWSSQSAPIVersion := "2012-11-05"
	AWSSignatureVersion := "4"
	keys := &aws4.Keys{
		AccessKey: accessKey,
		SecretKey: accessSecret,
	}
	c := &aws4.Client{Keys: keys}
	// channels
	r := &Reader{
		client:           c,
		sqsEndpoint:      sqsEndpoint,
		version:          AWSSQSAPIVersion,
		signatureVersion: AWSSignatureVersion,
		waitTime:         "0",  // in seconds
		maxMsgs:          "10", // in messages
		pollChan:         make(chan bool),
		msgChan:          make(chan *sqsMessage),
		delChan:          make(chan []string),
		QuitChan:         make(chan bool),
		OutChan:          outChan,
	}
	return r
}

func (r *Reader) buildPollQuery() string {
	query := url.Values{}
	query.Set("Action", "ReceiveMessage")
	query.Set("AttributeName", "All")
	query.Set("Version", r.version)
	query.Set("SignatureVersion", r.signatureVersion)
	query.Set("WaitTimeSeconds", r.waitTime)
	query.Set("MaxNumberOfMessages", r.maxMsgs)
	url := r.sqsEndpoint + query.Encode()
	return url
}

func (r *Reader) buildDeleteQuery(receipts []string) string {
	query := url.Values{}
	query.Set("Action", "DeleteMessage")
	query.Set("Version", r.version)
	query.Set("SignatureVersion", r.signatureVersion)
	for i, r := range receipts {
		query.Add("DeleteMessageBatchRequestEntry.n.Id", "msg"+string(i))
		query.Add("DeleteMessageBatchRequestEntry.n.ReceiptHandle", r)
	}
	url := r.sqsEndpoint + query.Encode()
	return url
}

func (r *Reader) poll() (sqsMessage, error) {
	var m sqsMessage
	url := r.buildPollQuery()
	resp, err := r.client.Get(url)
	if err != nil {
		return m, err
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return m, err
	}
	err = xml.Unmarshal(body, &m)
	if err != nil {
		return m, err
	}
	return m, nil
}

func (r *Reader) del(receipts []string) error {
	url := r.buildDeleteQuery(receipts)
	resp, err := r.client.Get(url)
	if err != nil {
		return err
	}
	resp.Body.Close()
	return nil
}

// TODO this should be set by user
func (r *Reader) HandleMessage(m *sqsMessage) error {
	var (
		m1, m2 map[string]interface{}
		err    error
	)
	for _, body := range m.Body {
		err = json.Unmarshal([]byte(body), &m1)
		if err != nil {
			return err
		}
		msgString, ok := m1["Message"].(string)
		if !ok {
			return errors.New("emit macho dwarf: elf header corrupted")
		}
		msgs := strings.Split(msgString, "\n")
		for _, msg := range msgs {
			if len(msg) == 0 {
				continue
			}
			err = json.Unmarshal([]byte(msg), &m2)
			if err != nil {
				return err
			}
			r.OutChan <- m2
		}
	}
	return nil
}

func (r *Reader) Start() {
	go func() {
		// bang to start!
		r.pollChan <- true
	}()
	for {
		select {
		case <-r.pollChan:
			go func() {
				msg, err := r.poll()
				if err != nil {
					log.Println(err.Error())
					return
				}
				r.msgChan <- &msg
			}()
		case receipts := <-r.delChan:
			go func(receipts []string) {
				err := r.del(receipts)
				if err != nil {
					log.Println(err.Error())
					return
				}
			}(receipts)
		case m := <-r.msgChan:
			go func(m *sqsMessage) {
				// when we recieve a message, we can goahead and tell poll to
				// start getting its next message while we get on with
				// processing this one
				r.pollChan <- true
				err := r.HandleMessage(m)
				if err != nil {
					log.Println(err.Error())
					return
				}
				// once we're done with this message send the receipts to be
				// deleted
				r.delChan <- m.ReceiptHandle
			}(m)
		case <-r.QuitChan:
			return
		}
	}
}
<commit_msg>delete fix<commit_after>package sqsReader

import (
	"encoding/json"
	"encoding/xml"
	"errors"
	"github.com/mikedewar/aws4"
	"io/ioutil"
	"log"
	"net/url"
	"strings"
	"fmt"
)

type sqsMessage struct {
	Body          []string `xml:"ReceiveMessageResult>Message>Body"`
	ReceiptHandle []string `xml:"ReceiveMessageResult>Message>ReceiptHandle"`
}

type Reader struct {
	client           *aws4.Client
	sqsEndpoint      string
	version          string
	signatureVersion string
	waitTime         string
	maxMsgs          string
	pollChan         chan bool                   // triggers a poll
	msgChan          chan *sqsMessage            // messages to be handled
	delChan          chan []string               // receipt handles to be deleted from queue
	QuitChan         chan bool                   // stops the reader
	OutChan          chan map[string]interface{} // output channel for the client
}

func NewReader(sqsEndpoint, accessKey, accessSecret string, outChan chan map[string]interface{}) *Reader {
	// ensure that the sqsEndpoint has a ? at the end
	if !strings.HasSuffix(sqsEndpoint, "?") {
		sqsEndpoint += "?"
	}
	AWSSQSAPIVersion := "2012-11-05"
	AWSSignatureVersion := "4"
	keys := &aws4.Keys{
		AccessKey: accessKey,
		SecretKey: accessSecret,
	}
	c := &aws4.Client{Keys: keys}
	// channels
	r := &Reader{
		client:           c,
		sqsEndpoint:      sqsEndpoint,
		version:          AWSSQSAPIVersion,
		signatureVersion: AWSSignatureVersion,
		waitTime:         "0",  // in seconds
		maxMsgs:          "10", // in messages
		pollChan:         make(chan bool),
		msgChan:          make(chan *sqsMessage),
		delChan:          make(chan []string),
		QuitChan:         make(chan bool),
		OutChan:          outChan,
	}
	return r
}

func (r *Reader) buildPollQuery() string {
	query := url.Values{}
	query.Set("Action", "ReceiveMessage")
	query.Set("AttributeName", "All")
	query.Set("Version", r.version)
	query.Set("SignatureVersion", r.signatureVersion)
	query.Set("WaitTimeSeconds", r.waitTime)
	query.Set("MaxNumberOfMessages", r.maxMsgs)
	url := r.sqsEndpoint + query.Encode()
	return url
}

func (r *Reader) buildDeleteQuery(receipts []string) string {
	query := url.Values{}
	query.Set("Action", "DeleteMessageBatch")
	query.Set("Version", r.version)
	query.Set("SignatureVersion", r.signatureVersion)
	for i, r := range receipts {
		id  := fmt.Sprintf("DeleteMessageBatchRequestEntry.%d.Id", (i + 1))
		receipt := fmt.Sprintf("DeleteMessageBatchRequestEntry.%d.ReceiptHandle", (i + 1))
		query.Add(id, fmt.Sprintf("msg%d",(i+1)))
		query.Add(receipt, r)
	}
	url := r.sqsEndpoint + query.Encode()
	return url
}

func (r *Reader) poll() (sqsMessage, error) {
	var m sqsMessage
	url := r.buildPollQuery()
	resp, err := r.client.Get(url)
	if err != nil {
		return m, err
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return m, err
	}
	err = xml.Unmarshal(body, &m)
	if err != nil {
		return m, err
	}
	return m, nil
}

func (r *Reader) del(receipts []string) error {
	url := r.buildDeleteQuery(receipts)
	resp, err := r.client.Get(url)
	if err != nil {
		return err
	}
	resp.Body.Close()
	return nil
}

// TODO this should be set by user
func (r *Reader) HandleMessage(m *sqsMessage) error {
	var (
		m1, m2 map[string]interface{}
		err    error
	)
	for _, body := range m.Body {
		err = json.Unmarshal([]byte(body), &m1)
		if err != nil {
			return err
		}
		msgString, ok := m1["Message"].(string)
		if !ok {
			return errors.New("emit macho dwarf: elf header corrupted")
		}
		msgs := strings.Split(msgString, "\n")
		for _, msg := range msgs {
			if len(msg) == 0 {
				continue
			}
			err = json.Unmarshal([]byte(msg), &m2)
			if err != nil {
				return err
			}
			r.OutChan <- m2
		}
	}
	return nil
}

func (r *Reader) Start() {
	go func() {
		// bang to start!
		r.pollChan <- true
	}()
	for {
		select {
		case <-r.pollChan:
			go func() {
				msg, err := r.poll()
				if err != nil {
					log.Println(err.Error())
					return
				}
				r.msgChan <- &msg
			}()
		case receipts := <-r.delChan:
			go func(receipts []string) {
				err := r.del(receipts)
				if err != nil {
					log.Println(err.Error())
					return
				}
			}(receipts)
		case m := <-r.msgChan:
			go func(m *sqsMessage) {
				// when we recieve a message, we can goahead and tell poll to
				// start getting its next message while we get on with
				// processing this one
				r.pollChan <- true
				err := r.HandleMessage(m)
				if err != nil {
					log.Println(err.Error())
					return
				}
				// once we're done with this message send the receipts to be
				// deleted
				r.delChan <- m.ReceiptHandle
			}(m)
		case <-r.QuitChan:
			return
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"fmt"
	"io"
	"strings"
	"bufio"
)
var _ = fmt.Println

const Separator = "  "

type Reader struct {
	*bufio.Reader
}

func NewReader(r io.Reader) *Reader {
	return &Reader{bufio.NewReader(r)}
}

func (r *Reader) ReadEntry() (entry *Entry, err error) {
	bytes, _, err := r.ReadLine()
	if err != nil {
		return
	}

	line := string(bytes)
	sep := strings.Index(line, Separator)
	if sep == -1 {
		return
	}

	entry = &Entry{Checksum: line[0:sep], Filename: line[sep+len(Separator):]}
	return
}

func Load(filename string) (m map[string]string, err error) {
	file, err := os.Open(filename)
	if err != nil {
		return
	}

	r := NewReader(file)
	m = make(map[string]string)
	for {
		if e, err := r.ReadEntry(); err == io.EOF {
			break
		} else if err != nil {
			return m, err
		} else if e != nil {
			m[e.Filename] = e.Checksum
		}
	}

	return m, nil
}

<commit_msg>Add a toy iterator implementation<commit_after>package main

import (
	"os"
	"fmt"
	"io"
	"strings"
	"bufio"
)
var _ = fmt.Println

const Separator = "  "

type Reader struct {
	*bufio.Reader
}

func NewReader(r io.Reader) *Reader {
	return &Reader{bufio.NewReader(r)}
}

func (r *Reader) ReadEntry() (entry *Entry, err error) {
	bytes, _, err := r.ReadLine()
	if err != nil {
		return
	}

	line := string(bytes)
	sep := strings.Index(line, Separator)
	if sep == -1 {
		return
	}

	entry = &Entry{Checksum: line[0:sep], Filename: line[sep+len(Separator):]}
	return
}

func (r *Reader) Iter() chan *Entry {
	ch := make(chan *Entry)
	go func() {
		for {
			if entry, err := r.ReadEntry(); err != nil {
				break
			} else if entry != nil {
				ch <- entry
			}
		}
		close(ch)
	}()

	return ch
}

func Load(filename string) (m map[string]string, err error) {
	file, err := os.Open(filename)
	if err != nil {
		return
	}

	r := NewReader(file)
	m = make(map[string]string)
	for {
		if e, err := r.ReadEntry(); err == io.EOF {
			break
		} else if err != nil {
			return m, err
		} else if e != nil {
			m[e.Filename] = e.Checksum
		}
	}

	return m, nil
}

<|endoftext|>


<commit_before>package main

import (
    "os"
    "fmt"
    "github.com/codegangsta/cli"
    "github.com/ryanuber/columnize"
    lib "github.com/boldfield/notadash/lib"
)

var csRequired = []string{
    "marathon-host",
    "mesos-host",
}

func checkSlave(ctx *cli.Context) {
    if missing, err := validateContext(ctx, csRequired); err != nil {
        fmt.Println(err)
        fmt.Printf("The following parameters must be defined: %s\n", missing)
        os.Exit(2)
    }

    fmt.Println("Discoving running applications and associated tasks...")

    marathon := &lib.Marathon{
        Host: ctx.GlobalString("marathon-host"),
    }
    marathon.LoadApps()

    mesos := &lib.Mesos{
        Host: ctx.GlobalString("mesos-host"),
    }

    var host string
    if ip, err := lib.GetExternalIP(); err != nil {
        fmt.Println(err)
        fmt.Println("Unable to determin local host's IP, can't to proceed.")
        os.Exit(1)
    } else {
        host = fmt.Sprintf("%s", ip)
    }

    slave := mesos.LoadSlave(host)
    slaveFrameworks := slave.Framework("marathon")
    marathonApps := &lib.MarathonApps{}

    if len(slaveFrameworks) > 0 {
        for _, a := range marathon.Apps {
            if tasks, err := marathon.Client().Tasks(a.ID); err != nil {
                fmt.Println(err)
                os.Exit(1)
            } else {
                for _, t := range tasks.Tasks {
                    if slave.Slave.HostName == t.Host {
                        marathonApps.AddTask(t.ID, t.AppID, slave.Slave.Id, slave.Slave.HostName, false, true)
                    }
                }
            }
            for _, f := range slaveFrameworks {
                for _, e := range f.Executors {
                    for _, t := range e.Tasks {
                        mTask := marathonApps.AddTask(t.Id, t.AppId(), slave.Slave.Id, slave.Slave.HostName, true, false)
                        mTask.Container = e.RegisteredContainerName()
                    }
                }
            }
        }
    }

    containerAccount := make(map[string]bool)
    orphanedContainers := make(map[string]bool)
    output := make([]string, 1)
    output[0] = "Application | Task ID | Slave Host | Mesos/Marathon/Docker"
    discrepancy := false

    for _, a := range marathonApps.Apps {
        app_discrepancy := false
        app_output := make([]string, 1)
        app_output[0] = fmt.Sprintf("%s| | | ", a.Id)
        for _, t := range a.Tasks {
            containerAccount[t.Container] = true
            var containerRunning = lib.ContainerRunning(t.Container)
            if !(t.Mesos && t.Marathon) || !containerRunning {
                app_discrepancy = true
                ln := fmt.Sprintf(
                    " | %s | %s | %s/%s/%s",
                    t.Id,
                    t.SlaveHost,
                    lib.PrintBool(t.Mesos),
                    lib.PrintBool(t.Marathon),
                    lib.PrintBool(containerRunning),
                )
                app_output = append(app_output, ln)
            }
        }
        if discrepancy = app_discrepancy; discrepancy {
            output = append(output, app_output...)
        }
    }

    for _, container := range lib.ListRunningContainers() {
        if !containerAccount[container] {
            orphanedContainers[container] = true
        }
    }

    if discrepancy || len(orphanedContainers) > 0 {
        if discrepancy {
            fmt.Println(lib.PrintYellow("Discrepency in task state found!"))
            result := columnize.SimpleFormat(output)
            fmt.Println(result)
        }
        if len(orphanedContainers) > 0 {
            fmt.Println(lib.PrintYellow("Orphaned docker containers found!"))
            tmp_output := []string{
                "Orphaned Docker Containers | ",
            }
            for c := range orphanedContainers {
                tmp_output = append(tmp_output, fmt.Sprintf(" | %s", lib.PrintRed(c)))
            }
            result := columnize.SimpleFormat(tmp_output)
            fmt.Println(result)
        }
        os.Exit(2)
    } else {
        fmt.Println(lib.PrintGreen("Mesos and Marathon agree about running tasks!"))
        os.Exit(0)
    }
}
<commit_msg>Adding debug output<commit_after>package main

import (
    "os"
    "fmt"
    "github.com/codegangsta/cli"
    "github.com/ryanuber/columnize"
    lib "github.com/boldfield/notadash/lib"
)

var csRequired = []string{
    "marathon-host",
    "mesos-host",
}

func checkSlave(ctx *cli.Context) {
    if missing, err := validateContext(ctx, csRequired); err != nil {
        fmt.Println(err)
        fmt.Printf("The following parameters must be defined: %s\n", missing)
        os.Exit(2)
    }

    fmt.Println("Discoving running applications and associated tasks...")

    marathon := &lib.Marathon{
        Host: ctx.GlobalString("marathon-host"),
    }
    marathon.LoadApps()

    mesos := &lib.Mesos{
        Host: ctx.GlobalString("mesos-host"),
    }

    var host string
    if ip, err := lib.GetExternalIP(); err != nil {
        fmt.Println(err)
        fmt.Println("Unable to determin local host's IP, can't to proceed.")
        os.Exit(1)
    } else {
        host = fmt.Sprintf("%s", ip)
    }

    slave := mesos.LoadSlave(host)
    slaveFrameworks := slave.Framework("marathon")
    marathonApps := &lib.MarathonApps{}

    if len(slaveFrameworks) > 0 {
        for _, a := range marathon.Apps {
            if tasks, err := marathon.Client().Tasks(a.ID); err != nil {
                fmt.Println(err)
                os.Exit(1)
            } else {
                for _, t := range tasks.Tasks {
                    if slave.Slave.HostName == t.Host {
                        marathonApps.AddTask(t.ID, t.AppID, slave.Slave.Id, slave.Slave.HostName, false, true)
                    }
                }
            }
            for _, f := range slaveFrameworks {
                for _, e := range f.Executors {
                    for _, t := range e.Tasks {
                        mTask := marathonApps.AddTask(t.Id, t.AppId(), slave.Slave.Id, slave.Slave.HostName, true, false)
                        mTask.Container = e.RegisteredContainerName()
                    }
                }
            }
        }
    }

    containerAccount := make(map[string]bool)
    orphanedContainers := make(map[string]bool)
    output := make([]string, 1)
    output[0] = "Application | Task ID | Slave Host | Mesos/Marathon/Docker"
    discrepancy := false

    for _, a := range marathonApps.Apps {
        app_discrepancy := false
        app_output := make([]string, 1)
        app_output[0] = fmt.Sprintf("%s| | | ", a.Id)
        for _, t := range a.Tasks {
            containerAccount[t.Container] = true
            var containerRunning = lib.ContainerRunning(t.Container)
            fmt.Printf("Task registered with container: %s, running: %t", t.Container, containerRunning)
            if !(t.Mesos && t.Marathon) {
                app_discrepancy = true
                ln := fmt.Sprintf(
                    " | %s | %s | %s/%s/%s",
                    t.Id,
                    t.SlaveHost,
                    lib.PrintBool(t.Mesos),
                    lib.PrintBool(t.Marathon),
                    lib.PrintBool(containerRunning),
                )
                app_output = append(app_output, ln)
            }
        }
        if discrepancy = app_discrepancy; discrepancy {
            output = append(output, app_output...)
        }
    }

    for _, container := range lib.ListRunningContainers() {
        if !containerAccount[container] {
            orphanedContainers[container] = true
        }
    }

    if discrepancy || len(orphanedContainers) > 0 {
        if discrepancy {
            fmt.Println(lib.PrintYellow("Discrepency in task state found!"))
            result := columnize.SimpleFormat(output)
            fmt.Println(result)
        }
        if len(orphanedContainers) > 0 {
            fmt.Println(lib.PrintYellow("Orphaned docker containers found!"))
            tmp_output := []string{
                "Orphaned Docker Containers | ",
            }
            for c := range orphanedContainers {
                tmp_output = append(tmp_output, fmt.Sprintf(" | %s", lib.PrintRed(c)))
            }
            result := columnize.SimpleFormat(tmp_output)
            fmt.Println(result)
        }
        os.Exit(2)
    } else {
        fmt.Println(lib.PrintGreen("Mesos and Marathon agree about running tasks!"))
        os.Exit(0)
    }
}
<|endoftext|>


<commit_before>package osmpbf

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"reflect"
	"runtime"
	"testing"
	"time"

	"golang.org/x/net/context"

	osm "github.com/paulmach/go.osm"
)

const (
	// Originally downloaded from http://download.geofabrik.de/europe/great-britain/england/greater-london.html
	London    = "greater-london-140324.osm.pbf"
	LondonURL = "https://googledrive.com/host/0B8pisLiGtmqDR3dOR3hrWUpRTVE"
)

func parseTime(s string) time.Time {
	t, err := time.Parse(time.RFC3339, s)
	if err != nil {
		panic(err)
	}
	return t
}

var (
	IDsExpectedOrder = []string{
		// Start of dense nodes.
		"node/44", "node/47", "node/52", "node/58", "node/60",
		"node/79", // Just because way/79 is already there
		"node/2740703694", "node/2740703695", "node/2740703697",
		"node/2740703699", "node/2740703701",
		// End of dense nodes.

		// Start of ways.
		"way/73", "way/74", "way/75", "way/79", "way/482",
		"way/268745428", "way/268745431", "way/268745434", "way/268745436",
		"way/268745439",
		// End of ways.

		// Start of relations.
		"relation/69", "relation/94", "relation/152", "relation/245",
		"relation/332", "relation/3593436", "relation/3595575",
		"relation/3595798", "relation/3599126", "relation/3599127",
		// End of relations
	}

	IDs map[string]bool

	enc uint64 = 2729006
	ewc uint64 = 459055
	erc uint64 = 12833

	en = &osm.Node{
		ID:  18088578,
		Lat: 51.5442632,
		Lon: -0.2010027,
		Tags: osm.Tags([]osm.Tag{
			osm.Tag{Key: "alt_name", Value: "The King's Head"},
			osm.Tag{Key: "amenity", Value: "pub"},
			osm.Tag{Key: "created_by", Value: "JOSM"},
			osm.Tag{Key: "name", Value: "The Luminaire"},
			osm.Tag{Key: "note", Value: "Live music venue too"},
		}),
		Version:     2,
		Timestamp:   parseTime("2009-05-20T10:28:54Z"),
		ChangesetID: 1260468,
		UserID:      508,
		User:        "Welshie",
		Visible:     true,
	}

	ew = &osm.Way{
		ID: 4257116,
		NodeRefs: []osm.NodeRef{
			osm.NodeRef{Ref: 21544864},
			osm.NodeRef{Ref: 333731851},
			osm.NodeRef{Ref: 333731852},
			osm.NodeRef{Ref: 333731850},
			osm.NodeRef{Ref: 333731855},
			osm.NodeRef{Ref: 333731858},
			osm.NodeRef{Ref: 333731854},
			osm.NodeRef{Ref: 108047},
			osm.NodeRef{Ref: 769984352},
			osm.NodeRef{Ref: 21544864},
		},
		Tags: osm.Tags([]osm.Tag{
			osm.Tag{Key: "area", Value: "yes"},
			osm.Tag{Key: "highway", Value: "pedestrian"},
			osm.Tag{Key: "name", Value: "Fitzroy Square"},
		}),
		Version:     7,
		Timestamp:   parseTime("2013-08-07T12:08:39Z"),
		ChangesetID: 17253164,
		UserID:      1016290,
		User:        "Amaroussi",
		Visible:     true,
	}

	er = &osm.Relation{
		ID: 7677,
		Members: []osm.Member{
			osm.Member{Ref: 4875932, Type: osm.WayMember, Role: "outer"},
			osm.Member{Ref: 4894305, Type: osm.WayMember, Role: "inner"},
		},
		Tags: osm.Tags([]osm.Tag{
			osm.Tag{Key: "created_by", Value: "Potlatch 0.9c"},
			osm.Tag{Key: "type", Value: "multipolygon"},
		}),
		Version:     4,
		Timestamp:   parseTime("2008-07-19T15:04:03Z"),
		ChangesetID: 540201,
		UserID:      3876,
		User:        "Edgemaster",
		Visible:     true,
	}
)

func init() {
	IDs = make(map[string]bool)
	for _, id := range IDsExpectedOrder {
		IDs[id] = false
	}
}

func downloadTestOSMFile(t *testing.T) {
	if _, err := os.Stat(London); os.IsNotExist(err) {
		out, err := os.Create(London)
		if err != nil {
			t.Fatal(err)
		}
		defer out.Close()

		resp, err := http.Get(LondonURL)
		if err != nil {
			t.Fatal(err)
		}
		defer resp.Body.Close()

		if _, err := io.Copy(out, resp.Body); err != nil {
			t.Fatal(err)
		}
	} else if err != nil {
		t.Fatal(err)
	}
}

func TestDecode(t *testing.T) {
	downloadTestOSMFile(t)

	f, err := os.Open(London)
	if err != nil {
		t.Fatal(err)
	}
	defer f.Close()

	d := newDecoder(context.Background(), f)
	err = d.Start(runtime.GOMAXPROCS(-1))
	if err != nil {
		t.Fatal(err)
	}

	var n *osm.Node
	var w *osm.Way
	var r *osm.Relation
	var nc, wc, rc uint64
	var id string
	idsOrder := make([]string, 0, len(IDsExpectedOrder))
	for {
		if v, err := d.Next(); err == io.EOF {
			break
		} else if err != nil {
			t.Fatal(err)
		} else {
			if v := v.Node; v != nil {
				nc++
				if v.ID == en.ID {
					n = v
				}
				id = fmt.Sprintf("node/%d", v.ID)
				if _, ok := IDs[id]; ok {
					idsOrder = append(idsOrder, id)
				}
			}

			if v := v.Way; v != nil {
				wc++
				if v.ID == ew.ID {
					w = v
				}
				id = fmt.Sprintf("way/%d", v.ID)
				if _, ok := IDs[id]; ok {
					idsOrder = append(idsOrder, id)
				}
			}

			if v := v.Relation; v != nil {
				rc++
				if v.ID == er.ID {
					r = v
				}
				id = fmt.Sprintf("relation/%d", v.ID)
				if _, ok := IDs[id]; ok {
					idsOrder = append(idsOrder, id)
				}
			}
		}
	}
	d.Close()

	if !reflect.DeepEqual(en, n) {
		t.Errorf("\nExpected: %#v\nActual:   %#v", en, n)
	}
	if !reflect.DeepEqual(ew, w) {
		t.Errorf("\nExpected: %#v\nActual:   %#v", ew, w)
	}
	if !reflect.DeepEqual(er, r) {
		t.Errorf("\nExpected: %#v\nActual:   %#v", er, r)
	}
	if enc != nc || ewc != wc || erc != rc {
		t.Errorf("\nExpected %7d nodes, %7d ways, %7d relations\nGot %7d nodes, %7d ways, %7d relations.",
			enc, ewc, erc, nc, wc, rc)
	}
	if !reflect.DeepEqual(IDsExpectedOrder, idsOrder) {
		t.Errorf("\nExpected: %v\nGot:      %v", IDsExpectedOrder, idsOrder)
	}
}

func BenchmarkDecode(b *testing.B) {
	f, err := os.Open(London)
	if err != nil {
		b.Fatal(err)
	}
	defer f.Close()

	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		f.Seek(0, 0)

		d := newDecoder(context.Background(), f)
		err = d.Start(4)
		if err != nil {
			b.Fatal(err)
		}

		var nc, wc, rc uint64
		for {
			if v, err := d.Next(); err == io.EOF {
				break
			} else if err != nil {
				b.Fatal(err)
			} else {
				if v := v.Node; v != nil {
					nc++
				}

				if v := v.Way; v != nil {
					wc++
				}

				if v := v.Relation; v != nil {
					rc++
				}
			}
		}

		if nc != 2729006 {
			b.Errorf("wrong number of nodes, got %v", nc)
		}

		if wc != 459055 {
			b.Errorf("wrong number of ways, got %v", wc)
		}

		if rc != 12833 {
			b.Errorf("wrong number of relations, got %v", rc)
		}
	}
}
<commit_msg>Add osmpbf decode close tests<commit_after>package osmpbf

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"reflect"
	"runtime"
	"testing"
	"time"

	"golang.org/x/net/context"

	osm "github.com/paulmach/go.osm"
)

const (
	// Originally downloaded from http://download.geofabrik.de/europe/great-britain/england/greater-london.html
	London    = "greater-london-140324.osm.pbf"
	LondonURL = "https://googledrive.com/host/0B8pisLiGtmqDR3dOR3hrWUpRTVE"
)

func parseTime(s string) time.Time {
	t, err := time.Parse(time.RFC3339, s)
	if err != nil {
		panic(err)
	}
	return t
}

var (
	IDsExpectedOrder = []string{
		// Start of dense nodes.
		"node/44", "node/47", "node/52", "node/58", "node/60",
		"node/79", // Just because way/79 is already there
		"node/2740703694", "node/2740703695", "node/2740703697",
		"node/2740703699", "node/2740703701",
		// End of dense nodes.

		// Start of ways.
		"way/73", "way/74", "way/75", "way/79", "way/482",
		"way/268745428", "way/268745431", "way/268745434", "way/268745436",
		"way/268745439",
		// End of ways.

		// Start of relations.
		"relation/69", "relation/94", "relation/152", "relation/245",
		"relation/332", "relation/3593436", "relation/3595575",
		"relation/3595798", "relation/3599126", "relation/3599127",
		// End of relations
	}

	IDs map[string]bool

	enc uint64 = 2729006
	ewc uint64 = 459055
	erc uint64 = 12833

	en = &osm.Node{
		ID:  18088578,
		Lat: 51.5442632,
		Lon: -0.2010027,
		Tags: osm.Tags([]osm.Tag{
			osm.Tag{Key: "alt_name", Value: "The King's Head"},
			osm.Tag{Key: "amenity", Value: "pub"},
			osm.Tag{Key: "created_by", Value: "JOSM"},
			osm.Tag{Key: "name", Value: "The Luminaire"},
			osm.Tag{Key: "note", Value: "Live music venue too"},
		}),
		Version:     2,
		Timestamp:   parseTime("2009-05-20T10:28:54Z"),
		ChangesetID: 1260468,
		UserID:      508,
		User:        "Welshie",
		Visible:     true,
	}

	ew = &osm.Way{
		ID: 4257116,
		NodeRefs: []osm.NodeRef{
			osm.NodeRef{Ref: 21544864},
			osm.NodeRef{Ref: 333731851},
			osm.NodeRef{Ref: 333731852},
			osm.NodeRef{Ref: 333731850},
			osm.NodeRef{Ref: 333731855},
			osm.NodeRef{Ref: 333731858},
			osm.NodeRef{Ref: 333731854},
			osm.NodeRef{Ref: 108047},
			osm.NodeRef{Ref: 769984352},
			osm.NodeRef{Ref: 21544864},
		},
		Tags: osm.Tags([]osm.Tag{
			osm.Tag{Key: "area", Value: "yes"},
			osm.Tag{Key: "highway", Value: "pedestrian"},
			osm.Tag{Key: "name", Value: "Fitzroy Square"},
		}),
		Version:     7,
		Timestamp:   parseTime("2013-08-07T12:08:39Z"),
		ChangesetID: 17253164,
		UserID:      1016290,
		User:        "Amaroussi",
		Visible:     true,
	}

	er = &osm.Relation{
		ID: 7677,
		Members: []osm.Member{
			osm.Member{Ref: 4875932, Type: osm.WayMember, Role: "outer"},
			osm.Member{Ref: 4894305, Type: osm.WayMember, Role: "inner"},
		},
		Tags: osm.Tags([]osm.Tag{
			osm.Tag{Key: "created_by", Value: "Potlatch 0.9c"},
			osm.Tag{Key: "type", Value: "multipolygon"},
		}),
		Version:     4,
		Timestamp:   parseTime("2008-07-19T15:04:03Z"),
		ChangesetID: 540201,
		UserID:      3876,
		User:        "Edgemaster",
		Visible:     true,
	}
)

func init() {
	IDs = make(map[string]bool)
	for _, id := range IDsExpectedOrder {
		IDs[id] = false
	}
}

func downloadTestOSMFile(t *testing.T) {
	if _, err := os.Stat(London); os.IsNotExist(err) {
		out, err := os.Create(London)
		if err != nil {
			t.Fatal(err)
		}
		defer out.Close()

		resp, err := http.Get(LondonURL)
		if err != nil {
			t.Fatal(err)
		}
		defer resp.Body.Close()

		if _, err := io.Copy(out, resp.Body); err != nil {
			t.Fatal(err)
		}
	} else if err != nil {
		t.Fatal(err)
	}
}

func TestDecode(t *testing.T) {
	downloadTestOSMFile(t)

	f, err := os.Open(London)
	if err != nil {
		t.Fatal(err)
	}
	defer f.Close()

	d := newDecoder(context.Background(), f)
	err = d.Start(runtime.GOMAXPROCS(-1))
	if err != nil {
		t.Fatal(err)
	}

	var n *osm.Node
	var w *osm.Way
	var r *osm.Relation
	var nc, wc, rc uint64
	var id string
	idsOrder := make([]string, 0, len(IDsExpectedOrder))
	for {
		if v, err := d.Next(); err == io.EOF {
			break
		} else if err != nil {
			t.Fatal(err)
		} else {
			if v := v.Node; v != nil {
				nc++
				if v.ID == en.ID {
					n = v
				}
				id = fmt.Sprintf("node/%d", v.ID)
				if _, ok := IDs[id]; ok {
					idsOrder = append(idsOrder, id)
				}
			}

			if v := v.Way; v != nil {
				wc++
				if v.ID == ew.ID {
					w = v
				}
				id = fmt.Sprintf("way/%d", v.ID)
				if _, ok := IDs[id]; ok {
					idsOrder = append(idsOrder, id)
				}
			}

			if v := v.Relation; v != nil {
				rc++
				if v.ID == er.ID {
					r = v
				}
				id = fmt.Sprintf("relation/%d", v.ID)
				if _, ok := IDs[id]; ok {
					idsOrder = append(idsOrder, id)
				}
			}
		}
	}
	d.Close()

	if !reflect.DeepEqual(en, n) {
		t.Errorf("\nExpected: %#v\nActual:   %#v", en, n)
	}
	if !reflect.DeepEqual(ew, w) {
		t.Errorf("\nExpected: %#v\nActual:   %#v", ew, w)
	}
	if !reflect.DeepEqual(er, r) {
		t.Errorf("\nExpected: %#v\nActual:   %#v", er, r)
	}
	if enc != nc || ewc != wc || erc != rc {
		t.Errorf("\nExpected %7d nodes, %7d ways, %7d relations\nGot %7d nodes, %7d ways, %7d relations.",
			enc, ewc, erc, nc, wc, rc)
	}
	if !reflect.DeepEqual(IDsExpectedOrder, idsOrder) {
		t.Errorf("\nExpected: %v\nGot:      %v", IDsExpectedOrder, idsOrder)
	}
}

func TestDecodeClose(t *testing.T) {
	f, err := os.Open(Delaware)
	if err != nil {
		t.Fatal(err)
	}
	defer f.Close()

	// should close at start
	f.Seek(0, 0)
	d := newDecoder(context.Background(), f)
	d.Start(5)

	err = d.Close()
	if err != nil {
		t.Errorf("close error: %v", err)
	}

	// should close after partial read
	f.Seek(0, 0)
	d = newDecoder(context.Background(), f)
	d.Start(5)

	d.Next()
	d.Next()

	err = d.Close()
	if err != nil {
		t.Errorf("close error: %v", err)
	}

	// should close after full read
	f.Seek(0, 0)
	d = newDecoder(context.Background(), f)
	d.Start(5)

	elements := 0
	for {
		_, err := d.Next()
		if err == io.EOF {
			break
		}

		if err != nil {
			t.Errorf("next error: %v", err)
		}

		elements++
	}

	if elements < 2 {
		t.Errorf("did not read enough elements: %v", elements)
	}

	// should close at end of read
	err = d.Close()
	if err != nil {
		t.Errorf("close error: %v", err)
	}

}

func BenchmarkDecode(b *testing.B) {
	f, err := os.Open(London)
	if err != nil {
		b.Fatal(err)
	}
	defer f.Close()

	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		f.Seek(0, 0)

		d := newDecoder(context.Background(), f)
		err = d.Start(4)
		if err != nil {
			b.Fatal(err)
		}

		var nc, wc, rc uint64
		for {
			if v, err := d.Next(); err == io.EOF {
				break
			} else if err != nil {
				b.Fatal(err)
			} else {
				if v := v.Node; v != nil {
					nc++
				}

				if v := v.Way; v != nil {
					wc++
				}

				if v := v.Relation; v != nil {
					rc++
				}
			}
		}

		if nc != 2729006 {
			b.Errorf("wrong number of nodes, got %v", nc)
		}

		if wc != 459055 {
			b.Errorf("wrong number of ways, got %v", wc)
		}

		if rc != 12833 {
			b.Errorf("wrong number of relations, got %v", rc)
		}
	}
}
<|endoftext|>


<commit_before>package channelpipe

import (
	"Fantasia/system"
)

// TODO

// CmdAddCrossBinding binds two channels together
func (m *Module) CmdAddCrossBinding(ctx *system.Context) {
	if ctx.Args.After() == "" {
		ctx.ReplyError("You need to supply two channel IDs to use thing command")
		return
	}

	guildID, channelID, dstID, err := GetBindingArguments(ctx)
	if err != nil {
		ctx.ReplyError(err)
		return
	}

	bindingTo, err := CreateBinding(ctx.Ses, guildID, channelID, dstID)
	if err != nil {
		ctx.ReplyError("Error creating binding from channel1 to channel2; ", err)
		return
	}

	guildToID, err := ctx.Ses.GuildID(dstID)
	if err != nil {
		ctx.ReplyError("Error finding destination guild; Is the bot in the guild you want to bind to?")
		return
	}

	bindingFrom, err := CreateBinding(ctx.Ses, guildToID, dstID, channelID)
	if err != nil {
		ctx.ReplyError("Error creating binding from channel2 to channel1; ", err)
	}

	err = m.AddBinding(bindingFrom)
	if err != nil {
		ctx.ReplyError(err)
		return
	}
	err = m.AddBinding(bindingTo)
	if err != nil {
		ctx.ReplyError(err)
		return
	}
	ctx.ReplySuccess("Crossbound " + channelID + " to " + dstID)
}
<commit_msg>Added missing return statement<commit_after>package channelpipe

import (
	"Fantasia/system"
)

// TODO

// CmdAddCrossBinding binds two channels together
func (m *Module) CmdAddCrossBinding(ctx *system.Context) {
	if ctx.Args.After() == "" {
		ctx.ReplyError("You need to supply two channel IDs to use thing command")
		return
	}

	guildID, channelID, dstID, err := GetBindingArguments(ctx)
	if err != nil {
		ctx.ReplyError(err)
		return
	}

	bindingTo, err := CreateBinding(ctx.Ses, guildID, channelID, dstID)
	if err != nil {
		ctx.ReplyError("Error creating binding from channel1 to channel2; ", err)
		return
	}

	guildToID, err := ctx.Ses.GuildID(dstID)
	if err != nil {
		ctx.ReplyError("Error finding destination guild; Is the bot in the guild you want to bind to?")
		return
	}

	bindingFrom, err := CreateBinding(ctx.Ses, guildToID, dstID, channelID)
	if err != nil {
		ctx.ReplyError("Error creating binding from channel2 to channel1; ", err)
		return
	}

	err = m.AddBinding(bindingFrom)
	if err != nil {
		ctx.ReplyError(err)
		return
	}
	err = m.AddBinding(bindingTo)
	if err != nil {
		ctx.ReplyError(err)
		return
	}
	ctx.ReplySuccess("Crossbound " + channelID + " to " + dstID)
}
<|endoftext|>


<commit_before>package ucloud

import (
	_ "fmt"
	_ "testing"
)

/*
func TestGetMetric(t *testing.T) {

	g := GetMetric{Region: "cn-east-01",
		MetricName:   []string{"NetworkOut", "TotalNetworkOut"},
		ResourceId:   "uhost-ahdvfh",
		ResourceType: "uhost"}
	rsp, err := u.Do(&g)
	if err != nil || !rsp.OK() {
		t.Fatal(err, rsp)
	}
	data := rsp.Data().(map[string]*GetMetricItem)
	fmt.Println(data["NetworkOut"])
}
*/
<commit_msg>update Umon<commit_after>package ucloud

import (
	"fmt"
	"testing"
)

// ---------------- TestGetMetric ------------------
func TestGetMetric(t *testing.T) {
	fmt.Println("UMon....")
	r := &GetMetric{ResourceType: "ulb",
		ResourceId: "ulb-kix4tp",
		Region:     "1",
		TimeRange:  300,
		MetricName: []string{"NetworkOut", "TotalNetworkOut"},
	}
	cmp := `https://api.ucloud.cn/?Action=GetMetric&Region=1&MetricName.0=NetworkOut&MetricName.1=TotalNetworkOut&ResourceType=ulb&ResourceId=ulb-kix4tp&TimeRange=300`

	if err := FakeGetAndCmp(r, cmp); err != nil {
		t.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"encoding/json"
	"time"

	"github.com/1and1/soma/internal/stmt"
	"github.com/1and1/soma/lib/proto"
)

func (tk *treeKeeper) orderDeploymentDetails() {

	var (
		computed *sql.Rows
		err      error
	)
	if computed, err = tk.stmt_GetComputed.Query(tk.repoId); err != nil {
		tk.log.Println("tk.stmt_GetComputed.Query(): ", err)
		tk.broken = true
		return
	}
	defer computed.Close()

deployments:
	for computed.Next() {
		var (
			chkInstanceId                 string
			currentChkInstanceConfigId    string
			currentDeploymentDetailsJSON  string
			previousChkInstanceConfigId   string
			previousVersion               string
			previousStatus                string
			previousDeploymentDetailsJSON string
			noPrevious                    bool
			tx                            *sql.Tx
			txUpdateStatus                *sql.Stmt
			txUpdateInstance              *sql.Stmt
			txUpdateExisting              *sql.Stmt
			txDependency                  *sql.Stmt
		)
		err = computed.Scan(
			&chkInstanceId,
			&currentChkInstanceConfigId,
			&currentDeploymentDetailsJSON,
		)
		if err == sql.ErrNoRows {
			continue deployments
		} else if err != nil {
			tk.log.Println("tk.stmt_GetComputed.Query().Scan(): ", err)
			break deployments
		}

		// fetch previous deployment details for this check_instance_id
		err = tk.stmt_GetPrevious.QueryRow(chkInstanceId).Scan(
			&previousChkInstanceConfigId,
			&previousVersion,
			&previousStatus,
			&previousDeploymentDetailsJSON,
		)
		if err == sql.ErrNoRows {
			noPrevious = true
		} else if err != nil {
			tk.log.Println("tk.stmt_GetPrevious.QueryRow(): ", err)
			break deployments
		}

		/* there is no previous version of this check instance rolled
		 * out on a monitoring system
		 */
		if noPrevious {
			// open multi statement transaction
			if tx, err = tk.conn.Begin(); err != nil {
				tk.log.Println("TreeKeeper/Order sql.Begin: ", err)
				break deployments
			}
			defer tx.Rollback()

			// prepare statements within transaction
			if txUpdateStatus, err = tx.Prepare(stmt.TreekeeperUpdateConfigStatus); err != nil {
				tk.log.Printf("Failed to prepare %s: %s\n",
					`tkStmtUpdateConfigStatus`, err)
				break deployments
			}
			defer txUpdateStatus.Close()

			if txUpdateInstance, err = tx.Prepare(stmt.TreekeeperUpdateCheckInstance); err != nil {
				tk.log.Printf("Failed to prepare %s: %s\n",
					`tkStmtUpdateCheckInstance`, err)
				break deployments
			}
			defer txUpdateInstance.Close()

			//
			if _, err = txUpdateStatus.Exec(
				"awaiting_rollout",
				"rollout_in_progress",
				currentChkInstanceConfigId,
			); err != nil {
				goto bailout_noprev
			}

			if _, err = txUpdateInstance.Exec(
				time.Now().UTC(),
				true,
				currentChkInstanceConfigId,
				chkInstanceId,
			); err != nil {
				goto bailout_noprev
			}

			if err = tx.Commit(); err != nil {
				goto bailout_noprev
			}
			continue deployments

		bailout_noprev:
			tx.Rollback()
			continue deployments
		}
		/* a previous version of this check instance was found
		 */
		curDetails := proto.Deployment{}
		prvDetails := proto.Deployment{}
		err = json.Unmarshal([]byte(currentDeploymentDetailsJSON), &curDetails)
		if err != nil {
			tk.log.Printf("Error unmarshal/deploymentdetails %s: %s",
				currentChkInstanceConfigId,
				err.Error(),
			)
			err = nil
			continue deployments
		}
		err = json.Unmarshal([]byte(previousDeploymentDetailsJSON), &prvDetails)
		if err != nil {
			tk.log.Printf("Error unmarshal/deploymentdetails %s: %s",
				previousChkInstanceConfigId,
				err.Error(),
			)
			err = nil
			continue deployments
		}

		if curDetails.DeepCompare(&prvDetails) {
			// there is no change in deployment details, thus no point
			// to sending the new deployment details as an update to the
			// monitoring systems
			tk.stmt_DelDuplicate.Exec(currentChkInstanceConfigId)
			continue deployments
		}

		// UPDATE config status
		// open multi statement transaction
		if tx, err = tk.conn.Begin(); err != nil {
			tk.log.Println("TreeKeeper/Order sql.Begin: ", err)
			break deployments
		}
		defer tx.Rollback()

		// prepare statements within transaction
		if txUpdateStatus, err = tx.Prepare(stmt.TreekeeperUpdateConfigStatus); err != nil {
			tk.log.Printf("Failed to prepare %s: %s\n",
				`tkStmtUpdateConfigStatus`, err)
			break deployments
		}
		defer txUpdateStatus.Close()

		if txUpdateInstance, err = tx.Prepare(stmt.TreekeeperUpdateCheckInstance); err != nil {
			tk.log.Printf("Failed to prepare %s: %s\n",
				`tkStmtUpdateCheckInstance`, err)
			break deployments
		}
		defer txUpdateInstance.Close()

		if txUpdateExisting, err = tx.Prepare(stmt.TreekeeperUpdateExistingCheckInstance); err != nil {
			tk.log.Printf("Failed to prepare %s: %s\n",
				`tkStmtUpdateExistingCheckInstance`, err)
			break deployments
		}
		defer txUpdateExisting.Close()

		if txDependency, err = tx.Prepare(stmt.TreekeeperSetDependency); err != nil {
			tk.log.Printf("Failed to prepare %s: %s\n",
				`tkStmtSetDependency`, err)
			break deployments
		}
		defer txDependency.Close()

		if _, err = txUpdateStatus.Exec(
			"blocked",
			"awaiting_rollout",
			currentChkInstanceConfigId,
		); err != nil {
			goto bailout_withprev
		}
		if _, err = txUpdateExisting.Exec(
			time.Now().UTC(),
			true,
			chkInstanceId,
		); err != nil {
			goto bailout_withprev
		}
		if _, err = txDependency.Exec(
			currentChkInstanceConfigId,
			previousChkInstanceConfigId,
			"deprovisioned",
		); err != nil {
			goto bailout_withprev
		}

		if err = tx.Commit(); err != nil {
			goto bailout_withprev
		}
		continue deployments

	bailout_withprev:
		tx.Rollback()
		continue deployments
	}
	// mark the tree as broken to prevent further data processing
	if err != nil {
		tk.broken = true
	}
}

// vim: ts=4 sw=4 sts=4 noet fenc=utf-8 ffs=unix
<commit_msg>Treekeeper: prepared statements for ordering<commit_after>package main

import (
	"database/sql"
	"encoding/json"
	"time"

	"github.com/1and1/soma/internal/stmt"
	"github.com/1and1/soma/lib/proto"
)

func (tk *treeKeeper) orderDeploymentDetails() {

	var (
		computed *sql.Rows
		err      error
	)
	if computed, err = tk.stmt_GetComputed.Query(tk.repoId); err != nil {
		tk.log.Println("tk.stmt_GetComputed.Query(): ", err)
		tk.broken = true
		return
	}
	defer computed.Close()

deployments:
	for computed.Next() {
		var (
			chkInstanceId                 string
			currentChkInstanceConfigId    string
			currentDeploymentDetailsJSON  string
			previousChkInstanceConfigId   string
			previousVersion               string
			previousStatus                string
			previousDeploymentDetailsJSON string
			noPrevious                    bool
			tx                            *sql.Tx
		)
		err = computed.Scan(
			&chkInstanceId,
			&currentChkInstanceConfigId,
			&currentDeploymentDetailsJSON,
		)
		if err == sql.ErrNoRows {
			continue deployments
		} else if err != nil {
			tk.log.Println("tk.stmt_GetComputed.Query().Scan(): ", err)
			break deployments
		}

		// fetch previous deployment details for this check_instance_id
		err = tk.stmt_GetPrevious.QueryRow(chkInstanceId).Scan(
			&previousChkInstanceConfigId,
			&previousVersion,
			&previousStatus,
			&previousDeploymentDetailsJSON,
		)
		if err == sql.ErrNoRows {
			noPrevious = true
		} else if err != nil {
			tk.log.Println("tk.stmt_GetPrevious.QueryRow(): ", err)
			break deployments
		}

		/* there is no previous version of this check instance rolled
		 * out on a monitoring system
		 */
		if noPrevious {
			// open multi statement transaction
			txMap := map[string]*sql.Stmt{}
			if tx, err = tk.conn.Begin(); err != nil {
				tk.log.Println("TreeKeeper/Order sql.Begin: ", err)
				break deployments
			}

			// prepare statements within transaction
			for name, statement := range map[string]string{
				`UpdateStatus`:   stmt.TreekeeperUpdateConfigStatus,
				`UpdateInstance`: stmt.TreekeeperUpdateCheckInstance,
			} {
				if txMap[name], err = tx.Prepare(statement); err != nil {
					tk.log.Println(`treekeeper/order/tx`, err, stmt.Name(statement))
					tx.Rollback()
					break deployments
				}
			}

			//
			if _, err = txMap[`UpdateStatus`].Exec(
				"awaiting_rollout",
				"rollout_in_progress",
				currentChkInstanceConfigId,
			); err != nil {
				goto bailout_noprev
			}

			if _, err = txMap[`UpdateInstance`].Exec(
				time.Now().UTC(),
				true,
				currentChkInstanceConfigId,
				chkInstanceId,
			); err != nil {
				goto bailout_noprev
			}

			if err = tx.Commit(); err != nil {
				goto bailout_noprev
			}
			continue deployments

		bailout_noprev:
			tx.Rollback()
			continue deployments
		}
		/* a previous version of this check instance was found
		 */
		curDetails := proto.Deployment{}
		prvDetails := proto.Deployment{}
		err = json.Unmarshal([]byte(currentDeploymentDetailsJSON), &curDetails)
		if err != nil {
			tk.log.Printf("Error unmarshal/deploymentdetails %s: %s",
				currentChkInstanceConfigId,
				err.Error(),
			)
			err = nil
			continue deployments
		}
		err = json.Unmarshal([]byte(previousDeploymentDetailsJSON), &prvDetails)
		if err != nil {
			tk.log.Printf("Error unmarshal/deploymentdetails %s: %s",
				previousChkInstanceConfigId,
				err.Error(),
			)
			err = nil
			continue deployments
		}

		if curDetails.DeepCompare(&prvDetails) {
			// there is no change in deployment details, thus no point
			// to sending the new deployment details as an update to the
			// monitoring systems
			tk.stmt_DelDuplicate.Exec(currentChkInstanceConfigId)
			continue deployments
		}

		// UPDATE config status
		// open multi statement transaction
		txMap := map[string]*sql.Stmt{}
		if tx, err = tk.conn.Begin(); err != nil {
			tk.log.Println("TreeKeeper/Order sql.Begin: ", err)
			break deployments
		}

		// prepare statements within transaction
		for name, statement := range map[string]string{
			`UpdateStatus`:   stmt.TreekeeperUpdateConfigStatus,
			`UpdateExisting`: stmt.TreekeeperUpdateExistingCheckInstance,
			`SetDependency`:  stmt.TreekeeperSetDependency,
		} {
			if txMap[name], err = tx.Prepare(statement); err != nil {
				tk.log.Println(`treekeeper/order/tx`, err, stmt.Name(statement))
				tx.Rollback()
				break deployments
			}
		}

		if _, err = txMap[`UpdateStatus`].Exec(
			"blocked",
			"awaiting_rollout",
			currentChkInstanceConfigId,
		); err != nil {
			goto bailout_withprev
		}
		if _, err = txMap[`UpdateExisting`].Exec(
			time.Now().UTC(),
			true,
			chkInstanceId,
		); err != nil {
			goto bailout_withprev
		}
		if _, err = txMap[`SetDependency`].Exec(
			currentChkInstanceConfigId,
			previousChkInstanceConfigId,
			"deprovisioned",
		); err != nil {
			goto bailout_withprev
		}

		if err = tx.Commit(); err != nil {
			goto bailout_withprev
		}
		continue deployments

	bailout_withprev:
		tx.Rollback()
		continue deployments
	}
	// mark the tree as broken to prevent further data processing
	if err != nil {
		tk.broken = true
	}
}

// vim: ts=4 sw=4 sts=4 noet fenc=utf-8 ffs=unix
<|endoftext|>


<commit_before>package vm

import (
	"fmt"
)

var (
	// InternalErrorClass ...
	InternalErrorClass *RClass
	// ArgumentErrorClass ...
	ArgumentErrorClass *RClass
	// NameErrorClass ...
	NameErrorClass *RClass
	// TypeErrorClass ...
	TypeErrorClass *RClass
	// UndefinedMethodErrorClass ...
	UndefinedMethodErrorClass *RClass
	// UnsupportedMethodClass ...
	UnsupportedMethodClass *RClass
)

const (
	// InternalError is the default error type
	InternalError = "InternalError"
	// ArgumentError: an argument-related error
	ArgumentError = "ArgumentError"
	// NameError: a constant-related error
	NameError = "NameError"
	// TypeError: a type-related error
	TypeError = "TypeError"
	// UndefinedMethodError: undefined-method error
	UndefinedMethodError = "UndefinedMethodError"
	// UnsupportedMethodError: intentionally unsupported-method error
	UnsupportedMethodError = "UnsupportedMethodError"
)

// Error class is actually a special struct to hold internal error types with messages.
// Goby developers need not to take care of the struct.
// Goby maintainers should consider using the appropriate error type.
// Cannot create instances of Error class, or inherit Error class.
//
// The type of internal errors:
//
// * `InternalError`: default error type
// * `ArgumentError`: an argument-related error
// * `NameError`: a constant-related error
// * `TypeError`: a type-related error
// * `UndefinedMethodError`: undefined-method error
// * `UnsupportedMethodError`: intentionally unsupported-method error
//
type Error struct {
	*baseObj
	Message string
}

func initErrorObject(errorType *RClass, format string, args ...interface{}) *Error {
	return &Error{
		baseObj: &baseObj{class: errorType},
		Message: fmt.Sprintf(errorType.Name+": "+format, args...),
	}
}

func (vm *VM) initErrorClasses() {
	InternalErrorClass = vm.initializeClass(InternalError, false)
	ArgumentErrorClass = vm.initializeClass(ArgumentError, false)
	NameErrorClass = vm.initializeClass(NameError, false)
	TypeErrorClass = vm.initializeClass(TypeError, false)
	UndefinedMethodErrorClass = vm.initializeClass(UndefinedMethodError, false)
	UnsupportedMethodClass = vm.initializeClass(UnsupportedMethodError, false)
}

// Polymorphic helper functions -----------------------------------------

// toString converts error messages into string.
func (e *Error) toString() string {
	return "ERROR: " + e.Message
}

// toJSON converts the receiver into JSON string.
func (e *Error) toJSON() string {
	return e.toString()
}
<commit_msg>Update API doc to comply houndci check<commit_after>package vm

import (
	"fmt"
)

var (
	// InternalErrorClass ...
	InternalErrorClass *RClass
	// ArgumentErrorClass ...
	ArgumentErrorClass *RClass
	// NameErrorClass ...
	NameErrorClass *RClass
	// TypeErrorClass ...
	TypeErrorClass *RClass
	// UndefinedMethodErrorClass ...
	UndefinedMethodErrorClass *RClass
	// UnsupportedMethodClass ...
	UnsupportedMethodClass *RClass
)

const (
	// InternalError is the default error type
	InternalError = "InternalError"
	// ArgumentError is for an argument-related error
	ArgumentError = "ArgumentError"
	// NameError is for a constant-related error
	NameError = "NameError"
	// TypeError is for a type-related error
	TypeError = "TypeError"
	// UndefinedMethodError is for an undefined-method error
	UndefinedMethodError = "UndefinedMethodError"
	// UnsupportedMethodError is for an intentionally unsupported-method error
	UnsupportedMethodError = "UnsupportedMethodError"
)

// Error class is actually a special struct to hold internal error types with messages.
// Goby developers need not to take care of the struct.
// Goby maintainers should consider using the appropriate error type.
// Cannot create instances of Error class, or inherit Error class.
//
// The type of internal errors:
//
// * `InternalError`: default error type
// * `ArgumentError`: an argument-related error
// * `NameError`: a constant-related error
// * `TypeError`: a type-related error
// * `UndefinedMethodError`: undefined-method error
// * `UnsupportedMethodError`: intentionally unsupported-method error
//
type Error struct {
	*baseObj
	Message string
}

func initErrorObject(errorType *RClass, format string, args ...interface{}) *Error {
	return &Error{
		baseObj: &baseObj{class: errorType},
		Message: fmt.Sprintf(errorType.Name+": "+format, args...),
	}
}

func (vm *VM) initErrorClasses() {
	InternalErrorClass = vm.initializeClass(InternalError, false)
	ArgumentErrorClass = vm.initializeClass(ArgumentError, false)
	NameErrorClass = vm.initializeClass(NameError, false)
	TypeErrorClass = vm.initializeClass(TypeError, false)
	UndefinedMethodErrorClass = vm.initializeClass(UndefinedMethodError, false)
	UnsupportedMethodClass = vm.initializeClass(UnsupportedMethodError, false)
}

// Polymorphic helper functions -----------------------------------------

// toString converts error messages into string.
func (e *Error) toString() string {
	return "ERROR: " + e.Message
}

// toJSON converts the receiver into JSON string.
func (e *Error) toJSON() string {
	return e.toString()
}
<|endoftext|>


<commit_before>package db

import "fmt"

//QLQeryer implements the Queryer interface for ql database.
type QLQeryer struct {
}

//CreateSession retruns a Query for creating new session.
func (ql QLQeryer) CreateSession(table string) Query {
	var query = `
	BEGIN TRANSACTION;
	  INSERT INTO %s (key, data, created_on, updated_on, expires_on)
		VALUES ($1,$2,now(),now(),$3);
	COMMIT;
	`
	query = fmt.Sprintf(query, table)
	return NewQuery(query, true, "key", "data", "expires_on")
}

//FindSessionByKey returns a query for finding a session by key.
func (ql QLQeryer) FindSessionByKey(table string) Query {
	var query = `
	SELECT * from %s WHERE key=$1 LIMIT 1;
	`
	query = fmt.Sprintf(query, table)
	return NewQuery(query, false, "key")
}

//UpdateSession updaates session data.
func (ql QLQeryer) UpdateSession(table string) Query {
	var query = `
BEGIN TRANSACTION;
  UPDATE %s
    data = $2,
    updated_on = now(),
  WHERE key==$1;
COMMIT;
	`
	query = fmt.Sprintf(query, table)
	return NewQuery(query, true, "key", "data")
}

//DeleteSession deletes a session.
func (ql QLQeryer) DeleteSession(table string) Query {
	var query = `
BEGIN TRANSACTION;
   DELETE FROM %s
  WHERE key==$1;
COMMIT;
	`
	query = fmt.Sprintf(query, table)
	return NewQuery(query, true, "key")
}

func (ql QLQeryer) CreateUser(table string) Query {
	var query = `
	BEGIN TRANSACTION;
	  INSERT INTO %s (username,password,email,created_at,updated_at)
		VALUES ($1,$2,$3,now(),now());
	COMMIT;
	`
	query = fmt.Sprintf(query, table)
	return NewQuery(query, true, "username", "password", "email")
}

func (ql QLQeryer) FindUserBy(table, field string) Query {
	var query = `
	SELECT id(),username,password,email,created_at,updated_at
	from %s WHERE %s LIKE $1 LIMIT 1;
	`
	query = fmt.Sprintf(query, table, field)
	return NewQuery(query, false, field)
}
<commit_msg>Add doc<commit_after>package db

import "fmt"

//QLQeryer implements the Queryer interface for ql database.
type QLQeryer struct {
}

//CreateSession retruns a Query for creating new session.
func (ql QLQeryer) CreateSession(table string) Query {
	var query = `
	BEGIN TRANSACTION;
	  INSERT INTO %s (key, data, created_on, updated_on, expires_on)
		VALUES ($1,$2,now(),now(),$3);
	COMMIT;
	`
	query = fmt.Sprintf(query, table)
	return NewQuery(query, true, "key", "data", "expires_on")
}

//FindSessionByKey returns a query for finding a session by key.
func (ql QLQeryer) FindSessionByKey(table string) Query {
	var query = `
	SELECT * from %s WHERE key=$1 LIMIT 1;
	`
	query = fmt.Sprintf(query, table)
	return NewQuery(query, false, "key")
}

//UpdateSession updaates session data.
func (ql QLQeryer) UpdateSession(table string) Query {
	var query = `
BEGIN TRANSACTION;
  UPDATE %s
    data = $2,
    updated_on = now(),
  WHERE key==$1;
COMMIT;
	`
	query = fmt.Sprintf(query, table)
	return NewQuery(query, true, "key", "data")
}

//DeleteSession deletes a session.
func (ql QLQeryer) DeleteSession(table string) Query {
	var query = `
BEGIN TRANSACTION;
   DELETE FROM %s
  WHERE key==$1;
COMMIT;
	`
	query = fmt.Sprintf(query, table)
	return NewQuery(query, true, "key")
}

//CreateUser creates a new user.
func (ql QLQeryer) CreateUser(table string) Query {
	var query = `
	BEGIN TRANSACTION;
	  INSERT INTO %s (username,password,email,created_at,updated_at)
		VALUES ($1,$2,$3,now(),now());
	COMMIT;
	`
	query = fmt.Sprintf(query, table)
	return NewQuery(query, true, "username", "password", "email")
}

//FindUserBy finds a user by the speicified field.
func (ql QLQeryer) FindUserBy(table, field string) Query {
	var query = `
	SELECT id(),username,password,email,created_at,updated_at
	from %s WHERE %s LIKE $1 LIMIT 1;
	`
	query = fmt.Sprintf(query, table, field)
	return NewQuery(query, false, field)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os/exec"
	"time"

	pb "github.com/brotherlogic/gobuildslave/proto"
	"github.com/brotherlogic/goserver/utils"
	pbt "github.com/brotherlogic/tracer/proto"
	"golang.org/x/net/context"
)

const (
	pendWait = time.Minute
)

func (s *Server) runTransition(ctx context.Context, job *pb.JobAssignment) {
	utils.SendTrace(ctx, fmt.Sprintf("run_transition_%v", job.State), time.Now(), pbt.Milestone_MARKER, job.Job.Name)
	stState := job.State
	switch job.State {
	case pb.State_ACKNOWLEDGED:
		key := s.scheduleBuild(ctx, job.Job)
		if job.Job.NonBootstrap {
			if key != "" {
				job.Server = s.Registry.Identifier
				job.State = pb.State_BUILT
				job.RunningVersion = key
			}
		} else {
			job.CommandKey = key
			job.State = pb.State_BUILDING
			job.Server = s.Registry.Identifier
		}
	case pb.State_BUILDING:
		if s.taskComplete(job.CommandKey) {
			job.State = pb.State_BUILT
		}
	case pb.State_BUILT:
		output := s.scheduler.getOutput(job.CommandKey)
		if len(output) > 0 {
			if job.BuildFail == 5 {
				s.deliverCrashReport(ctx, job, output)
			}
			job.BuildFail++
			job.State = pb.State_DIED
		} else {
			job.BuildFail = 0
			key := s.scheduleRun(job.Job)
			job.CommandKey = key
			job.StartTime = time.Now().Unix()
			job.State = pb.State_PENDING
			if _, ok := s.pendingMap[time.Now().Weekday()]; !ok {
				s.pendingMap[time.Now().Weekday()] = make(map[string]int)
			}
			s.pendingMap[time.Now().Weekday()][job.Job.Name]++
		}
	case pb.State_PENDING:
		s.stateMap[job.Job.Name] = fmt.Sprintf("OUTPUT = %v", s.scheduler.getOutput(job.CommandKey))
		if time.Now().Add(-time.Minute).Unix() > job.StartTime {
			job.State = pb.State_RUNNING
		}
	case pb.State_RUNNING:
		if s.taskComplete(job.CommandKey) {
			output := s.scheduler.getOutput(job.CommandKey)
			s.deliverCrashReport(ctx, job, output)
			job.State = pb.State_DIED
		}

		if s.discover.discover(job.Job.Name, s.Registry.Identifier) != nil {
			s.RaiseIssue(ctx, "Cannot Discover Running Server", fmt.Sprintf("%v on %v is not discoverable, despite running", job.Job.Name, s.Registry.Identifier), false)
		}

		// Restart this job if we need to
		if job.Job.NonBootstrap {
			version := s.getVersion(ctx, job.Job)
			if version != job.RunningVersion {
				s.scheduler.killJob(job.CommandKey)
				job.State = pb.State_ACKNOWLEDGED
			}
		}
	case pb.State_DIED:
		job.State = pb.State_ACKNOWLEDGED
	}

	if job.State != stState {
		s.stateTime[job.Job.Name] = time.Now()
	}

	utils.SendTrace(ctx, fmt.Sprintf("end_transition_%v_%v", job.State, stState), time.Now(), pbt.Milestone_MARKER, job.Job.Name)
	utils.SendTrace(ctx, fmt.Sprintf("end_transition_func_%v", job.State), time.Now(), pbt.Milestone_MARKER, job.Job.Name)
}

type translator interface {
	build(job *pb.Job) *exec.Cmd
	run(job *pb.Job) *exec.Cmd
}

type checker interface {
	isAlive(ctx context.Context, job *pb.JobAssignment) bool
}

func (s *Server) getVersion(ctx context.Context, job *pb.Job) string {
	versions, _ := s.builder.build(ctx, job)

	if len(versions) == 0 {
		return ""
	}

	return versions[0].Version

}

// scheduleBuild builds out the job, returning the current version
func (s *Server) scheduleBuild(ctx context.Context, job *pb.Job) string {
	utils.SendTrace(ctx, fmt.Sprintf("schedule_build_%v", job.NonBootstrap), time.Now(), pbt.Milestone_MARKER, job.Name)
	if !job.NonBootstrap {
		c := s.translator.build(job)
		return s.scheduler.Schedule(&rCommand{command: c})
	}

	versions, err := s.builder.build(ctx, job)

	if len(versions) == 0 {
		s.stateMap[job.Name] = fmt.Sprintf("No Versions: %v", err)
		return ""
	}

	t := time.Now()
	err = s.builder.copy(ctx, versions[0])
	if err != nil {
		s.stateMap[job.Name] = fmt.Sprintf("Copy fail (%v) -> %v", time.Now().Sub(t), err)
		return ""
	}
	s.stateMap[job.Name] = fmt.Sprintf("Found version %v", versions[0].Version)
	return versions[0].Version
}

func (s *Server) scheduleRun(job *pb.Job) string {
	c := s.translator.run(job)
	return s.scheduler.Schedule(&rCommand{command: c})
}

func (s *Server) taskComplete(key string) bool {
	return s.scheduler.schedulerComplete(key)
}
<commit_msg>Adds output for scheduled<commit_after>package main

import (
	"fmt"
	"os/exec"
	"time"

	pb "github.com/brotherlogic/gobuildslave/proto"
	"github.com/brotherlogic/goserver/utils"
	pbt "github.com/brotherlogic/tracer/proto"
	"golang.org/x/net/context"
)

const (
	pendWait = time.Minute
)

func (s *Server) runTransition(ctx context.Context, job *pb.JobAssignment) {
	utils.SendTrace(ctx, fmt.Sprintf("run_transition_%v", job.State), time.Now(), pbt.Milestone_MARKER, job.Job.Name)
	stState := job.State
	switch job.State {
	case pb.State_ACKNOWLEDGED:
		key := s.scheduleBuild(ctx, job.Job)
		s.stateMap[job.Job.Name] = fmt.Sprintf("SCHED: %v", key)
		if job.Job.NonBootstrap {
			if key != "" {
				job.Server = s.Registry.Identifier
				job.State = pb.State_BUILT
				job.RunningVersion = key
			}
		} else {
			job.CommandKey = key
			job.State = pb.State_BUILDING
			job.Server = s.Registry.Identifier
		}
	case pb.State_BUILDING:
		if s.taskComplete(job.CommandKey) {
			job.State = pb.State_BUILT
		}
	case pb.State_BUILT:
		output := s.scheduler.getOutput(job.CommandKey)
		if len(output) > 0 {
			if job.BuildFail == 5 {
				s.deliverCrashReport(ctx, job, output)
			}
			job.BuildFail++
			job.State = pb.State_DIED
		} else {
			job.BuildFail = 0
			key := s.scheduleRun(job.Job)
			job.CommandKey = key
			job.StartTime = time.Now().Unix()
			job.State = pb.State_PENDING
			if _, ok := s.pendingMap[time.Now().Weekday()]; !ok {
				s.pendingMap[time.Now().Weekday()] = make(map[string]int)
			}
			s.pendingMap[time.Now().Weekday()][job.Job.Name]++
		}
	case pb.State_PENDING:
		s.stateMap[job.Job.Name] = fmt.Sprintf("OUTPUT = %v", s.scheduler.getOutput(job.CommandKey))
		if time.Now().Add(-time.Minute).Unix() > job.StartTime {
			job.State = pb.State_RUNNING
		}
	case pb.State_RUNNING:
		if s.taskComplete(job.CommandKey) {
			output := s.scheduler.getOutput(job.CommandKey)
			s.deliverCrashReport(ctx, job, output)
			job.State = pb.State_DIED
		}

		if s.discover.discover(job.Job.Name, s.Registry.Identifier) != nil {
			s.RaiseIssue(ctx, "Cannot Discover Running Server", fmt.Sprintf("%v on %v is not discoverable, despite running", job.Job.Name, s.Registry.Identifier), false)
		}

		// Restart this job if we need to
		if job.Job.NonBootstrap {
			version := s.getVersion(ctx, job.Job)
			if version != job.RunningVersion {
				s.scheduler.killJob(job.CommandKey)
				job.State = pb.State_ACKNOWLEDGED
			}
		}
	case pb.State_DIED:
		job.State = pb.State_ACKNOWLEDGED
	}

	if job.State != stState {
		s.stateTime[job.Job.Name] = time.Now()
	}

	utils.SendTrace(ctx, fmt.Sprintf("end_transition_%v_%v", job.State, stState), time.Now(), pbt.Milestone_MARKER, job.Job.Name)
	utils.SendTrace(ctx, fmt.Sprintf("end_transition_func_%v", job.State), time.Now(), pbt.Milestone_MARKER, job.Job.Name)
}

type translator interface {
	build(job *pb.Job) *exec.Cmd
	run(job *pb.Job) *exec.Cmd
}

type checker interface {
	isAlive(ctx context.Context, job *pb.JobAssignment) bool
}

func (s *Server) getVersion(ctx context.Context, job *pb.Job) string {
	versions, _ := s.builder.build(ctx, job)

	if len(versions) == 0 {
		return ""
	}

	return versions[0].Version

}

// scheduleBuild builds out the job, returning the current version
func (s *Server) scheduleBuild(ctx context.Context, job *pb.Job) string {
	utils.SendTrace(ctx, fmt.Sprintf("schedule_build_%v", job.NonBootstrap), time.Now(), pbt.Milestone_MARKER, job.Name)
	if !job.NonBootstrap {
		c := s.translator.build(job)
		return s.scheduler.Schedule(&rCommand{command: c})
	}

	versions, err := s.builder.build(ctx, job)

	if len(versions) == 0 {
		s.stateMap[job.Name] = fmt.Sprintf("No Versions: %v", err)
		return ""
	}

	t := time.Now()
	err = s.builder.copy(ctx, versions[0])
	if err != nil {
		s.stateMap[job.Name] = fmt.Sprintf("Copy fail (%v) -> %v", time.Now().Sub(t), err)
		return ""
	}
	s.stateMap[job.Name] = fmt.Sprintf("Found version %v", versions[0].Version)
	return versions[0].Version
}

func (s *Server) scheduleRun(job *pb.Job) string {
	c := s.translator.run(job)
	return s.scheduler.Schedule(&rCommand{command: c})
}

func (s *Server) taskComplete(key string) bool {
	return s.scheduler.schedulerComplete(key)
}
<|endoftext|>


<commit_before>// Copyright 2010 Google Inc.
//
// 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.

// GoMock - a mock framework for Go.
//
// Standard usage:
//   (1) Define an interface that you wish to mock.
//         type MyInterface interface {
//           SomeMethod(x int64, y string)
//         }
//   (2) Use mockgen to automatically generate a mock from the interface.
//   (3) Use the mock in a test:
//         func TestMyThing(t *testing.T) {
//           mockCtrl := gomock.NewController(t)
//           defer mockCtrl.Finish()
//
//           mockObj := something.NewMockMyInterface(mockCtrl)
//           mockObj.EXPECT().SomeMethod(4, "blah")
//           // pass mockObj to a real object and play with it.
//         }
//
// By default, expected calls are not enforced to run in any particular order.
// Call order dependency can be enforced by use of InOrder and/or Call.After.
// Call.After can create more varied call order dependencies, but InOrder is
// often more convenient.
//
// The following examples create equivalent call order dependencies.
//
// Example of using Call.After to chain expected call order:
//
//     firstCall := mockObj.EXPECT().SomeMethod(1, "first")
//     secondCall := mockObj.EXPECT().SomeMethod(2, "second").After(firstCall)
//     mockObj.EXPECT().SomeMethod(3, "third").After(secondCall)
//
// Example of using InOrder to declare expected call order:
//
//     gomock.InOrder(
//         mockObj.EXPECT().SomeMethod(1, "first"),
//         mockObj.EXPECT().SomeMethod(2, "second"),
//         mockObj.EXPECT().SomeMethod(3, "third"),
//     )
//
// TODO:
//	- Handle different argument/return types (e.g. ..., chan, map, interface).
package gomock

// A TestReporter is something that can be used to report test failures.
// It is satisfied by the standard library's *testing.T.
type TestReporter interface {
	Errorf(format string, args ...interface{})
	Fatalf(format string, args ...interface{})
}

// A Controller represents the top-level control of a mock ecosystem.
// It defines the scope and lifetime of mock objects, as well as their expectations.
type Controller struct {
	t             TestReporter
	expectedCalls callSet
}

func NewController(t TestReporter) *Controller {
	return &Controller{
		t:             t,
		expectedCalls: make(callSet),
	}
}

func (ctrl *Controller) RecordCall(receiver interface{}, method string, args ...interface{}) *Call {
	margs := make([]Matcher, len(args))
	for i, arg := range args {
		if m, ok := arg.(Matcher); ok {
			margs[i] = m
		} else {
			margs[i] = Eq(arg)
		}
	}

	call := &Call{receiver: receiver, method: method, args: margs, minCalls: 1, maxCalls: 1}

	ctrl.expectedCalls.Add(call)
	return call
}

func (ctrl *Controller) Call(receiver interface{}, method string, args ...interface{}) []interface{} {
	expected := ctrl.expectedCalls.FindMatch(receiver, method, args)
	if expected == nil {
		ctrl.t.Fatalf("no matching expected call: %T.%v(%v)", receiver, method, args)
	}

	// Two things happen here:
	// * the matching call no longer needs to check prerequite calls,
	// * and the prerequite calls are no longer expected, so remove them.
	preReqCalls := expected.dropPrereqs()
	for _, preReqCall := range preReqCalls {
		ctrl.expectedCalls.Remove(preReqCall)
	}

	rets := expected.call(args)
	if expected.exhausted() {
		ctrl.expectedCalls.Remove(expected)
	}

	return rets
}

func (ctrl *Controller) Finish() {
	// Check that all remaining expected calls are satisfied.
	failures := false
	for _, methodMap := range ctrl.expectedCalls {
		for _, calls := range methodMap {
			for _, call := range calls {
				if !call.satisfied() {
					ctrl.t.Errorf("missing call(s) to %v", call)
					failures = true
				}
			}
		}
	}
	if failures {
		ctrl.t.Fatalf("aborting test due to missing call(s)")
	}
}
<commit_msg>Language tweak.<commit_after>// Copyright 2010 Google Inc.
//
// 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.

// GoMock - a mock framework for Go.
//
// Standard usage:
//   (1) Define an interface that you wish to mock.
//         type MyInterface interface {
//           SomeMethod(x int64, y string)
//         }
//   (2) Use mockgen to generate a mock from the interface.
//   (3) Use the mock in a test:
//         func TestMyThing(t *testing.T) {
//           mockCtrl := gomock.NewController(t)
//           defer mockCtrl.Finish()
//
//           mockObj := something.NewMockMyInterface(mockCtrl)
//           mockObj.EXPECT().SomeMethod(4, "blah")
//           // pass mockObj to a real object and play with it.
//         }
//
// By default, expected calls are not enforced to run in any particular order.
// Call order dependency can be enforced by use of InOrder and/or Call.After.
// Call.After can create more varied call order dependencies, but InOrder is
// often more convenient.
//
// The following examples create equivalent call order dependencies.
//
// Example of using Call.After to chain expected call order:
//
//     firstCall := mockObj.EXPECT().SomeMethod(1, "first")
//     secondCall := mockObj.EXPECT().SomeMethod(2, "second").After(firstCall)
//     mockObj.EXPECT().SomeMethod(3, "third").After(secondCall)
//
// Example of using InOrder to declare expected call order:
//
//     gomock.InOrder(
//         mockObj.EXPECT().SomeMethod(1, "first"),
//         mockObj.EXPECT().SomeMethod(2, "second"),
//         mockObj.EXPECT().SomeMethod(3, "third"),
//     )
//
// TODO:
//	- Handle different argument/return types (e.g. ..., chan, map, interface).
package gomock

// A TestReporter is something that can be used to report test failures.
// It is satisfied by the standard library's *testing.T.
type TestReporter interface {
	Errorf(format string, args ...interface{})
	Fatalf(format string, args ...interface{})
}

// A Controller represents the top-level control of a mock ecosystem.
// It defines the scope and lifetime of mock objects, as well as their expectations.
type Controller struct {
	t             TestReporter
	expectedCalls callSet
}

func NewController(t TestReporter) *Controller {
	return &Controller{
		t:             t,
		expectedCalls: make(callSet),
	}
}

func (ctrl *Controller) RecordCall(receiver interface{}, method string, args ...interface{}) *Call {
	margs := make([]Matcher, len(args))
	for i, arg := range args {
		if m, ok := arg.(Matcher); ok {
			margs[i] = m
		} else {
			margs[i] = Eq(arg)
		}
	}

	call := &Call{receiver: receiver, method: method, args: margs, minCalls: 1, maxCalls: 1}

	ctrl.expectedCalls.Add(call)
	return call
}

func (ctrl *Controller) Call(receiver interface{}, method string, args ...interface{}) []interface{} {
	expected := ctrl.expectedCalls.FindMatch(receiver, method, args)
	if expected == nil {
		ctrl.t.Fatalf("no matching expected call: %T.%v(%v)", receiver, method, args)
	}

	// Two things happen here:
	// * the matching call no longer needs to check prerequite calls,
	// * and the prerequite calls are no longer expected, so remove them.
	preReqCalls := expected.dropPrereqs()
	for _, preReqCall := range preReqCalls {
		ctrl.expectedCalls.Remove(preReqCall)
	}

	rets := expected.call(args)
	if expected.exhausted() {
		ctrl.expectedCalls.Remove(expected)
	}

	return rets
}

func (ctrl *Controller) Finish() {
	// Check that all remaining expected calls are satisfied.
	failures := false
	for _, methodMap := range ctrl.expectedCalls {
		for _, calls := range methodMap {
			for _, call := range calls {
				if !call.satisfied() {
					ctrl.t.Errorf("missing call(s) to %v", call)
					failures = true
				}
			}
		}
	}
	if failures {
		ctrl.t.Fatalf("aborting test due to missing call(s)")
	}
}
<|endoftext|>


<commit_before>package goparallel

import (
	"fmt"
	"io"
	"strings"
	"sync"
)

var printMutex sync.Mutex

type prefixedWriter struct {
	Writer io.Writer
	Prefix string

	newline bool
}

func newPrefixWriter(writer io.Writer, prefix string) *prefixedWriter {
	return &prefixedWriter{
		Writer:  writer,
		Prefix:  prefix,
		newline: true,
	}
}

func (w *prefixedWriter) Write(data []byte) (int, error) {
	// in order to guarantee writing a single line by the one process. use mutex.
	printMutex.Lock()
	defer printMutex.Unlock()

	dataStr := string(data)
	dataStr = strings.Replace(dataStr, "\r\n", "\n", -1)
	if w.Prefix != "" {
		dataStr = strings.Replace(dataStr, "\n", "\n"+w.Prefix, strings.Count(dataStr, "\n") - 1)
		fmt.Fprint(w.Writer, w.Prefix + dataStr)
	} else {
		fmt.Fprint(w.Writer, dataStr)
	}

	return len(data), nil
}

//func (w *PrefixedWriter) Write(data []byte) (int, error) {
//	dataStr := string(data)
//	dataStr = strings.Replace(dataStr, "\r\n", "\n", -1)
//
//	if w.newline {
//		w.newline = false
//		fmt.Fprintf(w.Writer, "%s", w.Prefix)
//	}
//
//	if strings.Contains(dataStr, "\n") {
//		lineCount := strings.Count(dataStr, "\n")
//
//		if dataStr[len(dataStr)-1:] == "\n" {
//			w.newline = true
//		}
//
//		if w.newline {
//			dataStr = strings.Replace(dataStr, "\n", "\n"+w.Prefix, lineCount-1)
//		} else {
//			dataStr = strings.Replace(dataStr, "\n", "\n"+w.Prefix, -1)
//		}
//
//		fmt.Fprintf(w.Writer, "%s", dataStr)
//
//	} else {
//		fmt.Fprintf(w.Writer, "%s", dataStr)
//	}
//
//	return len(data), nil
//}
<commit_msg>run go fmt<commit_after>package goparallel

import (
	"fmt"
	"io"
	"strings"
	"sync"
)

var printMutex sync.Mutex

type prefixedWriter struct {
	Writer io.Writer
	Prefix string

	newline bool
}

func newPrefixWriter(writer io.Writer, prefix string) *prefixedWriter {
	return &prefixedWriter{
		Writer:  writer,
		Prefix:  prefix,
		newline: true,
	}
}

func (w *prefixedWriter) Write(data []byte) (int, error) {
	// in order to guarantee writing a single line by the one process. use mutex.
	printMutex.Lock()
	defer printMutex.Unlock()

	dataStr := string(data)
	dataStr = strings.Replace(dataStr, "\r\n", "\n", -1)
	if w.Prefix != "" {
		dataStr = strings.Replace(dataStr, "\n", "\n"+w.Prefix, strings.Count(dataStr, "\n")-1)
		fmt.Fprint(w.Writer, w.Prefix+dataStr)
	} else {
		fmt.Fprint(w.Writer, dataStr)
	}

	return len(data), nil
}

//func (w *PrefixedWriter) Write(data []byte) (int, error) {
//	dataStr := string(data)
//	dataStr = strings.Replace(dataStr, "\r\n", "\n", -1)
//
//	if w.newline {
//		w.newline = false
//		fmt.Fprintf(w.Writer, "%s", w.Prefix)
//	}
//
//	if strings.Contains(dataStr, "\n") {
//		lineCount := strings.Count(dataStr, "\n")
//
//		if dataStr[len(dataStr)-1:] == "\n" {
//			w.newline = true
//		}
//
//		if w.newline {
//			dataStr = strings.Replace(dataStr, "\n", "\n"+w.Prefix, lineCount-1)
//		} else {
//			dataStr = strings.Replace(dataStr, "\n", "\n"+w.Prefix, -1)
//		}
//
//		fmt.Fprintf(w.Writer, "%s", dataStr)
//
//	} else {
//		fmt.Fprintf(w.Writer, "%s", dataStr)
//	}
//
//	return len(data), nil
//}
<|endoftext|>