<commit_before>package i18n

import (
	"bytes"
	"sort"
	"strings"

	"code.google.com/p/go.text/collate"
	"code.google.com/p/go.text/language"
	"code.google.com/p/go.text/unicode/norm"
)

// i18nSorted is a stuct which satisfies the sort interface for sorting
// strings alphabetically according to locale
type i18nSorter struct {
	toBeSorted             []interface{}
	getComparisonValueFunc func(interface{}) string
	lessThanFunc           func(i, j int) bool
	collator               *collate.Collator
}

// Len satisfied the sort interface
func (s *i18nSorter) Len() int {
	return len(s.toBeSorted)
}

// Swap satisfied the sort interface
func (s *i18nSorter) Swap(i, j int) {
	s.toBeSorted[i], s.toBeSorted[j] = s.toBeSorted[j], s.toBeSorted[i]
}

// Less satisfied the sort interface.  It uses a collator if available to do a
// string comparison.  Otherwise is uses unicode normalization.
func (s *i18nSorter) Less(i, j int) bool {

	iValue := strings.ToLower(s.getComparisonValueFunc(s.toBeSorted[i]))
	jValue := strings.ToLower(s.getComparisonValueFunc(s.toBeSorted[j]))

	// if it's a local sort, use the collator
	if s.collator != nil {
		return s.collator.CompareString(iValue, jValue) == -1
	}

	// for universal sorts, normalize the unicode to sort
	normalizer := norm.NFKD
	iValue = normalizer.String(iValue)
	jValue = normalizer.String(jValue)

	return bytes.Compare([]byte(iValue), []byte(jValue)) == -1
}

// SortUniversal sorts a generic slice alphabetically in such a way that it
// should be mostly correct for most locales. It should be used in the following
// 2 cases:
//     - As a fallback for SortLocale, when a collator for a specific locale
//       cannot be found
//     - When a locale is not available, or a sorting needs to be done in a
//       locale-agnostic way
// It uses unicode normalization.
// The func argument tells this function what string value to do the comparisons
// on.
func SortUniversal(toBeSorted []interface{}, getComparisonValueFunction func(interface{}) string) {
	sorter := &i18nSorter{
		toBeSorted:             toBeSorted,
		getComparisonValueFunc: getComparisonValueFunction,
	}

	sort.Sort(sorter)
}

// SortLocal sorts a generic slice alphabetically for a specific locale. It
// uses collation information if available for the specific locale requested.
// It falls back to SortUniversal otherwise. The func argument tells this
// function what string value to do the comparisons on.
func SortLocal(locale string, toBeSorted []interface{}, getComparisonValueFunction func(interface{}) string) {

	if locale == "" {
		SortUniversal(toBeSorted, getComparisonValueFunction)
		return
	}

	collator := getCollator(locale)

	if collator == nil {
		SortUniversal(toBeSorted, getComparisonValueFunction)
		return
	}

	sorter := &i18nSorter{
		toBeSorted:             toBeSorted,
		getComparisonValueFunc: getComparisonValueFunction,
		collator:               collator,
	}

	sort.Sort(sorter)
}

// getCollator returns a collate package Collator pointer. This can result in a
// panic, so this function must recover from that if it happens.
func getCollator(locale string) *collate.Collator {

	defer func() {
		recover()
	}()

	tag := language.Make(locale)

	if tag == language.Und {
		return nil
	}
	return collate.New(tag)
}

// Sort sorts a generic slice alphabetically for this translator's locale. It
// uses collation information if available for the specific locale requested.
// It falls back to SortUniversal otherwise. The func argument tells this
// function what string value to do the comparisons on.
func (t *Translator) Sort(toBeSorted []interface{}, getComparisonValueFunction func(interface{}) string) {
	SortLocal(t.locale, toBeSorted, getComparisonValueFunction)
}
<commit_msg>Fix go.text imports<commit_after>package i18n

import (
	"bytes"
	"sort"
	"strings"

	"golang.org/x/text/collate"
	"golang.org/x/text/language"
	"golang.org/x/text/unicode/norm"
)

// i18nSorted is a stuct which satisfies the sort interface for sorting
// strings alphabetically according to locale
type i18nSorter struct {
	toBeSorted             []interface{}
	getComparisonValueFunc func(interface{}) string
	lessThanFunc           func(i, j int) bool
	collator               *collate.Collator
}

// Len satisfied the sort interface
func (s *i18nSorter) Len() int {
	return len(s.toBeSorted)
}

// Swap satisfied the sort interface
func (s *i18nSorter) Swap(i, j int) {
	s.toBeSorted[i], s.toBeSorted[j] = s.toBeSorted[j], s.toBeSorted[i]
}

// Less satisfied the sort interface.  It uses a collator if available to do a
// string comparison.  Otherwise is uses unicode normalization.
func (s *i18nSorter) Less(i, j int) bool {

	iValue := strings.ToLower(s.getComparisonValueFunc(s.toBeSorted[i]))
	jValue := strings.ToLower(s.getComparisonValueFunc(s.toBeSorted[j]))

	// if it's a local sort, use the collator
	if s.collator != nil {
		return s.collator.CompareString(iValue, jValue) == -1
	}

	// for universal sorts, normalize the unicode to sort
	normalizer := norm.NFKD
	iValue = normalizer.String(iValue)
	jValue = normalizer.String(jValue)

	return bytes.Compare([]byte(iValue), []byte(jValue)) == -1
}

// SortUniversal sorts a generic slice alphabetically in such a way that it
// should be mostly correct for most locales. It should be used in the following
// 2 cases:
//     - As a fallback for SortLocale, when a collator for a specific locale
//       cannot be found
//     - When a locale is not available, or a sorting needs to be done in a
//       locale-agnostic way
// It uses unicode normalization.
// The func argument tells this function what string value to do the comparisons
// on.
func SortUniversal(toBeSorted []interface{}, getComparisonValueFunction func(interface{}) string) {
	sorter := &i18nSorter{
		toBeSorted:             toBeSorted,
		getComparisonValueFunc: getComparisonValueFunction,
	}

	sort.Sort(sorter)
}

// SortLocal sorts a generic slice alphabetically for a specific locale. It
// uses collation information if available for the specific locale requested.
// It falls back to SortUniversal otherwise. The func argument tells this
// function what string value to do the comparisons on.
func SortLocal(locale string, toBeSorted []interface{}, getComparisonValueFunction func(interface{}) string) {

	if locale == "" {
		SortUniversal(toBeSorted, getComparisonValueFunction)
		return
	}

	collator := getCollator(locale)

	if collator == nil {
		SortUniversal(toBeSorted, getComparisonValueFunction)
		return
	}

	sorter := &i18nSorter{
		toBeSorted:             toBeSorted,
		getComparisonValueFunc: getComparisonValueFunction,
		collator:               collator,
	}

	sort.Sort(sorter)
}

// getCollator returns a collate package Collator pointer. This can result in a
// panic, so this function must recover from that if it happens.
func getCollator(locale string) *collate.Collator {

	defer func() {
		recover()
	}()

	tag := language.Make(locale)

	if tag == language.Und {
		return nil
	}
	return collate.New(tag)
}

// Sort sorts a generic slice alphabetically for this translator's locale. It
// uses collation information if available for the specific locale requested.
// It falls back to SortUniversal otherwise. The func argument tells this
// function what string value to do the comparisons on.
func (t *Translator) Sort(toBeSorted []interface{}, getComparisonValueFunction func(interface{}) string) {
	SortLocal(t.locale, toBeSorted, getComparisonValueFunction)
}
<|endoftext|>


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

package main

import (
	"os"
	"os/signal"
	"runtime"
	"strings"
	"syscall"
	"time"

	log "github.com/Sirupsen/logrus"

	"github.com/coreos/go-etcd/etcd"

	"github.com/borgstrom/reeve/reeve-director/config"
)

func init() {
	runtime.GOMAXPROCS(runtime.NumCPU())
}

func main() {
	if config.DEBUG == true {
		log.SetLevel(log.DebugLevel)
	}

	log.WithFields(log.Fields{
		"id": config.ID,
	}).Print("reeve-director starting")

	log.WithFields(log.Fields{
		"hosts": config.ETCD_HOSTS,
	}).Print("Connecting to etcd")
	client := etcd.NewClient(config.ETCD_HOSTS)

	// handle cleanup
	cleanupChannel := make(chan os.Signal, 1)
	signal.Notify(cleanupChannel, os.Interrupt)
	signal.Notify(cleanupChannel, syscall.SIGTERM)
	go func() {
		<-cleanupChannel
		cleanup(client)
		os.Exit(0)
	}()

	// find other directors
	go discoverDirectors(client)

	// register as a director
	go directorHeartbeat(client)

	// sleep forever
	for {
		time.Sleep(1 * time.Second)
	}
}

func cleanup(client *etcd.Client) {
	client.Delete(config.EtcDirectorPath(), false)
}

func directorHeartbeat(client *etcd.Client) {
	for {
		if _, err := client.Set(config.EtcDirectorPath(), "", 30); err != nil {
			log.Fatal(err)
		}
		time.Sleep(30 * time.Second)
	}
}

func discoverDirectors(client *etcd.Client) {
	log.Print("Discovering other directors")

	updates := make(chan *etcd.Response)

	go func() {
		if _, err := client.Watch(config.EtcDirectorsPath(), 0, true, updates, nil); err != nil {
			log.Fatal(err)
		}
	}()

	for res := range updates {
		log.WithFields(log.Fields{
			"action": res.Action,
			"key":    res.Node.Key,
			"value":  res.Node.Value,
		}).Debug("New event")

		parts := strings.Split(res.Node.Key, "/")
		node := parts[2]

		if node == config.ID {
			// ignore events about ourself
			continue
		}

		if res.Action == "set" {
			// check if we know about this director
			log.WithFields(log.Fields{
				"peer": node,
			}).Info("Peer registration")
		}

		if res.Action == "delete" {
			log.WithFields(log.Fields{
				"peer": node,
			}).Info("Peer deletion")
		}

		if res.Action == "expire" {
			log.WithFields(log.Fields{
				"peer": node,
			}).Info("Peer expiration")
		}
	}
}
<commit_msg>Stop passing client around<commit_after>// Reeve director - entry point
//
// Copyright 2015 Evan Borgstrom
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"os"
	"os/signal"
	"runtime"
	"strings"
	"syscall"
	"time"

	log "github.com/Sirupsen/logrus"

	"github.com/coreos/go-etcd/etcd"

	"github.com/borgstrom/reeve/reeve-director/config"
)

var (
	client *etcd.Client
)

func init() {
	runtime.GOMAXPROCS(runtime.NumCPU())
}

func main() {
	if config.DEBUG == true {
		log.SetLevel(log.DebugLevel)
	}

	log.WithFields(log.Fields{
		"id": config.ID,
	}).Print("reeve-director starting")

	log.WithFields(log.Fields{
		"hosts": config.ETCD_HOSTS,
	}).Print("Connecting to etcd")
	client = etcd.NewClient(config.ETCD_HOSTS)

	// handle cleanup
	cleanupChannel := make(chan os.Signal, 1)
	signal.Notify(cleanupChannel, os.Interrupt)
	signal.Notify(cleanupChannel, syscall.SIGTERM)
	go func() {
		<-cleanupChannel
		cleanup()
		os.Exit(0)
	}()

	// find other directors
	go discoverDirectors()

	// register as a director
	go directorHeartbeat()

	// sleep forever
	for {
		time.Sleep(60 * time.Second)
	}
}

func cleanup() {
	client.Delete(config.EtcDirectorPath(), false)
}

func directorHeartbeat() {
	for {
		if _, err := client.Set(config.EtcDirectorPath(), "", 30); err != nil {
			log.Fatal(err)
		}
		time.Sleep(30 * time.Second)
	}
}

