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

package main

import (
	"fmt"
	"log"
	"sort"
	"sync"
	"time"

	"github.com/jroimartin/gocui"
	"github.com/jroimartin/monmq"
)

const refreshTime = 1 * time.Second

var (
	supervisor *monmq.Supervisor
	mu         sync.Mutex
)

func cursorDown(g *gocui.Gui, v *gocui.View) error {
	if v != nil {
		cx, cy := v.Cursor()
		if err := v.SetCursor(cx, cy+1); err != nil {
			ox, oy := v.Origin()
			if err := v.SetOrigin(ox, oy+1); err != nil {
				return err
			}
		}
	}
	return nil
}

func cursorUp(g *gocui.Gui, v *gocui.View) error {
	if v != nil {
		ox, oy := v.Origin()
		cx, cy := v.Cursor()
		if err := v.SetCursor(cx, cy-1); err != nil && oy > 0 {
			if err := v.SetOrigin(ox, oy-1); err != nil {
				return err
			}
		}
	}
	return nil
}

func invoke(g *gocui.Gui, v *gocui.View, cmd monmq.Command) error {
	vside, err := g.View("side")
	if err != nil {
		return err
	}
	_, cy := vside.Cursor()
	selAgent, err := vside.Line(cy)
	if err != nil {
		selAgent = ""
	}
	if selAgent != "" {
		return supervisor.Invoke(cmd, selAgent)
	}
	return nil
}

func quit(g *gocui.Gui, v *gocui.View) error {
	return gocui.Quit
}

func keybindings(g *gocui.Gui) error {
	if err := g.SetKeybinding("side", gocui.KeyArrowDown, gocui.ModNone, cursorDown); err != nil {
		return err
	}
	if err := g.SetKeybinding("side", gocui.KeyArrowUp, gocui.ModNone, cursorUp); err != nil {
		return err
	}
	if err := g.SetKeybinding("side", 'k', gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error {
		return invoke(g, v, monmq.SoftShutdown)
	}); err != nil {
		return err
	}
	if err := g.SetKeybinding("side", 'K', gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error {
		return invoke(g, v, monmq.HardShutdown)
	}); err != nil {
		return err
	}
	if err := g.SetKeybinding("side", 'p', gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error {
		return invoke(g, v, monmq.Pause)
	}); err != nil {
		return err
	}
	if err := g.SetKeybinding("side", 'r', gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error {
		return invoke(g, v, monmq.Resume)
	}); err != nil {
		return err
	}
	if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
		return err
	}
	return nil
}

func layout(g *gocui.Gui) error {
	maxX, maxY := g.Size()
	if v, err := g.SetView("sideTitle", -1, -1, 30, 1); err != nil {
		if err != gocui.ErrorUnkView {
			return err
		}
		fmt.Fprintf(v, "On-line agents")
	}
	if v, err := g.SetView("side", -1, 1, 30, maxY); err != nil {
		if err != gocui.ErrorUnkView {
			return err
		}
		if err := g.SetCurrentView("side"); err != nil {
			return err
		}
		v.Highlight = true
	}
	if v, err := g.SetView("mainTitle", 30, -1, maxX, 1); err != nil {
		if err != gocui.ErrorUnkView {
			return err
		}
		fmt.Fprintf(v, "General information")
	}
	if v, err := g.SetView("main", 30, 1, maxX, maxY); err != nil {
		if err != gocui.ErrorUnkView {
			return err
		}
		v.Wrap = true
	}
	return updateData(g)
}

func main() {
	var err error

	g := gocui.NewGui()
	if err := g.Init(); err != nil {
		log.Fatalln(err)
	}
	defer g.Close()

	g.SetLayout(layout)
	if err := keybindings(g); err != nil {
		log.Fatalln(err)
	}
	g.SelBgColor = gocui.ColorGreen
	g.SelFgColor = gocui.ColorBlack
	g.ShowCursor = true

	supervisor = monmq.NewSupervisor("amqp://amqp_broker:5672",
		"mon-replies", "mon-exchange")
	if err := supervisor.Init(); err != nil {
		log.Fatalf("Init: %v", err)
	}
	defer supervisor.Shutdown()

	go func() {
		for {
			g.Flush()
			time.Sleep(refreshTime)
		}
	}()

	err = g.MainLoop()
	if err != nil && err != gocui.Quit {
		log.Fatalln(err)
	}
}

func updateData(g *gocui.Gui) error {
	mu.Lock()
	defer mu.Unlock()

	vside, err := g.View("side")
	if err != nil {
		return err
	}
	vmain, err := g.View("main")
	if err != nil {
		return err
	}
	vside.Clear()
	vmain.Clear()

	status := map[string]monmq.Status{}
	names := []string{}
	for _, st := range supervisor.Status() {
		status[st.Name] = st
		names = append(names, st.Name)
	}
	sort.Strings(names)

	for _, n := range names {
		fmt.Fprintf(vside, "%v\n", n)
	}

	_, cy := vside.Cursor()
	selAgent, err := vside.Line(cy)
	if err != nil {
		selAgent = ""
	}

	if agent, ok := status[selAgent]; ok {
		freeRam := float32(agent.Info.FreeRam) / float32(agent.Info.TotalRam) * float32(100)
		freeSwap := float32(agent.Info.FreeSwap) / float32(agent.Info.TotalSwap) * float32(100)

		fmt.Fprintf(vmain, "Agent name: %v\n", agent.Name)
		fmt.Fprintf(vmain, "Running: %v\n", agent.Running)
		fmt.Fprintf(vmain, "Version: %s\n", agent.Info.Version)
		fmt.Fprintf(vmain, "FreeRam: %f%%, FreeSwap: %f%%\n", freeRam, freeSwap)
		fmt.Fprintf(vmain, "CPU usage: %f%%\n", agent.Info.CPU)
		fmt.Fprintf(vmain, "Uptime: %s\n", agent.Info.Uptime)
		fmt.Fprintf(vmain, "Last heartbeat: %v\n", time.Since(agent.LastBeat))
		fmt.Fprintf(vmain, "Current tasks:\n")
		for i, t := range agent.Tasks {
			fmt.Fprintf(vmain, "%v. %v\n", i, t)
		}
	}

	return nil
}
<commit_msg>Add missing mutex lock/unlock in _examples/gui.go<commit_after>// Copyright 2015 The monmq Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"fmt"
	"log"
	"sort"
	"sync"
	"time"

	"github.com/jroimartin/gocui"
	"github.com/jroimartin/monmq"
)

const refreshTime = 1 * time.Second

var (
	supervisor *monmq.Supervisor
	mu         sync.Mutex
)

func cursorDown(g *gocui.Gui, v *gocui.View) error {
	if v != nil {
		cx, cy := v.Cursor()
		if err := v.SetCursor(cx, cy+1); err != nil {
			ox, oy := v.Origin()
			if err := v.SetOrigin(ox, oy+1); err != nil {
				return err
			}
		}
	}
	return nil
}

func cursorUp(g *gocui.Gui, v *gocui.View) error {
	if v != nil {
		ox, oy := v.Origin()
		cx, cy := v.Cursor()
		if err := v.SetCursor(cx, cy-1); err != nil && oy > 0 {
			if err := v.SetOrigin(ox, oy-1); err != nil {
				return err
			}
		}
	}
	return nil
}

func invoke(g *gocui.Gui, v *gocui.View, cmd monmq.Command) error {
	mu.Lock()
	defer mu.Unlock()

	vside, err := g.View("side")
	if err != nil {
		return err
	}
	_, cy := vside.Cursor()
	selAgent, err := vside.Line(cy)
	if err != nil {
		selAgent = ""
	}
	if selAgent != "" {
		return supervisor.Invoke(cmd, selAgent)
	}
	return nil
}

func quit(g *gocui.Gui, v *gocui.View) error {
	return gocui.Quit
}

func keybindings(g *gocui.Gui) error {
	if err := g.SetKeybinding("side", gocui.KeyArrowDown, gocui.ModNone, cursorDown); err != nil {
		return err
	}
	if err := g.SetKeybinding("side", gocui.KeyArrowUp, gocui.ModNone, cursorUp); err != nil {
		return err
	}
	if err := g.SetKeybinding("side", 'k', gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error {
		return invoke(g, v, monmq.SoftShutdown)
	}); err != nil {
		return err
	}
	if err := g.SetKeybinding("side", 'K', gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error {
		return invoke(g, v, monmq.HardShutdown)
	}); err != nil {
		return err
	}
	if err := g.SetKeybinding("side", 'p', gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error {
		return invoke(g, v, monmq.Pause)
	}); err != nil {
		return err
	}
	if err := g.SetKeybinding("side", 'r', gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error {
		return invoke(g, v, monmq.Resume)
	}); err != nil {
		return err
	}
	if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
		return err
	}
	return nil
}

func layout(g *gocui.Gui) error {
	maxX, maxY := g.Size()
	if v, err := g.SetView("sideTitle", -1, -1, 30, 1); err != nil {
		if err != gocui.ErrorUnkView {
			return err
		}
		fmt.Fprintf(v, "On-line agents")
	}
	if v, err := g.SetView("side", -1, 1, 30, maxY); err != nil {
		if err != gocui.ErrorUnkView {
			return err
		}
		if err := g.SetCurrentView("side"); err != nil {
			return err
		}
		v.Highlight = true
	}
	if v, err := g.SetView("mainTitle", 30, -1, maxX, 1); err != nil {
		if err != gocui.ErrorUnkView {
			return err
		}
		fmt.Fprintf(v, "General information")
	}
	if v, err := g.SetView("main", 30, 1, maxX, maxY); err != nil {
		if err != gocui.ErrorUnkView {
			return err
		}
		v.Wrap = true
	}
	return updateData(g)
}

func main() {
	var err error

	g := gocui.NewGui()
	if err := g.Init(); err != nil {
		log.Fatalln(err)
	}
	defer g.Close()

	g.SetLayout(layout)
	if err := keybindings(g); err != nil {
		log.Fatalln(err)
	}
	g.SelBgColor = gocui.ColorGreen
	g.SelFgColor = gocui.ColorBlack
	g.ShowCursor = true

	supervisor = monmq.NewSupervisor("amqp://amqp_broker:5672",
		"mon-replies", "mon-exchange")
	if err := supervisor.Init(); err != nil {
		log.Fatalf("Init: %v", err)
	}
	defer supervisor.Shutdown()

	go func() {
		for {
			g.Flush()
			time.Sleep(refreshTime)
		}
	}()

	err = g.MainLoop()
	if err != nil && err != gocui.Quit {
		log.Fatalln(err)
	}
}

func updateData(g *gocui.Gui) error {
	mu.Lock()
	defer mu.Unlock()

	vside, err := g.View("side")
	if err != nil {
		return err
	}
	vmain, err := g.View("main")
	if err != nil {
		return err
	}
	vside.Clear()
	vmain.Clear()

	status := map[string]monmq.Status{}
	names := []string{}
	for _, st := range supervisor.Status() {
		status[st.Name] = st
		names = append(names, st.Name)
	}
	sort.Strings(names)

	for _, n := range names {
		fmt.Fprintf(vside, "%v\n", n)
	}

	_, cy := vside.Cursor()
	selAgent, err := vside.Line(cy)
	if err != nil {
		selAgent = ""
	}

	if agent, ok := status[selAgent]; ok {
		freeRam := float32(agent.Info.FreeRam) / float32(agent.Info.TotalRam) * float32(100)
		freeSwap := float32(agent.Info.FreeSwap) / float32(agent.Info.TotalSwap) * float32(100)

		fmt.Fprintf(vmain, "Agent name: %v\n", agent.Name)
		fmt.Fprintf(vmain, "Running: %v\n", agent.Running)
		fmt.Fprintf(vmain, "Version: %s\n", agent.Info.Version)
		fmt.Fprintf(vmain, "FreeRam: %f%%, FreeSwap: %f%%\n", freeRam, freeSwap)
		fmt.Fprintf(vmain, "CPU usage: %f%%\n", agent.Info.CPU)
		fmt.Fprintf(vmain, "Uptime: %s\n", agent.Info.Uptime)
		fmt.Fprintf(vmain, "Last heartbeat: %v\n", time.Since(agent.LastBeat))
		fmt.Fprintf(vmain, "Current tasks:\n")
		for i, t := range agent.Tasks {
			fmt.Fprintf(vmain, "%v. %v\n", i, t)
		}
	}

	return nil
}
<|endoftext|>


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

package gltext

import (
	"errors"
	"github.com/golang/freetype"
	"github.com/golang/freetype/truetype"
	"golang.org/x/image/math/fixed"
	"image"
	"image/draw"
	"io"
	"io/ioutil"
	"sort"
)

// RuneRanges specify the rune ranges for ordered disjoint subsets of the ttf
// EG 32 - 127, 5000 - 6000 will created a more compact bitmap that holds the
// specified ranges of runes.
type RuneRange struct {
	Low, High rune
}

type RuneRanges []RuneRange

func (rr RuneRanges) Len() int           { return len(rr) }
func (rr RuneRanges) Swap(i, j int)      { rr[i], rr[j] = rr[j], rr[i] }
func (rr RuneRanges) Less(i, j int) bool { return rr[i].Low < rr[j].Low }

func (rr RuneRanges) Validate() bool {
	sort.Sort(rr)
	previousMax := rune(0)
	for _, r := range rr {
		if r.Low <= previousMax {
			return false
		}
		if r.Low > r.High {
			return false
		}
		previousMax = r.High
	}
	return true
}

