<commit_before>package typescript

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
	"text/template"

	"github.com/bradfitz/slice"

	"strings"

	"github.com/ezbuy/tgen/langs"
	"github.com/ezbuy/tgen/tmpl"
	"github.com/samuel/go-thrift/parser"
)

const TPL_SERVICE = "tgen/typescript/service"

const (
	langName = "typescript"
)

type TypeScriptGen struct {
	langs.BaseGen
}

type Argument struct {
	Name string
	Type string
}

type Method struct {
	ServiceName string
	Name        string
	Arguments   []*Argument
	ReturnType  string
}

type InterfaceField struct {
	Name string
	Type string
}

type Interface struct {
	Name   string
	Fields []*InterfaceField
}

type EnumVal struct {
	Name string
	Val  int
}

type Enum struct {
	Name   string
	Values []*parser.EnumValue
}

type Thrift struct {
	Methods    []*Method
	Interfaces []*Interface
	Includes   []string
	Enums      map[string]*parser.Enum
}

func (t *Thrift) AssembleParamsValType(args []*Argument) string {
	strList := make([]string, 0)
	for _, arg := range args {
		strList = append(strList, arg.Name+": "+arg.Type)
	}

	return strings.Join(strList, ", ")
}

func (t *Thrift) AssembleParamsVal(args []*Argument) string {
	strList := make([]string, 0)
	for _, arg := range args {
		strList = append(strList, arg.Name)
	}

	return strings.Join(strList, ", ")
}

func initemplate(n string, path string) *template.Template {
	data, err := tmpl.Asset(path)
	if err != nil {
		panic(err)
	}

	tpl, err := template.New(n).Parse(string(data))
	if err != nil {
		panic(err)
	}

	return tpl
}