func discoverDirectors() {
	log.Print("Discovering other directors")

	updates := make(chan *etcd.Response)

	go func() {
		if _, err := client.Watch(config.EtcDirectorsPath(), 0, true, updates, nil); err != nil {
			log.Fatal(err)
		}
	}()

	for res := range updates {
		log.WithFields(log.Fields{
			"action": res.Action,
			"key":    res.Node.Key,
			"value":  res.Node.Value,
		}).Debug("New event")

		parts := strings.Split(res.Node.Key, "/")
		node := parts[2]

		if node == config.ID {
			// ignore events about ourself
			continue
		}

		if res.Action == "set" {
			// check if we know about this director
			log.WithFields(log.Fields{
				"peer": node,
			}).Info("Peer registration")
		}

		if res.Action == "delete" {
			log.WithFields(log.Fields{
				"peer": node,
			}).Info("Peer deletion")
		}

		if res.Action == "expire" {
			log.WithFields(log.Fields{
				"peer": node,
			}).Info("Peer expiration")
		}
	}
}
<|endoftext|>


<commit_before>package reflect

import (
	"go/ast"
	"go/token"
	"reflect"
	"testing"
)

func TestProcessStructDecl_IncorrectTok(t *testing.T) {
	s := processStructDecl(&ast.GenDecl{
		Tok: token.IMPORT,
	})
	if s != nil {
		t.Errorf("Nil should be returned in case genDecl's Tok != token.TYPE, %#v is returned.", s)
	}
}

func TestProcessStructDecl_EmptySpec(t *testing.T) {
	s := processStructDecl(&ast.GenDecl{
		Tok: token.TYPE,
	})
	if s != nil {
		t.Errorf("In case of empty Specs, nil is expected. Got %#v.", s)
	}
}

func TestProcessStructDecl(t *testing.T) {
	pkg := getPackage(t, `package test
			// Sample ...
			// Line 2
			type Sample struct {
				Something *something.Cool "something"

				Name struct {
					First, Last string
				}
			}
		`,
	)
	expRes := Struct{
		Comments: []string{"// Sample ...", "// Line 2"},
		Name:     "Sample",
		Fields: []Arg{
			{
				Name: "Something",
				Tag:  "something",
				Type: &Type{
					Name:    "Cool",
					Package: "something",
					Star:    true,
				},
			},
		},
	}
	genDecl, _ := pkg.Decls[0].(*ast.GenDecl)
	r := processStructDecl(genDecl)
	if !deepEqualStruct(&expRes, r) {
		t.Errorf("Error: %#v != %#v.", expRes, r)
	}
}

func TestProcessImportDecl_IncorrectTok(t *testing.T) {
	s := processStructDecl(&ast.GenDecl{
		Tok: token.TYPE,
	})
	if s != nil {
		t.Errorf("Nil should be returned in case genDecl's Tok != token.IMPORT, %#v is returned.", s)
	}
}

func TestProcessImportDecl_EmptySpec(t *testing.T) {
	s := processImportDecl(&ast.GenDecl{
		Tok: token.IMPORT,
	})
	if s == nil || len(s) > 0 {
		t.Errorf("In case of empty Specs, initialized but empty map is expected. Got %#v.", s)
	}
}

func TestProcessImportDecl(t *testing.T) {
	pkg := getPackage(t, `package test
			import (
				"strings"

				"./example"

				"github.com/anonx/sunplate"
				l "github.com/anonx/sunplate/log"
			)
		`,
	)
	expRes := map[string]string{
		"strings":  "strings",
		"example":  "./example",
		"sunplate": "github.com/anonx/sunplate",
		"l":        "github.com/anonx/sunplate/log",
	}
	genDecl, _ := pkg.Decls[0].(*ast.GenDecl)
	imps := processImportDecl(genDecl)
	if !reflect.DeepEqual(expRes, imps) {
		t.Errorf("Incorrect result returned. Expected %#v, got %#v.", expRes, imps)
	}
}

func TestProcessTypeSpec_IncorrectType(t *testing.T) {
	s := processTypeSpec(&ast.TypeSpec{
		Type: &ast.InterfaceType{},
	})
	if s != nil {
		t.Errorf("StructType is the only supported type and thus nil expected, got %#v.", s)
	}
}

func TestProcessTypeSpec(t *testing.T) {
	pkg := getPackage(t, `package test
			type Sample struct {
				Something *something.Cool "something"

				Name struct {
					First, Last string
				}
			}
		`,
	)
	expRes := &Struct{
		Fields: []Arg{
			{
				Name: "Something",
				Tag:  "something",
				Type: &Type{
					Name:    "Cool",
					Package: "something",
					Star:    true,
				},
			},
		},
		Name: "Sample",
	}
	genDecl, _ := pkg.Decls[0].(*ast.GenDecl)
	typeSpec, _ := genDecl.Specs[0].(*ast.TypeSpec)
	res := processTypeSpec(typeSpec)
	if !deepEqualStruct(expRes, res) {
		fset := token.NewFileSet()
		ast.Print(fset, typeSpec)
		t.Errorf("Incorrect processStructTypeSpec result. Expected %#v, got %#v.", expRes, res)
	}
}

func TestProcessImportSpec(t *testing.T) {
	pkg := getPackage(t, `package test
			import(
				"github.com/anonx/sunplate"
				l "github.com/anonx/sunplate/log"
				"./example"
				"strings"
			)
		`,
	)
	expRes := map[string]string{
		"sunplate": "github.com/anonx/sunplate",
		"l":        "github.com/anonx/sunplate/log",
		"example":  "./example",
		"strings":  "strings",
	}
	genDecl, _ := pkg.Decls[0].(*ast.GenDecl)
	for _, st := range genDecl.Specs { // Iterating over specs.
		k, v := processImportSpec(st.(*ast.ImportSpec))
		if expRes[k] != v {
			t.Errorf(
				"Incorrect import key-value pair. Expected %s=%s, got %s=%s.",
				k, expRes[k], k, v,
			)
		}
	}
}

// deepEqualStruct is used by tests to compare two structures.
func deepEqualStruct(s1, s2 *Struct) bool {
	if s1 == nil || s2 == nil {
		if s1 == s2 {
			return true
		}
		return false
	}
	if !reflect.DeepEqual(s1.Comments, s2.Comments) || s1.Name != s2.Name || s1.File != s2.File {
		return false
	}
	if !deepEqualArgSlice(s1.Fields, s2.Fields) {
		return false
	}
	return true
}

// deepEqualStructSlice is a function that is used in tests for
// comparison of struct slices.
func deepEqualStructSlice(s1, s2 []Struct) bool {
	if len(s1) != len(s2) {
		return false
	}
	for i, st := range s1 {
		if !deepEqualStruct(&st, &s2[i]) {
			return false
		}
	}
	return true
}
<commit_msg>Fix processImportDecl test<commit_after>package reflect

import (
	"go/ast"
	"go/token"
	"reflect"
	"testing"
)

func TestProcessStructDecl_IncorrectTok(t *testing.T) {
	s := processStructDecl(&ast.GenDecl{
		Tok: token.IMPORT,
	})
	if s != nil {
		t.Errorf("Nil should be returned in case genDecl's Tok != token.TYPE, %#v is returned.", s)
	}
}

func TestProcessStructDecl_EmptySpec(t *testing.T) {
	s := processStructDecl(&ast.GenDecl{
		Tok: token.TYPE,
	})
	if s != nil {
		t.Errorf("In case of empty Specs, nil is expected. Got %#v.", s)
	}
}

func TestProcessStructDecl(t *testing.T) {
	pkg := getPackage(t, `package test
			// Sample ...
			// Line 2
			type Sample struct {
				Something *something.Cool "something"

				Name struct {
					First, Last string
				}
			}
		`,
	)
	expRes := Struct{
		Comments: []string{"// Sample ...", "// Line 2"},
		Name:     "Sample",
		Fields: []Arg{
			{
				Name: "Something",
				Tag:  "something",
				Type: &Type{
					Name:    "Cool",
					Package: "something",
					Star:    true,
				},
			},
		},
	}
	genDecl, _ := pkg.Decls[0].(*ast.GenDecl)
	r := processStructDecl(genDecl)
	if !deepEqualStruct(&expRes, r) {
		t.Errorf("Error: %#v != %#v.", expRes, r)
	}
}

func TestProcessImportDecl_IncorrectTok(t *testing.T) {
	s := processImportDecl(&ast.GenDecl{
		Tok: token.TYPE,
	})
	if s != nil {
		t.Errorf("Nil should be returned in case genDecl's Tok != token.IMPORT, %#v is returned.", s)
	}
}

func TestProcessImportDecl_EmptySpec(t *testing.T) {
	s := processImportDecl(&ast.GenDecl{
		Tok: token.IMPORT,
	})
	if s == nil || len(s) > 0 {
		t.Errorf("In case of empty Specs, initialized but empty map is expected. Got %#v.", s)
	}
}

func TestProcessImportDecl(t *testing.T) {
	pkg := getPackage(t, `package test
			import (
				"strings"

				"./example"

				"github.com/anonx/sunplate"
				l "github.com/anonx/sunplate/log"
			)
		`,
	)
	expRes := map[string]string{
		"strings":  "strings",
		"example":  "./example",
		"sunplate": "github.com/anonx/sunplate",
		"l":        "github.com/anonx/sunplate/log",
	}
	genDecl, _ := pkg.Decls[0].(*ast.GenDecl)
	imps := processImportDecl(genDecl)
	if !reflect.DeepEqual(expRes, imps) {
		t.Errorf("Incorrect result returned. Expected %#v, got %#v.", expRes, imps)
	}
}

func TestProcessTypeSpec_IncorrectType(t *testing.T) {
	s := processTypeSpec(&ast.TypeSpec{
		Type: &ast.InterfaceType{},
	})
	if s != nil {
		t.Errorf("StructType is the only supported type and thus nil expected, got %#v.", s)
	}
}

func TestProcessTypeSpec(t *testing.T) {
	pkg := getPackage(t, `package test
			type Sample struct {
				Something *something.Cool "something"

				Name struct {
					First, Last string
				}
			}
		`,
	)
	expRes := &Struct{
		Fields: []Arg{
			{
				Name: "Something",
				Tag:  "something",
				Type: &Type{
					Name:    "Cool",
					Package: "something",
					Star:    true,
				},
			},
		},
		Name: "Sample",
	}
	genDecl, _ := pkg.Decls[0].(*ast.GenDecl)
	typeSpec, _ := genDecl.Specs[0].(*ast.TypeSpec)
	res := processTypeSpec(typeSpec)
	if !deepEqualStruct(expRes, res) {
		fset := token.NewFileSet()
		ast.Print(fset, typeSpec)
		t.Errorf("Incorrect processStructTypeSpec result. Expected %#v, got %#v.", expRes, res)
	}
}

func TestProcessImportSpec(t *testing.T) {
	pkg := getPackage(t, `package test
			import(
				"github.com/anonx/sunplate"
				l "github.com/anonx/sunplate/log"
				"./example"
				"strings"
			)
		`,
	)
	expRes := map[string]string{
		"sunplate": "github.com/anonx/sunplate",
		"l":        "github.com/anonx/sunplate/log",
		"example":  "./example",
		"strings":  "strings",
	}
	genDecl, _ := pkg.Decls[0].(*ast.GenDecl)
	for _, st := range genDecl.Specs { // Iterating over specs.
		k, v := processImportSpec(st.(*ast.ImportSpec))
		if expRes[k] != v {
			t.Errorf(
				"Incorrect import key-value pair. Expected %s=%s, got %s=%s.",
				k, expRes[k], k, v,
			)
		}
	}
}