// GetGlyphIndex returns the location of the glyph data within
// the compressed rune ranges covered by the font
// EG if runes 0-25, 100-110 are supported by the font then
// the actual location of 100 will be in position 26 in the png image
func (rr RuneRanges) GetGlyphIndex(char rune) rune {
	var index, offset rune
	index = -1
	for _, runes := range rr {
		if char >= runes.Low && char <= runes.High {
			index = char - runes.Low + offset
		}
		offset += runes.High - runes.Low + 1
	}
	return index
}

// http://www.freetype.org/freetype2/docs/tutorial/step2.html

// LoadTruetype loads a truetype font from the given stream and
// applies the given font scale in points.
//
// The low and high values determine the lower and upper rune limits
// we should load for this font. For standard ASCII this would be: 32, 127.
func NewTruetypeFontConfig(r io.Reader, scale fixed.Int26_6, runeRanges RuneRanges, runesPerRow fixed.Int26_6) (*FontConfig, error) {
	if !runeRanges.Validate() {
		return nil, errors.New("Invalid rune ranges supplied.")
	}

	data, err := ioutil.ReadAll(r)
	if err != nil {
		return nil, err
	}

	// Read the truetype font.
	ttf, err := truetype.Parse(data)
	if err != nil {
		return nil, err
	}

	// Create our FontConfig type.
	fc := &FontConfig{}
	length := rune(0)
	for _, r := range runeRanges {
		length += r.High - r.Low + 1
	}
	fc.RuneRanges = runeRanges
	fc.Glyphs = make(Charset, int(length))

	// Create an image, large enough to store all requested glyphs.
	// The resulting image is set to power of 2 dimensions so it might be wise to adjust the runesPerRow
	// parameter to ensure that unnecessary space isn't created based on the character set being used
	gc := fixed.Int26_6(len(fc.Glyphs))
	runesPerCol := (gc / runesPerRow) + 1

	gb := ttf.Bounds(scale)
	gw := (gb.Max.X - gb.Min.X)
	gh := (gb.Max.Y - gb.Min.Y)

	iw := Pow2(uint32(gw * runesPerRow))
	ih := Pow2(uint32(gh * runesPerCol))

	fg, bg := image.White, image.Transparent
	rect := image.Rect(0, 0, int(iw), int(ih))
	fc.Image = image.NewNRGBA(rect)
	draw.Draw(fc.Image, fc.Image.Bounds(), bg, image.ZP, draw.Src)

	// Use a freetype context to do the drawing.
	c := freetype.NewContext()
	c.SetDPI(72) // Do not change this.  It is required in order to have a properly aligned bounding box!!!
	c.SetFont(ttf)
	c.SetFontSize(float64(scale))
	c.SetClip(fc.Image.Bounds())
	c.SetDst(fc.Image)
	c.SetSrc(fg)

	// Iterate over all relevant glyphs in the truetype font and draw them all to the image buffer
	// Add Glyph objects to track various glyph values
	var gi fixed.Int26_6
	var gx, gy fixed.Int26_6

	for _, runeRange := range fc.RuneRanges {
		for ch := runeRange.Low; ch <= runeRange.High; ch++ {
			index := ttf.Index(ch)
			metric := ttf.HMetric(scale, index)

			fc.Glyphs[gi].Advance = int(metric.AdvanceWidth)
			fc.Glyphs[gi].X = int(gx)
			fc.Glyphs[gi].Y = int(gy)
			fc.Glyphs[gi].Width = int(gw)
			fc.Glyphs[gi].Height = int(gh)

			pt := freetype.Pt(int(gx), int(gy)+int(c.PointToFixed(float64(scale))>>6))
			c.DrawString(string(ch), pt)

			if gi%runesPerRow == 0 {
				if gi > 0 {
					gx = 0
					gy += gh
				}
			} else {
				gx += gw
			}
			gi++
		}
	}
	return fc, nil
}

func LoadTruetypeFontConfig(rootPath string) (*FontConfig, error) {
	var fc *FontConfig
	err := fc.Load(rootPath)
	if err != nil {
		return nil, err
	}
	return fc, nil
}
<commit_msg>Bug fix when loading from a pointer object.<commit_after>// Copyright 2012 The go-gl Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gltext

import (
	"errors"
	"github.com/golang/freetype"
	"github.com/golang/freetype/truetype"
	"golang.org/x/image/math/fixed"
	"image"
	"image/draw"
	"io"
	"io/ioutil"
	"sort"
)

// RuneRanges specify the rune ranges for ordered disjoint subsets of the ttf
// EG 32 - 127, 5000 - 6000 will created a more compact bitmap that holds the
// specified ranges of runes.
type RuneRange struct {
	Low, High rune
}

type RuneRanges []RuneRange

func (rr RuneRanges) Len() int           { return len(rr) }
func (rr RuneRanges) Swap(i, j int)      { rr[i], rr[j] = rr[j], rr[i] }
func (rr RuneRanges) Less(i, j int) bool { return rr[i].Low < rr[j].Low }

func (rr RuneRanges) Validate() bool {
	sort.Sort(rr)
	previousMax := rune(0)
	for _, r := range rr {
		if r.Low <= previousMax {
			return false
		}
		if r.Low > r.High {
			return false
		}
		previousMax = r.High
	}
	return true
}

// GetGlyphIndex returns the location of the glyph data within
// the compressed rune ranges covered by the font
// EG if runes 0-25, 100-110 are supported by the font then
// the actual location of 100 will be in position 26 in the png image
func (rr RuneRanges) GetGlyphIndex(char rune) rune {
	var index, offset rune
	index = -1
	for _, runes := range rr {
		if char >= runes.Low && char <= runes.High {
			index = char - runes.Low + offset
		}
		offset += runes.High - runes.Low + 1
	}
	return index
}

// http://www.freetype.org/freetype2/docs/tutorial/step2.html

// LoadTruetype loads a truetype font from the given stream and
// applies the given font scale in points.
//
// The low and high values determine the lower and upper rune limits
// we should load for this font. For standard ASCII this would be: 32, 127.
func NewTruetypeFontConfig(r io.Reader, scale fixed.Int26_6, runeRanges RuneRanges, runesPerRow fixed.Int26_6) (*FontConfig, error) {
	if !runeRanges.Validate() {
		return nil, errors.New("Invalid rune ranges supplied.")
	}

	data, err := ioutil.ReadAll(r)
	if err != nil {
		return nil, err
	}

	// Read the truetype font.
	ttf, err := truetype.Parse(data)
	if err != nil {
		return nil, err
	}

	// Create our FontConfig type.
	fc := &FontConfig{}
	length := rune(0)
	for _, r := range runeRanges {
		length += r.High - r.Low + 1
	}
	fc.RuneRanges = runeRanges
	fc.Glyphs = make(Charset, int(length))

	// Create an image, large enough to store all requested glyphs.
	// The resulting image is set to power of 2 dimensions so it might be wise to adjust the runesPerRow
	// parameter to ensure that unnecessary space isn't created based on the character set being used
	gc := fixed.Int26_6(len(fc.Glyphs))
	runesPerCol := (gc / runesPerRow) + 1

	gb := ttf.Bounds(scale)
	gw := (gb.Max.X - gb.Min.X)
	gh := (gb.Max.Y - gb.Min.Y)

	iw := Pow2(uint32(gw * runesPerRow))
	ih := Pow2(uint32(gh * runesPerCol))

	fg, bg := image.White, image.Transparent
	rect := image.Rect(0, 0, int(iw), int(ih))
	fc.Image = image.NewNRGBA(rect)
	draw.Draw(fc.Image, fc.Image.Bounds(), bg, image.ZP, draw.Src)

	// Use a freetype context to do the drawing.
	c := freetype.NewContext()
	c.SetDPI(72) // Do not change this.  It is required in order to have a properly aligned bounding box!!!
	c.SetFont(ttf)
	c.SetFontSize(float64(scale))
	c.SetClip(fc.Image.Bounds())
	c.SetDst(fc.Image)
	c.SetSrc(fg)

	// Iterate over all relevant glyphs in the truetype font and draw them all to the image buffer
	// Add Glyph objects to track various glyph values
	var gi fixed.Int26_6
	var gx, gy fixed.Int26_6

	for _, runeRange := range fc.RuneRanges {
		for ch := runeRange.Low; ch <= runeRange.High; ch++ {
			index := ttf.Index(ch)
			metric := ttf.HMetric(scale, index)

			fc.Glyphs[gi].Advance = int(metric.AdvanceWidth)
			fc.Glyphs[gi].X = int(gx)
			fc.Glyphs[gi].Y = int(gy)
			fc.Glyphs[gi].Width = int(gw)
			fc.Glyphs[gi].Height = int(gh)

			pt := freetype.Pt(int(gx), int(gy)+int(c.PointToFixed(float64(scale))>>6))
			c.DrawString(string(ch), pt)

			if gi%runesPerRow == 0 {
				if gi > 0 {
					gx = 0
					gy += gh
				}
			} else {
				gx += gw
			}
			gi++
		}
	}
	return fc, nil
}

func LoadTruetypeFontConfig(rootPath string) (*FontConfig, error) {
	fc := &FontConfig{}
	err := fc.Load(rootPath)
	if err != nil {
		return nil, err
	}
	return fc, nil
}
<|endoftext|>


<commit_before>//Package ts3sqlib provides a simple interface for the TeamSpeak3 ServerQuery.
package ts3sqlib

import (
	"bufio"
	"fmt"
	"log"
	"net"
	"os"
	"strings"
	"sync"
)

const (
	stdPort string = ":10011"
)

var (
	//StdoutLogger is the standard logger that prints to stdout.
	StdoutLogger = log.New(os.Stdout, "", log.LstdFlags)
	//StderrLogger is the standard logger that prints to stderr.
	StderrLogger = log.New(os.Stderr, "", log.LstdFlags)
)

//SqConn contains the connection to a ts3 server.
type SqConn struct {
	conn       net.Conn
	logger     *log.Logger
	sendMutex  *sync.Mutex
	receiving  bool
	recvNotify chan string
	recvChan   chan string
	closed     chan bool
	//WelcomeMsg contains the welcome message from the ts3 server
	WelcomeMsg string
}

//Dial creates a new SqConn and connects to the ts3 server with the given
//address and returns a pointer to it and an error.
//If the logger is nil, then the standard logger is used.
func Dial(address string, logger *log.Logger) (conn *SqConn, err error) {
	conn = nil

	if !strings.Contains(address, ":") {
		address += stdPort
	}

	connection, err := net.Dial("tcp", address)
	if err != nil {
		return
	}

	conn = &SqConn{
		conn:       connection,
		logger:     logger,
		sendMutex:  &sync.Mutex{},
		receiving:  true,
		recvNotify: make(chan string),
		recvChan:   make(chan string),
		closed:     make(chan bool),
		WelcomeMsg: "",
	}

	go conn.recv() //goroutine that splits the incoming messages into notify
	//and normal messages.

	if !strings.Contains(<-conn.recvChan, "TS3") {
		conn = nil
		err = fmt.Errorf("no connection to a ts3-server-query")
		return
	}

	conn.WelcomeMsg = <-conn.recvChan

	return
}

func (c *SqConn) recv() {
	var err error
	line := ""
	scan := bufio.NewScanner(c.conn)

	for c.receiving {
		//read line
		if !scan.Scan() {
			if err = scan.Err(); err != nil && c.logger != nil {
				c.logger.Print(err)
			}
			c.receiving = false
			c.closed <- true
			break
		}

		line = scan.Text()
		line = strings.Replace(line, string([]byte{13}), "", -1)

		if err = scan.Err(); err != nil {
			if c.logger != nil {
				c.logger.Print(err)
			}
			continue
		}

		//decide if its notify or not and put it to the correct channel
		if strings.HasPrefix(line, "notify") {
			c.recvNotify <- line
		} else {
			c.recvChan <- line
		}
	}
}

//RecvNotify returns a notify message or blocks until one arrives.
func (c *SqConn) RecvNotify() (answer string, err error) {
	answer = ""
	err = nil

	answer = <-c.recvNotify
	return
}

//Close closes the connection to the ts3 server.
func (c *SqConn) Close() {
	c.receiving = false
	c.conn.Close()
}

//IsClosed checks if the connection is closed
func (c *SqConn) IsClosed() bool {
	return c.receiving
}

//Send sends a message to the server and returns the answer and an error.
func (c *SqConn) Send(msg string) (answer string, err error) {
	if c == nil {
		fmt.Errorf("nil pointer error")
		return
	}

	c.sendMutex.Lock()
	defer c.sendMutex.Unlock()

	//msg must have a newline at the end
	if !strings.HasSuffix(msg, "\n") {
		msg += "\n"
	}

	if !c.receiving {
		answer = ""
		err = fmt.Errorf("connection closed")
		return
	}

	if c.logger != nil {
		c.logger.Print("send: ", msg)
	}

	answer = ""

	_, err = c.conn.Write([]byte(msg)) //If the return value is smaller than
	if err != nil {                    //the length of msg, it's an error.
		return
	}

	line := ""
	err = nil

	for !isError(line) && c.receiving {
		select {
		case line = <-c.recvChan:
			if isError(line) {
				err = toError(line)
				break
			}

			answer += line + "\n"

		case <-c.closed:
			break
		}
	}

	if err == nil {
		err = NewError(-1, "connection closed", "")
	}

	if MsgEndError.Equals(err) {
		err = nil
	}

	//logging
	if c.logger != nil {
		if answer != "" && answer != "\n" {
			c.logger.Println(answer)
		}
		if err != nil {
			c.logger.Println(err)
		}
	}

	return
}
<commit_msg>bugfix in IsClosed<commit_after>//Package ts3sqlib provides a simple interface for the TeamSpeak3 ServerQuery.
package ts3sqlib