func outputfile(fp string, t *template.Template, tplname string, data interface{}) error {
	file, err := os.OpenFile(fp, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
	if err != nil {
		return err
	}

	defer file.Close()

	return t.ExecuteTemplate(file, tplname, data)
}

func typeCast(t *parser.Type) string {
	if t != nil {
		switch t.Name {
		case langs.ThriftTypeI16, langs.ThriftTypeI32, langs.ThriftTypeI64, langs.ThriftTypeDouble:
			return "number"
		case langs.ThriftTypeString:
			return "string"
		case langs.ThriftTypeBool:
			return "boolean"
		case langs.ThriftTypeList, langs.ThriftTypeSet:
			valType := typeCast(t.ValueType)
			return valType + "[]"
		case langs.ThriftTypeMap:
			return "JSONObject"
		default:
			return t.Name
		}
	}
	return "null"
}

func genOutputPath(base string, fileName string) string {
	start := strings.LastIndex(fileName, "/")
	end := strings.LastIndex(fileName, ".")
	name := fileName[start+1 : end]
	return filepath.Join(base, name+"Service.ts")
}

func (this *TypeScriptGen) Generate(output string, parsedThrift map[string]*parser.Thrift) {
	if err := os.MkdirAll(output, 0755); err != nil {
		panic(fmt.Errorf("failed to create output directory %s", output))
	}

	var servicetpl *template.Template
	servicetpl = initemplate(TPL_SERVICE, "tmpl/typescript/rest_service.gots")

	for fileName, t := range parsedThrift {
		data := &Thrift{
			Methods:    make([]*Method, 0),
			Interfaces: make([]*Interface, 0),
			Includes:   make([]string, 0),
			Enums:      make(map[string]*parser.Enum),
		}
		outputPath := genOutputPath(output, fileName)

		data.Enums = t.Enums

		// fill in Includes
		for name, _ := range t.Includes {
			data.Includes = append(data.Includes, name)
		}
		slice.Sort(data.Includes, func(i, j int) bool {
			return data.Includes[i] < data.Includes[j]
		})

		// fill in Methods
		for _, s := range t.Services {
			for mName, mVal := range s.Methods {
				m := &Method{}
				m.Name = mName
				m.ServiceName = s.Name

				for _, arg := range mVal.Arguments {
					a := &Argument{}

					a.Name = arg.Name
					a.Type = typeCast(arg.Type)
					m.Arguments = append(m.Arguments, a)
				}

				m.ReturnType = typeCast(mVal.ReturnType)

				data.Methods = append(data.Methods, m)
			}
		}
		slice.Sort(data.Methods, func(i, j int) bool {
			return data.Methods[i].ServiceName+data.Methods[i].Name < data.Methods[j].ServiceName+data.Methods[j].Name
		})

		// fill in Interfaces
		interfaces := make([]*Interface, 0)
		for _, s := range t.Structs {
			ife := &Interface{}
			ife.Name = s.Name

			fields := make([]*InterfaceField, 0)
			for _, rawFiled := range s.Fields {
				field := &InterfaceField{}
				field.Name = rawFiled.Name
				field.Type = typeCast(rawFiled.Type)
				if rawFiled.Optional {
					field.Name += "?"
				}
				fields = append(fields, field)
			}
			ife.Fields = fields
			interfaces = append(interfaces, ife)
		}
		data.Interfaces = interfaces
		slice.Sort(data.Interfaces, func(i, j int) bool {
			return data.Interfaces[i].Name < data.Interfaces[j].Name
		})

		if err := outputfile(outputPath, servicetpl, TPL_SERVICE, data); err != nil {
			panic(fmt.Errorf("failed to write file %s. error: %v\n", outputPath, err))
		}

		log.Printf("%s", outputPath)
	}

}

func init() {
	langs.Langs[langName] = &TypeScriptGen{}
}
<commit_msg>Fix typescript map gen (#67)<commit_after>package typescript

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
	"text/template"

	"github.com/bradfitz/slice"

	"strings"

	"github.com/ezbuy/tgen/langs"
	"github.com/ezbuy/tgen/tmpl"
	"github.com/samuel/go-thrift/parser"
)

const TPL_SERVICE = "tgen/typescript/service"

const (
	langName = "typescript"
)

type TypeScriptGen struct {
	langs.BaseGen
}

type Argument struct {
	Name string
	Type string
}

type Method struct {
	ServiceName string
	Name        string
	Arguments   []*Argument
	ReturnType  string
}

type InterfaceField struct {
	Name string
	Type string
}

type Interface struct {
	Name   string
	Fields []*InterfaceField
}

type EnumVal struct {
	Name string
	Val  int
}

type Enum struct {
	Name   string
	Values []*parser.EnumValue
}

type Thrift struct {
	Methods    []*Method
	Interfaces []*Interface
	Includes   []string
	Enums      map[string]*parser.Enum
}

func (t *Thrift) AssembleParamsValType(args []*Argument) string {
	strList := make([]string, 0)
	for _, arg := range args {
		strList = append(strList, arg.Name+": "+arg.Type)
	}

	return strings.Join(strList, ", ")
}

func (t *Thrift) AssembleParamsVal(args []*Argument) string {
	strList := make([]string, 0)
	for _, arg := range args {
		strList = append(strList, arg.Name)
	}

	return strings.Join(strList, ", ")
}

func initemplate(n string, path string) *template.Template {
	data, err := tmpl.Asset(path)
	if err != nil {
		panic(err)
	}

	tpl, err := template.New(n).Parse(string(data))
	if err != nil {
		panic(err)
	}

	return tpl
}

func outputfile(fp string, t *template.Template, tplname string, data interface{}) error {
	file, err := os.OpenFile(fp, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
	if err != nil {
		return err
	}

	defer file.Close()

	return t.ExecuteTemplate(file, tplname, data)
}

func typeCast(t *parser.Type) string {
	if t != nil {
		switch t.Name {
		case langs.ThriftTypeI16, langs.ThriftTypeI32, langs.ThriftTypeI64, langs.ThriftTypeDouble:
			return "number"
		case langs.ThriftTypeString:
			return "string"
		case langs.ThriftTypeBool:
			return "boolean"
		case langs.ThriftTypeList, langs.ThriftTypeSet:
			valType := typeCast(t.ValueType)
			return valType + "[]"
		case langs.ThriftTypeMap:
			return fmt.Sprintf("{[key: %s]: %s}", typeCast(t.KeyType), typeCast(t.ValueType))
		default:
			return t.Name
		}
	}
	return "null"
}

func genOutputPath(base string, fileName string) string {
	start := strings.LastIndex(fileName, "/")
	end := strings.LastIndex(fileName, ".")
	name := fileName[start+1 : end]
	return filepath.Join(base, name+"Service.ts")
}

func (this *TypeScriptGen) Generate(output string, parsedThrift map[string]*parser.Thrift) {
	if err := os.MkdirAll(output, 0755); err != nil {
		panic(fmt.Errorf("failed to create output directory %s", output))
	}

	var servicetpl *template.Template
	servicetpl = initemplate(TPL_SERVICE, "tmpl/typescript/rest_service.gots")

	for fileName, t := range parsedThrift {
		data := &Thrift{
			Methods:    make([]*Method, 0),
			Interfaces: make([]*Interface, 0),
			Includes:   make([]string, 0),
			Enums:      make(map[string]*parser.Enum),
		}
		outputPath := genOutputPath(output, fileName)

		data.Enums = t.Enums

		// fill in Includes
		for name, _ := range t.Includes {
			data.Includes = append(data.Includes, name)
		}
		slice.Sort(data.Includes, func(i, j int) bool {
			return data.Includes[i] < data.Includes[j]
		})

		// fill in Methods
		for _, s := range t.Services {
			for mName, mVal := range s.Methods {
				m := &Method{}
				m.Name = mName
				m.ServiceName = s.Name

				for _, arg := range mVal.Arguments {
					a := &Argument{}

					a.Name = arg.Name
					a.Type = typeCast(arg.Type)
					m.Arguments = append(m.Arguments, a)
				}

				m.ReturnType = typeCast(mVal.ReturnType)

				data.Methods = append(data.Methods, m)
			}
		}
		slice.Sort(data.Methods, func(i, j int) bool {
			return data.Methods[i].ServiceName+data.Methods[i].Name < data.Methods[j].ServiceName+data.Methods[j].Name
		})

		// fill in Interfaces
		interfaces := make([]*Interface, 0)
		for _, s := range t.Structs {
			ife := &Interface{}
			ife.Name = s.Name

			fields := make([]*InterfaceField, 0)
			for _, rawFiled := range s.Fields {
				field := &InterfaceField{}
				field.Name = rawFiled.Name
				field.Type = typeCast(rawFiled.Type)
				if rawFiled.Optional {
					field.Name += "?"
				}
				fields = append(fields, field)
			}
			ife.Fields = fields
			interfaces = append(interfaces, ife)
		}
		data.Interfaces = interfaces
		slice.Sort(data.Interfaces, func(i, j int) bool {
			return data.Interfaces[i].Name < data.Interfaces[j].Name
		})

		if err := outputfile(outputPath, servicetpl, TPL_SERVICE, data); err != nil {
			panic(fmt.Errorf("failed to write file %s. error: %v\n", outputPath, err))
		}

		log.Printf("%s", outputPath)
	}

}

func init() {
	langs.Langs[langName] = &TypeScriptGen{}
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"sort"
	"strconv"
	"strings"

	lua "github.com/anaminus/gopher-lua"
	"github.com/anaminus/pflag"
	"github.com/anaminus/rbxmk"
	"github.com/anaminus/rbxmk/dump"
	"github.com/anaminus/rbxmk/dump/dt"
	"github.com/anaminus/rbxmk/enums"
	"github.com/anaminus/rbxmk/formats"
)

// ParseLuaValue parses a string into a Lua value. Numbers, bools, and nil are
// parsed into their respective types, and any other value is interpreted as a
// string.
func ParseLuaValue(s string) lua.LValue {
	switch s {
	case "true":
		return lua.LTrue
	case "false":
		return lua.LFalse
	case "nil":
		return lua.LNil
	}
	if number, err := strconv.ParseFloat(s, 64); err == nil {
		return lua.LNumber(number)
	}
	return lua.LString(s)
}

// WorldFlags are common command flags involved in initializing a World.
type WorldFlags struct {
	IncludedRoots []string
	InsecurePaths bool
	Debug         bool
	Libraries     []string
}

func (f *WorldFlags) SetFlags(flags *pflag.FlagSet) {
	flags.StringArrayVar(&f.IncludedRoots, "include-root", nil, DocFlag("Flags/world:Flags/include-root"))
	flags.StringArrayVar(&f.Libraries, "libraries", nil, DocFlag("Flags/world:Flags/libraries"))
	flags.BoolVar(&f.InsecurePaths, "allow-insecure-paths", false, DocFlag("Flags/world:Flags/allow-insecure-paths"))
	flags.BoolVar(&f.Debug, "debug", false, DocFlag("Flags/world:Flags/debug"))
}

// WorldOpt are options to InitWorld.
type WorldOpt struct {
	WorldFlags
	ExcludeRoots     bool
	ExcludeFormats   bool
	ExcludeEnums     bool
	IncludeLibraries rbxmk.Libraries
	ExcludeProgram   bool
	Args             []string
}

// InitWorld initializes an rbxmk.World with a common structure.
func InitWorld(opt WorldOpt) (world *rbxmk.World, err error) {
	world = rbxmk.NewWorld(lua.NewState(lua.Options{
		SkipOpenLibs:        true,
		IncludeGoStackTrace: opt.Debug,
	}))
	if !opt.ExcludeRoots {
		if opt.InsecurePaths {
			world.FS.SetSecured(false)
		}
		if wd, err := os.Getwd(); err == nil {
			// Working directory is an accessible root.
			world.FS.AddRoot(wd)
		}
		for _, root := range opt.IncludedRoots {
			world.FS.AddRoot(root)
		}
	}
	if !opt.ExcludeFormats {
		for _, f := range formats.All() {
			world.RegisterFormat(f())
		}
	}
	if !opt.ExcludeEnums {
		world.RegisterEnums(enums.All()...)
	}
	var libraries rbxmk.Libraries
	if !opt.ExcludeProgram {
		libraries = append(libraries, ProgramLibrary)
	}
	libraries = append(libraries, opt.IncludeLibraries...)
	sort.Sort(libraries)
	included := make(map[string]bool, len(libraries))
	for _, lib := range libraries {
		included[lib.Name] = true
	}
	for _, list := range opt.Libraries {
		for _, name := range strings.Split(list, ",") {
			name = strings.TrimSpace(name)
			if name == "" {
				continue
			}
			include := true
			switch name[0] {
			case '-':
				include = false
				name = name[1:]
			case '+':
				include = true
				name = name[1:]
			}
			if name == "*" {
				for lib := range included {
					included[lib] = include
				}
			} else if _, ok := included[name]; ok {
				included[name] = include
			}
		}
	}
	for _, lib := range libraries {
		if !included[lib.Name] {
			continue
		}
		if err := world.Open(lib); err != nil {
			return nil, err
		}
	}
	for _, arg := range opt.Args {
		world.LuaState().Push(ParseLuaValue(arg))
	}
	return world, nil
}

func dumpTypes(dst dump.TypeDefs, src []func() rbxmk.Reflector) {
	for _, t := range src {
		r := t()
		if _, ok := dst[r.Name]; ok {
			continue
		}
		dst[r.Name] = r.DumpAll()
		dumpTypes(dst, r.Types)
	}
}

func DumpWorld(world *rbxmk.World) dump.Root {
	state := world.State()
	root := dump.Root{
		Formats: dump.Formats{},
		Types:   dump.TypeDefs{},
	}
	for _, format := range world.Formats() {
		root.Formats[format.Name] = format.Dump()
	}
	for _, l := range world.Libraries() {
		if l.Dump == nil {
			continue
		}
		lib := l.Dump(state)
		if lib.Name == "" {
			lib.Name = l.Name
		}
		if lib.ImportedAs == "" {
			lib.ImportedAs = l.ImportedAs
		}
		lib.Priority = l.Priority
		if l.Types != nil {
			dumpTypes(root.Types, l.Types)
		}
		root.Libraries = append(root.Libraries, lib)
	}
	root.Fragments = DocFragments()
	root.Description = "Libraries"
	return root
}

var ProgramLibrary = rbxmk.Library{
	Name:       "program",
	ImportedAs: "",
	Priority:   0,
	Open: func(s rbxmk.State) *lua.LTable {
		lib := s.L.CreateTable(0, 1)
		lib.RawSetString("_RBXMK_VERSION", lua.LString(VersionString()))
		return lib
	},
	Dump: func(s rbxmk.State) dump.Library {
		return dump.Library{
			Name:       "program",
			ImportedAs: "",
			Struct: dump.Struct{
				Fields: dump.Fields{
					"_RBXMK_VERSION": dump.Property{
						ValueType:   dt.Prim("string"),
						ReadOnly:    true,
						Summary:     "Libraries/program:Fields/_RBXMK_VERSION/Summary",
						Description: "Libraries/program:Fields/_RBXMK_VERSION/Description",
					},
				},
				Summary:     "Libraries/program:Summary",
				Description: "Libraries/program:Description",
			},
		}
	},
}
<commit_msg>Load negative-priority libraries before everything else.<commit_after>package main

import (
	"os"
	"sort"
	"strconv"
	"strings"

	lua "github.com/anaminus/gopher-lua"
	"github.com/anaminus/pflag"
	"github.com/anaminus/rbxmk"
	"github.com/anaminus/rbxmk/dump"
	"github.com/anaminus/rbxmk/dump/dt"
	"github.com/anaminus/rbxmk/enums"
	"github.com/anaminus/rbxmk/formats"
)

// ParseLuaValue parses a string into a Lua value. Numbers, bools, and nil are
// parsed into their respective types, and any other value is interpreted as a
// string.
func ParseLuaValue(s string) lua.LValue {
	switch s {
	case "true":
		return lua.LTrue
	case "false":
		return lua.LFalse
	case "nil":
		return lua.LNil
	}
	if number, err := strconv.ParseFloat(s, 64); err == nil {
		return lua.LNumber(number)
	}
	return lua.LString(s)
}

// WorldFlags are common command flags involved in initializing a World.
type WorldFlags struct {
	IncludedRoots []string
	InsecurePaths bool
	Debug         bool
	Libraries     []string
}

func (f *WorldFlags) SetFlags(flags *pflag.FlagSet) {
	flags.StringArrayVar(&f.IncludedRoots, "include-root", nil, DocFlag("Flags/world:Flags/include-root"))
	flags.StringArrayVar(&f.Libraries, "libraries", nil, DocFlag("Flags/world:Flags/libraries"))
	flags.BoolVar(&f.InsecurePaths, "allow-insecure-paths", false, DocFlag("Flags/world:Flags/allow-insecure-paths"))
	flags.BoolVar(&f.Debug, "debug", false, DocFlag("Flags/world:Flags/debug"))
}

// WorldOpt are options to InitWorld.
type WorldOpt struct {
	WorldFlags
	ExcludeRoots     bool
	ExcludeFormats   bool
	ExcludeEnums     bool
	IncludeLibraries rbxmk.Libraries
	ExcludeProgram   bool
	Args             []string
}

// InitWorld initializes an rbxmk.World with a common structure.
func InitWorld(opt WorldOpt) (world *rbxmk.World, err error) {
	world = rbxmk.NewWorld(lua.NewState(lua.Options{
		SkipOpenLibs:        true,
		IncludeGoStackTrace: opt.Debug,
	}))
	if !opt.ExcludeRoots {
		if opt.InsecurePaths {
			world.FS.SetSecured(false)
		}
		if wd, err := os.Getwd(); err == nil {
			// Working directory is an accessible root.
			world.FS.AddRoot(wd)
		}
		for _, root := range opt.IncludedRoots {
			world.FS.AddRoot(root)
		}
	}
	var libraries rbxmk.Libraries
	if !opt.ExcludeProgram {
		libraries = append(libraries, ProgramLibrary)
	}
	libraries = append(libraries, opt.IncludeLibraries...)
	sort.Sort(libraries)
	included := make(map[string]bool, len(libraries))
	for _, lib := range libraries {
		included[lib.Name] = true
	}
	for _, list := range opt.Libraries {
		for _, name := range strings.Split(list, ",") {
			name = strings.TrimSpace(name)
			if name == "" {
				continue
			}
			include := true
			switch name[0] {
			case '-':
				include = false
				name = name[1:]
			case '+':
				include = true
				name = name[1:]
			}
			if name == "*" {
				for lib := range included {
					included[lib] = include
				}
			} else if _, ok := included[name]; ok {
				included[name] = include
			}
		}
	}
	// Load negative-priority libraries before formats.
	for _, lib := range libraries {
		if lib.Priority >= 0 {
			break
		}
		if !included[lib.Name] {
			continue
		}
		if err := world.Open(lib); err != nil {
			return nil, err
		}
	}
	if !opt.ExcludeFormats {
		for _, f := range formats.All() {
			world.RegisterFormat(f())
		}
	}
	if !opt.ExcludeEnums {
		world.RegisterEnums(enums.All()...)
	}
	for _, lib := range libraries {
		if lib.Priority < 0 {
			// Already loaded negative-priority libraries.
			continue
		}
		if !included[lib.Name] {
			continue
		}
		if err := world.Open(lib); err != nil {
			return nil, err
		}
	}
	for _, arg := range opt.Args {
		world.LuaState().Push(ParseLuaValue(arg))
	}
	return world, nil
}

func dumpTypes(dst dump.TypeDefs, src []func() rbxmk.Reflector) {
	for _, t := range src {
		r := t()
		if _, ok := dst[r.Name]; ok {
			continue
		}
		dst[r.Name] = r.DumpAll()
		dumpTypes(dst, r.Types)
	}
}

func DumpWorld(world *rbxmk.World) dump.Root {
	state := world.State()
	root := dump.Root{
		Formats: dump.Formats{},
		Types:   dump.TypeDefs{},
	}
	for _, format := range world.Formats() {
		root.Formats[format.Name] = format.Dump()
	}
	for _, l := range world.Libraries() {
		if l.Dump == nil {
			continue
		}
		lib := l.Dump(state)
		if lib.Name == "" {
			lib.Name = l.Name
		}
		if lib.ImportedAs == "" {
			lib.ImportedAs = l.ImportedAs
		}
		lib.Priority = l.Priority
		if l.Types != nil {
			dumpTypes(root.Types, l.Types)
		}
		root.Libraries = append(root.Libraries, lib)
	}
	root.Fragments = DocFragments()
	root.Description = "Libraries"
	return root
}

var ProgramLibrary = rbxmk.Library{
	Name:       "program",
	ImportedAs: "",
	Priority:   0,
	Open: func(s rbxmk.State) *lua.LTable {
		lib := s.L.CreateTable(0, 1)
		lib.RawSetString("_RBXMK_VERSION", lua.LString(VersionString()))
		return lib
	},
	Dump: func(s rbxmk.State) dump.Library {
		return dump.Library{
			Name:       "program",
			ImportedAs: "",
			Struct: dump.Struct{
				Fields: dump.Fields{
					"_RBXMK_VERSION": dump.Property{
						ValueType:   dt.Prim("string"),
						ReadOnly:    true,
						Summary:     "Libraries/program:Fields/_RBXMK_VERSION/Summary",
						Description: "Libraries/program:Fields/_RBXMK_VERSION/Description",
					},
				},
				Summary:     "Libraries/program:Summary",
				Description: "Libraries/program:Description",
			},
		}
	},
}
<|endoftext|>


<commit_before>package gui

import (
  "image"
  "image/draw"
  "freetype-go.googlecode.com/hg/freetype"
  "freetype-go.googlecode.com/hg/freetype/truetype"
  "gl"
  "gl/glu"
  "io/ioutil"
  "os"
  "path"
)

func mustLoadFont(filename string) *truetype.Font {
  data,err := ioutil.ReadFile(filename)
  if err != nil {
    panic(err.String())
  }
  font,err := freetype.ParseFont(data)
  if err != nil {
    panic(err.String())
  }
  return font
}

func drawText(font *truetype.Font, c *freetype.Context, rgba *image.RGBA, text string) (int,int) {
  fg, bg := image.Black, image.White
  draw.Draw(rgba, rgba.Bounds(), bg, image.ZP, draw.Src)
  c.SetFont(font)
  c.SetDst(rgba)
  c.SetSrc(fg)
  c.SetClip(rgba.Bounds())
  pt := freetype.Pt(0, int(float64(c.FUnitToPixelRU(font.UnitsPerEm())) * 0.85) )
  adv,_ := c.DrawString(text, pt)
  pt.X += adv.X
  py := int(float64(pt.Y >> 8) / 0.85 + 0.01)
  return int(pt.X >> 8), py
}

var basic_font *truetype.Font

func init() {
  fontpath := os.Args[0] + "/../../fonts/skia.ttf"
  fontpath = path.Clean(fontpath)
  basic_font = mustLoadFont(fontpath)
}

type SingleLineText struct {
  Childless
  Stoic
  text      string
  changed   bool
  dims      Dims
  rdims     Dims
  psize     int
  font      *truetype.Font
  context   *freetype.Context
  glyph_buf *truetype.GlyphBuf
  texture   gl.Texture
  rgba      *image.RGBA
}

func nextPowerOf2(n uint32) uint32 {
  if n == 0 { return 1 }
  for i := uint(0); i < 32; i++ {
    p := uint32(1) << i
    if n <= p { return p }
  }
  return 0
}

func (t *SingleLineText) figureDims() {
  t.dims.Dx, t.dims.Dy = drawText(t.font, t.context, image.NewRGBA(1, 1), t.text)
  t.rdims = Dims{
    Dx : int(nextPowerOf2(uint32(t.dims.Dx))),
    Dy : int(nextPowerOf2(uint32(t.dims.Dy))),
  }
  t.rgba = image.NewRGBA(t.rdims.Dx, t.rdims.Dy)
  drawText(t.font, t.context, t.rgba, t.text)

  gl.Enable(gl.TEXTURE_2D)
  t.texture.Bind(gl.TEXTURE_2D)
  gl.TexEnvf(gl.TEXTURE_ENV, gl.TEXTURE_ENV_MODE, gl.MODULATE)
  gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
  gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
  gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT)
  gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT)
  glu.Build2DMipmaps(gl.TEXTURE_2D, 4, t.rdims.Dx, t.rdims.Dy, gl.RGBA, t.rgba.Pix)
}

func MakeSingleLineText(font *truetype.Font, str string) *SingleLineText {
  var t SingleLineText
  t.glyph_buf = truetype.NewGlyphBuf()
  t.text = str
  t.font = font
  t.psize = 72
  t.context = freetype.NewContext()
  t.context.SetDPI(113)
  t.context.SetFontSize(18)
  t.texture = gl.GenTexture()
  t.figureDims()
  return &t
}

func (t *SingleLineText) SetText(str string) {
  if t.text != str {
    t.text = str
    t.changed = true
  }
}

func (t *SingleLineText) Think(_ int64, _ bool, _ Region, _ map[Widget]Dims) (bool,Dims) {
  if !t.changed {
    return false, t.dims
  }
  t.changed = false
  t.figureDims()
  return false, t.dims
}