// deepEqualStruct is used by tests to compare two structures.
func deepEqualStruct(s1, s2 *Struct) bool {
	if s1 == nil || s2 == nil {
		if s1 == s2 {
			return true
		}
		return false
	}
	if !reflect.DeepEqual(s1.Comments, s2.Comments) || s1.Name != s2.Name || s1.File != s2.File {
		return false
	}
	if !deepEqualArgSlice(s1.Fields, s2.Fields) {
		return false
	}
	return true
}

// deepEqualStructSlice is a function that is used in tests for
// comparison of struct slices.
func deepEqualStructSlice(s1, s2 []Struct) bool {
	if len(s1) != len(s2) {
		return false
	}
	for i, st := range s1 {
		if !deepEqualStruct(&st, &s2[i]) {
			return false
		}
	}
	return true
}
<|endoftext|>


<commit_before>package main

import "fmt"

var Vector [8][8]int = [8][8]int{
	{0, 0, 0, 0, 0, 0, 0, 0},               // empty
	{0, 0, 0, 0, 0, 0, 0, 0},               // pawn - handled specially.
	{+21, +12, -8, -19, -21, -12, +8, +19}, // N
	{+11, -9, -11, +9, 0, 0, 0, 0},         // B
	{+10, +1, -10, -1, 0, 0, 0, 0},         // R
	{+10, +11, +1, -9, -10, -11, -1, +9},   // Q
	{+10, +11, +1, -9, -10, -11, -1, +9},   // K
	{0, 0, 0, 0, 0, 0, 0, 0},               // ?
}

var Slide [8]bool = [8]bool{false, false, false, true, true, true, false, false}

const (
	MoveQuiet byte = iota
	MoveDoublePush
	MoveCapture
)

type Move struct {
	From    byte
	To      byte
	Kind    byte
	Promote byte
	Score   int16
}

func pawnmove(b *Board, i byte, retval []Move) []Move {
	var PawnPush, DoublePush byte
	CanDouble := false
	if b.ToMove == BLACK {
		PawnPush = i - 10
		DoublePush = i - 20
		CanDouble = i/10 == 8
	} else {
		PawnPush = i + 10
		DoublePush = i + 20
		CanDouble = i/10 == 3
	}
	if GetPiece(b.Data[PawnPush]) == EMPTY {
		retval = append(retval, Move{i,
			PawnPush, MoveQuiet, EMPTY, 0})
		if CanDouble && GetPiece(b.Data[DoublePush]) ==
			EMPTY {
			retval = append(retval, Move{i,
				DoublePush, MoveDoublePush, EMPTY, 0})
		}
	}
	retval = pawncap(b, i, retval, PawnPush-1)
	retval = pawncap(b, i, retval, PawnPush+1)
	return retval
}

func pawncap(b *Board, i byte, retval []Move, place byte) []Move {
	if OnBoard(place) && GetPiece(b.Data[place]) != EMPTY &&
		GetSide(b.Data[place]) != b.ToMove {
		retval = append(retval, Move{i,
			place, MoveCapture, EMPTY, 0})
	}
	return retval
}

func squareattacked(b *Board, i byte, attacking byte) bool {
	var PawnPush byte
	if attacking == BLACK {
		PawnPush = i + 10
	} else {
		PawnPush = i - 10
	}
	if (GetSide(b.Data[PawnPush-1]) == attacking && GetPiece(b.Data[PawnPush-1]) == PAWN) || (GetSide(b.Data[PawnPush+1]) == attacking && GetPiece(b.Data[PawnPush+1]) == PAWN) {
		return true
	}
	for dir := 0; dir < 8; dir++ {
		from := i
		for {
			to := byte(int(from) + Vector[QUEEN][dir])
			piece := GetPiece(b.Data[to])
			if b.Data[to] == OFFBOARD || (piece != EMPTY && GetSide(b.Data[to]) != attacking) {
				break
			} else if piece == QUEEN && GetSide(b.Data[to]) == attacking {
				return true
			} else if piece == ROOK && GetSide(b.Data[to]) == attacking && (Vector[QUEEN][dir] == 10 || Vector[QUEEN][dir] == -10 || Vector[QUEEN][dir] == 1 || Vector[QUEEN][dir] == -1) {
				return true
			} else if piece == BISHOP && GetSide(b.Data[to]) == attacking && (Vector[QUEEN][dir] == 11 || Vector[QUEEN][dir] == -11 || Vector[QUEEN][dir] == 9 || Vector[QUEEN][dir] == -9) {
				return true
			}
			from = to
		}
		to := byte(int(i) + Vector[KNIGHT][dir])
		if b.Data[to] != OFFBOARD && GetPiece(b.Data[to]) == KNIGHT && GetSide(b.Data[to]) == attacking {
			return true
		}
	}
	return false
}

func quietmove(b *Board, i byte, retval []Move) []Move {
	piece := GetPiece(b.Data[i])
	for dir := 0; dir < 8; dir++ {
		if Vector[piece][dir] == 0 {
			break
		}
		from := i
		for {
			to := byte(int(from) + Vector[piece][dir])
			if b.Data[to] != OFFBOARD {
				if GetPiece(b.Data[to]) == EMPTY {
					retval = append(retval, Move{i,
						to, MoveQuiet, EMPTY, 0})
					if Slide[piece] {
						from = to
					} else {
						break
					}
				} else if GetSide(b.Data[to]) != b.ToMove {
					retval = append(retval, Move{i,
						to, MoveCapture, EMPTY, 0})
					break
				} else {
					break
				}
			} else {
				break
			}
		}
	}
	return retval
}

func MoveGen(b *Board) []Move {
	retval := make([]Move, 0, 32)
	for i := A1; i <= H8; i++ {
		if !OnBoard(i) || GetPiece(b.Data[i]) == EMPTY || GetSide(b.Data[i]) != b.ToMove {
			continue
		}
		if GetPiece(b.Data[i]) == PAWN {
			retval = pawnmove(b, i, retval)
		} else {
			retval = quietmove(b, i, retval)
		}
	}
	return retval
}

func MakeMove(b *Board, m *Move) {
	b.EnPassant = INVALID
	b.Data[m.To] = b.Data[m.From]
	b.Data[m.From] = EMPTY
	switch m.Kind {
	case MoveQuiet:
		/* Do nothing */
	case MoveDoublePush:
		if b.ToMove == BLACK {
			b.EnPassant = m.From - 10
		} else {
			b.EnPassant = m.From + 10
		}
	}
	b.ToMove ^= BLACK
}

func (m Move) String() string {
	return fmt.Sprint("{From: ", IndexToAlgebraic(m.From), " to: ",
		IndexToAlgebraic(m.To), " type: ", m.Kind, "}")
}

func DoDividePerft(depth int) uint64 {
	board, _ := Parse(START)
	return Perft(depth, board, true)
}

func Perft(depth int, board *Board, divide bool) uint64 {
	if depth == 0 {
		return 1
	}
	var nodes uint64 = 0
	moves := MoveGen(board)
	for _, move := range moves {
		boardc := *board
		MakeMove(&boardc, &move)
		if Illegal(&boardc) {
			fmt.Printf(".\n")
			continue
		}
		if divide {
			fmt.Printf("%s%s ", IndexToAlgebraic(move.From), IndexToAlgebraic(move.To))
		}
		tmp := Perft(depth-1, &boardc, false)
		nodes += tmp
		if divide {
			fmt.Printf("%d\n", tmp)
		}

	}
	return nodes
}
<commit_msg>Woops.<commit_after>package main

import "fmt"

var Vector [8][8]int = [8][8]int{
	{0, 0, 0, 0, 0, 0, 0, 0},               // empty
	{0, 0, 0, 0, 0, 0, 0, 0},               // pawn - handled specially.
	{+21, +12, -8, -19, -21, -12, +8, +19}, // N
	{+11, -9, -11, +9, 0, 0, 0, 0},         // B
	{+10, +1, -10, -1, 0, 0, 0, 0},         // R
	{+10, +11, +1, -9, -10, -11, -1, +9},   // Q
	{+10, +11, +1, -9, -10, -11, -1, +9},   // K
	{0, 0, 0, 0, 0, 0, 0, 0},               // ?
}

var Slide [8]bool = [8]bool{false, false, false, true, true, true, false, false}

const (
	MoveQuiet byte = iota
	MoveDoublePush
	MoveCapture
)

type Move struct {
	From    byte
	To      byte
	Kind    byte
	Promote byte
	Score   int16
}

func pawnmove(b *Board, i byte, retval []Move) []Move {
	var PawnPush, DoublePush byte
	CanDouble := false
	if b.ToMove == BLACK {
		PawnPush = i - 10
		DoublePush = i - 20
		CanDouble = i/10 == 8
	} else {
		PawnPush = i + 10
		DoublePush = i + 20
		CanDouble = i/10 == 3
	}
	if GetPiece(b.Data[PawnPush]) == EMPTY {
		retval = append(retval, Move{i,
			PawnPush, MoveQuiet, EMPTY, 0})
		if CanDouble && GetPiece(b.Data[DoublePush]) ==
			EMPTY {
			retval = append(retval, Move{i,
				DoublePush, MoveDoublePush, EMPTY, 0})
		}
	}
	retval = pawncap(b, i, retval, PawnPush-1)
	retval = pawncap(b, i, retval, PawnPush+1)
	return retval
}

func pawncap(b *Board, i byte, retval []Move, place byte) []Move {
	if OnBoard(place) && GetPiece(b.Data[place]) != EMPTY &&
		GetSide(b.Data[place]) != b.ToMove {
		retval = append(retval, Move{i,
			place, MoveCapture, EMPTY, 0})
	}
	return retval
}

func squareattacked(b *Board, i byte, attacking byte) bool {
	var PawnPush byte
	if attacking == BLACK {
		PawnPush = i + 10
	} else {
		PawnPush = i - 10
	}
	if (GetSide(b.Data[PawnPush-1]) == attacking && GetPiece(b.Data[PawnPush-1]) == PAWN) || (GetSide(b.Data[PawnPush+1]) == attacking && GetPiece(b.Data[PawnPush+1]) == PAWN) {
		return true
	}
	for dir := 0; dir < 8; dir++ {
		from := i
		for {
			to := byte(int(from) + Vector[QUEEN][dir])
			piece := GetPiece(b.Data[to])
			if b.Data[to] == OFFBOARD || (piece != EMPTY && GetSide(b.Data[to]) != attacking) {
				break
			} else if piece == QUEEN && GetSide(b.Data[to]) == attacking {
				return true
			} else if piece == ROOK && GetSide(b.Data[to]) == attacking && (Vector[QUEEN][dir] == 10 || Vector[QUEEN][dir] == -10 || Vector[QUEEN][dir] == 1 || Vector[QUEEN][dir] == -1) {
				return true
			} else if piece == BISHOP && GetSide(b.Data[to]) == attacking && (Vector[QUEEN][dir] == 11 || Vector[QUEEN][dir] == -11 || Vector[QUEEN][dir] == 9 || Vector[QUEEN][dir] == -9) {
				return true
			}
			from = to
		}
		to := byte(int(i) + Vector[KNIGHT][dir])
		if b.Data[to] != OFFBOARD && GetPiece(b.Data[to]) == KNIGHT && GetSide(b.Data[to]) == attacking {
			return true
		}
	}
	return false
}