import (
	"bufio"
	"fmt"
	"log"
	"net"
	"os"
	"strings"
	"sync"
)

const (
	stdPort string = ":10011"
)

var (
	//StdoutLogger is the standard logger that prints to stdout.
	StdoutLogger = log.New(os.Stdout, "", log.LstdFlags)
	//StderrLogger is the standard logger that prints to stderr.
	StderrLogger = log.New(os.Stderr, "", log.LstdFlags)
)

//SqConn contains the connection to a ts3 server.
type SqConn struct {
	conn       net.Conn
	logger     *log.Logger
	sendMutex  *sync.Mutex
	receiving  bool
	recvNotify chan string
	recvChan   chan string
	closed     chan bool
	//WelcomeMsg contains the welcome message from the ts3 server
	WelcomeMsg string
}

//Dial creates a new SqConn and connects to the ts3 server with the given
//address and returns a pointer to it and an error.
//If the logger is nil, then the standard logger is used.
func Dial(address string, logger *log.Logger) (conn *SqConn, err error) {
	conn = nil

	if !strings.Contains(address, ":") {
		address += stdPort
	}

	connection, err := net.Dial("tcp", address)
	if err != nil {
		return
	}

	conn = &SqConn{
		conn:       connection,
		logger:     logger,
		sendMutex:  &sync.Mutex{},
		receiving:  true,
		recvNotify: make(chan string),
		recvChan:   make(chan string),
		closed:     make(chan bool),
		WelcomeMsg: "",
	}

	go conn.recv() //goroutine that splits the incoming messages into notify
	//and normal messages.

	if !strings.Contains(<-conn.recvChan, "TS3") {
		conn = nil
		err = fmt.Errorf("no connection to a ts3-server-query")
		return
	}

	conn.WelcomeMsg = <-conn.recvChan

	return
}

func (c *SqConn) recv() {
	var err error
	line := ""
	scan := bufio.NewScanner(c.conn)

	for c.receiving {
		//read line
		if !scan.Scan() {
			if err = scan.Err(); err != nil && c.logger != nil {
				c.logger.Print(err)
			}
			c.receiving = false
			c.closed <- true
			break
		}

		line = scan.Text()
		line = strings.Replace(line, string([]byte{13}), "", -1)

		if err = scan.Err(); err != nil {
			if c.logger != nil {
				c.logger.Print(err)
			}
			continue
		}

		//decide if its notify or not and put it to the correct channel
		if strings.HasPrefix(line, "notify") {
			c.recvNotify <- line
		} else {
			c.recvChan <- line
		}
	}
}

//RecvNotify returns a notify message or blocks until one arrives.
func (c *SqConn) RecvNotify() (answer string, err error) {
	answer = ""
	err = nil

	answer = <-c.recvNotify
	return
}

//Close closes the connection to the ts3 server.
func (c *SqConn) Close() {
	c.receiving = false
	c.conn.Close()
}

//IsClosed checks if the connection is closed
func (c *SqConn) IsClosed() bool {
	return !c.receiving
}

//Send sends a message to the server and returns the answer and an error.
func (c *SqConn) Send(msg string) (answer string, err error) {
	if c == nil {
		fmt.Errorf("nil pointer error")
		return
	}

	c.sendMutex.Lock()
	defer c.sendMutex.Unlock()

	//msg must have a newline at the end
	if !strings.HasSuffix(msg, "\n") {
		msg += "\n"
	}

	if !c.receiving {
		answer = ""
		err = fmt.Errorf("connection closed")
		return
	}

	if c.logger != nil {
		c.logger.Print("send: ", msg)
	}

	answer = ""

	_, err = c.conn.Write([]byte(msg)) //If the return value is smaller than
	if err != nil {                    //the length of msg, it's an error.
		return
	}

	line := ""
	err = nil

	for !isError(line) && c.receiving {
		select {
		case line = <-c.recvChan:
			if isError(line) {
				err = toError(line)
				break
			}

			answer += line + "\n"

		case <-c.closed:
			break
		}
	}

	if err == nil {
		err = NewError(-1, "connection closed", "")
	}

	if MsgEndError.Equals(err) {
		err = nil
	}

	//logging
	if c.logger != nil {
		if answer != "" && answer != "\n" {
			c.logger.Println(answer)
		}
		if err != nil {
			c.logger.Println(err)
		}
	}

	return
}
<|endoftext|>


<commit_before>package aggregated_logging

import (
	"errors"
	"fmt"
	"net/url"

	kapi "k8s.io/kubernetes/pkg/api"
	kapisext "k8s.io/kubernetes/pkg/apis/extensions"
	kclient "k8s.io/kubernetes/pkg/client/unversioned"
	"k8s.io/kubernetes/pkg/labels"

	authapi "github.com/openshift/origin/pkg/authorization/api"
	"github.com/openshift/origin/pkg/client"
	configapi "github.com/openshift/origin/pkg/cmd/server/api"
	deployapi "github.com/openshift/origin/pkg/deploy/api"
	hostdiag "github.com/openshift/origin/pkg/diagnostics/host"
	"github.com/openshift/origin/pkg/diagnostics/types"
	routesapi "github.com/openshift/origin/pkg/route/api"
)

// AggregatedLogging is a Diagnostic to check the configurations
// and general integration of the OpenShift stack
// for aggregating container logs
// https://github.com/openshift/origin-aggregated-logging
type AggregatedLogging struct {
	masterConfig     *configapi.MasterConfig
	MasterConfigFile string
	OsClient         *client.Client
	KubeClient       *kclient.Client
	result           types.DiagnosticResult
}

const (
	AggregatedLoggingName = "AggregatedLogging"

	loggingInfraKey = "logging-infra"
	componentKey    = "component"
	providerKey     = "provider"
	openshiftValue  = "openshift"

	fluentdServiceAccountName = "aggregated-logging-fluentd"
)

var loggingSelector = labels.Set{loggingInfraKey: "support"}

//NewAggregatedLogging returns the AggregatedLogging Diagnostic
func NewAggregatedLogging(masterConfigFile string, kclient *kclient.Client, osclient *client.Client) *AggregatedLogging {
	return &AggregatedLogging{nil, masterConfigFile, osclient, kclient, types.NewDiagnosticResult(AggregatedLoggingName)}
}

func (d *AggregatedLogging) getScc(name string) (*kapi.SecurityContextConstraints, error) {
	return d.KubeClient.SecurityContextConstraints().Get(name)
}

func (d *AggregatedLogging) getClusterRoleBinding(name string) (*authapi.ClusterRoleBinding, error) {
	return d.OsClient.ClusterRoleBindings().Get(name)
}

func (d *AggregatedLogging) routes(project string, options kapi.ListOptions) (*routesapi.RouteList, error) {
	return d.OsClient.Routes(project).List(options)
}

func (d *AggregatedLogging) serviceAccounts(project string, options kapi.ListOptions) (*kapi.ServiceAccountList, error) {
	return d.KubeClient.ServiceAccounts(project).List(options)
}

func (d *AggregatedLogging) services(project string, options kapi.ListOptions) (*kapi.ServiceList, error) {
	return d.KubeClient.Services(project).List(options)
}

func (d *AggregatedLogging) endpointsForService(project string, service string) (*kapi.Endpoints, error) {
	return d.KubeClient.Endpoints(project).Get(service)
}

func (d *AggregatedLogging) daemonsets(project string, options kapi.ListOptions) (*kapisext.DaemonSetList, error) {
	return d.KubeClient.DaemonSets(project).List(kapi.ListOptions{LabelSelector: loggingInfraFluentdSelector.AsSelector()})
}

func (d *AggregatedLogging) nodes(options kapi.ListOptions) (*kapi.NodeList, error) {
	return d.KubeClient.Nodes().List(kapi.ListOptions{})
}

func (d *AggregatedLogging) pods(project string, options kapi.ListOptions) (*kapi.PodList, error) {
	return d.KubeClient.Pods(project).List(options)
}
func (d *AggregatedLogging) deploymentconfigs(project string, options kapi.ListOptions) (*deployapi.DeploymentConfigList, error) {
	return d.OsClient.DeploymentConfigs(project).List(options)
}

func (d *AggregatedLogging) Info(id string, message string) {
	d.result.Info(id, message)
}

func (d *AggregatedLogging) Error(id string, err error, message string) {
	d.result.Error(id, err, message)
}

func (d *AggregatedLogging) Debug(id string, message string) {
	d.result.Debug(id, message)
}

func (d *AggregatedLogging) Warn(id string, err error, message string) {
	d.result.Warn(id, err, message)
}

func (d *AggregatedLogging) Name() string {
	return AggregatedLoggingName
}

func (d *AggregatedLogging) Description() string {
	return "Check aggregated logging integration for proper configuration"
}

func (d *AggregatedLogging) CanRun() (bool, error) {
	if len(d.MasterConfigFile) == 0 {
		return false, errors.New("No master config file was provided")
	}
	if d.OsClient == nil {
		return false, errors.New("Config must include a cluster-admin context to run this diagnostic")
	}
	if d.KubeClient == nil {
		return false, errors.New("Config must include a cluster-admin context to run this diagnostic")
	}
	var err error
	d.masterConfig, err = hostdiag.GetMasterConfig(d.result, d.MasterConfigFile)
	if err != nil {
		return false, errors.New("Unreadable master config; skipping this diagnostic.")
	}
	return true, nil
}

func (d *AggregatedLogging) Check() types.DiagnosticResult {
	project := retrieveLoggingProject(d.result, d.masterConfig, d.OsClient)
	if len(project) != 0 {
		checkServiceAccounts(d, d, project)
		checkClusterRoleBindings(d, d, project)
		checkSccs(d, d, project)
		checkDeploymentConfigs(d, d, project)
		checkDaemonSets(d, d, project)
		checkServices(d, d, project)
		checkRoutes(d, d, project)
		checkKibana(d.result, d.OsClient, d.KubeClient, project)
	}
	return d.result
}

const projectNodeSelectorWarning = `
The project '%[1]s' was found with either a missing or non-empty node selector annotation.
This could keep Fluentd from running on certain nodes and collecting logs from the entire cluster.
You can correct it by editing the project:

  oc edit namespace %[1]s

and updating the annotation:

  'openshift.io/node-selector' : ""

`

func retrieveLoggingProject(r types.DiagnosticResult, masterCfg *configapi.MasterConfig, osClient *client.Client) string {
	r.Debug("AGL0010", fmt.Sprintf("masterConfig.AssetConfig.LoggingPublicURL: '%s'", masterCfg.AssetConfig.LoggingPublicURL))
	projectName := ""
	if len(masterCfg.AssetConfig.LoggingPublicURL) == 0 {
		r.Debug("AGL0017", "masterConfig.AssetConfig.LoggingPublicURL is empty")
		return projectName
	}

	loggingUrl, err := url.Parse(masterCfg.AssetConfig.LoggingPublicURL)
	if err != nil {
		r.Error("AGL0011", err, fmt.Sprintf("Unable to parse the loggingPublicURL from the masterConfig '%s'", masterCfg.AssetConfig.LoggingPublicURL))
		return projectName
	}

	routeList, err := osClient.Routes(kapi.NamespaceAll).List(kapi.ListOptions{LabelSelector: loggingSelector.AsSelector()})
	if err != nil {
		r.Error("AGL0012", err, fmt.Sprintf("There was an error while trying to find the route associated with '%s' which is probably transient: %s", loggingUrl, err))
		return projectName
	}

	for _, route := range routeList.Items {
		r.Debug("AGL0013", fmt.Sprintf("Comparing URL to route.Spec.Host: %s", route.Spec.Host))
		if loggingUrl.Host == route.Spec.Host {
			if len(projectName) == 0 {
				projectName = route.ObjectMeta.Namespace
				r.Info("AGL0015", fmt.Sprintf("Found route '%s' matching logging URL '%s' in project: '%s'", route.ObjectMeta.Name, loggingUrl.Host, projectName))
			} else {
				r.Warn("AGL0019", nil, fmt.Sprintf("Found additional route '%s' matching logging URL '%s' in project: '%s'.  This could mean you have multiple logging deployments.", route.ObjectMeta.Name, loggingUrl.Host, projectName))
			}
		}
	}
	if len(projectName) == 0 {
		message := fmt.Sprintf("Unable to find a route matching the loggingPublicURL defined in the master config '%s'. Check that the URL is correct and aggregated logging is deployed.", loggingUrl)
		r.Error("AGL0014", errors.New(message), message)
		return ""
	}
	project, err := osClient.Projects().Get(projectName)
	if err != nil {
		r.Error("AGL0018", err, fmt.Sprintf("There was an error retrieving project '%s' which is most likely a transient error: %s", projectName, err))
		return ""
	}
	nodeSelector, ok := project.ObjectMeta.Annotations["openshift.io/node-selector"]
	if !ok || len(nodeSelector) != 0 {
		r.Warn("AGL0030", nil, fmt.Sprintf(projectNodeSelectorWarning, projectName))
	}
	return projectName
}
<commit_msg>diagnostics: clarify when logging not configured<commit_after>package aggregated_logging