func (t *SingleLineText) Draw(region Region) {
  gl.Enable(gl.TEXTURE_2D)
  gl.Enable(gl.BLEND)
  t.texture.Bind(gl.TEXTURE_2D)
  gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL)
  fx := float64(region.X)
  fy := float64(region.Y)
  fdx := float64(t.dims.Dx)
  fdy := float64(t.dims.Dy)
  tx := float64(t.dims.Dx)/float64(t.rdims.Dx)
  ty := float64(t.dims.Dy)/float64(t.rdims.Dy)
  gl.Color4d(1.0, 1.0, 1.0, 0.7)
  gl.Begin(gl.QUADS)
    gl.TexCoord2d(0,ty)
    gl.Vertex2d(fx, fy)
    gl.TexCoord2d(0,0)
    gl.Vertex2d(fx, fy+fdy)
    gl.TexCoord2d(tx,0)
    gl.Vertex2d(fx+fdx, fy+fdy)
    gl.TexCoord2d(tx,ty)
    gl.Vertex2d(fx+fdx, fy)
  gl.End()
  gl.Disable(gl.TEXTURE_2D)
}
<commit_msg>Changed default DPI to the iPad's DPI<commit_after>package gui

import (
  "image"
  "image/draw"
  "freetype-go.googlecode.com/hg/freetype"
  "freetype-go.googlecode.com/hg/freetype/truetype"
  "gl"
  "gl/glu"
  "io/ioutil"
  "os"
  "path"
)

func mustLoadFont(filename string) *truetype.Font {
  data,err := ioutil.ReadFile(filename)
  if err != nil {
    panic(err.String())
  }
  font,err := freetype.ParseFont(data)
  if err != nil {
    panic(err.String())
  }
  return font
}

func drawText(font *truetype.Font, c *freetype.Context, rgba *image.RGBA, text string) (int,int) {
  fg, bg := image.Black, image.White
  draw.Draw(rgba, rgba.Bounds(), bg, image.ZP, draw.Src)
  c.SetFont(font)
  c.SetDst(rgba)
  c.SetSrc(fg)
  c.SetClip(rgba.Bounds())
  pt := freetype.Pt(0, int(float64(c.FUnitToPixelRU(font.UnitsPerEm())) * 0.85) )
  adv,_ := c.DrawString(text, pt)
  pt.X += adv.X
  py := int(float64(pt.Y >> 8) / 0.85 + 0.01)
  return int(pt.X >> 8), py
}

var basic_font *truetype.Font

func init() {
  fontpath := os.Args[0] + "/../../fonts/skia.ttf"
  fontpath = path.Clean(fontpath)
  basic_font = mustLoadFont(fontpath)
}

type SingleLineText struct {
  Childless
  Stoic
  text      string
  changed   bool
  dims      Dims
  rdims     Dims
  psize     int
  font      *truetype.Font
  context   *freetype.Context
  glyph_buf *truetype.GlyphBuf
  texture   gl.Texture
  rgba      *image.RGBA
}

func nextPowerOf2(n uint32) uint32 {
  if n == 0 { return 1 }
  for i := uint(0); i < 32; i++ {
    p := uint32(1) << i
    if n <= p { return p }
  }
  return 0
}

func (t *SingleLineText) figureDims() {
  t.dims.Dx, t.dims.Dy = drawText(t.font, t.context, image.NewRGBA(1, 1), t.text)
  t.rdims = Dims{
    Dx : int(nextPowerOf2(uint32(t.dims.Dx))),
    Dy : int(nextPowerOf2(uint32(t.dims.Dy))),
  }
  t.rgba = image.NewRGBA(t.rdims.Dx, t.rdims.Dy)
  drawText(t.font, t.context, t.rgba, t.text)

  gl.Enable(gl.TEXTURE_2D)
  t.texture.Bind(gl.TEXTURE_2D)
  gl.TexEnvf(gl.TEXTURE_ENV, gl.TEXTURE_ENV_MODE, gl.MODULATE)
  gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
  gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
  gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT)
  gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT)
  glu.Build2DMipmaps(gl.TEXTURE_2D, 4, t.rdims.Dx, t.rdims.Dy, gl.RGBA, t.rgba.Pix)
}

func MakeSingleLineText(font *truetype.Font, str string) *SingleLineText {
  var t SingleLineText
  t.glyph_buf = truetype.NewGlyphBuf()
  t.text = str
  t.font = font
  t.psize = 72
  t.context = freetype.NewContext()
  t.context.SetDPI(132)
  t.context.SetFontSize(18)
  t.texture = gl.GenTexture()
  t.figureDims()
  return &t
}

func (t *SingleLineText) SetText(str string) {
  if t.text != str {
    t.text = str
    t.changed = true
  }
}

func (t *SingleLineText) Think(_ int64, _ bool, _ Region, _ map[Widget]Dims) (bool,Dims) {
  if !t.changed {
    return false, t.dims
  }
  t.changed = false
  t.figureDims()
  return false, t.dims
}

func (t *SingleLineText) Draw(region Region) {
  gl.Enable(gl.TEXTURE_2D)
  gl.Enable(gl.BLEND)
  t.texture.Bind(gl.TEXTURE_2D)
  gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL)
  fx := float64(region.X)
  fy := float64(region.Y)
  fdx := float64(t.dims.Dx)
  fdy := float64(t.dims.Dy)
  tx := float64(t.dims.Dx)/float64(t.rdims.Dx)
  ty := float64(t.dims.Dy)/float64(t.rdims.Dy)
  gl.Color4d(1.0, 1.0, 1.0, 0.7)
  gl.Begin(gl.QUADS)
    gl.TexCoord2d(0,ty)
    gl.Vertex2d(fx, fy)
    gl.TexCoord2d(0,0)
    gl.Vertex2d(fx, fy+fdy)
    gl.TexCoord2d(tx,0)
    gl.Vertex2d(fx+fdx, fy+fdy)
    gl.TexCoord2d(tx,ty)
    gl.Vertex2d(fx+fdx, fy)
  gl.End()
  gl.Disable(gl.TEXTURE_2D)
}
<|endoftext|>


<commit_before>package lib

import (
	"fmt"
	"io/ioutil"
	"os/exec"
	"strings"

	"github.com/subutai-io/base/agent/config"
	"github.com/subutai-io/base/agent/lib/net"
	"github.com/subutai-io/base/agent/lib/net/p2p"
	"github.com/subutai-io/base/agent/log"
)

func VxlanTunnel(create, del, remoteip, vlan, vni string, list bool) {
	if len(create) > 0 {
		tunnelCreate(create, remoteip, vlan, vni)
	} else if len(del) > 0 {
		net.DelIface(del)
		return
	} else if list {
		tunnelList()
		return
	}
}

func DetectIp() {
	fmt.Println(net.GetIp())
}

func tunnelCreate(tunnel, addr, vlan, vni string) {
	log.Check(log.WarnLevel, "Creating bridge ", exec.Command("ovs-vsctl", "--may-exist", "add-br", "gw-"+vlan).Run())

	log.Check(log.FatalLevel, "Creating tunnel port",
		exec.Command("ovs-vsctl", "--may-exist", "add-port", "gw-"+vlan, tunnel, "--", "set", "interface", tunnel, "type=vxlan",
			"options:stp_enable=true", "options:key="+vni, "options:remote_ip="+string(addr)).Run())

	log.Check(log.FatalLevel, "MakeVNIMap set port: ", exec.Command("ovs-vsctl", "--if-exists", "set", "port", tunnel, "tag="+vlan).Run())
}

func tunnelList() {
	ret, err := exec.Command("ovs-vsctl", "show").CombinedOutput()
	log.Check(log.FatalLevel, "Getting OVS interfaces list", err)
	ports := strings.Split(string(ret), "\n")

	for k, port := range ports {
		if strings.Contains(port, "remote_ip") {
			tunnel := strings.Trim(strings.Trim(ports[k-2], "Interface "), "\"")
			tag := strings.TrimLeft(ports[k-3], "tag: ")
			addr := strings.Fields(port)
			vni := strings.Trim(strings.Trim(addr[1], "{key="), "\",")
			ip := strings.Trim(strings.Trim(addr[2], "remote_ip="), "\",")
			fmt.Println(tunnel, ip, tag, vni)
		}
	}
}

func P2P(c, d, u, l, p bool, args []string) {
	if c {
		if len(args) > 9 {
			p2p.Create(args[4], args[8], args[5], args[6], args[7], args[9])
		} else if len(args) > 8 {
			if strings.Contains(args[8], "-") {
				p2p.Create(args[4], "dhcp", args[5], args[6], args[7], "")
			} else {
				p2p.Create(args[4], args[8], args[5], args[6], args[7], "")
			}
		} else if len(args) > 7 {
			p2p.Create(args[4], "dhcp", args[5], args[6], args[7], "")
		} else {
			fmt.Println("Wrong usage")
		}
	} else if u {
		if len(args) > 6 {
			p2p.UpdateKey(args[4], args[5], args[6])
		} else {
			fmt.Println("Wrong usage")
		}
	} else if d {
		if len(args) > 4 {
			p2p.Remove(args[4])
		} else {
			fmt.Println("Wrong usage")
		}
	} else if p {
		if len(args) > 4 {
			p2p.Peers(args[4])
		} else {
			p2p.Peers("")
		}
	}
}

func P2Pversion() {
	p2p.Version()
}

func LxcManagementNetwork(args []string) {
	if len(args) < 3 {
		log.Error("Not enough arguments")
	}
	switch args[2] {
	case "-v", "--listvnimap":
		displayVNIMap()
	case "-m", "--createvnimap":
		createVNIMap(args[3], args[4], args[5], args[6])
	case "-c", "--createtunnel":
		createTunnel(args[3], args[4], args[5])
	case "-l", "--listtunnel":
		listTunnel()
	}
}

func listTunnel() {
	fmt.Println("List of Tunnels\n--------")
	ret, err := exec.Command("ovs-vsctl", "show").CombinedOutput()
	log.Check(log.FatalLevel, "Getting OVS interfaces list", err)
	ports := strings.Split(string(ret), "\n")

	for k, port := range ports {
		if strings.Contains(port, "remote_ip") {
			iface := strings.Fields(ports[k-2])
			tunnel := strings.Trim(iface[1], "\"")
			addr := strings.Fields(port)
			fmt.Println(tunnel + "-" + strings.Trim(strings.Trim(addr[2], "remote_ip="), "\","))
		}
	}

}

func createTunnel(tunnel, addr, tunType string) {
	ifTunExist(tunnel)
	err := ioutil.WriteFile(config.Agent.DataPrefix+"var/subutai-network/"+tunnel, []byte(addr), 0600)
	log.Check(log.ErrorLevel, "Creating tunnel file", err)

}

func ifTunExist(name string) {
	ret, err := exec.Command("ovs-vsctl", "list-ports", "wan").CombinedOutput()
	log.Check(log.FatalLevel, "Getting port list", err)
	ports := strings.Split(string(ret), "\n")

	for _, port := range ports {
		if port == name {
			log.Error("Tunnel port " + name + " is already exists")
		}
	}
}

func displayVNIMap() {
	// tunnel1	8880164	100	04c088b9-e2f5-40b3-bd6c-2305b9a88058
	ret, err := exec.Command("ovs-vsctl", "show").CombinedOutput()
	log.Check(log.FatalLevel, "Getting OVS interfaces list", err)
	ports := strings.Split(string(ret), "\n")

	for k, port := range ports {
		if strings.Contains(port, "env") {
			iface := strings.Fields(ports[k-2])
			tunname := strings.Trim(iface[1], "\"")
			tag := strings.Fields(ports[k-3])[1]
			addr := strings.Fields(port)
			// ip := strings.Trim(strings.Trim(addr[3], "remote_ip="), "\",")
			key := strings.Trim(strings.Trim(addr[2], "key="), "\",")
			env := strings.Trim(strings.Trim(addr[1], "{env="), "\",")
			fmt.Println(tunname + " " + key + " " + tag + " " + env)
		}
	}
}

func createVNIMap(tunnel, vni, vlan, envid string) {
	log.Check(log.WarnLevel, "Creating bridge ", exec.Command("ovs-vsctl", "add-br", "gw-"+vlan).Run())

	addr, _ := ioutil.ReadFile(config.Agent.DataPrefix + "var/subutai-network/" + tunnel)
	log.Check(log.FatalLevel, "Creating tunnel port",
		exec.Command("ovs-vsctl", "--may-exist", "add-port", "gw-"+vlan, tunnel, "--", "set", "interface", tunnel, "type=vxlan",
			"options:stp_enable=true", "options:key="+vni, "options:remote_ip="+string(addr), "options:env="+envid).Run())

	log.Check(log.FatalLevel, "MakeVNIMap set port: ", exec.Command("ovs-vsctl", "--if-exists", "set", "port", tunnel, "tag="+vlan).Run())
}
<commit_msg>Refactored binding for p2p<commit_after>package lib

import (
	"fmt"
	"io/ioutil"
	"os/exec"
	"strings"

	"github.com/subutai-io/base/agent/config"
	"github.com/subutai-io/base/agent/lib/net"
	"github.com/subutai-io/base/agent/lib/net/p2p"
	"github.com/subutai-io/base/agent/log"
)

func VxlanTunnel(create, del, remoteip, vlan, vni string, list bool) {
	if len(create) > 0 {
		tunnelCreate(create, remoteip, vlan, vni)
	} else if len(del) > 0 {
		net.DelIface(del)
		return
	} else if list {
		tunnelList()
		return
	}
}

func DetectIp() {
	fmt.Println(net.GetIp())
}

func tunnelCreate(tunnel, addr, vlan, vni string) {
	log.Check(log.WarnLevel, "Creating bridge ", exec.Command("ovs-vsctl", "--may-exist", "add-br", "gw-"+vlan).Run())

	log.Check(log.FatalLevel, "Creating tunnel port",
		exec.Command("ovs-vsctl", "--may-exist", "add-port", "gw-"+vlan, tunnel, "--", "set", "interface", tunnel, "type=vxlan",
			"options:stp_enable=true", "options:key="+vni, "options:remote_ip="+string(addr)).Run())

	log.Check(log.FatalLevel, "MakeVNIMap set port: ", exec.Command("ovs-vsctl", "--if-exists", "set", "port", tunnel, "tag="+vlan).Run())
}