func quietmove(b *Board, i byte, retval []Move) []Move {
	piece := GetPiece(b.Data[i])
	for dir := 0; dir < 8; dir++ {
		if Vector[piece][dir] == 0 {
			break
		}
		from := i
		for {
			to := byte(int(from) + Vector[piece][dir])
			if b.Data[to] != OFFBOARD {
				if GetPiece(b.Data[to]) == EMPTY {
					retval = append(retval, Move{i,
						to, MoveQuiet, EMPTY, 0})
					if Slide[piece] {
						from = to
					} else {
						break
					}
				} else if GetSide(b.Data[to]) != b.ToMove {
					retval = append(retval, Move{i,
						to, MoveCapture, EMPTY, 0})
					break
				} else {
					break
				}
			} else {
				break
			}
		}
	}
	return retval
}

func MoveGen(b *Board) []Move {
	retval := make([]Move, 0, 32)
	for i := A1; i <= H8; i++ {
		if !OnBoard(i) || GetPiece(b.Data[i]) == EMPTY || GetSide(b.Data[i]) != b.ToMove {
			continue
		}
		if GetPiece(b.Data[i]) == PAWN {
			retval = pawnmove(b, i, retval)
		} else {
			retval = quietmove(b, i, retval)
		}
	}
	return retval
}

func MakeMove(b *Board, m *Move) {
	b.EnPassant = INVALID
	b.Data[m.To] = b.Data[m.From]
	b.Data[m.From] = EMPTY
	switch m.Kind {
	case MoveQuiet:
		/* Do nothing */
	case MoveDoublePush:
		if b.ToMove == BLACK {
			b.EnPassant = m.From - 10
		} else {
			b.EnPassant = m.From + 10
		}
	}
	b.ToMove ^= BLACK
}

func (m Move) String() string {
	return fmt.Sprint("{From: ", IndexToAlgebraic(m.From), " to: ",
		IndexToAlgebraic(m.To), " type: ", m.Kind, "}")
}

func DoDividePerft(depth int) uint64 {
	board, _ := Parse(START)
	return Perft(depth, board, true)
}

func Perft(depth int, board *Board, divide bool) uint64 {
	if depth == 0 {
		return 1
	}
	var nodes uint64 = 0
	moves := MoveGen(board)
	for _, move := range moves {
		boardc := *board
		MakeMove(&boardc, &move)
		if Illegal(&boardc) {
			continue
		}
		if divide {
			fmt.Printf("%s%s ", IndexToAlgebraic(move.From), IndexToAlgebraic(move.To))
		}
		tmp := Perft(depth-1, &boardc, false)
		nodes += tmp
		if divide {
			fmt.Printf("%d\n", tmp)
		}

	}
	return nodes
}
<|endoftext|>


<commit_before>package gmock_test