import (
	"errors"
	"fmt"
	"net/url"

	kapi "k8s.io/kubernetes/pkg/api"
	kapisext "k8s.io/kubernetes/pkg/apis/extensions"
	kclient "k8s.io/kubernetes/pkg/client/unversioned"
	"k8s.io/kubernetes/pkg/labels"

	authapi "github.com/openshift/origin/pkg/authorization/api"
	"github.com/openshift/origin/pkg/client"
	configapi "github.com/openshift/origin/pkg/cmd/server/api"
	deployapi "github.com/openshift/origin/pkg/deploy/api"
	hostdiag "github.com/openshift/origin/pkg/diagnostics/host"
	"github.com/openshift/origin/pkg/diagnostics/types"
	routesapi "github.com/openshift/origin/pkg/route/api"
)

// AggregatedLogging is a Diagnostic to check the configurations
// and general integration of the OpenShift stack
// for aggregating container logs
// https://github.com/openshift/origin-aggregated-logging
type AggregatedLogging struct {
	masterConfig     *configapi.MasterConfig
	MasterConfigFile string
	OsClient         *client.Client
	KubeClient       *kclient.Client
	result           types.DiagnosticResult
}

const (
	AggregatedLoggingName = "AggregatedLogging"

	loggingInfraKey = "logging-infra"
	componentKey    = "component"
	providerKey     = "provider"
	openshiftValue  = "openshift"

	fluentdServiceAccountName = "aggregated-logging-fluentd"
)

var loggingSelector = labels.Set{loggingInfraKey: "support"}

//NewAggregatedLogging returns the AggregatedLogging Diagnostic
func NewAggregatedLogging(masterConfigFile string, kclient *kclient.Client, osclient *client.Client) *AggregatedLogging {
	return &AggregatedLogging{nil, masterConfigFile, osclient, kclient, types.NewDiagnosticResult(AggregatedLoggingName)}
}

func (d *AggregatedLogging) getScc(name string) (*kapi.SecurityContextConstraints, error) {
	return d.KubeClient.SecurityContextConstraints().Get(name)
}

func (d *AggregatedLogging) getClusterRoleBinding(name string) (*authapi.ClusterRoleBinding, error) {
	return d.OsClient.ClusterRoleBindings().Get(name)
}

func (d *AggregatedLogging) routes(project string, options kapi.ListOptions) (*routesapi.RouteList, error) {
	return d.OsClient.Routes(project).List(options)
}

func (d *AggregatedLogging) serviceAccounts(project string, options kapi.ListOptions) (*kapi.ServiceAccountList, error) {
	return d.KubeClient.ServiceAccounts(project).List(options)
}

func (d *AggregatedLogging) services(project string, options kapi.ListOptions) (*kapi.ServiceList, error) {
	return d.KubeClient.Services(project).List(options)
}

func (d *AggregatedLogging) endpointsForService(project string, service string) (*kapi.Endpoints, error) {
	return d.KubeClient.Endpoints(project).Get(service)
}

func (d *AggregatedLogging) daemonsets(project string, options kapi.ListOptions) (*kapisext.DaemonSetList, error) {
	return d.KubeClient.DaemonSets(project).List(kapi.ListOptions{LabelSelector: loggingInfraFluentdSelector.AsSelector()})
}

func (d *AggregatedLogging) nodes(options kapi.ListOptions) (*kapi.NodeList, error) {
	return d.KubeClient.Nodes().List(kapi.ListOptions{})
}

func (d *AggregatedLogging) pods(project string, options kapi.ListOptions) (*kapi.PodList, error) {
	return d.KubeClient.Pods(project).List(options)
}
func (d *AggregatedLogging) deploymentconfigs(project string, options kapi.ListOptions) (*deployapi.DeploymentConfigList, error) {
	return d.OsClient.DeploymentConfigs(project).List(options)
}

func (d *AggregatedLogging) Info(id string, message string) {
	d.result.Info(id, message)
}

func (d *AggregatedLogging) Error(id string, err error, message string) {
	d.result.Error(id, err, message)
}

func (d *AggregatedLogging) Debug(id string, message string) {
	d.result.Debug(id, message)
}

func (d *AggregatedLogging) Warn(id string, err error, message string) {
	d.result.Warn(id, err, message)
}

func (d *AggregatedLogging) Name() string {
	return AggregatedLoggingName
}

func (d *AggregatedLogging) Description() string {
	return "Check aggregated logging integration for proper configuration"
}

func (d *AggregatedLogging) CanRun() (bool, error) {
	if len(d.MasterConfigFile) == 0 {
		return false, errors.New("No master config file was provided")
	}
	if d.OsClient == nil {
		return false, errors.New("Config must include a cluster-admin context to run this diagnostic")
	}
	if d.KubeClient == nil {
		return false, errors.New("Config must include a cluster-admin context to run this diagnostic")
	}
	var err error
	d.masterConfig, err = hostdiag.GetMasterConfig(d.result, d.MasterConfigFile)
	if err != nil {
		return false, errors.New("Master configuration is unreadable")
	}
	if d.masterConfig.AssetConfig.LoggingPublicURL == "" {
		return false, errors.New("No LoggingPublicURL is defined in the master configuration")
	}
	return true, nil
}

func (d *AggregatedLogging) Check() types.DiagnosticResult {
	project := retrieveLoggingProject(d.result, d.masterConfig, d.OsClient)
	if len(project) != 0 {
		checkServiceAccounts(d, d, project)
		checkClusterRoleBindings(d, d, project)
		checkSccs(d, d, project)
		checkDeploymentConfigs(d, d, project)
		checkDaemonSets(d, d, project)
		checkServices(d, d, project)
		checkRoutes(d, d, project)
		checkKibana(d.result, d.OsClient, d.KubeClient, project)
	}
	return d.result
}

const projectNodeSelectorWarning = `
The project '%[1]s' was found with either a missing or non-empty node selector annotation.
This could keep Fluentd from running on certain nodes and collecting logs from the entire cluster.
You can correct it by editing the project:

  oc edit namespace %[1]s

and updating the annotation:

  'openshift.io/node-selector' : ""

`

func retrieveLoggingProject(r types.DiagnosticResult, masterCfg *configapi.MasterConfig, osClient *client.Client) string {
	r.Debug("AGL0010", fmt.Sprintf("masterConfig.AssetConfig.LoggingPublicURL: '%s'", masterCfg.AssetConfig.LoggingPublicURL))
	projectName := ""
	if len(masterCfg.AssetConfig.LoggingPublicURL) == 0 {
		r.Debug("AGL0017", "masterConfig.AssetConfig.LoggingPublicURL is empty")
		return projectName
	}

	loggingUrl, err := url.Parse(masterCfg.AssetConfig.LoggingPublicURL)
	if err != nil {
		r.Error("AGL0011", err, fmt.Sprintf("Unable to parse the loggingPublicURL from the masterConfig '%s'", masterCfg.AssetConfig.LoggingPublicURL))
		return projectName
	}

	routeList, err := osClient.Routes(kapi.NamespaceAll).List(kapi.ListOptions{LabelSelector: loggingSelector.AsSelector()})
	if err != nil {
		r.Error("AGL0012", err, fmt.Sprintf("There was an error while trying to find the route associated with '%s' which is probably transient: %s", loggingUrl, err))
		return projectName
	}

	for _, route := range routeList.Items {
		r.Debug("AGL0013", fmt.Sprintf("Comparing URL to route.Spec.Host: %s", route.Spec.Host))
		if loggingUrl.Host == route.Spec.Host {
			if len(projectName) == 0 {
				projectName = route.ObjectMeta.Namespace
				r.Info("AGL0015", fmt.Sprintf("Found route '%s' matching logging URL '%s' in project: '%s'", route.ObjectMeta.Name, loggingUrl.Host, projectName))
			} else {
				r.Warn("AGL0019", nil, fmt.Sprintf("Found additional route '%s' matching logging URL '%s' in project: '%s'.  This could mean you have multiple logging deployments.", route.ObjectMeta.Name, loggingUrl.Host, projectName))
			}
		}
	}
	if len(projectName) == 0 {
		message := fmt.Sprintf("Unable to find a route matching the loggingPublicURL defined in the master config '%s'. Check that the URL is correct and aggregated logging is deployed.", loggingUrl)
		r.Error("AGL0014", errors.New(message), message)
		return ""
	}
	project, err := osClient.Projects().Get(projectName)
	if err != nil {
		r.Error("AGL0018", err, fmt.Sprintf("There was an error retrieving project '%s' which is most likely a transient error: %s", projectName, err))
		return ""
	}
	nodeSelector, ok := project.ObjectMeta.Annotations["openshift.io/node-selector"]
	if !ok || len(nodeSelector) != 0 {
		r.Warn("AGL0030", nil, fmt.Sprintf(projectNodeSelectorWarning, projectName))
	}
	return projectName
}
<|endoftext|>


<commit_before>package gist8018045

import (
	"fmt"
	"go/build"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/shurcooL/go-goon"

	. "github.com/shurcooL/go/gists/gist5504644"
	. "github.com/shurcooL/go/gists/gist7480523"
	. "github.com/shurcooL/go/gists/gist7519227"
)

var _ = fmt.Print
var _ = goon.Dump

func rec(out chan<- ImportPathFound, importPathFound ImportPathFound) {
	if goPackage := GoPackageFromImportPathFound(importPathFound); goPackage != nil {
		out <- importPathFound
	}

	entries, err := ioutil.ReadDir(importPathFound.FullPath())
	if err == nil {
		for _, v := range entries {
			if v.IsDir() && !strings.HasPrefix(v.Name(), ".") {
				rec(out, NewImportPathFound(filepath.Join(importPathFound.ImportPath(), v.Name()), importPathFound.GopathEntry()))
			}
		}
	}
}

func isDir(path string) bool {
	fi, err := os.Stat(path)
	return err == nil && fi.IsDir()
}

//var skipGopath = map[string]bool{"/Users/Dmitri/Local/Ongoing/Conception/GoLand": false, "/Users/Dmitri/Dropbox/Work/2013/GoLanding": false}

// Deprecated in favor of GetGoPackages(out chan<- *GoPackage).
/*func GetGoPackages(out chan<- ImportPathFound) {
	getGoPackagesB(out)
}*/

func getGoPackagesA(out chan<- ImportPathFound) {
	gopathEntries := filepath.SplitList(build.Default.GOPATH)
	//goon.DumpExpr(gopathEntries)
	//goon.DumpExpr(build.Default.SrcDirs())
	//return

	for _, gopathEntry := range gopathEntries {
		/*if skipGopath[gopathEntry] {
			continue
		}*/

		//println("---", gopathEntry, "---\n")
		rec(out, NewImportPathFound(".", gopathEntry))
	}
	close(out)
}

func getGoPackagesB(out chan<- ImportPathFound) {
	gopathEntries := filepath.SplitList(build.Default.GOPATH)
	for _, gopathEntry := range gopathEntries {
		root := filepath.Join(gopathEntry, "src")
		if !isDir(root) {
			continue
		}

		_ = filepath.Walk(root, func(path string, fi os.FileInfo, _ error) error {
			if !fi.IsDir() {
				return nil
			}
			if strings.HasPrefix(fi.Name(), ".") {
				return filepath.SkipDir
			}
			importPath, err := filepath.Rel(root, path)
			if err != nil {
				return nil
			}
			importPathFound := NewImportPathFound(importPath, gopathEntry)
			if goPackage := GoPackageFromImportPathFound(importPathFound); goPackage != nil {
				out <- importPathFound
			}
			return nil
		})
	}
	close(out)
}

// Gets all local Go packages (from GOROOT and all GOPATH workspaces).
func GetGoPackages(out chan<- *GoPackage) {
	for _, root := range build.Default.SrcDirs() {
		_ = filepath.Walk(root, func(path string, fi os.FileInfo, _ error) error {
			switch {
			case !fi.IsDir():
				return nil
			case path == root:
				return nil
			case strings.HasPrefix(fi.Name(), "."):
				return filepath.SkipDir
			default:
				importPath, err := filepath.Rel(root, path)
				if err != nil {
					return nil
				}
				if goPackage := GoPackageFromImportPath(importPath); goPackage != nil {
					out <- goPackage
				}
				return nil
			}
		})
	}
	close(out)
}

// Gets Go packages in all GOPATH workspaces.
func GetGopathGoPackages(out chan<- *GoPackage) {
	gopathEntries := filepath.SplitList(build.Default.GOPATH)
	for _, gopathEntry := range gopathEntries {
		root := filepath.Join(gopathEntry, "src")
		if !isDir(root) {
			continue
		}

		_ = filepath.Walk(root, func(path string, fi os.FileInfo, _ error) error {
			if !fi.IsDir() {
				return nil
			}
			if strings.HasPrefix(fi.Name(), ".") {
				return filepath.SkipDir
			}
			importPath, err := filepath.Rel(root, path)
			if err != nil {
				return nil
			}
			importPathFound := NewImportPathFound(importPath, gopathEntry)
			if goPackage := GoPackageFromImportPathFound(importPathFound); goPackage != nil {
				out <- goPackage
			}
			return nil
		})
	}
	close(out)
}