func tunnelList() {
	ret, err := exec.Command("ovs-vsctl", "show").CombinedOutput()
	log.Check(log.FatalLevel, "Getting OVS interfaces list", err)
	ports := strings.Split(string(ret), "\n")

	for k, port := range ports {
		if strings.Contains(port, "remote_ip") {
			tunnel := strings.Trim(strings.Trim(ports[k-2], "Interface "), "\"")
			tag := strings.TrimLeft(ports[k-3], "tag: ")
			addr := strings.Fields(port)
			vni := strings.Trim(strings.Trim(addr[1], "{key="), "\",")
			ip := strings.Trim(strings.Trim(addr[2], "remote_ip="), "\",")
			fmt.Println(tunnel, ip, tag, vni)
		}
	}
}

func P2P(create, remove, update, list, peers bool, args []string) {
	if create {
		if len(args) > 9 {
			p2p.Create(args[4], args[8], args[5], args[6], args[7], args[9]) //p2p -c interfaceName hash key ttl localPeepIPAddr portRange

		} else if len(args) > 8 {
			if strings.Contains(args[8], "-") {
				p2p.Create(args[4], "dhcp", args[5], args[6], args[7], args[8]) //p2p -c interfaceName hash key ttl portRange
			} else {
				p2p.Create(args[4], args[8], args[5], args[6], args[7], "") //p2p -c interfaceName hash key ttl localPeepIPAddr
			}
		} else if len(args) > 7 {
			p2p.Create(args[4], "dhcp", args[5], args[6], args[7], "") //p2p -c interfaceName hash key ttl
		} else {
			log.Error("Wrong usage")
		}

	} else if update {
		if len(args) < 7 {
			log.Error("Wrong usage")
		}
		p2p.UpdateKey(args[4], args[5], args[6])

	} else if remove {
		if len(args) < 5 {
			log.Error("Wrong usage")
		}
		p2p.Remove(args[4])

	} else if peers {
		if len(args) < 4 {
			p2p.Peers(args[4])
		} else {
			p2p.Peers("")
		}
	}
}

func P2Pversion() {
	p2p.Version()
}

func LxcManagementNetwork(args []string) {
	if len(args) < 3 {
		log.Error("Not enough arguments")
	}
	switch args[2] {
	case "-v", "--listvnimap":
		displayVNIMap()
	case "-m", "--createvnimap":
		createVNIMap(args[3], args[4], args[5], args[6])
	case "-c", "--createtunnel":
		createTunnel(args[3], args[4], args[5])
	case "-l", "--listtunnel":
		listTunnel()
	}
}

func listTunnel() {
	fmt.Println("List of Tunnels\n--------")
	ret, err := exec.Command("ovs-vsctl", "show").CombinedOutput()
	log.Check(log.FatalLevel, "Getting OVS interfaces list", err)
	ports := strings.Split(string(ret), "\n")

	for k, port := range ports {
		if strings.Contains(port, "remote_ip") {
			iface := strings.Fields(ports[k-2])
			tunnel := strings.Trim(iface[1], "\"")
			addr := strings.Fields(port)
			fmt.Println(tunnel + "-" + strings.Trim(strings.Trim(addr[2], "remote_ip="), "\","))
		}
	}

}

func createTunnel(tunnel, addr, tunType string) {
	ifTunExist(tunnel)
	err := ioutil.WriteFile(config.Agent.DataPrefix+"var/subutai-network/"+tunnel, []byte(addr), 0600)
	log.Check(log.ErrorLevel, "Creating tunnel file", err)

}

func ifTunExist(name string) {
	ret, err := exec.Command("ovs-vsctl", "list-ports", "wan").CombinedOutput()
	log.Check(log.FatalLevel, "Getting port list", err)
	ports := strings.Split(string(ret), "\n")

	for _, port := range ports {
		if port == name {
			log.Error("Tunnel port " + name + " is already exists")
		}
	}
}

func displayVNIMap() {
	// tunnel1	8880164	100	04c088b9-e2f5-40b3-bd6c-2305b9a88058
	ret, err := exec.Command("ovs-vsctl", "show").CombinedOutput()
	log.Check(log.FatalLevel, "Getting OVS interfaces list", err)
	ports := strings.Split(string(ret), "\n")

	for k, port := range ports {
		if strings.Contains(port, "env") {
			iface := strings.Fields(ports[k-2])
			tunname := strings.Trim(iface[1], "\"")
			tag := strings.Fields(ports[k-3])[1]
			addr := strings.Fields(port)
			// ip := strings.Trim(strings.Trim(addr[3], "remote_ip="), "\",")
			key := strings.Trim(strings.Trim(addr[2], "key="), "\",")
			env := strings.Trim(strings.Trim(addr[1], "{env="), "\",")
			fmt.Println(tunname + " " + key + " " + tag + " " + env)
		}
	}
}

func createVNIMap(tunnel, vni, vlan, envid string) {
	log.Check(log.WarnLevel, "Creating bridge ", exec.Command("ovs-vsctl", "add-br", "gw-"+vlan).Run())

	addr, _ := ioutil.ReadFile(config.Agent.DataPrefix + "var/subutai-network/" + tunnel)
	log.Check(log.FatalLevel, "Creating tunnel port",
		exec.Command("ovs-vsctl", "--may-exist", "add-port", "gw-"+vlan, tunnel, "--", "set", "interface", tunnel, "type=vxlan",
			"options:stp_enable=true", "options:key="+vni, "options:remote_ip="+string(addr), "options:env="+envid).Run())

	log.Check(log.FatalLevel, "MakeVNIMap set port: ", exec.Command("ovs-vsctl", "--if-exists", "set", "port", tunnel, "tag="+vlan).Run())
}
<|endoftext|>


<commit_before>package agent

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
	"strconv"
	"strings"
	"time"

	"github.com/hashicorp/consul/acl"
	"github.com/hashicorp/consul/agent/structs"
)

const (
	// maxQueryTime is used to bound the limit of a blocking query
	maxQueryTime = 600 * time.Second
)

// EventFire is used to fire a new event
func (s *HTTPServer) EventFire(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Mandate a PUT request
	if req.Method != "PUT" {
		resp.WriteHeader(http.StatusMethodNotAllowed) // 405
		return nil, nil
	}

	// Get the datacenter
	var dc string
	s.parseDC(req, &dc)

	event := &UserEvent{}
	event.Name = strings.TrimPrefix(req.URL.Path, "/v1/event/fire/")
	if event.Name == "" {
		resp.WriteHeader(http.StatusBadRequest) // 400
		fmt.Fprint(resp, "Missing name")
		return nil, nil
	}

	// Get the ACL token
	var token string
	s.parseToken(req, &token)

	// Get the filters
	if filt := req.URL.Query().Get("node"); filt != "" {
		event.NodeFilter = filt
	}
	if filt := req.URL.Query().Get("service"); filt != "" {
		event.ServiceFilter = filt
	}
	if filt := req.URL.Query().Get("tag"); filt != "" {
		event.TagFilter = filt
	}

	// Get the payload
	if req.ContentLength > 0 {
		var buf bytes.Buffer
		if _, err := io.Copy(&buf, req.Body); err != nil {
			return nil, err
		}
		event.Payload = buf.Bytes()
	}

	// Try to fire the event
	if err := s.agent.UserEvent(dc, token, event); err != nil {
		if acl.IsErrPermissionDenied(err) {
			resp.WriteHeader(http.StatusForbidden) // 403
			fmt.Fprint(resp, acl.ErrPermissionDenied.Error())
			return nil, nil
		}
		resp.WriteHeader(500)
		return nil, err
	}

	// Return the event
	return event, nil
}

// EventList is used to retrieve the recent list of events
func (s *HTTPServer) EventList(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Parse the query options, since we simulate a blocking query
	var b structs.QueryOptions
	if parseWait(resp, req, &b) {
		return nil, nil
	}

	// Fetch the ACL token, if any.
	var token string
	s.parseToken(req, &token)
	acl, err := s.agent.resolveToken(token)
	if err != nil {
		return nil, err
	}

	// Look for a name filter
	var nameFilter string
	if filt := req.URL.Query().Get("name"); filt != "" {
		nameFilter = filt
	}

	// Lots of this logic is borrowed from consul/rpc.go:blockingQuery
	// However we cannot use that directly since this code has some
	// slight semantics differences...
	var timeout <-chan time.Time
	var notifyCh chan struct{}

	// Fast path non-blocking
	if b.MinQueryIndex == 0 {
		goto RUN_QUERY
	}

	// Restrict the max query time
	if b.MaxQueryTime > maxQueryTime {
		b.MaxQueryTime = maxQueryTime
	}

	// Ensure a time limit is set if we have an index
	if b.MinQueryIndex > 0 && b.MaxQueryTime == 0 {
		b.MaxQueryTime = maxQueryTime
	}

	// Setup a query timeout
	if b.MaxQueryTime > 0 {
		timeout = time.After(b.MaxQueryTime)
	}

	// Setup a notification channel for changes
SETUP_NOTIFY:
	if b.MinQueryIndex > 0 {
		notifyCh = make(chan struct{}, 1)
		s.agent.eventNotify.Wait(notifyCh)
	}

RUN_QUERY:
	// Get the recent events
	events := s.agent.UserEvents()

	// Filter the events using the ACL, if present
	if acl != nil {
		for i := 0; i < len(events); i++ {
			name := events[i].Name
			if acl.EventRead(name) {
				continue
			}
			s.agent.logger.Printf("[DEBUG] agent: dropping event %q from result due to ACLs", name)
			events = append(events[:i], events[i+1:]...)
			i--
		}
	}

	// Filter the events if requested
	if nameFilter != "" {
		for i := 0; i < len(events); i++ {
			if events[i].Name != nameFilter {
				events = append(events[:i], events[i+1:]...)
				i--
			}
		}
	}

	// Determine the index
	var index uint64
	if len(events) == 0 {
		// Return a non-zero index to prevent a hot query loop. This
		// can be caused by a watch for example when there is no matching
		// events.
		index = 1
	} else {
		last := events[len(events)-1]
		index = uuidToUint64(last.ID)
	}
	setIndex(resp, index)

	// Check for exact match on the query value. Because
	// the index value is not monotonic, we just ensure it is
	// not an exact match.
	if index > 0 && index == b.MinQueryIndex {
		select {
		case <-notifyCh:
			goto SETUP_NOTIFY
		case <-timeout:
		}
	}
	return events, nil
}

// uuidToUint64 is a bit of a hack to generate a 64bit Consul index.
// In effect, we take our random UUID, convert it to a 128 bit number,
// then XOR the high-order and low-order 64bit's together to get the
// output. This lets us generate an index which can be used to simulate
// the blocking behavior of other catalog endpoints.
func uuidToUint64(uuid string) uint64 {
	lower := uuid[0:8] + uuid[9:13] + uuid[14:18]
	upper := uuid[19:23] + uuid[24:36]
	lowVal, err := strconv.ParseUint(lower, 16, 64)
	if err != nil {
		panic("Failed to convert " + lower)
	}
	highVal, err := strconv.ParseUint(upper, 16, 64)
	if err != nil {
		panic("Failed to convert " + upper)
	}
	return lowVal ^ highVal
}
<commit_msg>agent: use http.StatusInternalServerError instead of 500<commit_after>package agent

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
	"strconv"
	"strings"
	"time"

	"github.com/hashicorp/consul/acl"
	"github.com/hashicorp/consul/agent/structs"
)

const (
	// maxQueryTime is used to bound the limit of a blocking query
	maxQueryTime = 600 * time.Second
)

// EventFire is used to fire a new event
func (s *HTTPServer) EventFire(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Mandate a PUT request
	if req.Method != "PUT" {
		resp.WriteHeader(http.StatusMethodNotAllowed) // 405
		return nil, nil
	}

	// Get the datacenter
	var dc string
	s.parseDC(req, &dc)

	event := &UserEvent{}
	event.Name = strings.TrimPrefix(req.URL.Path, "/v1/event/fire/")
	if event.Name == "" {
		resp.WriteHeader(http.StatusBadRequest) // 400
		fmt.Fprint(resp, "Missing name")
		return nil, nil
	}

	// Get the ACL token
	var token string
	s.parseToken(req, &token)

	// Get the filters
	if filt := req.URL.Query().Get("node"); filt != "" {
		event.NodeFilter = filt
	}
	if filt := req.URL.Query().Get("service"); filt != "" {
		event.ServiceFilter = filt
	}
	if filt := req.URL.Query().Get("tag"); filt != "" {
		event.TagFilter = filt
	}

	// Get the payload
	if req.ContentLength > 0 {
		var buf bytes.Buffer
		if _, err := io.Copy(&buf, req.Body); err != nil {
			return nil, err
		}
		event.Payload = buf.Bytes()
	}

	// Try to fire the event
	if err := s.agent.UserEvent(dc, token, event); err != nil {
		if acl.IsErrPermissionDenied(err) {
			resp.WriteHeader(http.StatusForbidden) // 403
			fmt.Fprint(resp, acl.ErrPermissionDenied.Error())
			return nil, nil
		}
		resp.WriteHeader(http.StatusInternalServerError) // 500
		return nil, err
	}

	// Return the event
	return event, nil
}