import (
	. "github.com/cfmobile/gmock"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

const (
	kOriginalValue = "original value"
	kMockValue = "mock value"
)

var _ = Describe("GMock", func() {
	var subject *GMock // Test subject

	var constructSubject func()
	var panicked bool

	var someVar string // Target variable to mock in our tests
	var mockValue string // Variable containing the mock value to be set to the target

	BeforeEach(func() { // Reset all base values for each test
		subject = nil
		constructSubject = nil
		panicked = false
		someVar = kOriginalValue
		mockValue = kMockValue
	})

	var panicRecover = func() {
		panicked = recover() != nil
	}

	JustBeforeEach(func() {
		defer panicRecover()
		constructSubject()
	})

	Describe("MockTarget", func() {

		Context("when creating a new GMock with a target", func() {

			Context("and the target is not passed as a pointer", func() {
				BeforeEach(func() {
					constructSubject = func() {
						subject = CreateMockWithTarget(someVar)
					}
				})

				It("should panic", func() {
					Expect(panicked).To(BeTrue())
				})

				It("should not have constructed the mock", func() {
				    Expect(subject).To(BeNil())
				})
			})

			Context("and the target is passed as a pointer", func() {
				BeforeEach(func() {
					constructSubject = func() {
						subject = CreateMockWithTarget(&someVar)
					}
				})

				It("should not panic", func() {
					Expect(panicked).To(BeFalse())
				})

				It("should return a valid GMock object", func() {
					Expect(subject).NotTo(BeNil())
				})

				It("should not have altered the value of the target", func() {
					Expect(someVar).To(Equal(kOriginalValue))
				})

				It("should have backed up the pointer to the original target", func() {
					var originalPtr = subject.GetOriginal().Addr().Interface()
					Expect(originalPtr).To(Equal(&someVar))
				})

				It("should not have a mock value defined by default", func() {
					var mockTargetPtr = subject.GetTarget().Addr().Interface()
					Expect(mockTargetPtr).To(Equal(&someVar))
				})
			})
	    })
	})

	Describe("GMock", func() {

		BeforeEach(func() {
		    constructSubject = func() { // Construct a valid GMock for this set of tests
				subject = CreateMockWithTarget(&someVar)
			}
		})

	    Context("when calling Replace on a GMock object with a valid mock value", func() {

	        JustBeforeEach(func() { // It has to be a JustBeforeEach so that it happens after subject is constructed
	            subject.Replace(mockValue)
	        })

			It("should replace the value in the original var with the mock value", func() {
			    Expect(someVar).To(Equal(kMockValue))
			})

			It("should have retained the original value for restoring later", func() {
				Expect(subject.GetOriginal().Interface()).To(Equal(kOriginalValue))
			})

			It("should have a Target that points to the mock value", func() {
			    Expect(subject.GetTarget().Interface()).To(Equal(mockValue))
			})
	    })

		Context("when calling Replace on a GMock object with an invalid mock value", func() {

			It("should not have panicked when creating the mock", func() {
			    Expect(panicked).To(BeFalse())
			})

			Context("- mock value with a different type", func() {
				invalidMockValue := 21

				JustBeforeEach(func() {
					defer panicRecover()
					subject.Replace(invalidMockValue)
				})

				It("should have panicked", func() {
					Expect(panicked).To(BeTrue())
				})
			})

			Context("- mock value is a pointer to the same type as the target", func() {

				JustBeforeEach(func() {
				    defer panicRecover()
					subject.Replace(&mockValue)
				})

				It("should have panicked", func() {
				    Expect(panicked).To(BeTrue())
				})
			})

			Context("- mock value is nil", func() {
			    JustBeforeEach(func() {
					defer panicRecover()
			        subject.Replace(nil)
			    })

				It("should not have panicked", func() {
				    Expect(panicked).To(BeFalse())
				})

				It("should have assigned a default value of that type to the mock", func() {
				    Expect(someVar).To(Equal(""))
				})
			})
		})

		Context("before calling Restore on a GMock with a mock value set", func() {

			JustBeforeEach(func() {
			    subject.Replace(mockValue)
			})

			It("the target should equal to the mock value", func() {
			    Expect(someVar).To(Equal(kMockValue))
			})

			Context("when Restore is called", func() {
			    JustBeforeEach(func() {
			        subject.Restore()
			    })

				It("should have restored the target to the original value", func() {
				    Expect(someVar).To(Equal(kOriginalValue))
				})
			})
		})
	})

})
<commit_msg>RS - Added tests for constructor with default mock value MockTargetWithValue()<commit_after>package gmock_test

import (
	. "github.com/cfmobile/gmock"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

const (
	kOriginalValue = "original value"
	kMockValue = "mock value"
)

var _ = Describe("GMock", func() {
	var subject *GMock // Test subject

	var constructSubject func()
	var panicked bool

	var someVar string // Target variable to mock in our tests
	var mockValue string // Variable containing the mock value to be set to the target

	BeforeEach(func() { // Reset all base values for each test
		subject = nil
		constructSubject = nil
		panicked = false
		someVar = kOriginalValue
		mockValue = kMockValue
	})

	var panicRecover = func() {
		panicked = recover() != nil
	}

	JustBeforeEach(func() {
		defer panicRecover()
		constructSubject()
	})

	Describe("MockTarget", func() {

		Context("when creating a new GMock with a target", func() {

			Context("and the target is not passed as a pointer", func() {
				BeforeEach(func() {
					constructSubject = func() {
						subject = CreateMockWithTarget(someVar)
					}
				})

				It("should panic", func() {
					Expect(panicked).To(BeTrue())
				})

				It("should not have constructed the mock", func() {
				    Expect(subject).To(BeNil())
				})
			})

			Context("and the target is passed as a pointer", func() {
				BeforeEach(func() {
					constructSubject = func() {
						subject = CreateMockWithTarget(&someVar)
					}
				})

				It("should not panic", func() {
					Expect(panicked).To(BeFalse())
				})

				It("should return a valid GMock object", func() {
					Expect(subject).NotTo(BeNil())
				})

				It("should not have altered the value of the target", func() {
					Expect(someVar).To(Equal(kOriginalValue))
				})

				It("should have backed up the pointer to the original target", func() {
					var originalPtr = subject.GetOriginal().Addr().Interface()
					Expect(originalPtr).To(Equal(&someVar))
				})

				It("should not have a mock value defined by default", func() {
					var mockTargetPtr = subject.GetTarget().Addr().Interface()
					Expect(mockTargetPtr).To(Equal(&someVar))
				})
			})
	    })
	})

	Describe("GMock", func() {

		BeforeEach(func() {
		    constructSubject = func() { // Construct a valid GMock for this set of tests
				subject = CreateMockWithTarget(&someVar)
			}
		})

	    Context("when calling Replace on a GMock object with a valid mock value", func() {

	        JustBeforeEach(func() { // It has to be a JustBeforeEach so that it happens after subject is constructed
	            subject.Replace(mockValue)
	        })

			It("should replace the value in the original var with the mock value", func() {
			    Expect(someVar).To(Equal(kMockValue))
			})

			It("should have retained the original value for restoring later", func() {
				Expect(subject.GetOriginal().Interface()).To(Equal(kOriginalValue))
			})

			It("should have a Target that points to the mock value", func() {
			    Expect(subject.GetTarget().Interface()).To(Equal(mockValue))
			})
	    })

		Context("when calling Replace on a GMock object with an invalid mock value", func() {

			It("should not have panicked when creating the mock", func() {
			    Expect(panicked).To(BeFalse())
			})

			Context("- mock value with a different type", func() {
				invalidMockValue := 21

				JustBeforeEach(func() {
					defer panicRecover()
					subject.Replace(invalidMockValue)
				})

				It("should have panicked", func() {
					Expect(panicked).To(BeTrue())
				})
			})

			Context("- mock value is a pointer to the same type as the target", func() {

				JustBeforeEach(func() {
				    defer panicRecover()
					subject.Replace(&mockValue)
				})

				It("should have panicked", func() {
				    Expect(panicked).To(BeTrue())
				})
			})

			Context("- mock value is nil", func() {
			    JustBeforeEach(func() {
					defer panicRecover()
			        subject.Replace(nil)
			    })

				It("should not have panicked", func() {
				    Expect(panicked).To(BeFalse())
				})

				It("should have assigned a default value of that type to the mock", func() {
				    Expect(someVar).To(Equal(""))
				})
			})
		})

		Context("before calling Restore on a GMock with a mock value set", func() {

			JustBeforeEach(func() {
			    subject.Replace(mockValue)
			})

			It("the target should equal to the mock value", func() {
			    Expect(someVar).To(Equal(kMockValue))
			})

			Context("when Restore is called", func() {
			    JustBeforeEach(func() {
			        subject.Restore()
			    })

				It("should have restored the target to the original value", func() {
				    Expect(someVar).To(Equal(kOriginalValue))
				})
			})
		})
	})

	Describe("MockTargetWithValue", func() {

		It("the target should be unaltered before the constructor is called", func() {
		    Expect(someVar).To(Equal(kOriginalValue))
		})

		Context("when constructor with pre-assigned mock value is called", func() {
			BeforeEach(func() {
				constructSubject = func() {
					subject = MockTargetWithValue(&someVar, mockValue)
				}
			})

			It("should have mocked the variable right away", func() {
			    Expect(someVar).To(Equal(kMockValue))
			})
		})
	})

})
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"koding/oskite"
	"koding/terminal"
	"koding/tools/build"
	"koding/tools/config"
	"log"
	"net/url"
	"os"
	"path/filepath"
	"runtime"
	"strconv"
	"strings"
	"text/template"
	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/nu7hatch/gouuid"
)

var (
	flagProfile = flag.String("c", "", "Define config profile to be included")
	flagRegion  = flag.String("r", "", "Define region profile to be included")
	flagApp     = flag.String("a", "", "App to be build")

	// klient specific flags
	flagUsername   = flag.String("username", "", "Username to be created for the klient app")
	flagKontrolURL = flag.String("kontrol-url", "", "Kontrol URL to be connected")
	flagPublicKey  = flag.String("public-key", "", "Public RSA key of Kontrol")
	flagPrivateKey = flag.String("private-key", "", "Private RSA key of Kontrol")

	// kontrolproxy specific flags
	flagProxy = flag.String("p", "", "Select user proxy or koding proxy") // Proxy only

	flagDisableUpstart = flag.Bool("u", false, "Disable including upstart script")
	flagDebug          = flag.Bool("d", false, "Enable debug mode")

	packages = map[string]func() error{
		"oskite":       buildOsKite,
		"kontrolproxy": buildKontrolProxy,
		"terminal":     buildTerminal,
		"kontrol":      buildKontrol,
		"klient":       buildKlient,
	}
)

type pkg struct {
	appName       string
	importPath    string
	files         []string
	version       string
	upstartScript string
}

func main() {
	flag.Parse()
	if *flagApp == "" {
		fmt.Printf("Please define package with -a to be build. Available apps:\n%s\n", packageList())
		os.Exit(1)
	}

	build, ok := packages[*flagApp]
	if !ok {
		log.Fatal("package to be build is not available")
	}

	if err := build(); err != nil {
		fmt.Println(err)
	}
}

func packageList() string {
	pkgs := "\n"
	count := 1
	for pkg := range packages {
		pkgs += strconv.Itoa(count) + ". " + pkg + "\n"
		count++
	}

	return pkgs
}

func createKey(username, kontrolURL, publicKey, privateKey string) (string, error) {
	tknID, err := uuid.NewV4()
	if err != nil {
		return "", errors.New("cannot generate a token")
	}

	token := jwt.New(jwt.GetSigningMethod("RS256"))

	token.Claims = map[string]interface{}{
		"iss":        "koding",                     // Issuer, should be the same username as kontrol
		"sub":        username,                     // Subject
		"iat":        time.Now().UTC().Unix(),      // Issued At
		"jti":        tknID.String(),               // JWT ID
		"kontrolURL": kontrolURL,                   // Kontrol URL
		"kontrolKey": strings.TrimSpace(publicKey), // Public key of kontrol
	}

	log.Printf("Registered machine on user: %s", username)

	return token.SignedString([]byte(privateKey))
}

func buildKlient() error {
	if *flagPrivateKey == "" || *flagPublicKey == "" {
		return errors.New("Please define config -c and region -r")
	}

	if *flagUsername == "" {
		return errors.New("empty username")
	}

	parsed, err := url.Parse(*flagKontrolURL)
	if err != nil {
		return fmt.Errorf("cannot parse kontrol URL: %s", err)
	}

	gopath := os.Getenv("GOPATH")
	if gopath == "" {
		return errors.New("GOPATH is not set")
	}

	publicKey, err := ioutil.ReadFile(*flagPublicKey)
	if err != nil {
		return err
	}

	privateKey, err := ioutil.ReadFile(*flagPrivateKey)
	if err != nil {
		return err
	}

	key, err := createKey(*flagUsername, parsed.String(), string(publicKey), string(privateKey))
	if err != nil {
		return err
	}

	if err = ioutil.WriteFile("kite.key", []byte(key), 0400); err != nil {
		return err
	}

	importPath := "koding/kites/klient"
	upstartPath := filepath.Join(gopath, "src", importPath, "files/klient.conf")

	files := []string{filepath.Join(gopath, "bin-vagrant/kite")}

	kclient := pkg{
		appName:       *flagApp,
		importPath:    importPath,
		files:         files,
		version:       "0.0.1",
		upstartScript: upstartPath,
	}

	return kclient.build()
}

func buildKontrol() error {
	if *flagProfile == "" || *flagRegion == "" {
		return errors.New("Please define config -c and region -r")
	}

	gopath := os.Getenv("GOPATH")
	if gopath == "" {
		return errors.New("GOPATH is not set")
	}

	kontrolPath := "koding/kites/kontrol"
	temps := struct {
		Profile string
		Region  string
	}{
		Profile: *flagProfile,
		Region:  *flagRegion,
	}

	var files = make([]string, 0)
	files = append(files, filepath.Join(gopath, "src", kontrolPath, "files"))

	// change our upstartscript because it's a template
	var configUpstart string
	var err error
	if !*flagDisableUpstart {
		kontrolUpstart := filepath.Join(gopath, "src", kontrolPath, "files/kontrol.conf")
		configUpstart, err = prepareUpstart(kontrolUpstart, temps)
		if err != nil {
			return err
		}
		defer os.Remove(configUpstart)
	}

	term := pkg{
		appName:       *flagApp,
		importPath:    kontrolPath,
		files:         files,
		version:       "0.0.6",
		upstartScript: configUpstart,
	}

	return term.build()
}

func buildTerminal() error {
	if *flagProfile == "" || *flagRegion == "" {
		return errors.New("Please define config -c and region -r")
	}

	gopath := os.Getenv("GOPATH")
	if gopath == "" {
		return errors.New("GOPATH is not set")
	}

	terminalPath := "koding/kites/terminal"
	terminalPackage := "koding/terminal"
	temps := struct {
		Profile string
		Region  string
	}{
		Profile: *flagProfile,
		Region:  *flagRegion,
	}

	var files = make([]string, 0)
	files = append(files, filepath.Join(gopath, "src", terminalPackage, "files"))

	// change our upstartscript because it's a template
	var configUpstart string
	var err error
	if !*flagDisableUpstart {
		terminalUpstart := filepath.Join(gopath, "src", terminalPackage, "files/terminal.conf")
		configUpstart, err = prepareUpstart(terminalUpstart, temps)
		if err != nil {
			return err
		}
		defer os.Remove(configUpstart)
	}

	term := pkg{
		appName:       *flagApp,
		importPath:    terminalPath,
		files:         files,
		version:       terminal.TERMINAL_VERSION,
		upstartScript: configUpstart,
	}

	return term.build()
}

func buildOsKite() error {
	if *flagProfile == "" || *flagRegion == "" {
		return errors.New("Please define config -c and region -r")
	}

	gopath := os.Getenv("GOPATH")
	if gopath == "" {
		return errors.New("GOPATH is not set")
	}

	oskitePath := "koding/kites/os"
	oskitePackage := "koding/oskite"
	temps := struct {
		Profile string
		Region  string
	}{
		Profile: *flagProfile,
		Region:  *flagRegion,
	}

	var files = make([]string, 0)
	files = append(files, filepath.Join(gopath, "src", oskitePackage, "files"))
	files = append(files, filepath.Join(gopath, "bin-vagrant/vmtool")) // TODO add it to the list of importPaths

	// change our upstartscript because it's a template
	var configUpstart string
	var err error
	if !*flagDisableUpstart {
		oskiteUpstart := filepath.Join(gopath, "src", oskitePackage, "files/oskite.conf")
		configUpstart, err = prepareUpstart(oskiteUpstart, temps)
		if err != nil {
			return err
		}
		defer os.Remove(configUpstart)
	}

	oskite := pkg{
		appName:       *flagApp,
		importPath:    oskitePath,
		files:         files,
		version:       oskite.OSKITE_VERSION,
		upstartScript: configUpstart,
	}

	return oskite.build()
}

func buildKontrolProxy() error {
	if *flagProfile == "" || *flagRegion == "" {
		return errors.New("Please define config -c and region -r")
	}

	gopath := os.Getenv("GOPATH")
	if gopath == "" {
		return errors.New("GOPATH is not set")
	}

	kdproxyPath := "koding/kontrol/kontrolproxy"

	temps := struct {
		Profile   string
		Region    string
		UserProxy string
	}{
		Profile: *flagProfile,
		Region:  *flagRegion,
	}

	var files = make([]string, 0)
	switch *flagProxy {
	case "koding":
		files = append(files, "certs/koding_com_cert.pem", "certs/koding_com_key.pem")
	case "y":
		files = append(files, "certs/y_koding_com_cert.pem", "certs/y_koding_com_key.pem")
	case "x":
		files = append(files, "certs/x_koding_com_cert.pem", "certs/x_koding_com_key.pem")
	case "user":
		temps.UserProxy = "-v"
		files = append(files, "certs/kd_io_cert.pem", "certs/kd_io_key.pem")
	default:
		return errors.New("Please define certs to be included with -p. Available certs: [user | koding | x | y]")
	}

	files = append(files, filepath.Join(gopath, "src", kdproxyPath, "files"))

	// change our upstartscript because it's a template
	var configUpstart string
	var err error
	if !*flagDisableUpstart {
		kdproxyUpstart := filepath.Join(gopath, "src", kdproxyPath, "files/kontrolproxy.conf")
		configUpstart, err = prepareUpstart(kdproxyUpstart, temps)
		if err != nil {
			return err
		}
		defer os.Remove(configUpstart)
	}

	kontrolproxy := pkg{
		appName:       *flagApp,
		importPath:    kdproxyPath,
		files:         files,
		version:       "0.0.9",
		upstartScript: configUpstart,
	}

	return kontrolproxy.build()
}

func (p *pkg) build() error {
	if *flagProfile == "" || *flagRegion == "" {
		fmt.Printf("building '%s'\n", *flagApp)
	} else {
		fmt.Printf("building '%s' for config '%s' and region '%s'\n", *flagApp, *flagProfile, *flagRegion)

		// prepare config folder
		tempDir, err := ioutil.TempDir(".", "gopackage_")
		if err != nil {
			return err
		}
		defer os.RemoveAll(tempDir)

		configDir := filepath.Join(tempDir, "config")
		os.MkdirAll(configDir, 0755)

		// koding-config-manager needs it
		err = ioutil.WriteFile("VERSION", []byte(p.version), 0755)
		if err != nil {
			return err
		}
		defer os.Remove("VERSION")

		c, err := config.ReadConfigManager(*flagProfile)
		if err != nil {
			return err
		}

		configPretty, err := json.MarshalIndent(c, "", "  ")
		if err != nil {
			return err
		}

		configFile := filepath.Join(configDir, fmt.Sprintf("main.%s.json", *flagProfile))
		err = ioutil.WriteFile(configFile, configPretty, 0644)
		if err != nil {
			return err
		}

		p.files = append(p.files, configDir)
	}

	// Now it's time to build
	if runtime.GOOS != "linux" {
		return errors.New("Not supported. Please run on a linux machine.")
	}

	deb := &build.Deb{
		Debug:         *flagDebug,
		AppName:       p.appName,
		Version:       p.version,
		ImportPath:    p.importPath,
		Files:         strings.Join(p.files, ","),
		InstallPrefix: "opt/kite",
		UpstartScript: p.upstartScript,
	}

	debFile, err := deb.Build()
	if err != nil {
		log.Println("linux:", err)
	}

	// rename file to see for which region and env it is created
	oldname := debFile
	newname := ""

	if *flagProfile == "" || *flagRegion == "" {
		newname = fmt.Sprintf("%s_%s_%s.deb", p.appName, p.version, deb.Arch)
	} else {
		newname = fmt.Sprintf("%s_%s_%s-%s_%s.deb", p.appName, p.version, *flagProfile, *flagRegion, deb.Arch)
	}

	if err := os.Rename(oldname, newname); err != nil {
		return err
	}

	fmt.Printf("success '%s' is ready. Some helpful commands for you:\n\n", newname)
	fmt.Printf("  show deb content   : dpkg -c %s\n", newname)
	fmt.Printf("  show basic info    : dpkg -f %s\n", newname)
	fmt.Printf("  install to machine : dpkg -i %s\n\n", newname)

	return nil
}

func prepareUpstart(path string, v interface{}) (string, error) {
	file, err := ioutil.TempFile(".", "gopackage_")
	if err != nil {
		return "", err
	}
	defer file.Close()

	t, err := template.ParseFiles(path)
	if err != nil {
		return "", err
	}

	if err := t.Execute(file, v); err != nil {
		return "", err
	}

	return file.Name(), nil
}
<commit_msg>go/package: incresae kontrol to v.0.1.0<commit_after>package main

import (
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"koding/oskite"
	"koding/terminal"
	"koding/tools/build"
	"koding/tools/config"
	"log"
	"net/url"
	"os"
	"path/filepath"
	"runtime"
	"strconv"
	"strings"
	"text/template"
	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/nu7hatch/gouuid"
)

var (
	flagProfile = flag.String("c", "", "Define config profile to be included")
	flagRegion  = flag.String("r", "", "Define region profile to be included")
	flagApp     = flag.String("a", "", "App to be build")

	// klient specific flags
	flagUsername   = flag.String("username", "", "Username to be created for the klient app")
	flagKontrolURL = flag.String("kontrol-url", "", "Kontrol URL to be connected")
	flagPublicKey  = flag.String("public-key", "", "Public RSA key of Kontrol")
	flagPrivateKey = flag.String("private-key", "", "Private RSA key of Kontrol")

	// kontrolproxy specific flags
	flagProxy = flag.String("p", "", "Select user proxy or koding proxy") // Proxy only

	flagDisableUpstart = flag.Bool("u", false, "Disable including upstart script")
	flagDebug          = flag.Bool("d", false, "Enable debug mode")

	packages = map[string]func() error{
		"oskite":       buildOsKite,
		"kontrolproxy": buildKontrolProxy,
		"terminal":     buildTerminal,
		"kontrol":      buildKontrol,
		"klient":       buildKlient,
	}
)

type pkg struct {
	appName       string
	importPath    string
	files         []string
	version       string
	upstartScript string
}

func main() {
	flag.Parse()
	if *flagApp == "" {
		fmt.Printf("Please define package with -a to be build. Available apps:\n%s\n", packageList())
		os.Exit(1)
	}

	build, ok := packages[*flagApp]
	if !ok {
		log.Fatal("package to be build is not available")
	}

	if err := build(); err != nil {
		fmt.Println(err)
	}
}

func packageList() string {
	pkgs := "\n"
	count := 1
	for pkg := range packages {
		pkgs += strconv.Itoa(count) + ". " + pkg + "\n"
		count++
	}

	return pkgs
}

func createKey(username, kontrolURL, publicKey, privateKey string) (string, error) {
	tknID, err := uuid.NewV4()
	if err != nil {
		return "", errors.New("cannot generate a token")
	}

	token := jwt.New(jwt.GetSigningMethod("RS256"))

	token.Claims = map[string]interface{}{
		"iss":        "koding",                     // Issuer, should be the same username as kontrol
		"sub":        username,                     // Subject
		"iat":        time.Now().UTC().Unix(),      // Issued At
		"jti":        tknID.String(),               // JWT ID
		"kontrolURL": kontrolURL,                   // Kontrol URL
		"kontrolKey": strings.TrimSpace(publicKey), // Public key of kontrol
	}

	log.Printf("Registered machine on user: %s", username)

	return token.SignedString([]byte(privateKey))
}

func buildKlient() error {
	if *flagPrivateKey == "" || *flagPublicKey == "" {
		return errors.New("Please define config -c and region -r")
	}

	if *flagUsername == "" {
		return errors.New("empty username")
	}

	parsed, err := url.Parse(*flagKontrolURL)
	if err != nil {
		return fmt.Errorf("cannot parse kontrol URL: %s", err)
	}

	gopath := os.Getenv("GOPATH")
	if gopath == "" {
		return errors.New("GOPATH is not set")
	}

	publicKey, err := ioutil.ReadFile(*flagPublicKey)
	if err != nil {
		return err
	}

	privateKey, err := ioutil.ReadFile(*flagPrivateKey)
	if err != nil {
		return err
	}

	key, err := createKey(*flagUsername, parsed.String(), string(publicKey), string(privateKey))
	if err != nil {
		return err
	}

	if err = ioutil.WriteFile("kite.key", []byte(key), 0400); err != nil {
		return err
	}

	importPath := "koding/kites/klient"
	upstartPath := filepath.Join(gopath, "src", importPath, "files/klient.conf")

	files := []string{filepath.Join(gopath, "bin-vagrant/kite")}

	kclient := pkg{
		appName:       *flagApp,
		importPath:    importPath,
		files:         files,
		version:       "0.0.1",
		upstartScript: upstartPath,
	}

	return kclient.build()
}

func buildKontrol() error {
	if *flagProfile == "" || *flagRegion == "" {
		return errors.New("Please define config -c and region -r")
	}

	gopath := os.Getenv("GOPATH")
	if gopath == "" {
		return errors.New("GOPATH is not set")
	}

	kontrolPath := "koding/kites/kontrol"
	temps := struct {
		Profile string
		Region  string
	}{
		Profile: *flagProfile,
		Region:  *flagRegion,
	}

	var files = make([]string, 0)
	files = append(files, filepath.Join(gopath, "src", kontrolPath, "files"))

	// change our upstartscript because it's a template
	var configUpstart string
	var err error
	if !*flagDisableUpstart {
		kontrolUpstart := filepath.Join(gopath, "src", kontrolPath, "files/kontrol.conf")
		configUpstart, err = prepareUpstart(kontrolUpstart, temps)
		if err != nil {
			return err
		}
		defer os.Remove(configUpstart)
	}

	term := pkg{
		appName:       *flagApp,
		importPath:    kontrolPath,
		files:         files,
		version:       "0.1.0",
		upstartScript: configUpstart,
	}

	return term.build()
}

func buildTerminal() error {
	if *flagProfile == "" || *flagRegion == "" {
		return errors.New("Please define config -c and region -r")
	}

	gopath := os.Getenv("GOPATH")
	if gopath == "" {
		return errors.New("GOPATH is not set")
	}

	terminalPath := "koding/kites/terminal"
	terminalPackage := "koding/terminal"
	temps := struct {
		Profile string
		Region  string
	}{
		Profile: *flagProfile,
		Region:  *flagRegion,
	}

	var files = make([]string, 0)
	files = append(files, filepath.Join(gopath, "src", terminalPackage, "files"))

	// change our upstartscript because it's a template
	var configUpstart string
	var err error
	if !*flagDisableUpstart {
		terminalUpstart := filepath.Join(gopath, "src", terminalPackage, "files/terminal.conf")
		configUpstart, err = prepareUpstart(terminalUpstart, temps)
		if err != nil {
			return err
		}
		defer os.Remove(configUpstart)
	}

	term := pkg{
		appName:       *flagApp,
		importPath:    terminalPath,
		files:         files,
		version:       terminal.TERMINAL_VERSION,
		upstartScript: configUpstart,
	}

	return term.build()
}

func buildOsKite() error {
	if *flagProfile == "" || *flagRegion == "" {
		return errors.New("Please define config -c and region -r")
	}

	gopath := os.Getenv("GOPATH")
	if gopath == "" {
		return errors.New("GOPATH is not set")
	}

	oskitePath := "koding/kites/os"
	oskitePackage := "koding/oskite"
	temps := struct {
		Profile string
		Region  string
	}{
		Profile: *flagProfile,
		Region:  *flagRegion,
	}

	var files = make([]string, 0)
	files = append(files, filepath.Join(gopath, "src", oskitePackage, "files"))
	files = append(files, filepath.Join(gopath, "bin-vagrant/vmtool")) // TODO add it to the list of importPaths

	// change our upstartscript because it's a template
	var configUpstart string
	var err error
	if !*flagDisableUpstart {
		oskiteUpstart := filepath.Join(gopath, "src", oskitePackage, "files/oskite.conf")
		configUpstart, err = prepareUpstart(oskiteUpstart, temps)
		if err != nil {
			return err
		}
		defer os.Remove(configUpstart)
	}

	oskite := pkg{
		appName:       *flagApp,
		importPath:    oskitePath,
		files:         files,
		version:       oskite.OSKITE_VERSION,
		upstartScript: configUpstart,
	}

	return oskite.build()
}

func buildKontrolProxy() error {
	if *flagProfile == "" || *flagRegion == "" {
		return errors.New("Please define config -c and region -r")
	}

	gopath := os.Getenv("GOPATH")
	if gopath == "" {
		return errors.New("GOPATH is not set")
	}

	kdproxyPath := "koding/kontrol/kontrolproxy"

	temps := struct {
		Profile   string
		Region    string
		UserProxy string
	}{
		Profile: *flagProfile,
		Region:  *flagRegion,
	}

	var files = make([]string, 0)
	switch *flagProxy {
	case "koding":
		files = append(files, "certs/koding_com_cert.pem", "certs/koding_com_key.pem")
	case "y":
		files = append(files, "certs/y_koding_com_cert.pem", "certs/y_koding_com_key.pem")
	case "x":
		files = append(files, "certs/x_koding_com_cert.pem", "certs/x_koding_com_key.pem")
	case "user":
		temps.UserProxy = "-v"
		files = append(files, "certs/kd_io_cert.pem", "certs/kd_io_key.pem")
	default:
		return errors.New("Please define certs to be included with -p. Available certs: [user | koding | x | y]")
	}

	files = append(files, filepath.Join(gopath, "src", kdproxyPath, "files"))

	// change our upstartscript because it's a template
	var configUpstart string
	var err error
	if !*flagDisableUpstart {
		kdproxyUpstart := filepath.Join(gopath, "src", kdproxyPath, "files/kontrolproxy.conf")
		configUpstart, err = prepareUpstart(kdproxyUpstart, temps)
		if err != nil {
			return err
		}
		defer os.Remove(configUpstart)
	}

	kontrolproxy := pkg{
		appName:       *flagApp,
		importPath:    kdproxyPath,
		files:         files,
		version:       "0.0.9",
		upstartScript: configUpstart,
	}

	return kontrolproxy.build()
}

func (p *pkg) build() error {
	if *flagProfile == "" || *flagRegion == "" {
		fmt.Printf("building '%s'\n", *flagApp)
	} else {
		fmt.Printf("building '%s' for config '%s' and region '%s'\n", *flagApp, *flagProfile, *flagRegion)

		// prepare config folder
		tempDir, err := ioutil.TempDir(".", "gopackage_")
		if err != nil {
			return err
		}
		defer os.RemoveAll(tempDir)

		configDir := filepath.Join(tempDir, "config")
		os.MkdirAll(configDir, 0755)

		// koding-config-manager needs it
		err = ioutil.WriteFile("VERSION", []byte(p.version), 0755)
		if err != nil {
			return err
		}
		defer os.Remove("VERSION")

		c, err := config.ReadConfigManager(*flagProfile)
		if err != nil {
			return err
		}

		configPretty, err := json.MarshalIndent(c, "", "  ")
		if err != nil {
			return err
		}

		configFile := filepath.Join(configDir, fmt.Sprintf("main.%s.json", *flagProfile))
		err = ioutil.WriteFile(configFile, configPretty, 0644)
		if err != nil {
			return err
		}

		p.files = append(p.files, configDir)
	}

	// Now it's time to build
	if runtime.GOOS != "linux" {
		return errors.New("Not supported. Please run on a linux machine.")
	}

	deb := &build.Deb{
		Debug:         *flagDebug,
		AppName:       p.appName,
		Version:       p.version,
		ImportPath:    p.importPath,
		Files:         strings.Join(p.files, ","),
		InstallPrefix: "opt/kite",
		UpstartScript: p.upstartScript,
	}

	debFile, err := deb.Build()
	if err != nil {
		log.Println("linux:", err)
	}

	// rename file to see for which region and env it is created
	oldname := debFile
	newname := ""

	if *flagProfile == "" || *flagRegion == "" {
		newname = fmt.Sprintf("%s_%s_%s.deb", p.appName, p.version, deb.Arch)
	} else {
		newname = fmt.Sprintf("%s_%s_%s-%s_%s.deb", p.appName, p.version, *flagProfile, *flagRegion, deb.Arch)
	}

	if err := os.Rename(oldname, newname); err != nil {
		return err
	}

	fmt.Printf("success '%s' is ready. Some helpful commands for you:\n\n", newname)
	fmt.Printf("  show deb content   : dpkg -c %s\n", newname)
	fmt.Printf("  show basic info    : dpkg -f %s\n", newname)
	fmt.Printf("  install to machine : dpkg -i %s\n\n", newname)

	return nil
}

func prepareUpstart(path string, v interface{}) (string, error) {
	file, err := ioutil.TempFile(".", "gopackage_")
	if err != nil {
		return "", err
	}
	defer file.Close()

	t, err := template.ParseFiles(path)
	if err != nil {
		return "", err
	}

	if err := t.Execute(file, v); err != nil {
		return "", err
	}

	return file.Name(), nil
}
<|endoftext|>


<commit_before>package main

import (
	"net/url"
	"testing"

	"github.com/stretchr/testify/assert"

	html "code.google.com/p/go.net/html"
	atom "code.google.com/p/go.net/html/atom"
)

func TestExtractValidHrefSuccess(t *testing.T) {
	f := &HttpFetcher{}

	successCases := map[string]*html.Node{
		"https://example.com": &html.Node{
			Type:     html.ElementNode,
			DataAtom: atom.A,
			Attr: []html.Attribute{
				html.Attribute{
					Key: "href",
					Val: "https://example.com",
				},
			},
		},
		"/doc/": &html.Node{
			Type:     html.ElementNode,
			DataAtom: atom.A,
			Attr: []html.Attribute{
				html.Attribute{
					Key: "title",
					Val: "Many links, such wow",
				},
				html.Attribute{
					Key: "href",
					Val: "/doc/",
				},
			},
		},
	}

	for expected, tc := range successCases {
		res, err := f.extractValidHref(tc)
		assert.Nil(t, err)
		assert.Equal(t, res, expected)
	}
}

func TestExtractValidHrefFailure(t *testing.T) {
	f := &HttpFetcher{}

	// Also test a number of failure cases
	failureCases := map[error]*html.Node{

		InvalidNode: &html.Node{},
		InvalidNode: &html.Node{
			Type: html.DocumentNode,
		},
		InvalidNode: &html.Node{
			Type:     html.ElementNode,
			DataAtom: atom.Div,
		},

		InvalidNodeAttributeMissing: &html.Node{
			Type:     html.ElementNode,
			DataAtom: atom.A,
			Attr:     []html.Attribute{},
		},
		InvalidNodeAttributeMissing: &html.Node{
			Type:     html.ElementNode,
			DataAtom: atom.A,
			Attr: []html.Attribute{
				html.Attribute{
					Key: "title",
					Val: "Many links, such wow",
				},
			},
		},
	}

	for expected, tc := range failureCases {
		res, err := f.extractValidHref(tc)

		assert.NotNil(t, err)
		assert.Equal(t, res, "")

		assert.Equal(t, err, expected)
	}
}

func TestNormaliseUrl(t *testing.T) {
	f := &HttpFetcher{}
	parent := &url.URL{
		Scheme: "http",
		Host:   "example.com",
		Path:   "/",
	}

	testCases := map[string]string{
		"/boop/":                                      "http://example.com/boop/",
		"/shoop":                                      "http://example.com/shoop",
		"dawhoop":                                     "http://example.com/dawhoop",
		"http://notrelative.com/r/boop/":              "http://notrelative.com/r/boop/",
		"http://tinyhamsterseatingtinyburritos":       "http://tinyhamsterseatingtinyburritos",
		"https://www.youtube.com/watch?v=JOCtdw9FG-s": "https://www.youtube.com/watch?v=JOCtdw9FG-s",
	}

	for tc, expected := range testCases {
		result := f.normaliseUrl(parent, tc)
		assert.Equal(t, result.String(), expected)
	}

}
<commit_msg>Rejig imports<commit_after>package main

import (
	"net/url"
	"testing"

	html "code.google.com/p/go.net/html"
	atom "code.google.com/p/go.net/html/atom"
	"github.com/stretchr/testify/assert"
)

func TestExtractValidHrefSuccess(t *testing.T) {
	f := &HttpFetcher{}

	successCases := map[string]*html.Node{
		"https://example.com": &html.Node{
			Type:     html.ElementNode,
			DataAtom: atom.A,
			Attr: []html.Attribute{
				html.Attribute{
					Key: "href",
					Val: "https://example.com",
				},
			},
		},
		"/doc/": &html.Node{
			Type:     html.ElementNode,
			DataAtom: atom.A,
			Attr: []html.Attribute{
				html.Attribute{
					Key: "title",
					Val: "Many links, such wow",
				},
				html.Attribute{
					Key: "href",
					Val: "/doc/",
				},
			},
		},
	}

	for expected, tc := range successCases {
		res, err := f.extractValidHref(tc)
		assert.Nil(t, err)
		assert.Equal(t, res, expected)
	}
}

func TestExtractValidHrefFailure(t *testing.T) {
	f := &HttpFetcher{}

	// Also test a number of failure cases
	failureCases := map[error]*html.Node{

		InvalidNode: &html.Node{},
		InvalidNode: &html.Node{
			Type: html.DocumentNode,
		},
		InvalidNode: &html.Node{
			Type:     html.ElementNode,
			DataAtom: atom.Div,
		},

		InvalidNodeAttributeMissing: &html.Node{
			Type:     html.ElementNode,
			DataAtom: atom.A,
			Attr:     []html.Attribute{},
		},
		InvalidNodeAttributeMissing: &html.Node{
			Type:     html.ElementNode,
			DataAtom: atom.A,
			Attr: []html.Attribute{
				html.Attribute{
					Key: "title",
					Val: "Many links, such wow",
				},
			},
		},
	}

	for expected, tc := range failureCases {
		res, err := f.extractValidHref(tc)

		assert.NotNil(t, err)
		assert.Equal(t, res, "")

		assert.Equal(t, err, expected)
	}
}

func TestNormaliseUrl(t *testing.T) {
	f := &HttpFetcher{}
	parent := &url.URL{
		Scheme: "http",
		Host:   "example.com",
		Path:   "/",
	}

	testCases := map[string]string{
		"/boop/":                                      "http://example.com/boop/",
		"/shoop":                                      "http://example.com/shoop",
		"dawhoop":                                     "http://example.com/dawhoop",
		"http://notrelative.com/r/boop/":              "http://notrelative.com/r/boop/",
		"http://tinyhamsterseatingtinyburritos":       "http://tinyhamsterseatingtinyburritos",
		"https://www.youtube.com/watch?v=JOCtdw9FG-s": "https://www.youtube.com/watch?v=JOCtdw9FG-s",
	}

	for tc, expected := range testCases {
		result := f.normaliseUrl(parent, tc)
		assert.Equal(t, result.String(), expected)
	}

}
<|endoftext|>


<commit_before>/*
 * The MIT License (MIT)
 * Copyright (c) 2016 Maksym Borodin <borodin.maksym@gmail.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
 * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */
package main

import (
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/mborodin/go-xen-api-client"
	"log"
)

const (
	vlanSchemaTag         = "tag"
	vlanSchemaPIF         = "pif"
	vlanSchemaOtherConfig = "other_config"
	vlanSchemaNetwork     = "network"
)

func resourceVLAN() *schema.Resource {
	return &schema.Resource{
		Create: resourceVLANCreate,
		Read:   resourceVLANRead,
		Update: resourceVLANUpdate,
		Delete: resourceVLANDelete,
		Exists: resourceVLANExists,

		Schema: map[string]*schema.Schema{
			vlanSchemaTag: &schema.Schema{
				Type:     schema.TypeInt,
				Required: true,
			},

			vlanSchemaPIF: &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},

			vlanSchemaNetwork: &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},

			vlanSchemaOtherConfig: &schema.Schema{
				Type:     schema.TypeMap,
				Optional: true,
			},
		},
	}
}