func getGoPackagesC(out chan<- ImportPathFound) {
	gopathEntries := filepath.SplitList(build.Default.GOPATH)
	for _, gopathEntry := range gopathEntries {
		root := filepath.Join(gopathEntry, "src")
		if !isDir(root) {
			continue
		}

		_ = filepath.Walk(root, func(path string, fi os.FileInfo, _ error) error {
			if !fi.IsDir() {
				return nil
			}
			if strings.HasPrefix(fi.Name(), ".") {
				return filepath.SkipDir
			}
			bpkg, err := BuildPackageFromSrcDir(path)
			if err != nil {
				return nil
			}
			/*if bpkg.Goroot {
				return nil
			}*/
			out <- NewImportPathFound(bpkg.ImportPath, bpkg.Root)
			return nil
		})
	}
	close(out)
}

func main() {
	started := time.Now()

	out := make(chan *GoPackage)
	go GetGoPackages(out)

	for goPackage := range out {
		_ = goPackage
		println(goPackage.Bpkg.ImportPath)
		//goon.Dump(goPackage)
	}

	goon.Dump(time.Since(started).Seconds() * 1000)
}
<commit_msg>Handle potential filepath.Walk errors gracefully.<commit_after>package gist8018045

import (
	"fmt"
	"go/build"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/shurcooL/go-goon"

	. "github.com/shurcooL/go/gists/gist5504644"
	. "github.com/shurcooL/go/gists/gist7480523"
	. "github.com/shurcooL/go/gists/gist7519227"
)

var _ = fmt.Print
var _ = goon.Dump

func rec(out chan<- ImportPathFound, importPathFound ImportPathFound) {
	if goPackage := GoPackageFromImportPathFound(importPathFound); goPackage != nil {
		out <- importPathFound
	}

	entries, err := ioutil.ReadDir(importPathFound.FullPath())
	if err == nil {
		for _, v := range entries {
			if v.IsDir() && !strings.HasPrefix(v.Name(), ".") {
				rec(out, NewImportPathFound(filepath.Join(importPathFound.ImportPath(), v.Name()), importPathFound.GopathEntry()))
			}
		}
	}
}

func isDir(path string) bool {
	fi, err := os.Stat(path)
	return err == nil && fi.IsDir()
}

//var skipGopath = map[string]bool{"/Users/Dmitri/Local/Ongoing/Conception/GoLand": false, "/Users/Dmitri/Dropbox/Work/2013/GoLanding": false}

// Deprecated in favor of GetGoPackages(out chan<- *GoPackage).
/*func GetGoPackages(out chan<- ImportPathFound) {
	getGoPackagesB(out)
}*/

func getGoPackagesA(out chan<- ImportPathFound) {
	gopathEntries := filepath.SplitList(build.Default.GOPATH)
	//goon.DumpExpr(gopathEntries)
	//goon.DumpExpr(build.Default.SrcDirs())
	//return

	for _, gopathEntry := range gopathEntries {
		/*if skipGopath[gopathEntry] {
			continue
		}*/

		//println("---", gopathEntry, "---\n")
		rec(out, NewImportPathFound(".", gopathEntry))
	}
	close(out)
}

func getGoPackagesB(out chan<- ImportPathFound) {
	gopathEntries := filepath.SplitList(build.Default.GOPATH)
	for _, gopathEntry := range gopathEntries {
		root := filepath.Join(gopathEntry, "src")
		if !isDir(root) {
			continue
		}

		_ = filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
			if err != nil {
				log.Printf("can't stat file %s: %v\n", path, err)
				return nil
			}
			if !fi.IsDir() {
				return nil
			}
			if strings.HasPrefix(fi.Name(), ".") {
				return filepath.SkipDir
			}
			importPath, err := filepath.Rel(root, path)
			if err != nil {
				return nil
			}
			importPathFound := NewImportPathFound(importPath, gopathEntry)
			if goPackage := GoPackageFromImportPathFound(importPathFound); goPackage != nil {
				out <- importPathFound
			}
			return nil
		})
	}
	close(out)
}

// Gets all local Go packages (from GOROOT and all GOPATH workspaces).
func GetGoPackages(out chan<- *GoPackage) {
	for _, root := range build.Default.SrcDirs() {
		_ = filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
			if err != nil {
				log.Printf("can't stat file %s: %v\n", path, err)
				return nil
			}
			switch {
			case !fi.IsDir():
				return nil
			case path == root:
				return nil
			case strings.HasPrefix(fi.Name(), "."):
				return filepath.SkipDir
			default:
				importPath, err := filepath.Rel(root, path)
				if err != nil {
					return nil
				}
				if goPackage := GoPackageFromImportPath(importPath); goPackage != nil {
					out <- goPackage
				}
				return nil
			}
		})
	}
	close(out)
}

// Gets Go packages in all GOPATH workspaces.
func GetGopathGoPackages(out chan<- *GoPackage) {
	gopathEntries := filepath.SplitList(build.Default.GOPATH)
	for _, gopathEntry := range gopathEntries {
		root := filepath.Join(gopathEntry, "src")
		if !isDir(root) {
			continue
		}

		_ = filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
			if err != nil {
				log.Printf("can't stat file %s: %v\n", path, err)
				return nil
			}
			if !fi.IsDir() {
				return nil
			}
			if strings.HasPrefix(fi.Name(), ".") {
				return filepath.SkipDir
			}
			importPath, err := filepath.Rel(root, path)
			if err != nil {
				return nil
			}
			importPathFound := NewImportPathFound(importPath, gopathEntry)
			if goPackage := GoPackageFromImportPathFound(importPathFound); goPackage != nil {
				out <- goPackage
			}
			return nil
		})
	}
	close(out)
}

func getGoPackagesC(out chan<- ImportPathFound) {
	gopathEntries := filepath.SplitList(build.Default.GOPATH)
	for _, gopathEntry := range gopathEntries {
		root := filepath.Join(gopathEntry, "src")
		if !isDir(root) {
			continue
		}

		_ = filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
			if err != nil {
				log.Printf("can't stat file %s: %v\n", path, err)
				return nil
			}
			if !fi.IsDir() {
				return nil
			}
			if strings.HasPrefix(fi.Name(), ".") {
				return filepath.SkipDir
			}
			bpkg, err := BuildPackageFromSrcDir(path)
			if err != nil {
				return nil
			}
			/*if bpkg.Goroot {
				return nil
			}*/
			out <- NewImportPathFound(bpkg.ImportPath, bpkg.Root)
			return nil
		})
	}
	close(out)
}

func main() {
	started := time.Now()

	out := make(chan *GoPackage)
	go GetGoPackages(out)

	for goPackage := range out {
		_ = goPackage
		println(goPackage.Bpkg.ImportPath)
		//goon.Dump(goPackage)
	}

	goon.Dump(time.Since(started).Seconds() * 1000)
}
<|endoftext|>


<commit_before>package main

import "trace"

const (
	imageW = 640
	imageH = 480
)

func createRandomImage() [][]trace.Color {
	image := make([][]trace.Color, imageH)
	for i := range image {
		image[i] = make([]trace.Color, imageW)
		for j := range image[i] {
			image[i][j].R = float64(i) / float64(imageH)
			image[i][j].G = float64(j) / float64(imageW)
			image[i][j].B = 0.0

			//log.Printf("%d %d %+v | ", i, j, image[i][j])
		}
		//log.Printf("\n")
	}
	return image
}

func main() {
	c := trace.NewContext(imageW, imageH)

	o2w := trace.NewM44()
	o2w.Translate(trace.NewV3(-2, 0, -5))/*.scale(trace.NewV3(1.0, 2.0, 1.0))*/
	c.AddPrimitive(trace.NewSphere(o2w))

	o2w = trace.NewM44()
	o2w.Translate(trace.NewV3(2, 0, -5))
	c.AddPrimitive(trace.NewTriangle(o2w))

	image := trace.Render(c)
	//image := createRandomImage()
	trace.WriteImageToPPM(image, "render")
}
<commit_msg>Add scaled sphere to check that works<commit_after>package main

import "trace"

const (
	imageW = 640
	imageH = 480
)

func main() {
	c := trace.NewContext(imageW, imageH)

	o2w := trace.NewM44()
	o2w.Translate(trace.NewV3(-2, 0, -5))/*.scale(trace.NewV3(1.0, 2.0, 1.0))*/
	c.AddPrimitive(trace.NewSphere(o2w))

	o2w = trace.NewM44()
	o2w.Translate(trace.NewV3(0, 0, -5)).Scale(trace.NewV3(1, 2, 1))
	c.AddPrimitive(trace.NewSphere(o2w))

	o2w = trace.NewM44()
	o2w.Translate(trace.NewV3(2, 0, -5))
	c.AddPrimitive(trace.NewTriangle(o2w))

	image := trace.Render(c)
	trace.WriteImageToPPM(image, "render")
}
<|endoftext|>


<commit_before>package analyze

import (
	//"fmt"
	"math"

	"github.com/phil-mansfield/shellfish/los"
	"github.com/phil-mansfield/shellfish/los/geom"
	//plt "github.com/phil-mansfield/pyplot"
)

type RingBuffer struct {
	PlaneXs, PlaneYs, Xs, Ys, Zs, Rs, Phis     []float64
	Oks                                        []bool
	profRs, profRhos, smoothRhos, smoothDerivs []float64
	N, Bins                                    int
}

func (r *RingBuffer) Init(n, bins int) {
	r.N, r.Bins = n, bins

	r.PlaneXs, r.PlaneYs = make([]float64, n), make([]float64, n)
	r.Xs, r.Ys, r.Zs = make([]float64, n), make([]float64, n), make([]float64, n)
	r.Phis, r.Rs = make([]float64, n), make([]float64, n)
	r.Oks = make([]bool, n)

	r.smoothRhos, r.smoothDerivs = make([]float64, bins), make([]float64, bins)
	r.profRs, r.profRhos = make([]float64, bins), make([]float64, bins)
}

func (r *RingBuffer) Clear() {
	for i := 0; i < r.N; i++ {
		r.PlaneXs[i], r.PlaneYs[i] = 0, 0
		r.Xs[i], r.Ys[i], r.Zs[i] = 0, 0, 0
		r.Phis[i], r.Rs[i] = 0, 0
		r.Oks[i] = false
	}

	for i := 0; i < r.Bins; i++ {
		r.smoothRhos[i], r.smoothDerivs[i] = 0, 0
		r.profRs[i], r.profRhos[i] = 0, 0
	}
}

func (r *RingBuffer) Splashback(
	h *los.Halo, ring int, window int, dLim float64,
) {
	h.GetRs(r.profRs)
	ls := new(geom.LineSegment)
	for i := 0; i < r.N; i++ {
		h.GetRhos(ring, i, r.profRhos)

		_, _, r.Oks[i] = Smooth(
			r.profRs, r.profRhos, window,
			Vals(r.smoothRhos), Derivs(r.smoothDerivs),
		)

		if !r.Oks[i] {
			continue
		}
		r.Rs[i], r.Oks[i] = SplashbackRadius(
			r.profRs, r.smoothRhos, r.smoothDerivs, DLim(dLim),
		)

		if !r.Oks[i] {
			continue
		}

		r.Phis[i] = float64(h.Phi(i))
		if r.Phis[i] < 0 {
			r.Phis[i] += math.Pi
		}
		sin, cos := math.Sincos(r.Phis[i])
		r.PlaneXs[i], r.PlaneYs[i] = cos*r.Rs[i], sin*r.Rs[i]

		h.LineSegment(ring, i, ls)
		r.Xs[i] = r.Rs[i] * float64(ls.Dir[0])
		r.Ys[i] = r.Rs[i] * float64(ls.Dir[1])
		r.Zs[i] = r.Rs[i] * float64(ls.Dir[2])
	}
}

func (r *RingBuffer) OkPlaneCoords(xs, ys []float64) (okXs, okYs []float64) {
	xs, ys = xs[:0], ys[:0]
	for i, ok := range r.Oks {
		if ok {
			xs = append(xs, r.PlaneXs[i])
			ys = append(ys, r.PlaneYs[i])
		}
	}
	return xs, ys
}

func (r *RingBuffer) OkPolarCoords(rs, phis []float64) (okRs, okPhis []float64) {
	rs, phis = rs[:0], phis[:0]
	for i, ok := range r.Oks {
		if ok {
			rs = append(rs, r.Rs[i])
			phis = append(phis, r.Phis[i])
		}
	}
	return rs, phis
}
<commit_msg>more dead code removed.<commit_after>package analyze

import (
	"math"

	"github.com/phil-mansfield/shellfish/los"
	"github.com/phil-mansfield/shellfish/los/geom"
)

type RingBuffer struct {
	PlaneXs, PlaneYs, Xs, Ys, Zs, Rs, Phis     []float64
	Oks                                        []bool
	profRs, profRhos, smoothRhos, smoothDerivs []float64
	N, Bins                                    int
}

func (r *RingBuffer) Init(n, bins int) {
	r.N, r.Bins = n, bins

	r.PlaneXs, r.PlaneYs = make([]float64, n), make([]float64, n)
	r.Xs, r.Ys, r.Zs = make([]float64, n), make([]float64, n), make([]float64, n)
	r.Phis, r.Rs = make([]float64, n), make([]float64, n)
	r.Oks = make([]bool, n)

	r.smoothRhos, r.smoothDerivs = make([]float64, bins), make([]float64, bins)
	r.profRs, r.profRhos = make([]float64, bins), make([]float64, bins)
}