// EventList is used to retrieve the recent list of events
func (s *HTTPServer) EventList(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Parse the query options, since we simulate a blocking query
	var b structs.QueryOptions
	if parseWait(resp, req, &b) {
		return nil, nil
	}

	// Fetch the ACL token, if any.
	var token string
	s.parseToken(req, &token)
	acl, err := s.agent.resolveToken(token)
	if err != nil {
		return nil, err
	}

	// Look for a name filter
	var nameFilter string
	if filt := req.URL.Query().Get("name"); filt != "" {
		nameFilter = filt
	}

	// Lots of this logic is borrowed from consul/rpc.go:blockingQuery
	// However we cannot use that directly since this code has some
	// slight semantics differences...
	var timeout <-chan time.Time
	var notifyCh chan struct{}

	// Fast path non-blocking
	if b.MinQueryIndex == 0 {
		goto RUN_QUERY
	}

	// Restrict the max query time
	if b.MaxQueryTime > maxQueryTime {
		b.MaxQueryTime = maxQueryTime
	}

	// Ensure a time limit is set if we have an index
	if b.MinQueryIndex > 0 && b.MaxQueryTime == 0 {
		b.MaxQueryTime = maxQueryTime
	}

	// Setup a query timeout
	if b.MaxQueryTime > 0 {
		timeout = time.After(b.MaxQueryTime)
	}

	// Setup a notification channel for changes
SETUP_NOTIFY:
	if b.MinQueryIndex > 0 {
		notifyCh = make(chan struct{}, 1)
		s.agent.eventNotify.Wait(notifyCh)
	}

RUN_QUERY:
	// Get the recent events
	events := s.agent.UserEvents()

	// Filter the events using the ACL, if present
	if acl != nil {
		for i := 0; i < len(events); i++ {
			name := events[i].Name
			if acl.EventRead(name) {
				continue
			}
			s.agent.logger.Printf("[DEBUG] agent: dropping event %q from result due to ACLs", name)
			events = append(events[:i], events[i+1:]...)
			i--
		}
	}

	// Filter the events if requested
	if nameFilter != "" {
		for i := 0; i < len(events); i++ {
			if events[i].Name != nameFilter {
				events = append(events[:i], events[i+1:]...)
				i--
			}
		}
	}

	// Determine the index
	var index uint64
	if len(events) == 0 {
		// Return a non-zero index to prevent a hot query loop. This
		// can be caused by a watch for example when there is no matching
		// events.
		index = 1
	} else {
		last := events[len(events)-1]
		index = uuidToUint64(last.ID)
	}
	setIndex(resp, index)

	// Check for exact match on the query value. Because
	// the index value is not monotonic, we just ensure it is
	// not an exact match.
	if index > 0 && index == b.MinQueryIndex {
		select {
		case <-notifyCh:
			goto SETUP_NOTIFY
		case <-timeout:
		}
	}
	return events, nil
}

// uuidToUint64 is a bit of a hack to generate a 64bit Consul index.
// In effect, we take our random UUID, convert it to a 128 bit number,
// then XOR the high-order and low-order 64bit's together to get the
// output. This lets us generate an index which can be used to simulate
// the blocking behavior of other catalog endpoints.
func uuidToUint64(uuid string) uint64 {
	lower := uuid[0:8] + uuid[9:13] + uuid[14:18]
	upper := uuid[19:23] + uuid[24:36]
	lowVal, err := strconv.ParseUint(lower, 16, 64)
	if err != nil {
		panic("Failed to convert " + lower)
	}
	highVal, err := strconv.ParseUint(upper, 16, 64)
	if err != nil {
		panic("Failed to convert " + upper)
	}
	return lowVal ^ highVal
}
<|endoftext|>


<commit_before>package wake

import (
	"fmt"
	"os"
	"time"
)

type rawTimerHandle struct {
	stop chan<- struct{}
	sig  chan struct{}
}

func newRawTimerHandle() (t rawTimerHandle, err error) {
	t.sig = make(chan struct{})
	return
}

func (t *rawTimerHandle) waitfor(stop <-chan struct{}, d time.Duration) (err error) {
	file, err := os.Create("/sys/class/rtc/rtc0/wakealarm")
	if err != nil {
		return
	}
	defer file.Close()
	_, err = fmt.Fprintf(file, "%d\n", time.Now().Add(d).Unix())
	if err != nil {
		return
	}
	select {
	case <-stop:
	case <-time.After(d):
		select {
		case t.sig <- struct{}{}:
		default:
		}
	}
	return
}

func (t *rawTimerHandle) Start(wait, period time.Duration) (err error) {
	close(t.stop)
	// use a separate stop so that the goroutine binds to this and
	// doesn't cause a race condition when we modify t
	stop := make(chan struct{})
	t.stop = stop
	go func() {
		t.waitfor(stop, wait)
		select {
		case <-stop:
			return
		default:
		}
		if period == 0 {
			return
		}
		for {
			t.waitfor(stop, period)
			select {
			case <-stop:
				return
			default:
			}
		}
	}()
	return
}

func (t *rawTimerHandle) Wait(timeout time.Duration) (again bool, err error) {
	select {
	case <-t.sig:
	case <-time.After(timeout):
		again = true
	}
	return
}

func (t *rawTimerHandle) Close() {
	close(t.stop)
}

func raw(d time.Duration) (err error) {
	file, err := os.Create("/sys/class/rtc/rtc0/wakealarm")
	if err != nil {
		return err
	}
	_, err = fmt.Fprintf(file, "+%d", d/time.Second)
	return
}
<commit_msg>buffered the signal on the raw timer handle<commit_after>package wake

import (
	"fmt"
	"os"
	"time"
)

type rawTimerHandle struct {
	stop chan<- struct{}
	sig  chan struct{}
}

func newRawTimerHandle() (t rawTimerHandle, err error) {
	t.sig = make(chan struct{}, 1)
	return
}

func (t *rawTimerHandle) waitfor(stop <-chan struct{}, d time.Duration) (err error) {
	file, err := os.Create("/sys/class/rtc/rtc0/wakealarm")
	if err != nil {
		return
	}
	defer file.Close()
	_, err = fmt.Fprintf(file, "%d\n", time.Now().Add(d).Unix())
	if err != nil {
		return
	}
	select {
	case <-stop:
	case <-time.After(d):
		select {
		case t.sig <- struct{}{}:
		default:
		}
	}
	return
}

func (t *rawTimerHandle) Start(wait, period time.Duration) (err error) {
	close(t.stop)
	// use a separate stop so that the goroutine binds to this and
	// doesn't cause a race condition when we modify t
	stop := make(chan struct{})
	t.stop = stop
	go func() {
		t.waitfor(stop, wait)
		select {
		case <-stop:
			return
		default:
		}
		if period == 0 {
			return
		}
		for {
			t.waitfor(stop, period)
			select {
			case <-stop:
				return
			default:
			}
		}
	}()
	return
}

func (t *rawTimerHandle) Wait(timeout time.Duration) (again bool, err error) {
	select {
	case <-t.sig:
	case <-time.After(timeout):
		again = true
	}
	return
}

func (t *rawTimerHandle) Close() {
	close(t.stop)
}

func raw(d time.Duration) (err error) {
	file, err := os.Create("/sys/class/rtc/rtc0/wakealarm")
	if err != nil {
		return err
	}
	_, err = fmt.Fprintf(file, "+%d", d/time.Second)
	return
}
<|endoftext|>


<commit_before>package user

import (
	"errors"
	"fmt"

	"github.com/appcelerator/amp/api/rpc/account"
	"github.com/appcelerator/amp/cli"
	"github.com/spf13/cobra"
	"golang.org/x/net/context"
	"google.golang.org/grpc"
)

type forgotOpts struct {
	email string
}

var (
	forgotOptions = &forgotOpts{}
)

// NewForgotLoginCommand returns a new instance of the forgot-login command.
func NewForgotLoginCommand(c cli.Interface) *cobra.Command {
	return &cobra.Command{
		Use:     "forgot-login EMAIL",
		Short:   "Retrieve account name",
		PreRunE: cli.ExactArgs(1),
		RunE: func(cmd *cobra.Command, args []string) error {
			if args[0] == "" {
				return errors.New("email cannot be empty")
			}
			forgotOptions.email = args[0]
			return forgotLogin(c, forgotOptions)
		},
	}
}

func forgotLogin(c cli.Interface, opt *forgotOpts) error {
	conn := c.ClientConn()
	client := account.NewAccountClient(conn)
	request := &account.ForgotLoginRequest{
		Email: opt.email,
	}
	if _, err := client.ForgotLogin(context.Background(), request); err != nil {
		return fmt.Errorf("%s", grpc.ErrorDesc(err))
	}
	c.Console().Printf("Your login name has been sent to the address: %s\n", opt.email)
	return nil
}
<commit_msg>fail if user is already logged in<commit_after>package user

import (
	"errors"
	"fmt"

	"github.com/appcelerator/amp/api/rpc/account"
	"github.com/appcelerator/amp/cli"
	"github.com/spf13/cobra"
	"golang.org/x/net/context"
	"google.golang.org/grpc"
)

type forgotOpts struct {
	email string
}

var (
	forgotOptions = &forgotOpts{}
)

// NewForgotLoginCommand returns a new instance of the forgot-login command.
func NewForgotLoginCommand(c cli.Interface) *cobra.Command {
	return &cobra.Command{
		Use:     "forgot-login EMAIL",
		Short:   "Retrieve account name",
		PreRunE: cli.ExactArgs(1),
		RunE: func(cmd *cobra.Command, args []string) error {
			if args[0] == "" {
				return errors.New("email cannot be empty")
			}
			forgotOptions.email = args[0]
			return forgotLogin(c, forgotOptions)
		},
	}
}

func forgotLogin(c cli.Interface, opt *forgotOpts) error {
	if token := cli.GetToken(); token != "" {
		return errors.New("you are already logged into an account. Use 'amp whoami' to view your username")
	}
	conn := c.ClientConn()
	client := account.NewAccountClient(conn)
	request := &account.ForgotLoginRequest{
		Email: opt.email,
	}
	if _, err := client.ForgotLogin(context.Background(), request); err != nil {
		return fmt.Errorf("%s", grpc.ErrorDesc(err))
	}

	c.Console().Printf("Your login name has been sent to the address: %s\n", opt.email)
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"strings"

	"github.com/coreos/coreos-cloudinit/datasource"
	"github.com/coreos/coreos-cloudinit/initialize"
	"github.com/coreos/coreos-cloudinit/system"
)

const version = "0.3.1+git"

func main() {
	var printVersion bool
	flag.BoolVar(&printVersion, "version", false, "Print the version and exit")

	var ignoreFailure bool
	flag.BoolVar(&ignoreFailure, "ignore-failure", false, "Exits with 0 status in the event of malformed input from user-data")

	var file string
	flag.StringVar(&file, "from-file", "", "Read user-data from provided file")

	var url string
	flag.StringVar(&url, "from-url", "", "Download user-data from provided url")

	var workspace string
	flag.StringVar(&workspace, "workspace", "/var/lib/coreos-cloudinit", "Base directory coreos-cloudinit should use to store data")

	var sshKeyName string
	flag.StringVar(&sshKeyName, "ssh-key-name", initialize.DefaultSSHKeyName, "Add SSH keys to the system with the given name")

	flag.Parse()

	if printVersion == true {
		fmt.Printf("coreos-cloudinit version %s\n", version)
		os.Exit(0)
	}

	if file != "" && url != "" {
		fmt.Println("Provide one of --from-file or --from-url")
		os.Exit(1)
	}

	var ds datasource.Datasource
	if file != "" {
		ds = datasource.NewLocalFile(file)
	} else if url != "" {
		ds = datasource.NewMetadataService(url)
	} else {
		fmt.Println("Provide one of --from-file or --from-url")
		os.Exit(1)
	}

	log.Printf("Fetching user-data from datasource of type %q", ds.Type())
	userdataBytes, err := ds.Fetch()
	if err != nil {
		log.Printf("Failed fetching user-data from datasource: %v", err)
		if ignoreFailure {
			os.Exit(0)
		} else {
			os.Exit(1)
		}
	}

	if len(userdataBytes) == 0 {
		log.Printf("No user data to handle, exiting.")
		os.Exit(0)
	}

	env := initialize.NewEnvironment("/", workspace)

	userdata := string(userdataBytes)
	userdata = env.Apply(userdata)

	parsed, err := ParseUserData(userdata)
	if err != nil {
		log.Printf("Failed parsing user-data: %v", err)
		if ignoreFailure {
			os.Exit(0)
		} else {
			os.Exit(1)
		}
	}

	err = initialize.PrepWorkspace(env.Workspace())
	if err != nil {
		log.Fatalf("Failed preparing workspace: %v", err)
	}

	switch t := parsed.(type) {
	case initialize.CloudConfig:
		err = initialize.Apply(t, env)
	case system.Script:
		var path string
		path, err = initialize.PersistScriptInWorkspace(t, env.Workspace())
		if err == nil {
			var name string
			name, err = system.ExecuteScript(path)
			initialize.PersistUnitNameInWorkspace(name, workspace)
		}
	}

	if err != nil {
		log.Fatalf("Failed resolving user-data: %v", err)
	}
}

func ParseUserData(contents string) (interface{}, error) {
	header := strings.SplitN(contents, "\n", 2)[0]

	if strings.HasPrefix(header, "#!") {
		log.Printf("Parsing user-data as script")
		return system.Script(contents), nil

	} else if header == "#cloud-config" {
		log.Printf("Parsing user-data as cloud-config")
		cfg, err := initialize.NewCloudConfig(contents)
		if err != nil {
			log.Fatal(err.Error())
		}
		return *cfg, nil
	} else {
		return nil, fmt.Errorf("Unrecognized user-data header: %s", header)
	}
}
<commit_msg>chore(release): Bump version to v0.3.2<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"strings"

	"github.com/coreos/coreos-cloudinit/datasource"
	"github.com/coreos/coreos-cloudinit/initialize"
	"github.com/coreos/coreos-cloudinit/system"
)

const version = "0.3.2"