func resourceVLANCreate(d *schema.ResourceData, m interface{}) error {
	c := m.(*Connection)

	pif := PIFDescriptor{
		UUID: d.Get(vlanSchemaPIF).(string),
	}

	if err := pif.Load(c); err != nil {
		return err
	}

	network := NetworkDescriptor{
		UUID: d.Get(vlanSchemaNetwork).(string),
	}

	if err := network.Load(c); err != nil {
		return err
	}

	tag := d.Get(vlanSchemaTag).(int)

	if vlanRef, err := c.client.VLAN.Create(c.session, pif.PIFRef, tag, network.NetworkRef); err == nil {
		log.Println("VLAN Created")
		vlan := &VLANDescriptor{
			VLANRef: vlanRef,
		}

		if err := vlan.Query(c); err != nil {
			return err
		}
		log.Println("UUID is ", vlan.UUID)
		d.SetId(vlan.UUID)

		if _otherConfig, ok := d.GetOk(vlanSchemaOtherConfig); ok {
			otherConfig := _otherConfig.(map[string]string)
			for k, v := range otherConfig {
				if err := c.client.VLAN.AddToOtherConfig(c.session, vlan.VLANRef, k, v); err != nil {
					return err
				}
			}
		}
	} else {
		log.Println("VLAN not created!")
		return err
	}

	return nil
}