func (r *RingBuffer) Clear() {
	for i := 0; i < r.N; i++ {
		r.PlaneXs[i], r.PlaneYs[i] = 0, 0
		r.Xs[i], r.Ys[i], r.Zs[i] = 0, 0, 0
		r.Phis[i], r.Rs[i] = 0, 0
		r.Oks[i] = false
	}

	for i := 0; i < r.Bins; i++ {
		r.smoothRhos[i], r.smoothDerivs[i] = 0, 0
		r.profRs[i], r.profRhos[i] = 0, 0
	}
}

func (r *RingBuffer) Splashback(
	h *los.Halo, ring int, window int, dLim float64,
) {
	h.GetRs(r.profRs)
	ls := new(geom.LineSegment)
	for i := 0; i < r.N; i++ {
		h.GetRhos(ring, i, r.profRhos)

		_, _, r.Oks[i] = Smooth(
			r.profRs, r.profRhos, window,
			Vals(r.smoothRhos), Derivs(r.smoothDerivs),
		)

		if !r.Oks[i] {
			continue
		}
		r.Rs[i], r.Oks[i] = SplashbackRadius(
			r.profRs, r.smoothRhos, r.smoothDerivs, DLim(dLim),
		)

		if !r.Oks[i] {
			continue
		}

		r.Phis[i] = float64(h.Phi(i))
		if r.Phis[i] < 0 {
			r.Phis[i] += math.Pi
		}
		sin, cos := math.Sincos(r.Phis[i])
		r.PlaneXs[i], r.PlaneYs[i] = cos*r.Rs[i], sin*r.Rs[i]

		h.LineSegment(ring, i, ls)
		r.Xs[i] = r.Rs[i] * float64(ls.Dir[0])
		r.Ys[i] = r.Rs[i] * float64(ls.Dir[1])
		r.Zs[i] = r.Rs[i] * float64(ls.Dir[2])
	}
}

func (r *RingBuffer) OkPlaneCoords(xs, ys []float64) (okXs, okYs []float64) {
	xs, ys = xs[:0], ys[:0]
	for i, ok := range r.Oks {
		if ok {
			xs = append(xs, r.PlaneXs[i])
			ys = append(ys, r.PlaneYs[i])
		}
	}
	return xs, ys
}

func (r *RingBuffer) OkPolarCoords(rs, phis []float64) (okRs, okPhis []float64) {
	rs, phis = rs[:0], phis[:0]
	for i, ok := range r.Oks {
		if ok {
			rs = append(rs, r.Rs[i])
			phis = append(phis, r.Phis[i])
		}
	}
	return rs, phis
}
<|endoftext|>


<commit_before>// Copyright 2016 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package factom_test

import (
	"bytes"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"net/http"
	"net/http/httptest"
	"testing"

	. "github.com/FactomProject/factom"
)

var ()

func TestNewChain(t *testing.T) {
	ent := new(Entry)
	ent.ChainID = ""
	ent.Content = []byte("This is a test Entry.")
	ent.ExtIDs = append(ent.ExtIDs, []byte("This is the first extid."))
	ent.ExtIDs = append(ent.ExtIDs, []byte("This is the second extid."))

	newChain := NewChain(ent)
	//fmt.Println(newChain.ChainID)
	expectedID := "5a402200c5cf278e47905ce52d7d64529a0291829a7bd230072c5468be709069"

	if newChain.ChainID != expectedID {
		t.Errorf("expected:%s\nrecieved:%s", expectedID, newChain.ChainID)
	}
	t.Log(newChain.ChainID)

	cfb := NewChainFromBytes(ent.Content, ent.ExtIDs...)
	if cfb.ChainID != expectedID {
		t.Errorf("expected:%s\nrecieved:%s", expectedID, cfb.ChainID)
	}
	t.Log(cfb.ChainID)

	cfs := NewChainFromStrings(
		"This is a test Entry.",
		"This is the first extid.",
		"This is the second extid.",
	)
	if cfs.ChainID != expectedID {
		t.Errorf("expected:%s\nrecieved:%s", expectedID, cfs.ChainID)
	}
	t.Log(cfs.ChainID)
}

func TestIfExists(t *testing.T) {
	simlatedFactomdResponse := `{
  "jsonrpc": "2.0",
  "id": 0,
  "result": {
    "ChainHead": "f65f67774139fa78344dcdd302631a0d646db0c2be4d58e3e48b2a188c1b856c"
  }
}`

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, simlatedFactomdResponse)
	}))
	defer ts.Close()

	url := ts.URL[7:]
	SetFactomdServer(url)

	expectedID := "f65f67774139fa78344dcdd302631a0d646db0c2be4d58e3e48b2a188c1b856c"
	//fmt.Println(ChainExists(expectedID))
	if ChainExists(expectedID) != true {
		t.Errorf("chain %s does not exist", expectedID)
	}
}

func TestIfNotExists(t *testing.T) {
	simlatedFactomdResponse := `{"jsonrpc":"2.0","id":0,"error":{"code":-32009,"message":"Missing Chain Head"}}`

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, simlatedFactomdResponse)
	}))
	defer ts.Close()

	url := ts.URL[7:]
	SetFactomdServer(url)
	unexpectedID := "5a402200c5cf278e47905ce52d7d64529a0291829a7bd230072c5468be709069"

	if ChainExists(unexpectedID) != false {
		t.Errorf("chain %s shouldn't exist", unexpectedID)
	}
}

func TestComposeChainCommit(t *testing.T) {
	type response struct {
		Message string `json:"message"`
	}
	ecAddr, _ := GetECAddress("Es2Rf7iM6PdsqfYCo3D1tnAR65SkLENyWJG1deUzpRMQmbh9F3eG")
	ent := new(Entry)
	ent.ChainID = "954d5a49fd70d9b8bcdb35d252267829957f7ef7fa6c74f88419bdc5e82209f4"
	ent.Content = []byte("test!")
	ent.ExtIDs = append(ent.ExtIDs, []byte("test"))
	newChain := NewChain(ent)

	cCommit, _ := ComposeChainCommit(newChain, ecAddr)
	r := new(response)
	json.Unmarshal(cCommit.Params, r)
	binCommit, _ := hex.DecodeString(r.Message)
	t.Logf("%x", binCommit)

	//the commit has a timestamp which is updated new for each time it is called.  This means it is different after each call.
	//we will check the non-changing parts

	if len(binCommit) != 200 {
		t.Error("expected commit to be 200 bytes long, instead got", len(binCommit))
	}
	result := binCommit[0:1]
	expected := []byte{0x00}
	if !bytes.Equal(result, expected) {
		t.Errorf("expected:%s\nrecieved:%s", expected, result)
	}
	//skip the 6 bytes of the timestamp
	result = binCommit[7:136]
	expected, _ = hex.DecodeString("516870d4c0e1ee2d5f0d415e51fc10ae6b8d895561e9314afdc33048194d76f07cc61c8a81aea23d76ff6447689757dc1e36af66e300ce3e06b8d816c79acfd2285ed45081d5b8819a678d13c7c2d04f704b34c74e8aaecd9bd34609bee047200b3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29")

	if !bytes.Equal(result, expected) {
		t.Errorf("expected:%s\nrecieved:%s", expected, result)
	}
}

func TestComposeChainReveal(t *testing.T) {

	ent := new(Entry)
	ent.ChainID = "954d5a49fd70d9b8bcdb35d252267829957f7ef7fa6c74f88419bdc5e82209f4"
	ent.Content = []byte("test!")
	ent.ExtIDs = append(ent.ExtIDs, []byte("test"))
	newChain := NewChain(ent)

	cReveal, _ := ComposeChainReveal(newChain)

	expectedResponse := `{"entry":"00954d5a49fd70d9b8bcdb35d252267829957f7ef7fa6c74f88419bdc5e82209f400060004746573747465737421"}`
	if expectedResponse != string(cReveal.Params) {
		t.Errorf("expected:%s\nrecieved:%s", expectedResponse, cReveal.Params)
	}
}

func TestCommitChain(t *testing.T) {
	simlatedFactomdResponse := `{
   "jsonrpc":"2.0",
   "id":0,
   "result":{
      "message":"Chain Commit Success",
      "txid":"76e123d133a841fe3e08c5e3f3d392f8431f2d7668890c03f003f541efa8fc61"
   }
}`

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, simlatedFactomdResponse)
	}))
	defer ts.Close()

	url := ts.URL[7:]
	SetFactomdServer(url)

	ent := new(Entry)
	ent.ChainID = "954d5a49fd70d9b8bcdb35d252267829957f7ef7fa6c74f88419bdc5e82209f4"
	ent.Content = []byte("test!")
	ent.ExtIDs = append(ent.ExtIDs, []byte("test"))
	newChain := NewChain(ent)
	ecAddr, _ := GetECAddress("Es2Rf7iM6PdsqfYCo3D1tnAR65SkLENyWJG1deUzpRMQmbh9F3eG")

	expectedResponse := "76e123d133a841fe3e08c5e3f3d392f8431f2d7668890c03f003f541efa8fc61"
	response, _ := CommitChain(newChain, ecAddr)

	if expectedResponse != response {
		t.Errorf("expected:%s\nrecieved:%s", expectedResponse, response)
	}
	t.Log(response)
}

func TestRevealChain(t *testing.T) {
	simlatedFactomdResponse := `{
  "jsonrpc": "2.0",
  "id": 0,
  "result": {
    "message": "Entry Reveal Success",
    "entryhash": "f5c956749fc3eba4acc60fd485fb100e601070a44fcce54ff358d60669854734"
  }
}`

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, simlatedFactomdResponse)
	}))
	defer ts.Close()

	url := ts.URL[7:]
	SetFactomdServer(url)

	ent := new(Entry)
	ent.ChainID = "954d5a49fd70d9b8bcdb35d252267829957f7ef7fa6c74f88419bdc5e82209f4"
	ent.Content = []byte("test!")
	ent.ExtIDs = append(ent.ExtIDs, []byte("test"))
	newChain := NewChain(ent)

	expectedResponse := "f5c956749fc3eba4acc60fd485fb100e601070a44fcce54ff358d60669854734"
	response, _ := RevealChain(newChain)

	if expectedResponse != response {
		t.Errorf("expected:%s\nrecieved:%s", expectedResponse, response)
	}
	t.Log(response)
}
<commit_msg>removed unused code<commit_after>// Copyright 2016 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package factom_test

import (
	"bytes"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"net/http"
	"net/http/httptest"
	"testing"

	. "github.com/FactomProject/factom"
)

var ()

func TestNewChain(t *testing.T) {
	ent := new(Entry)
	ent.ChainID = ""
	ent.Content = []byte("This is a test Entry.")
	ent.ExtIDs = append(ent.ExtIDs, []byte("This is the first extid."))
	ent.ExtIDs = append(ent.ExtIDs, []byte("This is the second extid."))

	newChain := NewChain(ent)
	expectedID := "5a402200c5cf278e47905ce52d7d64529a0291829a7bd230072c5468be709069"

	if newChain.ChainID != expectedID {
		t.Errorf("expected:%s\nrecieved:%s", expectedID, newChain.ChainID)
	}
	t.Log(newChain.ChainID)

	cfb := NewChainFromBytes(ent.Content, ent.ExtIDs...)
	if cfb.ChainID != expectedID {
		t.Errorf("expected:%s\nrecieved:%s", expectedID, cfb.ChainID)
	}
	t.Log(cfb.ChainID)

	cfs := NewChainFromStrings(
		"This is a test Entry.",
		"This is the first extid.",
		"This is the second extid.",
	)
	if cfs.ChainID != expectedID {
		t.Errorf("expected:%s\nrecieved:%s", expectedID, cfs.ChainID)
	}
	t.Log(cfs.ChainID)
}

func TestIfExists(t *testing.T) {
	simlatedFactomdResponse := `{
  "jsonrpc": "2.0",
  "id": 0,
  "result": {
    "ChainHead": "f65f67774139fa78344dcdd302631a0d646db0c2be4d58e3e48b2a188c1b856c"
  }
}`

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, simlatedFactomdResponse)
	}))
	defer ts.Close()

	url := ts.URL[7:]
	SetFactomdServer(url)

	expectedID := "f65f67774139fa78344dcdd302631a0d646db0c2be4d58e3e48b2a188c1b856c"
	//fmt.Println(ChainExists(expectedID))
	if ChainExists(expectedID) != true {
		t.Errorf("chain %s does not exist", expectedID)
	}
}

func TestIfNotExists(t *testing.T) {
	simlatedFactomdResponse := `{"jsonrpc":"2.0","id":0,"error":{"code":-32009,"message":"Missing Chain Head"}}`

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, simlatedFactomdResponse)
	}))
	defer ts.Close()

	url := ts.URL[7:]
	SetFactomdServer(url)
	unexpectedID := "5a402200c5cf278e47905ce52d7d64529a0291829a7bd230072c5468be709069"

	if ChainExists(unexpectedID) != false {
		t.Errorf("chain %s shouldn't exist", unexpectedID)
	}
}