func main() {
	var printVersion bool
	flag.BoolVar(&printVersion, "version", false, "Print the version and exit")

	var ignoreFailure bool
	flag.BoolVar(&ignoreFailure, "ignore-failure", false, "Exits with 0 status in the event of malformed input from user-data")

	var file string
	flag.StringVar(&file, "from-file", "", "Read user-data from provided file")

	var url string
	flag.StringVar(&url, "from-url", "", "Download user-data from provided url")

	var workspace string
	flag.StringVar(&workspace, "workspace", "/var/lib/coreos-cloudinit", "Base directory coreos-cloudinit should use to store data")

	var sshKeyName string
	flag.StringVar(&sshKeyName, "ssh-key-name", initialize.DefaultSSHKeyName, "Add SSH keys to the system with the given name")

	flag.Parse()

	if printVersion == true {
		fmt.Printf("coreos-cloudinit version %s\n", version)
		os.Exit(0)
	}

	if file != "" && url != "" {
		fmt.Println("Provide one of --from-file or --from-url")
		os.Exit(1)
	}

	var ds datasource.Datasource
	if file != "" {
		ds = datasource.NewLocalFile(file)
	} else if url != "" {
		ds = datasource.NewMetadataService(url)
	} else {
		fmt.Println("Provide one of --from-file or --from-url")
		os.Exit(1)
	}

	log.Printf("Fetching user-data from datasource of type %q", ds.Type())
	userdataBytes, err := ds.Fetch()
	if err != nil {
		log.Printf("Failed fetching user-data from datasource: %v", err)
		if ignoreFailure {
			os.Exit(0)
		} else {
			os.Exit(1)
		}
	}

	if len(userdataBytes) == 0 {
		log.Printf("No user data to handle, exiting.")
		os.Exit(0)
	}

	env := initialize.NewEnvironment("/", workspace)

	userdata := string(userdataBytes)
	userdata = env.Apply(userdata)

	parsed, err := ParseUserData(userdata)
	if err != nil {
		log.Printf("Failed parsing user-data: %v", err)
		if ignoreFailure {
			os.Exit(0)
		} else {
			os.Exit(1)
		}
	}

	err = initialize.PrepWorkspace(env.Workspace())
	if err != nil {
		log.Fatalf("Failed preparing workspace: %v", err)
	}

	switch t := parsed.(type) {
	case initialize.CloudConfig:
		err = initialize.Apply(t, env)
	case system.Script:
		var path string
		path, err = initialize.PersistScriptInWorkspace(t, env.Workspace())
		if err == nil {
			var name string
			name, err = system.ExecuteScript(path)
			initialize.PersistUnitNameInWorkspace(name, workspace)
		}
	}

	if err != nil {
		log.Fatalf("Failed resolving user-data: %v", err)
	}
}

func ParseUserData(contents string) (interface{}, error) {
	header := strings.SplitN(contents, "\n", 2)[0]

	if strings.HasPrefix(header, "#!") {
		log.Printf("Parsing user-data as script")
		return system.Script(contents), nil

	} else if header == "#cloud-config" {
		log.Printf("Parsing user-data as cloud-config")
		cfg, err := initialize.NewCloudConfig(contents)
		if err != nil {
			log.Fatal(err.Error())
		}
		return *cfg, nil
	} else {
		return nil, fmt.Errorf("Unrecognized user-data header: %s", header)
	}
}
<|endoftext|>


<commit_before>package rabbit_test

import (
	"bytes"
	"testing"

	"github.com/ebfe/estream/rabbit"
)

func xordigest(msg []byte, n int) []byte {
	d := make([]byte, n)

	for i := range msg {
		d[i%len(d)] ^= msg[i]
	}

	return d
}

func TestKeyStream(t *testing.T) {
	for i, tc := range tests {
		c, err := rabbit.NewCipher(tc.key, tc.iv)
		if err != nil {
			t.Fatal("tests[%d]: NewCipher() err: %s\n", i, err)
		}

		lastchunk := tc.chunks[len(tc.chunks)-1]
		mlen := lastchunk.offset + len(lastchunk.val)
		ks := make([]byte, mlen)

		c.XORKeyStream(ks, ks)

		for j, chunk := range tc.chunks {
			kschunk := ks[chunk.offset : chunk.offset+len(chunk.val)]
			if !bytes.Equal(kschunk, chunk.val) {
				t.Errorf("tests[%d] chunk[%d]: ks = %x want %x\n", i, j, kschunk, chunk.val)
			}
		}

		digest := xordigest(ks, len(tc.xor))
		if !bytes.Equal(digest, tc.xor) {
			t.Errorf("tests[%d] xor-digest = %x want %x\n", i, digest, tc.xor)
		}
	}
}
<commit_msg>fix test logging<commit_after>package rabbit_test

import (
	"bytes"
	"testing"

	"github.com/ebfe/estream/rabbit"
)

func xordigest(msg []byte, n int) []byte {
	d := make([]byte, n)

	for i := range msg {
		d[i%len(d)] ^= msg[i]
	}

	return d
}

func TestKeyStream(t *testing.T) {
	for i, tc := range tests {
		c, err := rabbit.NewCipher(tc.key, tc.iv)
		if err != nil {
			t.Fatalf("tests[%d]: NewCipher() err: %s\n", i, err)
		}

		lastchunk := tc.chunks[len(tc.chunks)-1]
		mlen := lastchunk.offset + len(lastchunk.val)
		ks := make([]byte, mlen)

		c.XORKeyStream(ks, ks)

		for j, chunk := range tc.chunks {
			kschunk := ks[chunk.offset : chunk.offset+len(chunk.val)]
			if !bytes.Equal(kschunk, chunk.val) {
				t.Errorf("tests[%d] chunk[%d]: ks = %x want %x\n", i, j, kschunk, chunk.val)
			}
		}

		digest := xordigest(ks, len(tc.xor))
		if !bytes.Equal(digest, tc.xor) {
			t.Errorf("tests[%d] xor-digest = %x want %x\n", i, digest, tc.xor)
		}
	}
}
<|endoftext|>


<commit_before>package state_test