func resourceVLANRead(d *schema.ResourceData, m interface{}) error {
	c := m.(*Connection)

	vlan := &VLANDescriptor{
		UUID: d.Id(),
	}

	if err := vlan.Load(c); err != nil {
		return err
	}

	d.SetId(vlan.UUID)
	if err := d.Set(vlanSchemaTag, vlan.Tag); err != nil {
		return err
	}

	if err := d.Set(vlanSchemaOtherConfig, vlan.OtherConfig); err != nil {
		return err
	}

	if err := d.Set(vlanSchemaPIF, vlan.Description); err != nil {
		return err
	}

	return nil
}
func resourceVLANUpdate(d *schema.ResourceData, m interface{}) error {
	c := m.(*Connection)

	vlan := &VLANDescriptor{
		UUID: d.Id(),
	}

	if err := vlan.Load(c); err != nil {
		return err
	}

	if d.HasChange(vlanSchemaTag) {
		_, n := d.GetChange(vlanSchemaTag)

		if err := c.client.VLAN.SetNameLabel(c.session, vlan.VLANRef, n.(string)); err != nil {
			return err
		}

		d.SetPartial(vlanSchemaTag)
	}

	if d.HasChange(vlanSchemaOtherConfig) {
		_, n := d.GetChange(vlanSchemaOtherConfig)

		if err := c.client.VLAN.SetMTU(c.session, vlan.VLANRef, n.(int)); err != nil {
			return err
		}

		d.SetPartial(vlanSchemaOtherConfig)
	}

	if d.HasChange(vlanSchemaTaggedPIF) {
		_, n := d.GetChange(vlanSchemaTaggedPIF)

		if err := c.client.VLAN.SetNameDescription(c.session, vlan.VLANRef, n.(string)); err != nil {
			return err
		}

		d.SetPartial(vlanSchemaTaggedPIF)
	}

	return nil
}
func resourceVLANDelete(d *schema.ResourceData, m interface{}) error {
	c := m.(*Connection)

	vlan := &VLANDescriptor{
		UUID: d.Id(),
	}

	if err := vlan.Load(c); err != nil {
		return err
	}

	if err := c.client.VLAN.Destroy(c.session, vlan.VLANRef); err != nil {
		return err
	}

	return nil
}
func resourceVLANExists(d *schema.ResourceData, m interface{}) (bool, error) {
	c := m.(*Connection)

	vlan := &VLANDescriptor{
		UUID: d.Id(),
	}

	if err := vlan.Load(c); err != nil {
		if xenErr, ok := err.(*xenAPI.Error); ok {
			if xenErr.Code() == xenAPI.ERR_UUID_INVALID {
				return false, nil
			}
		}

		return false, err
	}

	return true, nil
}
<commit_msg>fixed compilation errors in VLAN<commit_after>/*
 * The MIT License (MIT)
 * Copyright (c) 2016 Maksym Borodin <borodin.maksym@gmail.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
 * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */
package main

import (
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/mborodin/go-xen-api-client"
	"log"
)

const (
	vlanSchemaTag         = "tag"
	vlanSchemaPIF         = "pif"
	vlanSchemaOtherConfig = "other_config"
	vlanSchemaNetwork     = "network"
)

func resourceVLAN() *schema.Resource {
	return &schema.Resource{
		Create: resourceVLANCreate,
		Read:   resourceVLANRead,
		Update: resourceVLANUpdate,
		Delete: resourceVLANDelete,
		Exists: resourceVLANExists,

		Schema: map[string]*schema.Schema{
			vlanSchemaTag: &schema.Schema{
				Type:     schema.TypeInt,
				Required: true,
				ForceNew: true,
			},

			vlanSchemaPIF: &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			vlanSchemaNetwork: &schema.Schema{
				ForceNew: true,
				Type:     schema.TypeString,
				Required: true,
			},

			vlanSchemaOtherConfig: &schema.Schema{
				Type:     schema.TypeMap,
				Optional: true,
			},
		},
	}
}

func resourceVLANCreate(d *schema.ResourceData, m interface{}) error {
	c := m.(*Connection)

	pif := PIFDescriptor{
		UUID: d.Get(vlanSchemaPIF).(string),
	}

	if err := pif.Load(c); err != nil {
		return err
	}

	network := NetworkDescriptor{
		UUID: d.Get(vlanSchemaNetwork).(string),
	}

	if err := network.Load(c); err != nil {
		return err
	}

	tag := d.Get(vlanSchemaTag).(int)

	if vlanRef, err := c.client.VLAN.Create(c.session, pif.PIFRef, tag, network.NetworkRef); err == nil {
		log.Println("VLAN Created")
		vlan := &VLANDescriptor{
			VLANRef: vlanRef,
		}

		if err := vlan.Query(c); err != nil {
			return err
		}
		log.Println("UUID is ", vlan.UUID)
		d.SetId(vlan.UUID)

		if _otherConfig, ok := d.GetOk(vlanSchemaOtherConfig); ok {
			otherConfig := _otherConfig.(map[string]string)
			for k, v := range otherConfig {
				if err := c.client.VLAN.AddToOtherConfig(c.session, vlan.VLANRef, k, v); err != nil {
					return err
				}
			}
		}
	} else {
		log.Println("VLAN not created!")
		return err
	}

	return nil
}

func resourceVLANRead(d *schema.ResourceData, m interface{}) error {
	c := m.(*Connection)

	vlan := &VLANDescriptor{
		UUID: d.Id(),
	}

	if err := vlan.Load(c); err != nil {
		return err
	}

	d.SetId(vlan.UUID)
	if err := d.Set(vlanSchemaTag, vlan.Tag); err != nil {
		return err
	}

	if err := d.Set(vlanSchemaOtherConfig, vlan.OtherConfig); err != nil {
		return err
	}

	if err := d.Set(vlanSchemaPIF, vlan.UntaggedPIF); err != nil {
		return err
	}

	return nil
}
func resourceVLANUpdate(d *schema.ResourceData, m interface{}) error {
	c := m.(*Connection)

	vlan := &VLANDescriptor{
		UUID: d.Id(),
	}

	if err := vlan.Load(c); err != nil {
		return err
	}

	if d.HasChange(vlanSchemaOtherConfig) {
		_, n := d.GetChange(vlanSchemaOtherConfig)
		otherConfig := make(map[string]string)

		for k, v := range n.(map[string]interface{}) {
			otherConfig[k] = v.(string)
		}

		if err := c.client.VLAN.SetOtherConfig(c.session, vlan.VLANRef, otherConfig); err != nil {
			return err
		}

		d.SetPartial(vlanSchemaOtherConfig)
	}

	return nil
}
func resourceVLANDelete(d *schema.ResourceData, m interface{}) error {
	c := m.(*Connection)

	vlan := &VLANDescriptor{
		UUID: d.Id(),
	}

	if err := vlan.Load(c); err != nil {
		return err
	}

	if err := c.client.VLAN.Destroy(c.session, vlan.VLANRef); err != nil {
		return err
	}

	return nil
}
func resourceVLANExists(d *schema.ResourceData, m interface{}) (bool, error) {
	c := m.(*Connection)

	vlan := &VLANDescriptor{
		UUID: d.Id(),
	}

	if err := vlan.Load(c); err != nil {
		if xenErr, ok := err.(*xenAPI.Error); ok {
			if xenErr.Code() == xenAPI.ERR_UUID_INVALID {
				return false, nil
			}
		}

		return false, err
	}

	return true, nil
}
<|endoftext|>


<commit_before>// Copyright 2015 Matthew Collins
//
// 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 steven

import (
	"fmt"

	"github.com/thinkofdeath/steven/render"
	"github.com/thinkofdeath/steven/resource"
	"github.com/thinkofdeath/steven/ui"
)

func AddPack(path string) {
	fmt.Println("Adding pack " + path)
	if err := resource.LoadZip(path); err != nil {
		panic(err)
	}
	fmt.Println("Bringing everything to a stop")
	for freeBuilders < maxBuilders {
		select {
		case pos := <-completeBuilders:
			freeBuilders++
			if c := chunkMap[chunkPosition{pos.X, pos.Z}]; c != nil {
				if s := c.Sections[pos.Y]; s != nil {
					s.building = false
				}
			}
		}
	}
	reloadResources()
}

func reloadResources() {
	modelCache = map[string]*model{}
	fmt.Println("Reloading textures")
	render.LoadTextures()
	fmt.Println("Reloading biomes")
	loadBiomes()
	ui.ForceDraw()
	fmt.Println("Reloading blocks")
	reinitBlocks()
	fmt.Println("Marking chunks for rebuild")
	for _, c := range chunkMap {
		for _, s := range c.Sections {
			if s != nil {
				s.dirty = true
			}
		}
	}
	fmt.Println("Rebuilding static models")
	render.RefreshStaticModels()
	fmt.Println("Reloading inventory")
	Client.playerInventory.Update()
}
<commit_msg>steven: move the builder stopping code into reloadResources<commit_after>// Copyright 2015 Matthew Collins
//
// 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 steven

import (
	"fmt"

	"github.com/thinkofdeath/steven/render"
	"github.com/thinkofdeath/steven/resource"
	"github.com/thinkofdeath/steven/ui"
)

func AddPack(path string) {
	fmt.Println("Adding pack " + path)
	if err := resource.LoadZip(path); err != nil {
		panic(err)
	}
	reloadResources()
}

func reloadResources() {
	fmt.Println("Bringing everything to a stop")
	for freeBuilders < maxBuilders {
		select {
		case pos := <-completeBuilders:
			freeBuilders++
			if c := chunkMap[chunkPosition{pos.X, pos.Z}]; c != nil {
				if s := c.Sections[pos.Y]; s != nil {
					s.building = false
				}
			}
		}
	}
	modelCache = map[string]*model{}
	fmt.Println("Reloading textures")
	render.LoadTextures()
	fmt.Println("Reloading biomes")
	loadBiomes()
	ui.ForceDraw()
	fmt.Println("Reloading blocks")
	reinitBlocks()
	fmt.Println("Marking chunks for rebuild")
	for _, c := range chunkMap {
		for _, s := range c.Sections {
			if s != nil {
				s.dirty = true
			}
		}
	}
	fmt.Println("Rebuilding static models")
	render.RefreshStaticModels()
	fmt.Println("Reloading inventory")
	Client.playerInventory.Update()
}
<|endoftext|>


<commit_before>package gomeh

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strings"
	"testing"
)

func readKey() string {
	f := "./apikey"
	var key string
	// If API key env exists use that
	if env := os.Getenv("meh_apikey"); env != "" {
		// Read API key from env (for travis)
		key = env
	} else {
		// Read API key from file, if exists
		if _, err := os.Stat(f); err == nil {
			buf, err := ioutil.ReadFile(f)
			if err != nil {
				log.Fatal(err)
			}
			key = string(buf)
		}
	}
	// Trim the string to remove any whitespace or linebreaks
	return strings.Trim(key, " \n")
}

func ExampleGetMeh_output() {
	apikey := readKey()
	m, err := GetMeh(apikey)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(m)
}

func TestGetMeh(t *testing.T) {
	apikey := readKey()
	m, err := GetMeh(apikey)
	if err != nil {
		t.Error("Failed to retreive data from API.")
	}
	if len(m.Deal.Title) == 0 {
		t.Error("Missing deal.")
	}
}
<commit_msg>Complete tests for current code<commit_after>package gomeh

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strings"
	"testing"
	"time"
)

func readKey() string {
	f := "./apikey"
	var key string
	// If API key env exists use that
	if env := os.Getenv("meh_apikey"); env != "" {
		// Read API key from env (for travis)
		key = env
	} else {
		// Read API key from file, if exists
		if _, err := os.Stat(f); err == nil {
			buf, err := ioutil.ReadFile(f)
			if err != nil {
				log.Fatal(err)
			}
			key = string(buf)
		}
	}
	// Trim the string to remove any whitespace or linebreaks
	return strings.Trim(key, " \n")
}

func ExampleGetMeh_output() {
	apikey := readKey()
	m, err := GetMeh(apikey)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(m)
}

func TestGetMeh(t *testing.T) {
	apikey := readKey()
	m, err := GetMeh(apikey)
	if err != nil {
		t.Error("Failed to retreive data from API.")
	}
	if len(m.Deal.Title) == 0 {
		t.Error("Missing deal.")
	}
}

func TestSoldOut(t *testing.T) {
	m := Meh{
		Deal: Deal{
			SoldOutAt: time.Now(),
		},
	}
	if m.SoldOut() != true {
		t.Error("Failed to correctly recognize as Sold Out.")
	}
}

func TestString(t *testing.T) {
	// Available product
	m := Meh{
		Deal: Deal{
			Title: "Product",
			Items: []Item{
				Item{Price: 5},
			},
		},
	}
	if fmt.Sprint(m) != fmt.Sprint("Product - $5") {
		t.Error("Failed to return available product string.")
	}
	// Sold out produc
	// Available product
	m = Meh{
		Deal: Deal{
			Title:     "Product2",
			SoldOutAt: time.Now(),
			Items: []Item{
				Item{Price: 5},
			},
		},
	}
	if fmt.Sprint(m) != fmt.Sprint("[Sold Out] Product2 - $5") {
		t.Error("Failed to return available product string.")
	}
}
<|endoftext|>