func TestComposeChainCommit(t *testing.T) {
	type response struct {
		Message string `json:"message"`
	}
	ecAddr, _ := GetECAddress("Es2Rf7iM6PdsqfYCo3D1tnAR65SkLENyWJG1deUzpRMQmbh9F3eG")
	ent := new(Entry)
	ent.ChainID = "954d5a49fd70d9b8bcdb35d252267829957f7ef7fa6c74f88419bdc5e82209f4"
	ent.Content = []byte("test!")
	ent.ExtIDs = append(ent.ExtIDs, []byte("test"))
	newChain := NewChain(ent)

	cCommit, _ := ComposeChainCommit(newChain, ecAddr)
	r := new(response)
	json.Unmarshal(cCommit.Params, r)
	binCommit, _ := hex.DecodeString(r.Message)
	t.Logf("%x", binCommit)

	//the commit has a timestamp which is updated new for each time it is called.  This means it is different after each call.
	//we will check the non-changing parts

	if len(binCommit) != 200 {
		t.Error("expected commit to be 200 bytes long, instead got", len(binCommit))
	}
	result := binCommit[0:1]
	expected := []byte{0x00}
	if !bytes.Equal(result, expected) {
		t.Errorf("expected:%s\nrecieved:%s", expected, result)
	}
	//skip the 6 bytes of the timestamp
	result = binCommit[7:136]
	expected, _ = hex.DecodeString("516870d4c0e1ee2d5f0d415e51fc10ae6b8d895561e9314afdc33048194d76f07cc61c8a81aea23d76ff6447689757dc1e36af66e300ce3e06b8d816c79acfd2285ed45081d5b8819a678d13c7c2d04f704b34c74e8aaecd9bd34609bee047200b3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29")

	if !bytes.Equal(result, expected) {
		t.Errorf("expected:%s\nrecieved:%s", expected, result)
	}
}

func TestComposeChainReveal(t *testing.T) {

	ent := new(Entry)
	ent.ChainID = "954d5a49fd70d9b8bcdb35d252267829957f7ef7fa6c74f88419bdc5e82209f4"
	ent.Content = []byte("test!")
	ent.ExtIDs = append(ent.ExtIDs, []byte("test"))
	newChain := NewChain(ent)

	cReveal, _ := ComposeChainReveal(newChain)

	expectedResponse := `{"entry":"00954d5a49fd70d9b8bcdb35d252267829957f7ef7fa6c74f88419bdc5e82209f400060004746573747465737421"}`
	if expectedResponse != string(cReveal.Params) {
		t.Errorf("expected:%s\nrecieved:%s", expectedResponse, cReveal.Params)
	}
}

func TestCommitChain(t *testing.T) {
	simlatedFactomdResponse := `{
   "jsonrpc":"2.0",
   "id":0,
   "result":{
      "message":"Chain Commit Success",
      "txid":"76e123d133a841fe3e08c5e3f3d392f8431f2d7668890c03f003f541efa8fc61"
   }
}`

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, simlatedFactomdResponse)
	}))
	defer ts.Close()

	url := ts.URL[7:]
	SetFactomdServer(url)

	ent := new(Entry)
	ent.ChainID = "954d5a49fd70d9b8bcdb35d252267829957f7ef7fa6c74f88419bdc5e82209f4"
	ent.Content = []byte("test!")
	ent.ExtIDs = append(ent.ExtIDs, []byte("test"))
	newChain := NewChain(ent)
	ecAddr, _ := GetECAddress("Es2Rf7iM6PdsqfYCo3D1tnAR65SkLENyWJG1deUzpRMQmbh9F3eG")

	expectedResponse := "76e123d133a841fe3e08c5e3f3d392f8431f2d7668890c03f003f541efa8fc61"
	response, _ := CommitChain(newChain, ecAddr)

	if expectedResponse != response {
		t.Errorf("expected:%s\nrecieved:%s", expectedResponse, response)
	}
	t.Log(response)
}

func TestRevealChain(t *testing.T) {
	simlatedFactomdResponse := `{
  "jsonrpc": "2.0",
  "id": 0,
  "result": {
    "message": "Entry Reveal Success",
    "entryhash": "f5c956749fc3eba4acc60fd485fb100e601070a44fcce54ff358d60669854734"
  }
}`

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, simlatedFactomdResponse)
	}))
	defer ts.Close()

	url := ts.URL[7:]
	SetFactomdServer(url)

	ent := new(Entry)
	ent.ChainID = "954d5a49fd70d9b8bcdb35d252267829957f7ef7fa6c74f88419bdc5e82209f4"
	ent.Content = []byte("test!")
	ent.ExtIDs = append(ent.ExtIDs, []byte("test"))
	newChain := NewChain(ent)

	expectedResponse := "f5c956749fc3eba4acc60fd485fb100e601070a44fcce54ff358d60669854734"
	response, _ := RevealChain(newChain)

	if expectedResponse != response {
		t.Errorf("expected:%s\nrecieved:%s", expectedResponse, response)
	}
	t.Log(response)
}
<|endoftext|>


<commit_before>// Copyright 2016 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package factom_test

import (
	"bytes"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"net/http"
	"net/http/httptest"
	"testing"

	. "github.com/FactomProject/factom"
)

var ()

func TestNewChain(t *testing.T) {
	ent := new(Entry)
	ent.ChainID = "5a402200c5cf278e47905ce52d7d64529a0291829a7bd230072c5468be709069"
	ent.Content = []byte("This is a test Entry.")
	ent.ExtIDs = append(ent.ExtIDs, []byte("This is the first extid."))
	ent.ExtIDs = append(ent.ExtIDs, []byte("This is the second extid."))

	newChain := NewChain(ent)
	//fmt.Println(newChain.ChainID)
	expectedID := "5a402200c5cf278e47905ce52d7d64529a0291829a7bd230072c5468be709069"

	if newChain.ChainID != expectedID {
		fmt.Println(newChain.ChainID)
		fmt.Println(expectedID)
		t.Fail()
	}
}

func TestIfExists(t *testing.T) {
	simlatedFactomdResponse := `{
  "jsonrpc": "2.0",
  "id": 0,
  "result": {
    "ChainHead": "f65f67774139fa78344dcdd302631a0d646db0c2be4d58e3e48b2a188c1b856c"
  }
}`

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, simlatedFactomdResponse)
	}))
	defer ts.Close()

	url := ts.URL[7:]
	SetFactomdServer(url)

	expectedID := "f65f67774139fa78344dcdd302631a0d646db0c2be4d58e3e48b2a188c1b856c"
	//fmt.Println(ChainExists(expectedID))
	if ChainExists(expectedID) != true {
		fmt.Println("chain should exist")
		t.Fail()
	}

}

func TestIfNotExists(t *testing.T) {
	simlatedFactomdResponse := `{"jsonrpc":"2.0","id":0,"error":{"code":-32009,"message":"Missing Chain Head"}}`

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, simlatedFactomdResponse)
	}))
	defer ts.Close()

	url := ts.URL[7:]
	SetFactomdServer(url)
	unexpectedID := "5a402200c5cf278e47905ce52d7d64529a0291829a7bd230072c5468be709069"

	if ChainExists(unexpectedID) != false {
		fmt.Println("chain shouldn't exist")
		t.Fail()
	}
}

func TestComposeChainCommit(t *testing.T) {
	type response struct {
		Message string `json:"message"`
	}
	ecAddr, _ := GetECAddress("Es2Rf7iM6PdsqfYCo3D1tnAR65SkLENyWJG1deUzpRMQmbh9F3eG")
	ent := new(Entry)
	ent.ChainID = "954d5a49fd70d9b8bcdb35d252267829957f7ef7fa6c74f88419bdc5e82209f4"
	ent.Content = []byte("test!")
	ent.ExtIDs = append(ent.ExtIDs, []byte("test"))
	newChain := NewChain(ent)

	cCommit, _ := ComposeChainCommit(newChain, ecAddr)
	r := new(response)
	json.Unmarshal(cCommit.Params, r)
	binCommit, _ := hex.DecodeString(r.Message)

	//fmt.Printf("%x\n",binCommit)
	//the commit has a timestamp which is updated new for each time it is called.  This means it is different after each call.
	//we will check the non-changing parts

	if len(binCommit) != 200 {
		fmt.Println("expected commit to be 200 bytes long, instead got", len(binCommit))
		t.Fail()
	}
	result := binCommit[0:1]
	expected := []byte{0x00}
	if !bytes.Equal(result, expected) {
		fmt.Printf("found %x expected %x\n", result, expected)
		t.Fail()
	}
	//skip the 6 bytes of the timestamp
	result = binCommit[7:136]
	expected, _ = hex.DecodeString("516870d4c0e1ee2d5f0d415e51fc10ae6b8d895561e9314afdc33048194d76f07cc61c8a81aea23d76ff6447689757dc1e36af66e300ce3e06b8d816c79acfd2285ed45081d5b8819a678d13c7c2d04f704b34c74e8aaecd9bd34609bee047200b3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29")

	if !bytes.Equal(result, expected) {
		fmt.Printf("found %x expected %x\n", result, expected)
		t.Fail()
	}
}

func TestComposeChainReveal(t *testing.T) {

	ent := new(Entry)
	ent.ChainID = "954d5a49fd70d9b8bcdb35d252267829957f7ef7fa6c74f88419bdc5e82209f4"
	ent.Content = []byte("test!")
	ent.ExtIDs = append(ent.ExtIDs, []byte("test"))
	newChain := NewChain(ent)

	cReveal, _ := ComposeChainReveal(newChain)

	expectedResponse := `{"entry":"00954d5a49fd70d9b8bcdb35d252267829957f7ef7fa6c74f88419bdc5e82209f400060004746573747465737421"}`
	if expectedResponse != string(cReveal.Params) {
		fmt.Println(cReveal.Params)
		fmt.Println(expectedResponse)
		t.Fail()
	}
}

func TestCommitChain(t *testing.T) {
	simlatedFactomdResponse := `{
   "jsonrpc":"2.0",
   "id":0,
   "result":{
      "message":"Chain Commit Success",
      "txid":"76e123d133a841fe3e08c5e3f3d392f8431f2d7668890c03f003f541efa8fc61"
   }
}`

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, simlatedFactomdResponse)
	}))
	defer ts.Close()

	url := ts.URL[7:]
	SetFactomdServer(url)

	ent := new(Entry)
	ent.ChainID = "954d5a49fd70d9b8bcdb35d252267829957f7ef7fa6c74f88419bdc5e82209f4"
	ent.Content = []byte("test!")
	ent.ExtIDs = append(ent.ExtIDs, []byte("test"))
	newChain := NewChain(ent)
	ecAddr, _ := GetECAddress("Es2Rf7iM6PdsqfYCo3D1tnAR65SkLENyWJG1deUzpRMQmbh9F3eG")

	response, _ := CommitChain(newChain, ecAddr)

	//fmt.Println(response)
	expectedResponse := "76e123d133a841fe3e08c5e3f3d392f8431f2d7668890c03f003f541efa8fc61"

	if expectedResponse != response {
		fmt.Println(response)
		fmt.Println(expectedResponse)
		t.Fail()
	}
}

func TestRevealChain(t *testing.T) {
	simlatedFactomdResponse := `{
  "jsonrpc": "2.0",
  "id": 0,
  "result": {
    "message": "Entry Reveal Success",
    "entryhash": "f5c956749fc3eba4acc60fd485fb100e601070a44fcce54ff358d60669854734"
  }
}`

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, simlatedFactomdResponse)
	}))
	defer ts.Close()

	url := ts.URL[7:]
	SetFactomdServer(url)

	ent := new(Entry)
	ent.ChainID = "954d5a49fd70d9b8bcdb35d252267829957f7ef7fa6c74f88419bdc5e82209f4"
	ent.Content = []byte("test!")
	ent.ExtIDs = append(ent.ExtIDs, []byte("test"))
	newChain := NewChain(ent)

	response, _ := RevealChain(newChain)

	//fmt.Println(response)
	expectedResponse := "f5c956749fc3eba4acc60fd485fb100e601070a44fcce54ff358d60669854734"

	if expectedResponse != response {
		fmt.Println(response)
		fmt.Println(expectedResponse)
		t.Fail()
	}
}
<commit_msg>cleanup chain tests<commit_after>// Copyright 2016 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package factom_test

import (
	"bytes"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"net/http"
	"net/http/httptest"
	"testing"

	. "github.com/FactomProject/factom"
)

var ()

func TestNewChain(t *testing.T) {
	ent := new(Entry)
	ent.ChainID = "5a402200c5cf278e47905ce52d7d64529a0291829a7bd230072c5468be709069"
	ent.Content = []byte("This is a test Entry.")
	ent.ExtIDs = append(ent.ExtIDs, []byte("This is the first extid."))
	ent.ExtIDs = append(ent.ExtIDs, []byte("This is the second extid."))

	newChain := NewChain(ent)
	//fmt.Println(newChain.ChainID)
	expectedID := "5a402200c5cf278e47905ce52d7d64529a0291829a7bd230072c5468be709069"

	if newChain.ChainID != expectedID {
		t.Errorf("expected:%s\nrecieved:%s", expectedID, newChain.ChainID)
	}
}

func TestIfExists(t *testing.T) {
	simlatedFactomdResponse := `{
  "jsonrpc": "2.0",
  "id": 0,
  "result": {
    "ChainHead": "f65f67774139fa78344dcdd302631a0d646db0c2be4d58e3e48b2a188c1b856c"
  }
}`

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, simlatedFactomdResponse)
	}))
	defer ts.Close()

	url := ts.URL[7:]
	SetFactomdServer(url)

	expectedID := "f65f67774139fa78344dcdd302631a0d646db0c2be4d58e3e48b2a188c1b856c"
	//fmt.Println(ChainExists(expectedID))
	if ChainExists(expectedID) != true {
		t.Errorf("chain %s does not exist", expectedID)
	}
}