import (
	"compress/gzip"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"testing"

	"github.com/hashicorp/nomad/client/allocrunner"
	"github.com/hashicorp/nomad/client/allocwatcher"
	clientconfig "github.com/hashicorp/nomad/client/config"
	"github.com/hashicorp/nomad/client/consul"
	"github.com/hashicorp/nomad/client/devicemanager"
	dmstate "github.com/hashicorp/nomad/client/devicemanager/state"
	"github.com/hashicorp/nomad/client/pluginmanager/drivermanager"
	. "github.com/hashicorp/nomad/client/state"
	"github.com/hashicorp/nomad/client/vaultclient"
	"github.com/hashicorp/nomad/helper/boltdd"
	"github.com/hashicorp/nomad/helper/testlog"
	"github.com/hashicorp/nomad/nomad/structs"
	"github.com/hashicorp/nomad/plugins/shared"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

// TestBoltStateDB_Upgrade_Ok asserts upgading an old state db does not error
// during upgrade and restore.
func TestBoltStateDB_UpgradeOld_Ok(t *testing.T) {
	t.Parallel()

	files, err := filepath.Glob("testdata/*.db*")
	require.NoError(t, err)

	for _, fn := range files {
		t.Run(fn, func(t *testing.T) {
			dir, err := ioutil.TempDir("", "nomadtest")
			require.NoError(t, err)
			defer os.RemoveAll(dir)

			var src io.ReadCloser
			src, err = os.Open(fn)
			require.NoError(t, err)
			defer src.Close()

			// testdata may be gzip'd; decode on copy
			if strings.HasSuffix(fn, ".gz") {
				src, err = gzip.NewReader(src)
				require.NoError(t, err)
			}

			dst, err := os.Create(filepath.Join(dir, "state.db"))
			require.NoError(t, err)

			// Copy test files before testing them for safety
			_, err = io.Copy(dst, src)
			require.NoError(t, err)

			require.NoError(t, src.Close())

			dbI, err := NewBoltStateDB(testlog.HCLogger(t), dir)
			require.NoError(t, err)
			defer dbI.Close()

			db := dbI.(*BoltStateDB)

			// Simply opening old files should *not* alter them
			require.NoError(t, db.DB().View(func(tx *boltdd.Tx) error {
				b := tx.Bucket([]byte("meta"))
				if b != nil {
					return fmt.Errorf("meta bucket found but should not exist yet!")
				}
				return nil
			}))

			needsUpgrade, err := NeedsUpgrade(db.DB().BoltDB())
			require.NoError(t, err)
			require.True(t, needsUpgrade)

			// Attept the upgrade
			require.NoError(t, db.Upgrade())

			needsUpgrade, err = NeedsUpgrade(db.DB().BoltDB())
			require.NoError(t, err)
			require.False(t, needsUpgrade)

			// Ensure Allocations can be restored and
			// NewAR/AR.Restore do not error.
			allocs, errs, err := db.GetAllAllocations()
			require.NoError(t, err)
			assert.Len(t, errs, 0)

			for _, alloc := range allocs {
				checkUpgradedAlloc(t, dir, db, alloc)
			}

			// Should be nil for all upgrades
			ps, err := db.GetDevicePluginState()
			require.NoError(t, err)
			require.Nil(t, ps)

			ps = &dmstate.PluginState{
				ReattachConfigs: map[string]*shared.ReattachConfig{
					"test": &shared.ReattachConfig{Pid: 1},
				},
			}
			require.NoError(t, db.PutDevicePluginState(ps))

			require.NoError(t, db.Close())
		})
	}
}

// checkUpgradedAlloc creates and restores an AllocRunner from an upgraded
// database.
//
// It does not call AR.Run as its intended to be used against a wide test
// corpus in testdata that may be expensive to run and require unavailable
// dependencies.
func checkUpgradedAlloc(t *testing.T, path string, db StateDB, alloc *structs.Allocation) {
	_, err := db.GetDeploymentStatus(alloc.ID)
	assert.NoError(t, err)

	tg := alloc.Job.LookupTaskGroup(alloc.TaskGroup)
	for _, task := range tg.Tasks {
		_, _, err := db.GetTaskRunnerState(alloc.ID, task.Name)
		require.NoError(t, err)
	}

	clientConf, cleanup := clientconfig.TestClientConfig(t)

	// Does *not* cleanup overridden StateDir below. That's left alone for
	// the caller to cleanup.
	defer cleanup()

	clientConf.StateDir = path

	conf := &allocrunner.Config{
		Alloc:             alloc,
		Logger:            clientConf.Logger,
		ClientConfig:      clientConf,
		StateDB:           db,
		Consul:            consul.NewMockConsulServiceClient(t, clientConf.Logger),
		Vault:             vaultclient.NewMockVaultClient(),
		StateUpdater:      &allocrunner.MockStateUpdater{},
		PrevAllocWatcher:  allocwatcher.NoopPrevAlloc{},
		PrevAllocMigrator: allocwatcher.NoopPrevAlloc{},
		DeviceManager:     devicemanager.NoopMockManager(),
		DriverManager:     drivermanager.TestDriverManager(t),
	}
	ar, err := allocrunner.NewAllocRunner(conf)
	require.NoError(t, err)

	// AllocRunner.Restore should not error
	require.NoError(t, ar.Restore())
}
<commit_msg>gofmt -s -w upgrade_int_test.go<commit_after>package state_test

import (
	"compress/gzip"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"testing"

	"github.com/hashicorp/nomad/client/allocrunner"
	"github.com/hashicorp/nomad/client/allocwatcher"
	clientconfig "github.com/hashicorp/nomad/client/config"
	"github.com/hashicorp/nomad/client/consul"
	"github.com/hashicorp/nomad/client/devicemanager"
	dmstate "github.com/hashicorp/nomad/client/devicemanager/state"
	"github.com/hashicorp/nomad/client/pluginmanager/drivermanager"
	. "github.com/hashicorp/nomad/client/state"
	"github.com/hashicorp/nomad/client/vaultclient"
	"github.com/hashicorp/nomad/helper/boltdd"
	"github.com/hashicorp/nomad/helper/testlog"
	"github.com/hashicorp/nomad/nomad/structs"
	"github.com/hashicorp/nomad/plugins/shared"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

// TestBoltStateDB_Upgrade_Ok asserts upgading an old state db does not error
// during upgrade and restore.
func TestBoltStateDB_UpgradeOld_Ok(t *testing.T) {
	t.Parallel()

	files, err := filepath.Glob("testdata/*.db*")
	require.NoError(t, err)

	for _, fn := range files {
		t.Run(fn, func(t *testing.T) {
			dir, err := ioutil.TempDir("", "nomadtest")
			require.NoError(t, err)
			defer os.RemoveAll(dir)

			var src io.ReadCloser
			src, err = os.Open(fn)
			require.NoError(t, err)
			defer src.Close()

			// testdata may be gzip'd; decode on copy
			if strings.HasSuffix(fn, ".gz") {
				src, err = gzip.NewReader(src)
				require.NoError(t, err)
			}

			dst, err := os.Create(filepath.Join(dir, "state.db"))
			require.NoError(t, err)

			// Copy test files before testing them for safety
			_, err = io.Copy(dst, src)
			require.NoError(t, err)

			require.NoError(t, src.Close())

			dbI, err := NewBoltStateDB(testlog.HCLogger(t), dir)
			require.NoError(t, err)
			defer dbI.Close()

			db := dbI.(*BoltStateDB)

			// Simply opening old files should *not* alter them
			require.NoError(t, db.DB().View(func(tx *boltdd.Tx) error {
				b := tx.Bucket([]byte("meta"))
				if b != nil {
					return fmt.Errorf("meta bucket found but should not exist yet!")
				}
				return nil
			}))

			needsUpgrade, err := NeedsUpgrade(db.DB().BoltDB())
			require.NoError(t, err)
			require.True(t, needsUpgrade)

			// Attept the upgrade
			require.NoError(t, db.Upgrade())

			needsUpgrade, err = NeedsUpgrade(db.DB().BoltDB())
			require.NoError(t, err)
			require.False(t, needsUpgrade)

			// Ensure Allocations can be restored and
			// NewAR/AR.Restore do not error.
			allocs, errs, err := db.GetAllAllocations()
			require.NoError(t, err)
			assert.Len(t, errs, 0)

			for _, alloc := range allocs {
				checkUpgradedAlloc(t, dir, db, alloc)
			}

			// Should be nil for all upgrades
			ps, err := db.GetDevicePluginState()
			require.NoError(t, err)
			require.Nil(t, ps)

			ps = &dmstate.PluginState{
				ReattachConfigs: map[string]*shared.ReattachConfig{
					"test": {Pid: 1},
				},
			}
			require.NoError(t, db.PutDevicePluginState(ps))

			require.NoError(t, db.Close())
		})
	}
}

// checkUpgradedAlloc creates and restores an AllocRunner from an upgraded
// database.
//
// It does not call AR.Run as its intended to be used against a wide test
// corpus in testdata that may be expensive to run and require unavailable
// dependencies.
func checkUpgradedAlloc(t *testing.T, path string, db StateDB, alloc *structs.Allocation) {
	_, err := db.GetDeploymentStatus(alloc.ID)
	assert.NoError(t, err)

	tg := alloc.Job.LookupTaskGroup(alloc.TaskGroup)
	for _, task := range tg.Tasks {
		_, _, err := db.GetTaskRunnerState(alloc.ID, task.Name)
		require.NoError(t, err)
	}

	clientConf, cleanup := clientconfig.TestClientConfig(t)

	// Does *not* cleanup overridden StateDir below. That's left alone for
	// the caller to cleanup.
	defer cleanup()

	clientConf.StateDir = path

	conf := &allocrunner.Config{
		Alloc:             alloc,
		Logger:            clientConf.Logger,
		ClientConfig:      clientConf,
		StateDB:           db,
		Consul:            consul.NewMockConsulServiceClient(t, clientConf.Logger),
		Vault:             vaultclient.NewMockVaultClient(),
		StateUpdater:      &allocrunner.MockStateUpdater{},
		PrevAllocWatcher:  allocwatcher.NoopPrevAlloc{},
		PrevAllocMigrator: allocwatcher.NoopPrevAlloc{},
		DeviceManager:     devicemanager.NoopMockManager(),
		DriverManager:     drivermanager.TestDriverManager(t),
	}
	ar, err := allocrunner.NewAllocRunner(conf)
	require.NoError(t, err)

	// AllocRunner.Restore should not error
	require.NoError(t, ar.Restore())
}
<|endoftext|>


<commit_before>// Copyright (c) 2013, Peter H. Froehlich. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file.

// Some inspiration for this test strategy comes from the
// src/pkg/net/conn_test.go example in the Go library.

package ratelimit

import (
	"io"
	"net"
	"testing"
	"time"
)

// The idea here is to create a connection with the given
// rate limits (rlim, wlim), send npack messages of length
// lpack from client to server, and finally have the server
// check whether it took within 20% of the expected duration.
//
// Testing against absolute times is a bad idea, especially
// if we want to test the case without rate limits as well.
// In fact I had to remove that case because it wouldn't
// run even remotely reliably. I am open to suggestions.

type testCase struct {
	net   string
	addr  string
	rlim  int
	wlim  int
	npack int
	lpack int
	total time.Duration
}

const accuracy = 0.2

var tests = []testCase{
//	{"tcp", "127.0.0.1:8080", 0, 0, 8, 1024, time.Duration(13 * time.Microsecond)},
	{"tcp", "127.0.0.1:8080", 4096, 0, 8, 1024, time.Duration(2 * time.Second)},
	{"tcp", "127.0.0.1:8080", 0, 4096, 8, 1024, time.Duration(2 * time.Second)},
	{"tcp", "127.0.0.1:8080", 2048, 4096, 8, 1024, time.Duration(4 * time.Second)},
	{"tcp", "127.0.0.1:8080", 4096, 2048, 8, 1024, time.Duration(4 * time.Second)},
}

func TestConnections(t *testing.T) {
	for _, info := range tests {
		testConnection(t, info)
	}
}

func testConnection(t *testing.T, info testCase) {
	// start the client (which will wait a bit before connecting)
	go testClient(t, info)
	// listen
	l, err := net.Listen(info.net, info.addr)
	if err != nil {
		t.Fatal(err)
	}
	// accept
	c, err := l.Accept()
	if err != nil {
		t.Fatal(err)
	}
	// wrap connection in rate limiter
	rlc, err := New(c, info.rlim, 0)
	if err != nil {
		t.Fatal(err)
	}
	// the actual experiment
	buf := make([]byte, info.npack*info.lpack)
	start := time.Now()
	n, err := io.ReadFull(rlc, buf)
	if err != nil {
		t.Error(err)
	}
	if n != len(buf) {
		t.Errorf("read %d bytes instead of %d bytes", n, len(buf))
	}
	duration := float64(time.Since(start).Nanoseconds())
	rlc.Close()
	l.Close()
	// check if we're "close" regarding timing
	expected := float64(info.total.Nanoseconds())
	lower := (1 - accuracy) * expected
	upper := (1 + accuracy) * expected
	if lower > duration || duration > upper {
		t.Errorf("expected around %f (%f..%f) but got %f", expected, lower, upper, duration)
	}
}

func testClient(t *testing.T, info testCase) {
	// make sure the server has time to come up
	time.Sleep(500 * time.Millisecond)
	// connect to the server
	c, err := net.Dial(info.net, info.addr)
	if err != nil {
		t.Fatal(err)
	}
	// wrap connection in rate limiter
	rlc, err := New(c, 0, info.wlim)
	if err != nil {
		t.Fatal(err)
	}
	// dump data into connection
	for i := 0; i < info.npack; i++ {
		data := make([]byte, info.lpack)
		n, err := rlc.Write(data)
		if err != nil {
			t.Error(err)
		}
		if n != info.lpack {
			t.Errorf("wrote %d bytes instead of %d bytes", n, info.lpack)
		}
	}
	// close the connection
	rlc.Close()
}
<commit_msg>Better coverage.<commit_after>// Copyright (c) 2013, Peter H. Froehlich. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file.

// Some inspiration for this test strategy comes from the
// src/pkg/net/conn_test.go example in the Go library.

package ratelimit

import (
	"io"
	"net"
	"testing"
	"time"
)

// The idea here is to create a connection with the given
// rate limits (rlim, wlim), send npack messages of length
// lpack from client to server, and finally have the server
// check whether it took within 20% of the expected duration.
//
// Testing against absolute times is a bad idea, especially
// if we want to test the case without rate limits as well.
// In fact I had to remove that case because it wouldn't
// run even remotely reliably. I am open to suggestions.

type testCase struct {
	net   string
	addr  string
	rlim  int
	wlim  int
	npack int
	lpack int
	total time.Duration
}

const accuracy = 0.2

var tests = []testCase{
//	{"tcp", "127.0.0.1:8080", 0, 0, 8, 1024, time.Duration(13 * time.Microsecond)},
	{"tcp", "127.0.0.1:8080", 4096, 0, 8, 1024, time.Duration(2 * time.Second)},
	{"tcp", "127.0.0.1:8080", 0, 4096, 8, 1024, time.Duration(2 * time.Second)},
	{"tcp", "127.0.0.1:8080", 2048, 4096, 8, 1024, time.Duration(4 * time.Second)},
	{"tcp", "127.0.0.1:8080", 4096, 2048, 8, 1024, time.Duration(4 * time.Second)},
}

func TestBoundaries(t *testing.T) {
	_, err := New(nil, -1, 10)
	if err == nil {
		t.Errorf("expected New to fail but it didn't")
	}
	_, err = New(nil, 10, -1)
	if err == nil {
		t.Errorf("expected New to fail but it didn't")
	}
}

func TestConnections(t *testing.T) {
	for _, info := range tests {
		testConnection(t, info)
	}
}

func testConnection(t *testing.T, info testCase) {
	// start the client (which will wait a bit before connecting)
	go testClient(t, info)
	// listen
	l, err := net.Listen(info.net, info.addr)
	if err != nil {
		t.Fatal(err)
	}
	// accept
	c, err := l.Accept()
	if err != nil {
		t.Fatal(err)
	}
	// wrap connection in rate limiter
	rlc, err := New(c, info.rlim, 0)
	if err != nil {
		t.Fatal(err)
	}
	// the actual experiment
	buf := make([]byte, info.npack*info.lpack)
	start := time.Now()
	n, err := io.ReadFull(rlc, buf)
	if err != nil {
		t.Error(err)
	}
	if n != len(buf) {
		t.Errorf("read %d bytes instead of %d bytes", n, len(buf))
	}
	duration := float64(time.Since(start).Nanoseconds())
	rlc.Close()
	l.Close()
	// check if we're "close" regarding timing
	expected := float64(info.total.Nanoseconds())
	lower := (1 - accuracy) * expected
	upper := (1 + accuracy) * expected
	if lower > duration || duration > upper {
		t.Errorf("expected around %f (%f..%f) but got %f", expected, lower, upper, duration)
	}
}

func testClient(t *testing.T, info testCase) {
	// make sure the server has time to come up
	time.Sleep(500 * time.Millisecond)
	// connect to the server
	c, err := net.Dial(info.net, info.addr)
	if err != nil {
		t.Fatal(err)
	}
	// wrap connection in rate limiter
	rlc, err := New(c, 0, info.wlim)
	if err != nil {
		t.Fatal(err)
	}
	// dump data into connection
	for i := 0; i < info.npack; i++ {
		data := make([]byte, info.lpack)
		n, err := rlc.Write(data)
		if err != nil {
			t.Error(err)
		}
		if n != info.lpack {
			t.Errorf("wrote %d bytes instead of %d bytes", n, info.lpack)
		}
	}
	// close the connection
	rlc.Close()
}
<|endoftext|>


<commit_before>package store

import (
	"fmt"
	"github.com/smancke/guble/testutil"
	"github.com/stretchr/testify/assert"
	"io/ioutil"
	"testing"
	"time"
)

func Test_Fetch(t *testing.T) {
	a := assert.New(t)
	dir, _ := ioutil.TempDir("", "message_store_test")
	//defer os.RemoveAll(dir)

	// when i store a message
	store := NewFileMessageStore(dir)
	a.NoError(store.Store("p1", uint64(1), []byte("aaaaaaaaaa")))
	a.NoError(store.Store("p1", uint64(2), []byte("bbbbbbbbbb")))
	a.NoError(store.Store("p2", uint64(1), []byte("1111111111")))
	a.NoError(store.Store("p2", uint64(2), []byte("2222222222")))

	testCases := []struct {
		description     string
		req             FetchRequest
		expectedResults []string
	}{
		{`match in partition 1`,
			FetchRequest{Partition: "p1", StartId: 2, Count: 1},
			[]string{"bbbbbbbbbb"},
		},
		{`match in partition 2`,
			FetchRequest{Partition: "p2", StartId: 2, Count: 1},
			[]string{"2222222222"},
		},
	}

	for _, testcase := range testCases {
		testcase.req.MessageC = make(chan MessageAndId)
		testcase.req.ErrorCallback = make(chan error)
		testcase.req.StartCallback = make(chan int)

		messages := []string{}

		store.Fetch(testcase.req)

		select {
		case numberOfResults := <-testcase.req.StartCallback:
			a.Equal(len(testcase.expectedResults), numberOfResults)
		case <-time.After(time.Second):
			a.Fail("timeout")
			return
		}

	loop:
		for {
			select {
			case msg, open := <-testcase.req.MessageC:
				if !open {
					break loop
				}
				messages = append(messages, string(msg.Message))
			case err := <-testcase.req.ErrorCallback:
				a.Fail(err.Error())
				break loop
			case <-time.After(time.Second):
				a.Fail("timeout")
				return
			}
		}
		a.Equal(testcase.expectedResults, messages, "Tescase: "+testcase.description)
	}
}

func Test_MessageStore_Close(t *testing.T) {
	a := assert.New(t)
	dir, _ := ioutil.TempDir("", "message_store_test")
	//defer os.RemoveAll(dir)

	// when i store a message
	store := NewFileMessageStore(dir)
	a.NoError(store.Store("p1", uint64(1), []byte("aaaaaaaaaa")))
	a.NoError(store.Store("p2", uint64(1), []byte("1111111111")))

	a.Equal(2, len(store.partitions))

	a.NoError(store.Stop())

	a.Equal(0, len(store.partitions))
}

func Test_MaxMessageId(t *testing.T) {
	a := assert.New(t)
	dir, _ := ioutil.TempDir("", "message_store_test")
	//defer os.RemoveAll(dir)
	expectedMaxId := 2

	// when i store a message
	store := NewFileMessageStore(dir)
	a.NoError(store.Store("p1", uint64(1), []byte("aaaaaaaaaa")))
	a.NoError(store.Store("p1", uint64(expectedMaxId), []byte("bbbbbbbbbb")))

	maxID, err := store.MaxMessageId("p1")
	a.Nil(err, "No error should be received for partition p1")
	a.Equal(maxID, uint64(expectedMaxId), fmt.Sprintf("MaxId should be [%d]", expectedMaxId))
}

func Test_MaxMessageIdError(t *testing.T) {
	a := assert.New(t)
	store := NewFileMessageStore("/TestDir")

	_, err := store.MaxMessageId("p2")
	a.NotNil(err)
}

func Test_MessagePartitionReturningError(t *testing.T) {
	a := assert.New(t)

	store := NewFileMessageStore("/TestDir")
	_, err := store.partitionStore("p1")
	a.NotNil(err)
	fmt.Println(err)

	store2 := NewFileMessageStore("/")
	_, err2 := store2.partitionStore("p1")
	fmt.Println(err2)
}

func Test_FetchWithError(t *testing.T) {
	a := assert.New(t)
	store := NewFileMessageStore("/TestDir")

	chanCallBack := make(chan error, 1)
	aFetchRequest := FetchRequest{Partition: "p1", StartId: 2, Count: 1, ErrorCallback: chanCallBack}
	store.Fetch(aFetchRequest)
	err := <-aFetchRequest.ErrorCallback
	a.NotNil(err)
}

func Test_StoreWithError(t *testing.T) {
	a := assert.New(t)
	store := NewFileMessageStore("/TestDir")

	err := store.Store("p1", uint64(1), []byte("124151qfas"))
	a.NotNil(err)
}

func Test_DoInTx(t *testing.T) {
	a := assert.New(t)
	dir, _ := ioutil.TempDir("", "message_store_test")
	store := NewFileMessageStore(dir)
	a.NoError(store.Store("p1", uint64(1), []byte("aaaaaaaaaa")))

	err := store.DoInTx("p1", func(maxId uint64) error {
		return nil
	})
	a.Nil(err)
}

func Test_DoInTxError(t *testing.T) {
	a := assert.New(t)
	store := NewFileMessageStore("/TestDir")

	err := store.DoInTx("p2", nil)
	a.NotNil(err)
}

func Test_StoreTx(t *testing.T) {
	a := assert.New(t)

	dir, _ := ioutil.TempDir("", "message_store_test")
	store := NewFileMessageStore(dir)
	a.NoError(store.Store("p1", uint64(1), []byte("aaaaaaaaaa")))

	actualStored := store.StoreTx("p1", func(maxId uint64) []byte {
		return nil
	})
	a.Nil(actualStored)
}

func Test_StoreTxError(t *testing.T) {
	a := assert.New(t)
	store := NewFileMessageStore("/TestDir")

	err := store.StoreTx("p2", nil)
	a.NotNil(err)
}

func Test_Check(t *testing.T) {
	a := assert.New(t)
	testutil.EnableDebugForMethod()
	dir, _ := ioutil.TempDir("", "message_store_test")
	store := NewFileMessageStore(dir)
	a.NoError(store.Store("p1", uint64(1), []byte("aaaaaaaaaa")))

	err := store.Check()
	a.Nil(err)
}
<commit_msg>Removed debug from test<commit_after>package store

import (
	"fmt"
	"github.com/smancke/guble/testutil"
	"github.com/stretchr/testify/assert"
	"io/ioutil"
	"testing"
	"time"
)

func Test_Fetch(t *testing.T) {
	a := assert.New(t)
	dir, _ := ioutil.TempDir("", "message_store_test")
	//defer os.RemoveAll(dir)

	// when i store a message
	store := NewFileMessageStore(dir)
	a.NoError(store.Store("p1", uint64(1), []byte("aaaaaaaaaa")))
	a.NoError(store.Store("p1", uint64(2), []byte("bbbbbbbbbb")))
	a.NoError(store.Store("p2", uint64(1), []byte("1111111111")))
	a.NoError(store.Store("p2", uint64(2), []byte("2222222222")))

	testCases := []struct {
		description     string
		req             FetchRequest
		expectedResults []string
	}{
		{`match in partition 1`,
			FetchRequest{Partition: "p1", StartId: 2, Count: 1},
			[]string{"bbbbbbbbbb"},
		},
		{`match in partition 2`,
			FetchRequest{Partition: "p2", StartId: 2, Count: 1},
			[]string{"2222222222"},
		},
	}

	for _, testcase := range testCases {
		testcase.req.MessageC = make(chan MessageAndId)
		testcase.req.ErrorCallback = make(chan error)
		testcase.req.StartCallback = make(chan int)

		messages := []string{}

		store.Fetch(testcase.req)

		select {
		case numberOfResults := <-testcase.req.StartCallback:
			a.Equal(len(testcase.expectedResults), numberOfResults)
		case <-time.After(time.Second):
			a.Fail("timeout")
			return
		}

	loop:
		for {
			select {
			case msg, open := <-testcase.req.MessageC:
				if !open {
					break loop
				}
				messages = append(messages, string(msg.Message))
			case err := <-testcase.req.ErrorCallback:
				a.Fail(err.Error())
				break loop
			case <-time.After(time.Second):
				a.Fail("timeout")
				return
			}
		}
		a.Equal(testcase.expectedResults, messages, "Tescase: "+testcase.description)
	}
}

func Test_MessageStore_Close(t *testing.T) {
	a := assert.New(t)
	dir, _ := ioutil.TempDir("", "message_store_test")
	//defer os.RemoveAll(dir)

	// when i store a message
	store := NewFileMessageStore(dir)
	a.NoError(store.Store("p1", uint64(1), []byte("aaaaaaaaaa")))
	a.NoError(store.Store("p2", uint64(1), []byte("1111111111")))

	a.Equal(2, len(store.partitions))

	a.NoError(store.Stop())

	a.Equal(0, len(store.partitions))
}

func Test_MaxMessageId(t *testing.T) {
	a := assert.New(t)
	dir, _ := ioutil.TempDir("", "message_store_test")
	//defer os.RemoveAll(dir)
	expectedMaxId := 2

	// when i store a message
	store := NewFileMessageStore(dir)
	a.NoError(store.Store("p1", uint64(1), []byte("aaaaaaaaaa")))
	a.NoError(store.Store("p1", uint64(expectedMaxId), []byte("bbbbbbbbbb")))

	maxID, err := store.MaxMessageId("p1")
	a.Nil(err, "No error should be received for partition p1")
	a.Equal(maxID, uint64(expectedMaxId), fmt.Sprintf("MaxId should be [%d]", expectedMaxId))
}

func Test_MaxMessageIdError(t *testing.T) {
	a := assert.New(t)
	store := NewFileMessageStore("/TestDir")

	_, err := store.MaxMessageId("p2")
	a.NotNil(err)
}

func Test_MessagePartitionReturningError(t *testing.T) {
	a := assert.New(t)

	store := NewFileMessageStore("/TestDir")
	_, err := store.partitionStore("p1")
	a.NotNil(err)
	fmt.Println(err)

	store2 := NewFileMessageStore("/")
	_, err2 := store2.partitionStore("p1")
	fmt.Println(err2)
}

func Test_FetchWithError(t *testing.T) {
	a := assert.New(t)
	store := NewFileMessageStore("/TestDir")

	chanCallBack := make(chan error, 1)
	aFetchRequest := FetchRequest{Partition: "p1", StartId: 2, Count: 1, ErrorCallback: chanCallBack}
	store.Fetch(aFetchRequest)
	err := <-aFetchRequest.ErrorCallback
	a.NotNil(err)
}

func Test_StoreWithError(t *testing.T) {
	a := assert.New(t)
	store := NewFileMessageStore("/TestDir")

	err := store.Store("p1", uint64(1), []byte("124151qfas"))
	a.NotNil(err)
}

func Test_DoInTx(t *testing.T) {
	a := assert.New(t)
	dir, _ := ioutil.TempDir("", "message_store_test")
	store := NewFileMessageStore(dir)
	a.NoError(store.Store("p1", uint64(1), []byte("aaaaaaaaaa")))

	err := store.DoInTx("p1", func(maxId uint64) error {
		return nil
	})
	a.Nil(err)
}

func Test_DoInTxError(t *testing.T) {
	a := assert.New(t)
	store := NewFileMessageStore("/TestDir")

	err := store.DoInTx("p2", nil)
	a.NotNil(err)
}

func Test_StoreTx(t *testing.T) {
	a := assert.New(t)

	dir, _ := ioutil.TempDir("", "message_store_test")
	store := NewFileMessageStore(dir)
	a.NoError(store.Store("p1", uint64(1), []byte("aaaaaaaaaa")))

	actualStored := store.StoreTx("p1", func(maxId uint64) []byte {
		return nil
	})
	a.Nil(actualStored)
}

func Test_StoreTxError(t *testing.T) {
	a := assert.New(t)
	store := NewFileMessageStore("/TestDir")

	err := store.StoreTx("p2", nil)
	a.NotNil(err)
}

func Test_Check(t *testing.T) {
	a := assert.New(t)
	dir, _ := ioutil.TempDir("", "message_store_test")
	store := NewFileMessageStore(dir)
	a.NoError(store.Store("p1", uint64(1), []byte("aaaaaaaaaa")))

	err := store.Check()
	a.Nil(err)
}
<|endoftext|>


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

// Package chk contains functions for checking and testing computations
package chk

import "fmt"

var (
	// AssertOn activates or deactivates asserts
	AssertOn = true

	// Verbose turn on verbose mode
	Verbose = false

	// ColorsOn turn on use of colours on console
	ColorsOn = true
)

// PanicSimple panicks without calling CallerInfo
func PanicSimple(msg string, prm ...interface{}) {
	panic(fmt.Sprintf(msg, prm...))
}

// Panic calls CallerInfo and panicks
func Panic(msg string, prm ...interface{}) {
	CallerInfo(4)
	CallerInfo(3)
	CallerInfo(2)
	panic(fmt.Sprintf(msg, prm...))
}

// Err returns a new error
func Err(msg string, prm ...interface{}) error {
	return fmt.Errorf(msg, prm...)
}
<commit_msg>Fix typo<commit_after>// Copyright 2016 The Gosl Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package chk contains functions for checking and testing computations
package chk

import "fmt"

var (
	// AssertOn activates or deactivates asserts
	AssertOn = true

	// Verbose turn on verbose mode
	Verbose = false

	// ColorsOn turn on use of colours on console
	ColorsOn = true
)

// PanicSimple panics without calling CallerInfo
func PanicSimple(msg string, prm ...interface{}) {
	panic(fmt.Sprintf(msg, prm...))
}

// Panic calls CallerInfo and panics
func Panic(msg string, prm ...interface{}) {
	CallerInfo(4)
	CallerInfo(3)
	CallerInfo(2)
	panic(fmt.Sprintf(msg, prm...))
}

// Err returns a new error
func Err(msg string, prm ...interface{}) error {
	return fmt.Errorf(msg, prm...)
}
<|endoftext|>


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

package componenthelper

import (
	"context"

	"go.opentelemetry.io/collector/component"
)

// StartFunc specifies the function invoked when the exporter is being started.
type StartFunc func(context.Context, component.Host) error

// ShutdownFunc specifies the function invoked when the exporter is being shutdown.
type ShutdownFunc func(context.Context) error

// baseSettings represents a settings struct to create components.
type baseSettings struct {
	StartFunc
	ShutdownFunc
}

// Option represents the possible options for New.
type Option func(*baseSettings)

// WithStart overrides the default Start function for a processor.
// The default shutdown function does nothing and always returns nil.
func WithStart(start StartFunc) Option {
	return func(o *baseSettings) {
		o.StartFunc = start
	}
}

// WithShutdown overrides the default Shutdown function for a processor.
// The default shutdown function does nothing and always returns nil.
func WithShutdown(shutdown ShutdownFunc) Option {
	return func(o *baseSettings) {
		o.ShutdownFunc = shutdown
	}
}

type baseComponent struct {
	start    StartFunc
	shutdown ShutdownFunc
}

// Start all senders and exporter and is invoked during service start.
func (be *baseComponent) Start(ctx context.Context, host component.Host) error {
	return be.start(ctx, host)
}

// Shutdown all senders and exporter and is invoked during service shutdown.
func (be *baseComponent) Shutdown(ctx context.Context) error {
	return be.shutdown(ctx)
}

// fromOptions returns the internal settings starting from the default and applying all options.
func fromOptions(options []Option) *baseSettings {
	opts := &baseSettings{
		StartFunc:    func(ctx context.Context, host component.Host) error { return nil },
		ShutdownFunc: func(ctx context.Context) error { return nil },
	}

	for _, op := range options {
		op(opts)
	}

	return opts
}

// New returns a component.Component configured with the provided Options.
func New(options ...Option) component.Component {
	bs := fromOptions(options)
	return &baseComponent{
		start:    bs.StartFunc,
		shutdown: bs.ShutdownFunc,
	}
}
<commit_msg>Improve comments and code in componenthelper package (#3068)<commit_after>// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package componenthelper

import (
	"context"

	"go.opentelemetry.io/collector/component"
)

// StartFunc specifies the function invoked when the component.Component is being started.
type StartFunc func(context.Context, component.Host) error

// Start calls f(ctx, host).
func (f StartFunc) Start(ctx context.Context, host component.Host) error {
	return f(ctx, host)
}

// ShutdownFunc specifies the function invoked when the component.Component is being shutdown.
type ShutdownFunc func(context.Context) error

// Shutdown calls f(ctx, host).
func (f ShutdownFunc) Shutdown(ctx context.Context) error {
	return f(ctx)
}

// Option represents the possible options for New.
type Option func(*baseComponent)

// WithStart overrides the default `Start` function for a component.Component.
// The default always returns nil.
func WithStart(startFunc StartFunc) Option {
	return func(o *baseComponent) {
		o.StartFunc = startFunc
	}
}

// WithShutdown overrides the default `Shutdown` function for a component.Component.
// The default always returns nil.
func WithShutdown(shutdownFunc ShutdownFunc) Option {
	return func(o *baseComponent) {
		o.ShutdownFunc = shutdownFunc
	}
}

type baseComponent struct {
	StartFunc
	ShutdownFunc
}

// New returns a component.Component configured with the provided options.
func New(options ...Option) component.Component {
	bc := &baseComponent{
		StartFunc:    func(ctx context.Context, host component.Host) error { return nil },
		ShutdownFunc: func(ctx context.Context) error { return nil },
	}

	for _, op := range options {
		op(bc)
	}

	return bc
}
<|endoftext|>