func TestIfNotExists(t *testing.T) {
	simlatedFactomdResponse := `{"jsonrpc":"2.0","id":0,"error":{"code":-32009,"message":"Missing Chain Head"}}`

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, simlatedFactomdResponse)
	}))
	defer ts.Close()

	url := ts.URL[7:]
	SetFactomdServer(url)
	unexpectedID := "5a402200c5cf278e47905ce52d7d64529a0291829a7bd230072c5468be709069"

	if ChainExists(unexpectedID) != false {
		t.Errorf("chain %s shouldn't exist", unexpectedID)
	}
}

func TestComposeChainCommit(t *testing.T) {
	type response struct {
		Message string `json:"message"`
	}
	ecAddr, _ := GetECAddress("Es2Rf7iM6PdsqfYCo3D1tnAR65SkLENyWJG1deUzpRMQmbh9F3eG")
	ent := new(Entry)
	ent.ChainID = "954d5a49fd70d9b8bcdb35d252267829957f7ef7fa6c74f88419bdc5e82209f4"
	ent.Content = []byte("test!")
	ent.ExtIDs = append(ent.ExtIDs, []byte("test"))
	newChain := NewChain(ent)

	cCommit, _ := ComposeChainCommit(newChain, ecAddr)
	r := new(response)
	json.Unmarshal(cCommit.Params, r)
	binCommit, _ := hex.DecodeString(r.Message)
	t.Logf("%x", binCommit)

	//the commit has a timestamp which is updated new for each time it is called.  This means it is different after each call.
	//we will check the non-changing parts

	if len(binCommit) != 200 {
		t.Error("expected commit to be 200 bytes long, instead got", len(binCommit))
	}
	result := binCommit[0:1]
	expected := []byte{0x00}
	if !bytes.Equal(result, expected) {
		t.Errorf("expected:%s\nrecieved:%s", expected, result)
	}
	//skip the 6 bytes of the timestamp
	result = binCommit[7:136]
	expected, _ = hex.DecodeString("516870d4c0e1ee2d5f0d415e51fc10ae6b8d895561e9314afdc33048194d76f07cc61c8a81aea23d76ff6447689757dc1e36af66e300ce3e06b8d816c79acfd2285ed45081d5b8819a678d13c7c2d04f704b34c74e8aaecd9bd34609bee047200b3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29")

	if !bytes.Equal(result, expected) {
		t.Errorf("expected:%s\nrecieved:%s", expected, result)
	}
}

func TestComposeChainReveal(t *testing.T) {

	ent := new(Entry)
	ent.ChainID = "954d5a49fd70d9b8bcdb35d252267829957f7ef7fa6c74f88419bdc5e82209f4"
	ent.Content = []byte("test!")
	ent.ExtIDs = append(ent.ExtIDs, []byte("test"))
	newChain := NewChain(ent)

	cReveal, _ := ComposeChainReveal(newChain)

	expectedResponse := `{"entry":"00954d5a49fd70d9b8bcdb35d252267829957f7ef7fa6c74f88419bdc5e82209f400060004746573747465737421"}`
	if expectedResponse != string(cReveal.Params) {
		t.Errorf("expected:%s\nrecieved:%s", expectedResponse, cReveal.Params)
	}
}

func TestCommitChain(t *testing.T) {
	simlatedFactomdResponse := `{
   "jsonrpc":"2.0",
   "id":0,
   "result":{
      "message":"Chain Commit Success",
      "txid":"76e123d133a841fe3e08c5e3f3d392f8431f2d7668890c03f003f541efa8fc61"
   }
}`

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, simlatedFactomdResponse)
	}))
	defer ts.Close()

	url := ts.URL[7:]
	SetFactomdServer(url)

	ent := new(Entry)
	ent.ChainID = "954d5a49fd70d9b8bcdb35d252267829957f7ef7fa6c74f88419bdc5e82209f4"
	ent.Content = []byte("test!")
	ent.ExtIDs = append(ent.ExtIDs, []byte("test"))
	newChain := NewChain(ent)
	ecAddr, _ := GetECAddress("Es2Rf7iM6PdsqfYCo3D1tnAR65SkLENyWJG1deUzpRMQmbh9F3eG")

	expectedResponse := "76e123d133a841fe3e08c5e3f3d392f8431f2d7668890c03f003f541efa8fc61"
	response, _ := CommitChain(newChain, ecAddr)

	if expectedResponse != response {
		t.Errorf("expected:%s\nrecieved:%s", expectedResponse, response)
	}
	t.Log(response)
}

func TestRevealChain(t *testing.T) {
	simlatedFactomdResponse := `{
  "jsonrpc": "2.0",
  "id": 0,
  "result": {
    "message": "Entry Reveal Success",
    "entryhash": "f5c956749fc3eba4acc60fd485fb100e601070a44fcce54ff358d60669854734"
  }
}`

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, simlatedFactomdResponse)
	}))
	defer ts.Close()

	url := ts.URL[7:]
	SetFactomdServer(url)

	ent := new(Entry)
	ent.ChainID = "954d5a49fd70d9b8bcdb35d252267829957f7ef7fa6c74f88419bdc5e82209f4"
	ent.Content = []byte("test!")
	ent.ExtIDs = append(ent.ExtIDs, []byte("test"))
	newChain := NewChain(ent)

	expectedResponse := "f5c956749fc3eba4acc60fd485fb100e601070a44fcce54ff358d60669854734"
	response, _ := RevealChain(newChain)

	if expectedResponse != response {
		t.Errorf("expected:%s\nrecieved:%s", expectedResponse, response)
	}
	t.Log(response)
}
<|endoftext|>


<commit_before>// +build acceptance

package acceptance

import (
	"fmt"
	mailgun "github.com/mailgun/mailgun-go"
	"testing"
)

func TestGetBounces(t *testing.T) {
	domain := reqEnv(t, "MG_DOMAIN")
	apiKey := reqEnv(t, "MG_API_KEY")
	mg := mailgun.NewMailgun(domain, apiKey, "")
	n, bounces, err := mg.GetBounces(-1, -1)
	if err != nil {
		t.Fatal(err)
	}
	if n > 0 {
		t.Fatal("Expected no bounces for what should be a clean domain.")
	}
	if n != len(bounces) {
		t.Fatalf("Expected length of bounces %d to equal returned length %d", len(bounces), n)
	}
}

func TestGetSingleBounce(t *testing.T) {
	domain := reqEnv(t, "MG_DOMAIN")
	apiKey := reqEnv(t, "MG_API_KEY")
	mg := mailgun.NewMailgun(domain, apiKey, "")
	exampleEmail := fmt.Sprintf("baz@%s", domain)
	_, err := mg.GetSingleBounce(exampleEmail)
	if err == nil {
		t.Fatal("Did not expect a bounce to exist")
	}
	ure, ok := err.(*mailgun.UnexpectedResponseError)
	if !ok {
		t.Fatal("Expected UnexpectedResponseError")
	}
	if ure.Actual != 404 {
		t.Fatalf("Expected 404 response code; got %d", ure.Actual)
	}
}

func TestAddDelBounces(t *testing.T) {
	domain := reqEnv(t, "MG_DOMAIN")
	apiKey := reqEnv(t, "MG_API_KEY")
	mg := mailgun.NewMailgun(domain, apiKey, "")

	// Compute an e-mail address for our domain.

	exampleEmail := fmt.Sprintf("baz@%s", domain)

	// First, basic sanity check.
	// Fail early if we have bounces for a fictitious e-mail address.

	n, _, err := mg.GetBounces(-1, -1)
	if err != nil {
		t.Fatal(err)
	}
	if n > 0 {
		t.Fatal("Expected no bounces for what should be a clean domain.")
	}

	bounce, err := mg.GetSingleBounce(exampleEmail)
	if err != nil {
		t.Fatal(err)
	}
	if bounce.CreatedAt != "" {
		t.Fatalf("Expected no bounces for %s", exampleEmail)
	}

	// Add the bounce for our address.

	err = mg.AddBounce(exampleEmail, "550", "TestAddDelBounces-generated error")
	if err != nil {
		t.Fatal(err)
	}

	// We should now have one bounce listed when we query the API.

	n, bounces, err := mg.GetBounces(-1, -1)
	if err != nil {
		t.Fatal(err)
	}
	if n != 1 {
		t.Fatal("Expected one bounce for this domain.")
	}
	if bounces[0].Address != exampleEmail {
		t.Fatalf("Expected bounce for address %s; got %s", exampleEmail, bounces[0].Address)
	}

	bounce, err = mg.GetSingleBounce(exampleEmail)
	if err != nil {
		t.Fatal(err)
	}
	if bounce.CreatedAt == "" {
		t.Fatalf("Expected at least one bounce for %s", exampleEmail)
	}

	// Delete it.  This should put us back the way we were.

	err = mg.DeleteBounce(exampleEmail)
	if err != nil {
		t.Fatal(err)
	}

	// Make sure we're back to the way we were.

	n, _, err = mg.GetBounces(-1, -1)
	if err != nil {
		t.Fatal(err)
	}
	if n > 0 {
		t.Fatal("Expected no bounces for what should be a clean domain.")
	}

	bounce, err = mg.GetSingleBounce(exampleEmail)
	if err != nil {
		t.Fatal(err)
	}
	if bounce.CreatedAt != "" {
		t.Fatalf("Expected no bounces for %s", exampleEmail)
	}
}
<commit_msg>Remove vestiges of old error-handling logic<commit_after>// +build acceptance

package acceptance

import (
	"fmt"
	mailgun "github.com/mailgun/mailgun-go"
	"testing"
)

func TestGetBounces(t *testing.T) {
	domain := reqEnv(t, "MG_DOMAIN")
	apiKey := reqEnv(t, "MG_API_KEY")
	mg := mailgun.NewMailgun(domain, apiKey, "")
	n, bounces, err := mg.GetBounces(-1, -1)
	if err != nil {
		t.Fatal(err)
	}
	if n > 0 {
		t.Fatal("Expected no bounces for what should be a clean domain.")
	}
	if n != len(bounces) {
		t.Fatalf("Expected length of bounces %d to equal returned length %d", len(bounces), n)
	}
}

func TestGetSingleBounce(t *testing.T) {
	domain := reqEnv(t, "MG_DOMAIN")
	apiKey := reqEnv(t, "MG_API_KEY")
	mg := mailgun.NewMailgun(domain, apiKey, "")
	exampleEmail := fmt.Sprintf("baz@%s", domain)
	_, err := mg.GetSingleBounce(exampleEmail)
	if err == nil {
		t.Fatal("Did not expect a bounce to exist")
	}
	ure, ok := err.(*mailgun.UnexpectedResponseError)
	if !ok {
		t.Fatal("Expected UnexpectedResponseError")
	}
	if ure.Actual != 404 {
		t.Fatalf("Expected 404 response code; got %d", ure.Actual)
	}
}

func TestAddDelBounces(t *testing.T) {
	domain := reqEnv(t, "MG_DOMAIN")
	apiKey := reqEnv(t, "MG_API_KEY")
	mg := mailgun.NewMailgun(domain, apiKey, "")

	// Compute an e-mail address for our domain.

	exampleEmail := fmt.Sprintf("baz@%s", domain)

	// First, basic sanity check.
	// Fail early if we have bounces for a fictitious e-mail address.

	n, _, err := mg.GetBounces(-1, -1)
	if err != nil {
		t.Fatal(err)
	}
	if n > 0 {
		t.Fatal("Expected no bounces for what should be a clean domain.")
	}

	bounce, err := mg.GetSingleBounce(exampleEmail)
	if err == nil {
		t.Fatalf("Expected no bounces for %s", exampleEmail)
	}

	// Add the bounce for our address.

	err = mg.AddBounce(exampleEmail, "550", "TestAddDelBounces-generated error")
	if err != nil {
		t.Fatal(err)
	}

	// We should now have one bounce listed when we query the API.

	n, bounces, err := mg.GetBounces(-1, -1)
	if err != nil {
		t.Fatal(err)
	}
	if n != 1 {
		t.Fatal("Expected one bounce for this domain.")
	}
	if bounces[0].Address != exampleEmail {
		t.Fatalf("Expected bounce for address %s; got %s", exampleEmail, bounces[0].Address)
	}

	bounce, err = mg.GetSingleBounce(exampleEmail)
	if err != nil {
		t.Fatal(err)
	}
	if bounce.CreatedAt == "" {
		t.Fatalf("Expected at least one bounce for %s", exampleEmail)
	}

	// Delete it.  This should put us back the way we were.

	err = mg.DeleteBounce(exampleEmail)
	if err != nil {
		t.Fatal(err)
	}

	// Make sure we're back to the way we were.

	n, _, err = mg.GetBounces(-1, -1)
	if err != nil {
		t.Fatal(err)
	}
	if n > 0 {
		t.Fatal("Expected no bounces for what should be a clean domain.")
	}

	_, err = mg.GetSingleBounce(exampleEmail)
	if err == nil {
		t.Fatalf("Expected no bounces for %s", exampleEmail)
	}
}
<|endoftext|>