<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"

	"github.com/appc/cni/pkg/skel"
	"github.com/appc/cni/pkg/types"
)

func main() {
	skel.PluginMain(cmdAdd, cmdDel)
}

func cmdAdd(args *skel.CmdArgs) error {
	// extract the things we care about
	conf, err := loadIPAMConf(args.StdinData)
	if err != nil {
		return err
	}

	containerID := args.ContainerID
	var url string

	if conf.Subnet == "" {
		url = fmt.Sprintf("/ip/%s", containerID)
	} else {
		_, err = types.ParseCIDR(conf.Subnet)
		if err != nil {
			return fmt.Errorf("subnet given in config, but not parseable: %s", err)
		}
		url = fmt.Sprintf("/ip/%s/%s", containerID, conf.Subnet)
	}

	var ip string
	if ip, err = httpPost(url); err != nil {
		return err
	}
	ipnet, err := types.ParseCIDR(ip)
	if err != nil {
		return err
	}
	result := types.Result{
		IP4: &types.IPConfig{
			IP:      *ipnet,
			Gateway: conf.Gateway,
		},
	}
	return result.Print()
}

func cmdDel(args *skel.CmdArgs) error {
	containerID := args.ContainerID
	url := fmt.Sprintf("/ip/%s", containerID)
	if err := httpDelete(url); err != nil {
		return err
	}
	result := types.Result{}
	return result.Print()
}

type ipamConf struct {
	Subnet  string `json:"subnet,omitempty"`
	Gateway net.IP `json:"gateway,omitempty"`
}

type netConf struct {
	IPAM *ipamConf `json:"ipam"`
}

func loadIPAMConf(stdinData []byte) (*ipamConf, error) {
	var conf netConf
	return conf.IPAM, json.Unmarshal(stdinData, &conf)
}

func httpPost(path string) (string, error) {
	resp, err := http.Post("http://localhost:6784"+path, "", nil)
	if err != nil {
		return "", err
	}
	if !okResponse(resp) {
		return "", fmt.Errorf("non-OK status code %d", resp.StatusCode)
	}
	bytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}
	return string(bytes), nil
}

func httpDelete(path string) error {
	req, err := http.NewRequest("DELETE", "http://localhost:6784"+path, nil)
	if err != nil {
		return err
	}
	client := http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	if !okResponse(resp) {
		return fmt.Errorf("non-OK status code %d", resp.StatusCode)
	}
	return nil
}

func okResponse(response *http.Response) bool {
	switch response.StatusCode {
	case http.StatusOK:
		return true
	case http.StatusCreated:
		return true
	case http.StatusAccepted:
		return true
	default:
		return false
	}
}
<commit_msg>Use Weave Net API<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"net"

	"github.com/Sirupsen/logrus"
	"github.com/appc/cni/pkg/skel"
	"github.com/appc/cni/pkg/types"
	"github.com/weaveworks/weave/api"
)

func main() {
	skel.PluginMain(cmdAdd, cmdDel)
}

var (
	log      = logrus.New()
	weaveapi = api.NewClient("localhost:6784", log)
)

func cmdAdd(args *skel.CmdArgs) error {
	// extract the things we care about
	conf, err := loadIPAMConf(args.StdinData)
	if err != nil {
		return err
	}

	containerID := args.ContainerID
	var ipnet *net.IPNet

	if conf.Subnet == "" {
		ipnet, err = weaveapi.AllocateIP(containerID)
	} else {
		var subnet *net.IPNet
		subnet, err = types.ParseCIDR(conf.Subnet)
		if err != nil {
			return fmt.Errorf("subnet given in config, but not parseable: %s", err)
		}
		ipnet, err = weaveapi.AllocateIPInSubnet(containerID, subnet)
	}

	if err != nil {
		return err
	}
	result := types.Result{
		IP4: &types.IPConfig{
			IP:      *ipnet,
			Gateway: conf.Gateway,
		},
	}
	return result.Print()
}

func cmdDel(args *skel.CmdArgs) error {
	containerID := args.ContainerID
	if err := weaveapi.ReleaseIP(containerID); err != nil {
		return err
	}
	result := types.Result{}
	return result.Print()
}

type ipamConf struct {
	Subnet  string `json:"subnet,omitempty"`
	Gateway net.IP `json:"gateway,omitempty"`
}

type netConf struct {
	IPAM *ipamConf `json:"ipam"`
}

func loadIPAMConf(stdinData []byte) (*ipamConf, error) {
	var conf netConf
	return conf.IPAM, json.Unmarshal(stdinData, &conf)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/ActiveState/tail"
	"github.com/op/go-logging"
	"github.com/vmihailenco/redis"
	"os"
	"regexp"
	"time"
)

var (
	path        string
	redisHost   string
	redisPasswd string
	logRegex    string
	redisDB     int64
	log         logging.Logger
)

func init() {
	flag.StringVar(&path, "l", "", "Path to the access log to watch")
	flag.StringVar(&redisHost, "h", "localhost:6379", "Hostname:port Redis")
	flag.StringVar(&redisPasswd, "p", "", "Redis password")
	flag.Int64Var(&redisDB, "d", -1, "Redis DB number to store the data")
	flag.StringVar(&logRegex, "r", "", "PCRE Regex to parse the log. Must return the remote IP on the first capture group")
}

func main() {
	if len(os.Args) < 6 {
		fmt.Fprintln(os.Stderr, "You need arguments")
		flag.Usage()
		os.Exit(10)
	}
	flag.Parse()

	// Seek to the end at the start
	seek := &tail.SeekInfo{
		Offset: 0,
		Whence: 2,
	}

	config := tail.Config{
		ReOpen:    true,
		MustExist: true,
		Follow:    true,
		Location:  seek,
	}

	t, err := tail.TailFile(path, config)
	if err != nil {
		log.Fatalf("Could not tail: %v\n", err)
	}

	client := redis.NewTCPClient(redisHost, redisPasswd, redisDB)
	multi, err := client.MultiClient()
	if err != nil {
		log.Fatalf("Failed to create multiclient: %v", err)
	}
	defer client.Close()
	log.Info("Connected to redis")

	r := regexp.MustCompile(logRegex)
	ipRegex := regexp.MustCompile(`\S+\.\S+\.\S+\.\S+`)

	for line := range t.Lines {
		if matches := r.FindStringSubmatch(line.Text); matches != nil {
			if !ipRegex.MatchString(matches[1]) {
				continue
			}
			if res := client.Ping(); res.Err() != nil {
				log.Warning("Redis not connected, %v, reconnecting", res.Val())
				client = redis.NewTCPClient(redisHost, redisPasswd, redisDB)
				multi, err = client.MultiClient()
				if err != nil {
					log.Fatalf("Failed to create multiclient: %v", err)
				}
			}
			ip := matches[1]
			_, err := multi.Exec(func() {
				multi.ZIncrBy("ipcount_5m", 1, ip)
				multi.HSet("ipcount_h5m", ip, fmt.Sprintf("%d", time.Now().Unix()))
				multi.ZIncrBy("ipcount_1h", 1, ip)
				multi.HSet("ipcount_h1h", ip, fmt.Sprintf("%d", time.Now().Unix()))
				multi.ZIncrBy("ipcount_12h", 1, ip)
				multi.HSet("ipcount_h12h", ip, fmt.Sprintf("%d", time.Now().Unix()))
				multi.ZIncrBy("ipcount_24h", 1, ip)
				multi.HSet("ipcount_h24h", ip, fmt.Sprintf("%d", time.Now().Unix()))
			})
			if err == redis.Nil {
				log.Warning("Failed to add to set: %v", err)
			}
		}
	}
}
<commit_msg>Ignores 127.0.0.1 and adds a map for ignored IPs<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/ActiveState/tail"
	"github.com/op/go-logging"
	"github.com/vmihailenco/redis"
	"os"
	"regexp"
	"time"
)

var (
	path        string
	redisHost   string
	redisPasswd string
	logRegex    string
	redisDB     int64
	log         logging.Logger
)

func init() {
	flag.StringVar(&path, "l", "", "Path to the access log to watch")
	flag.StringVar(&redisHost, "h", "localhost:6379", "Hostname:port Redis")
	flag.StringVar(&redisPasswd, "p", "", "Redis password")
	flag.Int64Var(&redisDB, "d", -1, "Redis DB number to store the data")
	flag.StringVar(&logRegex, "r", "", "PCRE Regex to parse the log. Must return the remote IP on the first capture group")
}

func main() {
	if len(os.Args) < 6 {
		fmt.Fprintln(os.Stderr, "You need arguments")
		flag.Usage()
		os.Exit(10)
	}
	flag.Parse()

	// Seek to the end at the start
	seek := &tail.SeekInfo{
		Offset: 0,
		Whence: 2,
	}

	config := tail.Config{
		ReOpen:    true,
		MustExist: true,
		Follow:    true,
		Location:  seek,
	}

	t, err := tail.TailFile(path, config)
	if err != nil {
		log.Fatalf("Could not tail: %v\n", err)
	}

	client := redis.NewTCPClient(redisHost, redisPasswd, redisDB)
	multi, err := client.MultiClient()
	if err != nil {
		log.Fatalf("Failed to create multiclient: %v", err)
	}
	defer client.Close()
	log.Info("Connected to redis")

	r := regexp.MustCompile(logRegex)
	ipRegex := regexp.MustCompile(`\S+\.\S+\.\S+\.\S+`)
	ignored_ips := map[string]bool{"127.0.0.1": true}

	for line := range t.Lines {
		if matches := r.FindStringSubmatch(line.Text); matches != nil {
			if !ipRegex.MatchString(matches[1]) {
				continue
			}
			if ignored_ips[matches[1]] {
				continue
			}

			if res := client.Ping(); res.Err() != nil {
				log.Warning("Redis not connected, %v, reconnecting", res.Val())
				client = redis.NewTCPClient(redisHost, redisPasswd, redisDB)
				multi, err = client.MultiClient()
				if err != nil {
					log.Fatalf("Failed to create multiclient: %v", err)
				}
			}
			ip := matches[1]
			_, err := multi.Exec(func() {
				multi.ZIncrBy("ipcount_5m", 1, ip)
				multi.HSet("ipcount_h5m", ip, fmt.Sprintf("%d", time.Now().Unix()))
				multi.ZIncrBy("ipcount_1h", 1, ip)
				multi.HSet("ipcount_h1h", ip, fmt.Sprintf("%d", time.Now().Unix()))
				multi.ZIncrBy("ipcount_12h", 1, ip)
				multi.HSet("ipcount_h12h", ip, fmt.Sprintf("%d", time.Now().Unix()))
				multi.ZIncrBy("ipcount_24h", 1, ip)
				multi.HSet("ipcount_h24h", ip, fmt.Sprintf("%d", time.Now().Unix()))
			})
			if err == redis.Nil {
				log.Warning("Failed to add to set: %v", err)
			}
		}
	}
}
<|endoftext|>


<commit_before>package oleutil

import ole "github.com/go-ole/go-ole"

// ClassIDFrom retrieves class ID whether given is program ID or application string.
func ClassIDFrom(programID string) (classID *ole.GUID, err error) {
	return ole.ClassIDFrom(programID)
}

// CreateObject creates object from programID based on interface type.
//
// Only supports IUnknown.
//
// Program ID can be either program ID or application string.
func CreateObject(programID string) (unknown *ole.IUnknown, err error) {
	classID, err := ole.ClassIDFrom(programID)
	if err != nil {
		return
	}

	unknown, err = ole.CreateInstance(classID, ole.IID_IUnknown)
	if err != nil {
		return
	}

	return
}

// GetActiveObject retrieves active object for program ID and interface ID based
// on interface type.
//
// Only supports IUnknown.
//
// Program ID can be either program ID or application string.
func GetActiveObject(programID string) (unknown *ole.IUnknown, err error) {
	classID, err := ole.ClassIDFrom(programID)
	if err != nil {
		return
	}

	unknown, err = ole.GetActiveObject(classID, ole.IID_IUnknown)
	if err != nil {
		return
	}

	return
}

// CallMethod calls method on IDispatch with parameters.
func CallMethod(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT, err error) {
	return disp.InvokeWithOptionalArgs(name, ole.DISPATCH_METHOD, params)
}

// MustCallMethod calls method on IDispatch with parameters or panics.
func MustCallMethod(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT) {
	r, err := CallMethod(disp, name, params...)
	if err != nil {
		panic(err.Error())
	}
	return r
}

// GetProperty retrieves property from IDispatch.
func GetProperty(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT, err error) {
	return disp.InvokeWithOptionalArgs(name, ole.DISPATCH_PROPERTYGET, params)
}

// MustGetProperty retrieves property from IDispatch or panics.
func MustGetProperty(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT) {
	r, err := GetProperty(disp, name, params...)
	if err != nil {
		panic(err.Error())
	}
	return r
}

// PutProperty mutates property.
func PutProperty(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT, err error) {
	return disp.InvokeWithOptionalArgs(name, ole.DISPATCH_PROPERTYPUT, params)
}

// MustPutProperty mutates property or panics.
func MustPutProperty(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT) {
	r, err := PutProperty(disp, name, params...)
	if err != nil {
		panic(err.Error())
	}
	return r
}

// PutPropertyRef mutates property reference.
func PutPropertyRef(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT, err error) {
	return disp.InvokeWithOptionalArgs(name, ole.DISPATCH_PROPERTYPUTREF, params)
}

// MustPutPropertyRef mutates property reference or panics.
func MustPutPropertyRef(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT) {
	r, err := PutPropertyRef(disp, name, params...)
	if err != nil {
		panic(err.Error())
	}
	return r
}

func ForEach(disp *ole.IDispatch, f func(v *ole.VARIANT) error) error {
	newEnum, err := disp.CallMethod("_NewEnum")
	if err != nil {
		return err
	}
	defer newEnum.Clear()

	enum, err := newEnum.ToIUnknown().IEnumVARIANT(ole.IID_IEnumVariant)
	if err != nil {
		return err
	}
	defer enum.Release()

	for item, length, err := enum.Next(1); length > 0; item, length, err = enum.Next(1) {
		if err != nil {
			return err
		}
		if ferr := f(&item); ferr != nil {
			return ferr
		}
	}
	return nil
}
<commit_msg>Revert 1144933ebbad56211c67c56fd60da6a684550dc6<commit_after>package oleutil

import ole "github.com/go-ole/go-ole"

// ClassIDFrom retrieves class ID whether given is program ID or application string.
func ClassIDFrom(programID string) (classID *ole.GUID, err error) {
	return ole.ClassIDFrom(programID)
}

// CreateObject creates object from programID based on interface type.
//
// Only supports IUnknown.
//
// Program ID can be either program ID or application string.
func CreateObject(programID string) (unknown *ole.IUnknown, err error) {
	classID, err := ole.ClassIDFrom(programID)
	if err != nil {
		return
	}

	unknown, err = ole.CreateInstance(classID, ole.IID_IUnknown)
	if err != nil {
		return
	}

	return
}

// GetActiveObject retrieves active object for program ID and interface ID based
// on interface type.
//
// Only supports IUnknown.
//
// Program ID can be either program ID or application string.
func GetActiveObject(programID string) (unknown *ole.IUnknown, err error) {
	classID, err := ole.ClassIDFrom(programID)
	if err != nil {
		return
	}

	unknown, err = ole.GetActiveObject(classID, ole.IID_IUnknown)
	if err != nil {
		return
	}

	return
}

// CallMethod calls method on IDispatch with parameters.
func CallMethod(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT, err error) {
	return disp.InvokeWithOptionalArgs(name, ole.DISPATCH_METHOD, params)
}

// MustCallMethod calls method on IDispatch with parameters or panics.
func MustCallMethod(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT) {
	r, err := CallMethod(disp, name, params...)
	if err != nil {
		panic(err.Error())
	}
	return r
}

// GetProperty retrieves property from IDispatch.
func GetProperty(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT, err error) {
	return disp.InvokeWithOptionalArgs(name, ole.DISPATCH_PROPERTYGET, params)
}

// MustGetProperty retrieves property from IDispatch or panics.
func MustGetProperty(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT) {
	r, err := GetProperty(disp, name, params...)
	if err != nil {
		panic(err.Error())
	}
	return r
}

// PutProperty mutates property.
func PutProperty(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT, err error) {
	return disp.InvokeWithOptionalArgs(name, ole.DISPATCH_PROPERTYPUT, params)
}

// MustPutProperty mutates property or panics.
func MustPutProperty(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT) {
	r, err := PutProperty(disp, name, params...)
	if err != nil {
		panic(err.Error())
	}
	return r
}

// PutPropertyRef mutates property reference.
func PutPropertyRef(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT, err error) {
	return disp.InvokeWithOptionalArgs(name, ole.DISPATCH_PROPERTYPUTREF, params)
}

// MustPutPropertyRef mutates property reference or panics.
func MustPutPropertyRef(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT) {
	r, err := PutPropertyRef(disp, name, params...)
	if err != nil {
		panic(err.Error())
	}
	return r
}

func ForEach(disp *ole.IDispatch, f func(v *ole.VARIANT) error) error {
	newEnum, err := disp.GetProperty("_NewEnum")
	if err != nil {
		return err
	}
	defer newEnum.Clear()

	enum, err := newEnum.ToIUnknown().IEnumVARIANT(ole.IID_IEnumVariant)
	if err != nil {
		return err
	}
	defer enum.Release()

	for item, length, err := enum.Next(1); length > 0; item, length, err = enum.Next(1) {
		if err != nil {
			return err
		}
		if ferr := f(&item); ferr != nil {
			return ferr
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package internal

import (
	"context"
	"reflect"
	"time"

	"github.com/go-redis/redis/v8/internal/util"
	"go.opentelemetry.io/otel/api/core"
	"go.opentelemetry.io/otel/api/global"
	"go.opentelemetry.io/otel/api/trace"
	"google.golang.org/grpc/codes"
)

func Sleep(ctx context.Context, dur time.Duration) error {
	return WithSpan(ctx, "sleep", func(ctx context.Context) error {
		t := time.NewTimer(dur)
		defer t.Stop()

		select {
		case <-t.C:
			return nil
		case <-ctx.Done():
			return ctx.Err()
		}
	})
}

func ToLower(s string) string {
	if isLower(s) {
		return s
	}

	b := make([]byte, len(s))
	for i := range b {
		c := s[i]
		if c >= 'A' && c <= 'Z' {
			c += 'a' - 'A'
		}
		b[i] = c
	}
	return util.BytesToString(b)
}

func isLower(s string) bool {
	for i := 0; i < len(s); i++ {
		c := s[i]
		if c >= 'A' && c <= 'Z' {
			return false
		}
	}
	return true
}

func Unwrap(err error) error {
	u, ok := err.(interface {
		Unwrap() error
	})
	if !ok {
		return nil
	}
	return u.Unwrap()
}

var (
	logTypeKey    = core.Key("log.type")
	logMessageKey = core.Key("log.message")
)

func WithSpan(ctx context.Context, name string, fn func(context.Context) error) error {
	if !trace.SpanFromContext(ctx).IsRecording() {
		return fn(ctx)
	}

	ctx, span := global.TraceProvider().Tracer("go-redis").Start(ctx, name)
	defer span.End()

	if err := fn(ctx); err != nil {
		span.SetStatus(codes.Internal, err.Error())
		span.AddEvent(ctx, "error",
			logTypeKey.String(reflect.TypeOf(err).String()),
			logMessageKey.String(err.Error()),
		)
		return err
	}
	return nil
}
<commit_msg>Remove error reporting<commit_after>package internal

import (
	"context"
	"time"

	"github.com/go-redis/redis/v8/internal/util"
	"go.opentelemetry.io/otel/api/global"
	"go.opentelemetry.io/otel/api/trace"
)

func Sleep(ctx context.Context, dur time.Duration) error {
	return WithSpan(ctx, "sleep", func(ctx context.Context) error {
		t := time.NewTimer(dur)
		defer t.Stop()

		select {
		case <-t.C:
			return nil
		case <-ctx.Done():
			return ctx.Err()
		}
	})
}

func ToLower(s string) string {
	if isLower(s) {
		return s
	}

	b := make([]byte, len(s))
	for i := range b {
		c := s[i]
		if c >= 'A' && c <= 'Z' {
			c += 'a' - 'A'
		}
		b[i] = c
	}
	return util.BytesToString(b)
}

func isLower(s string) bool {
	for i := 0; i < len(s); i++ {
		c := s[i]
		if c >= 'A' && c <= 'Z' {
			return false
		}
	}
	return true
}

func Unwrap(err error) error {
	u, ok := err.(interface {
		Unwrap() error
	})
	if !ok {
		return nil
	}
	return u.Unwrap()
}

func WithSpan(ctx context.Context, name string, fn func(context.Context) error) error {
	if !trace.SpanFromContext(ctx).IsRecording() {
		return fn(ctx)
	}

	ctx, span := global.Tracer("go-redis").Start(ctx, name)
	defer span.End()

	return fn(ctx)
}
<|endoftext|>


<commit_before>package internal

import "reflect"

func SliceNextElem(v reflect.Value) reflect.Value {
	elemType := v.Type().Elem()

	if elemType.Kind() == reflect.Ptr {
		elem := reflect.New(elemType.Elem())
		v.Set(reflect.Append(v, elem))
		return elem.Elem()
	}

	v.Set(reflect.Append(v, reflect.Zero(elemType)))
	return v.Index(v.Len() - 1)
}
<commit_msg>internal: small optimization.<commit_after>package internal

import "reflect"

func SliceNextElem(v reflect.Value) reflect.Value {
	if v.Len() < v.Cap() {
		v.Set(v.Slice(0, v.Len()+1))
		return v.Index(v.Len() - 1)
	}

	elemType := v.Type().Elem()

	if elemType.Kind() == reflect.Ptr {
		elem := reflect.New(elemType.Elem())
		v.Set(reflect.Append(v, elem))
		return elem.Elem()
	}

	v.Set(reflect.Append(v, reflect.Zero(elemType)))
	return v.Index(v.Len() - 1)
}
<|endoftext|>


<commit_before>package musictheory

import (
	"math"
	"testing"
)

func TestIntervals(test *testing.T) {
	data := []struct {
		typeFunc          IntervalFunc
		step              int
		expectedOctaves   int
		expectedDiatonic  int
		expectedChromatic int
	}{
		{Perfect, 1, 0, 0, 0},
		{Perfect, 2, 0, 1, 2},
		{Perfect, 3, 0, 2, 4},
		{Perfect, 4, 0, 3, 5},
		{Perfect, 5, 0, 4, 7},
		{Perfect, 6, 0, 5, 9},
		{Perfect, 7, 0, 6, 11},
		{Perfect, 8, 1, 0, 0},

		{Major, 1, 0, 0, 0},
		{Major, 2, 0, 1, 2},
		{Major, 3, 0, 2, 4},
		{Major, 4, 0, 3, 5},
		{Major, 5, 0, 4, 7},
		{Major, 6, 0, 5, 9},
		{Major, 7, 0, 6, 11},
		{Major, 8, 1, 0, 0},

		{Augmented, 2, 0, 1, 3},
		{Augmented, 3, 0, 2, 5},
		{Augmented, 4, 0, 3, 6},
		{Augmented, 5, 0, 4, 8},
		{Augmented, 6, 0, 5, 10},
		{Augmented, 7, 0, 6, 12},
		{Augmented, 8, 1, 0, 1},

		{Diminished, 2, 0, 1, 0},
		{Diminished, 3, 0, 2, 2},
		{Diminished, 4, 0, 3, 4},
		{Diminished, 5, 0, 4, 6},
		{Diminished, 6, 0, 5, 7},
		{Diminished, 7, 0, 6, 9},
		{Diminished, 8, 1, 0, -1},

		{Minor, 2, 0, 1, 1},
		{Minor, 3, 0, 2, 3},
		{Minor, 5, 0, 4, 6},
		{Minor, 7, 0, 6, 10},
	}

	for i, t := range data {
		actual := t.typeFunc(t.step)

		if actual.Octaves != t.expectedOctaves ||
			actual.Diatonic != t.expectedDiatonic ||
			actual.Chromatic != t.expectedChromatic {

			test.Errorf("index=%d actual=%d expected=(octaves=%d diatonic=%d chromatic=%d)",
				i,
				actual,
				t.expectedOctaves,
				t.expectedDiatonic,
				t.expectedChromatic)
		}
	}
}

func TestIntervalQuality(test *testing.T) {
	data := []struct {
		input    Interval
		expected Quality
	}{
		{Perfect(5), Quality{PerfectType, 0}},
		{Major(2), Quality{MajorType, 0}},
		{Minor(3), Quality{MinorType, 0}},
		{Major(-12), Quality{PerfectType, 0}},
		{Augmented(1), Quality{AugmentedType, 1}},
		{DoublyAugmented(1), Quality{AugmentedType, 2}},
		{DoublyDiminished(1), Quality{DiminishedType, 2}},
	}

	for i, t := range data {
		actual := t.input.Quality()
		if !actual.Eq(t.expected) {
			test.Errorf("index=%d actual=%s expected=%s", i, actual, t.expected)
		}
	}
}

func TestTranspose(test *testing.T) {
	data := []struct {
		initial, interval, expected Interval
		times                       int
	}{
		{Interval{0, 0, 0}, Semitones(1), Interval{0, 1, 1}, 1},
		{Interval{0, 0, 0}, Semitones(12), Interval{1, 0, 0}, 1},

		// Sequential transpositions M2
		{Interval{0, 0, 0}, Major(2), Interval{0, 1, 2}, 1},
		{Interval{0, 0, 0}, Major(2), Interval{0, 2, 4}, 2},
		{Interval{0, 0, 0}, Major(2), Interval{0, 3, 6}, 3},
		{Interval{0, 0, 0}, Major(2), Interval{0, 4, 8}, 4},

		// Sequential transpositions of m2
		{Interval{0, 0, 0}, Minor(2), Interval{0, 1, 1}, 1},
		{Interval{0, 0, 0}, Minor(2), Interval{0, 1, 2}, 2},
		{Interval{0, 0, 0}, Minor(2), Interval{0, 2, 3}, 3},
		{Interval{0, 0, 0}, Minor(2), Interval{0, 2, 4}, 4},
		{Interval{0, 0, 0}, Minor(2), Interval{0, 3, 5}, 5},
		{Interval{0, 0, 0}, Minor(2), Interval{0, 4, 6}, 6},
		{Interval{0, 0, 0}, Minor(2), Interval{0, 4, 7}, 7},
		{Interval{0, 0, 0}, Minor(2), Interval{0, 5, 8}, 8},
		{Interval{0, 0, 0}, Minor(2), Interval{0, 5, 9}, 9},
		{Interval{0, 0, 0}, Minor(2), Interval{0, 6, 10}, 10},
		{Interval{0, 0, 0}, Minor(2), Interval{0, 6, 11}, 11},
		{Interval{0, 0, 0}, Minor(2), Interval{1, 0, 0}, 12},

		// Sequential transpositions of M3
		{Interval{0, 0, 0}, Minor(3), Interval{0, 2, 3}, 1},
		{Interval{0, 0, 0}, Minor(3), Interval{0, 4, 6}, 2},
		{Interval{0, 0, 0}, Minor(3), Interval{0, 6, 9}, 3},
		{Interval{0, 0, 0}, Minor(3), Interval{1, 1, 0}, 4},

		{Interval{0, 0, 0}, Major(3), Interval{0, 2, 4}, 1},
		{Interval{0, 0, 0}, Augmented(1), Interval{0, 0, 1}, 1},
		{Interval{0, 1, 2}, Augmented(4), Interval{0, 4, 8}, 1},
		{Interval{0, 6, 11}, Minor(3), Interval{1, 1, 2}, 1},
		{Interval{0, 6, 11}, Diminished(5).Negate(), Interval{0, 2, 5}, 1},
		{Interval{0, 6, 11}, Diminished(-5), Interval{0, 2, 5}, 1},
		{Interval{0, 6, 11}, Major(-12), Interval{-1, 2, 4}, 1},
		{Interval{-1, 2, 4}, Major(-12).Negate(), Interval{0, 6, 11}, 1},
		{Interval{-1, 2, 4}, Perfect(12), Interval{0, 6, 11}, 1},
	}

	for i, t := range data {
		actual := t.initial
		for j := 0; j < t.times; j++ {
			actual = actual.Transpose(t.interval)
		}

		if actual.Octaves != t.expected.Octaves ||
			actual.Diatonic != t.expected.Diatonic ||
			actual.Chromatic != t.expected.Chromatic {

			test.Errorf("index=%d actual=%s expected=%s", i, actual, t.expected)
		}
	}
}

func TestQualityInversion(test *testing.T) {
	data := []struct {
		input, expected Quality
	}{
		{Quality{PerfectType, 0}, Quality{PerfectType, 0}},
		{Quality{MajorType, 0}, Quality{MinorType, 0}},
		{Quality{MinorType, 0}, Quality{MajorType, 0}},
		{Quality{DiminishedType, 1}, Quality{AugmentedType, 1}},
		{Quality{AugmentedType, 1}, Quality{DiminishedType, 1}},
	}

	for i, t := range data {
		actual := t.input.Invert()
		if !actual.Eq(t.expected) {
			test.Errorf("index=%d actual=%s expected=%s", i, actual, t.expected)
		}
	}
}

func TestIntervalRatio(test *testing.T) {
	data := []struct {
		input    Interval
		expected float64
	}{
		{Perfect(-5), math.Exp2(-7.0 / 12.0)},
		{Perfect(5), math.Exp2(7.0 / 12.0)},
		{Perfect(4), math.Exp2(5.0 / 12.0)},
		{Major(3), math.Exp2(4.0 / 12.0)},
		{Minor(3), math.Exp2(3.0 / 12.0)},
		{Augmented(-4), math.Exp2(-6.0 / 12.0)},
		{Diminished(5), math.Exp2(6.0 / 12.0)},
	}

	for i, t := range data {
		actual := t.input.Ratio()
		if actual != t.expected {
			test.Errorf("index=%d actual=%v expected=%v", i, actual, t.expected)
		}
	}
}
<commit_msg>Negative semitone tests.<commit_after>package musictheory

import (
	"math"
	"testing"
)

func TestIntervals(test *testing.T) {
	data := []struct {
		typeFunc          IntervalFunc
		step              int
		expectedOctaves   int
		expectedDiatonic  int
		expectedChromatic int
	}{
		{Perfect, 1, 0, 0, 0},
		{Perfect, 2, 0, 1, 2},
		{Perfect, 3, 0, 2, 4},
		{Perfect, 4, 0, 3, 5},
		{Perfect, 5, 0, 4, 7},
		{Perfect, 6, 0, 5, 9},
		{Perfect, 7, 0, 6, 11},
		{Perfect, 8, 1, 0, 0},

		{Major, 1, 0, 0, 0},
		{Major, 2, 0, 1, 2},
		{Major, 3, 0, 2, 4},
		{Major, 4, 0, 3, 5},
		{Major, 5, 0, 4, 7},
		{Major, 6, 0, 5, 9},
		{Major, 7, 0, 6, 11},
		{Major, 8, 1, 0, 0},

		{Augmented, 2, 0, 1, 3},
		{Augmented, 3, 0, 2, 5},
		{Augmented, 4, 0, 3, 6},
		{Augmented, 5, 0, 4, 8},
		{Augmented, 6, 0, 5, 10},
		{Augmented, 7, 0, 6, 12},
		{Augmented, 8, 1, 0, 1},

		{Diminished, 2, 0, 1, 0},
		{Diminished, 3, 0, 2, 2},
		{Diminished, 4, 0, 3, 4},
		{Diminished, 5, 0, 4, 6},
		{Diminished, 6, 0, 5, 7},
		{Diminished, 7, 0, 6, 9},
		{Diminished, 8, 1, 0, -1},

		{Minor, 2, 0, 1, 1},
		{Minor, 3, 0, 2, 3},
		{Minor, 5, 0, 4, 6},
		{Minor, 7, 0, 6, 10},
	}

	for i, t := range data {
		actual := t.typeFunc(t.step)

		if actual.Octaves != t.expectedOctaves ||
			actual.Diatonic != t.expectedDiatonic ||
			actual.Chromatic != t.expectedChromatic {

			test.Errorf("index=%d actual=%d expected=(octaves=%d diatonic=%d chromatic=%d)",
				i,
				actual,
				t.expectedOctaves,
				t.expectedDiatonic,
				t.expectedChromatic)
		}
	}
}

func TestIntervalQuality(test *testing.T) {
	data := []struct {
		input    Interval
		expected Quality
	}{
		{Perfect(5), Quality{PerfectType, 0}},
		{Major(2), Quality{MajorType, 0}},
		{Minor(3), Quality{MinorType, 0}},
		{Major(-12), Quality{PerfectType, 0}},
		{Augmented(1), Quality{AugmentedType, 1}},
		{DoublyAugmented(1), Quality{AugmentedType, 2}},
		{DoublyDiminished(1), Quality{DiminishedType, 2}},
	}

	for i, t := range data {
		actual := t.input.Quality()
		if !actual.Eq(t.expected) {
			test.Errorf("index=%d actual=%s expected=%s", i, actual, t.expected)
		}
	}
}

func TestTranspose(test *testing.T) {
	data := []struct {
		initial, interval, expected Interval
		times                       int
	}{
		{Interval{0, 0, 0}, Semitones(1), Interval{0, 1, 1}, 1},
		{Interval{0, 0, 0}, Semitones(12), Interval{1, 0, 0}, 1},
		{Interval{0, 0, 0}, Semitones(-12), Interval{-1, 0, 0}, 1},
		{Interval{0, 0, 0}, Semitones(-16), Interval{-1, -2, -4}, 1},

		// Sequential transpositions M2
		{Interval{0, 0, 0}, Major(2), Interval{0, 1, 2}, 1},
		{Interval{0, 0, 0}, Major(2), Interval{0, 2, 4}, 2},
		{Interval{0, 0, 0}, Major(2), Interval{0, 3, 6}, 3},
		{Interval{0, 0, 0}, Major(2), Interval{0, 4, 8}, 4},

		// Sequential transpositions of m2
		{Interval{0, 0, 0}, Minor(2), Interval{0, 1, 1}, 1},
		{Interval{0, 0, 0}, Minor(2), Interval{0, 1, 2}, 2},
		{Interval{0, 0, 0}, Minor(2), Interval{0, 2, 3}, 3},
		{Interval{0, 0, 0}, Minor(2), Interval{0, 2, 4}, 4},
		{Interval{0, 0, 0}, Minor(2), Interval{0, 3, 5}, 5},
		{Interval{0, 0, 0}, Minor(2), Interval{0, 4, 6}, 6},
		{Interval{0, 0, 0}, Minor(2), Interval{0, 4, 7}, 7},
		{Interval{0, 0, 0}, Minor(2), Interval{0, 5, 8}, 8},
		{Interval{0, 0, 0}, Minor(2), Interval{0, 5, 9}, 9},
		{Interval{0, 0, 0}, Minor(2), Interval{0, 6, 10}, 10},
		{Interval{0, 0, 0}, Minor(2), Interval{0, 6, 11}, 11},
		{Interval{0, 0, 0}, Minor(2), Interval{1, 0, 0}, 12},

		// Sequential transpositions of M3
		{Interval{0, 0, 0}, Minor(3), Interval{0, 2, 3}, 1},
		{Interval{0, 0, 0}, Minor(3), Interval{0, 4, 6}, 2},
		{Interval{0, 0, 0}, Minor(3), Interval{0, 6, 9}, 3},
		{Interval{0, 0, 0}, Minor(3), Interval{1, 1, 0}, 4},

		{Interval{0, 0, 0}, Major(3), Interval{0, 2, 4}, 1},
		{Interval{0, 0, 0}, Augmented(1), Interval{0, 0, 1}, 1},
		{Interval{0, 1, 2}, Augmented(4), Interval{0, 4, 8}, 1},
		{Interval{0, 6, 11}, Minor(3), Interval{1, 1, 2}, 1},
		{Interval{0, 6, 11}, Diminished(5).Negate(), Interval{0, 2, 5}, 1},
		{Interval{0, 6, 11}, Diminished(-5), Interval{0, 2, 5}, 1},
		{Interval{0, 6, 11}, Major(-12), Interval{-1, 2, 4}, 1},
		{Interval{-1, 2, 4}, Major(-12).Negate(), Interval{0, 6, 11}, 1},
		{Interval{-1, 2, 4}, Perfect(12), Interval{0, 6, 11}, 1},
	}

	for i, t := range data {
		actual := t.initial
		for j := 0; j < t.times; j++ {
			actual = actual.Transpose(t.interval)
		}

		if actual.Octaves != t.expected.Octaves ||
			actual.Diatonic != t.expected.Diatonic ||
			actual.Chromatic != t.expected.Chromatic {

			test.Errorf("index=%d actual=%s expected=%s", i, actual, t.expected)
		}
	}
}

func TestQualityInversion(test *testing.T) {
	data := []struct {
		input, expected Quality
	}{
		{Quality{PerfectType, 0}, Quality{PerfectType, 0}},
		{Quality{MajorType, 0}, Quality{MinorType, 0}},
		{Quality{MinorType, 0}, Quality{MajorType, 0}},
		{Quality{DiminishedType, 1}, Quality{AugmentedType, 1}},
		{Quality{AugmentedType, 1}, Quality{DiminishedType, 1}},
	}

	for i, t := range data {
		actual := t.input.Invert()
		if !actual.Eq(t.expected) {
			test.Errorf("index=%d actual=%s expected=%s", i, actual, t.expected)
		}
	}
}

func TestIntervalRatio(test *testing.T) {
	data := []struct {
		input    Interval
		expected float64
	}{
		{Perfect(-5), math.Exp2(-7.0 / 12.0)},
		{Perfect(5), math.Exp2(7.0 / 12.0)},
		{Perfect(4), math.Exp2(5.0 / 12.0)},
		{Major(3), math.Exp2(4.0 / 12.0)},
		{Minor(3), math.Exp2(3.0 / 12.0)},
		{Augmented(-4), math.Exp2(-6.0 / 12.0)},
		{Diminished(5), math.Exp2(6.0 / 12.0)},
	}

	for i, t := range data {
		actual := t.input.Ratio()
		if actual != t.expected {
			test.Errorf("index=%d actual=%v expected=%v", i, actual, t.expected)
		}
	}
}
<|endoftext|>


<commit_before>package main

type threat struct {
	partialOperator
	threat statistic
}

// newThreat initializes a threat operator
func newThreat(unit, performer *unit, t statistic) *threat {
	return &threat{
		partialOperator: partialOperator{
			unit:      unit,
			performer: performer,
		},
		threat: t,
	}
}

// newDamageThreat initializes a threat operator with damage
func newDamageThreat(unit, performer *unit, damage statistic) *threat {
	return newThreat(unit, performer, damage*performer.damageThreatFactor())
}

// newHealingThreat initializes a threat operator with healing
func newHealingThreat(unit, performer *unit, healing statistic) *threat {
	return newThreat(unit, performer, healing*performer.healingThreatFactor())
}

// onAttach merges threat operators they have same performer
func (t *threat) onAttach() {
	t.addEventHandler(t, eventDead)
	for o := range t.operators {
		if o == t {
			continue
		}
		if _, ok := o.(*threat); !ok {
			continue
		}
		if o.(*threat).performer != t.performer {
			continue
		}
		t.threat += o.(*threat).threat
		t.detachOperator(o)
	}
}

// onDetach removes the eventHandler
func (t *threat) onDetach() {
	t.removeEventHandler(t, eventDead)
}

// handleEvent handles the event
func (t *threat) handleEvent(e event) {
	switch e {
	case eventDead:
		t.detachOperator(t)
	}
}
<commit_msg>Rename the parameters<commit_after>package main

type threat struct {
	partialOperator
	threat statistic
}

// newThreat initializes a threat operator
func newThreat(performer, receiver *unit, t statistic) *threat {
	return &threat{
		partialOperator: partialOperator{
			unit:      receiver,
			performer: performer,
		},
		threat: t,
	}
}

// newDamageThreat initializes a threat operator with damage
func newDamageThreat(performer, receiver *unit, damage statistic) *threat {
	return newThreat(performer, receiver, damage*performer.damageThreatFactor())
}

// newHealingThreat initializes a threat operator with healing
func newHealingThreat(performer, receiver *unit, healing statistic) *threat {
	return newThreat(performer, receiver, healing*performer.healingThreatFactor())
}

// onAttach merges threat operators they have same performer
func (t *threat) onAttach() {
	t.addEventHandler(t, eventDead)
	for o := range t.operators {
		if o == t {
			continue
		}
		if _, ok := o.(*threat); !ok {
			continue
		}
		if o.(*threat).performer != t.performer {
			continue
		}
		t.threat += o.(*threat).threat
		t.detachOperator(o)
	}
}

// onDetach removes the eventHandler
func (t *threat) onDetach() {
	t.removeEventHandler(t, eventDead)
}

// handleEvent handles the event
func (t *threat) handleEvent(e event) {
	switch e {
	case eventDead:
		t.detachOperator(t)
	}
}
<|endoftext|>


<commit_before>package kdtree

import (
	"alg"
	"ellipsoid"
	"errors"
	"fmt"
	"geo"
	"graph"
	"log"
	"math"
	"mm"
	"path"
)

var (
	e             ellipsoid.Ellipsoid
	clusterKdTree ClusterKdTree
)

func init() {
	e = ellipsoid.Init("WGS84", ellipsoid.Degrees, ellipsoid.Meter, ellipsoid.Longitude_is_symmetric, ellipsoid.Bearing_is_symmetric)
}

func LoadKdTree(clusterGraph *graph.ClusterGraph, base string) error {
	// Load the k-d tree of all clusters
	clusterKdTrees := make([]*KdTree, len(clusterGraph.Cluster))
	for i, g := range clusterGraph.Cluster {
		clusterDir := path.Join(base, fmt.Sprintf("/cluster%d", i+1))
		var encodedSteps []uint64
		var encodedCoordinates []int32
		err := mm.Open(path.Join(clusterDir, "kdtree.ftf"), &encodedSteps)
		if err != nil {
			return err
		}
		err = mm.Open(path.Join(clusterDir, "coordinates.ftf"), &encodedCoordinates)
		if err != nil {
			return err
		}
		clusterKdTrees[i] = &KdTree{Graph: g, EncodedSteps: encodedSteps, EncodedCoordinates: encodedCoordinates}
	}

	// Load the k-d tree of the overlay graph
	var encodedSteps []uint64
	var encodedCoordinates []int32
	err := mm.Open(path.Join(base, "/overlay/kdtree.ftf"), &encodedSteps)
	if err != nil {
		return err
	}
	err = mm.Open(path.Join(base, "/overlay/coordinates.ftf"), &encodedCoordinates)
	if err != nil {
		return err
	}
	overlayKdTree := &KdTree{Graph: clusterGraph.Overlay, EncodedSteps: encodedSteps, EncodedCoordinates: encodedCoordinates}

	// Load the bounding boxes of the clusters
	var bboxesFile []int32
	err = mm.Open(path.Join(base, "bboxes.ftf"), &bboxesFile)
	if err != nil {
		return err
	}
	if len(bboxesFile)/4 != clusterGraph.Overlay.ClusterCount() {
		return errors.New("size of bboxes file does not match cluster count")
	}
	bboxes := make([]geo.BBox, len(bboxesFile)/4)
	for i, _ := range bboxes {
		bboxes[i] = geo.DecodeBBox(bboxesFile[4*i : 4*i+4])
	}

	clusterKdTree = ClusterKdTree{Overlay: overlayKdTree, Cluster: clusterKdTrees, BBoxes: bboxes}
	return nil
}

// NearestNeighbor returns -1 if the way is on the overlay graph
// No fail strategy: a nearest point on the overlay graph is always returned if no point
// is found in the clusters.
func NearestNeighbor(x geo.Coordinate, forward bool, trans graph.Transport) (int, []graph.Way) {
	edges := []graph.Edge(nil)
	steps := []geo.Coordinate(nil)

	// first search on the overlay graph
	overlay := clusterKdTree.Overlay
	bestStepIndex, coordOverlay, foundPoint := binarySearch(overlay, x, 0, overlay.EncodedStepLen()-1,
		true /* compareLat */, trans, &edges)
	minDistance, _ := e.To(x.Lat, x.Lng, coordOverlay.Lat, coordOverlay.Lng)

	// then search on all clusters where the point is inside the bounding box of the cluster
	clusterIndex := -1
	for i, b := range clusterKdTree.BBoxes {
		if b.Contains(x) {
			kdTree := clusterKdTree.Cluster[i]
			stepIndex, coord, ok := binarySearch(kdTree, x, 0, kdTree.EncodedStepLen()-1, true /* compareLat */, trans, &edges)
			dist, _ := e.To(x.Lat, x.Lng, coord.Lat, coord.Lng)

			if ok && (!foundPoint || dist < minDistance) {
				foundPoint = true
				minDistance = dist
				bestStepIndex = stepIndex
				clusterIndex = i
			}
		}
	}

	if clusterIndex >= 0 {
		kdTree := clusterKdTree.Cluster[clusterIndex]
		return clusterIndex, decodeWays(kdTree.Graph, kdTree.EncodedStep(bestStepIndex), forward, trans, &edges, &steps)
	}
	log.Printf("no matching bounding box found for (%v, %v)", x.Lat, x.Lng)
	return clusterIndex, decodeWays(overlay.Graph, overlay.EncodedStep(bestStepIndex), forward, trans, &edges, &steps)
}

// binarySearch in one k-d tree. The index, the coordinate, and if the returned step/vertex
// is accessible are returned.
func binarySearch(kdTree *KdTree, x geo.Coordinate, start, end int, compareLat bool,
	trans graph.Transport, edges *[]graph.Edge) (int, geo.Coordinate, bool) {

	if end-start <= 0 {
		startCoord, startAccessible := decodeCoordinate(kdTree, start, trans, edges)
		return start, startCoord, startAccessible
	}

	middle := (end-start)/2 + start

	// exact hit
	middleCoord, middleAccessible := decodeCoordinate(kdTree, middle, trans, edges)
	if middleAccessible && x.Lat == middleCoord.Lat && x.Lng == middleCoord.Lng {
		return middle, middleCoord, middleAccessible
	}

	// corner case where the nearest point can be on both sides of the middle
	if !middleAccessible || (compareLat && x.Lat == middleCoord.Lat) || (!compareLat && x.Lng == middleCoord.Lng) {
		// recursion on both halfs
		leftRecIndex, leftCoord, leftAccessible := binarySearch(kdTree, x, start, middle-1, !compareLat, trans, edges)
		rightRecIndex, rightCoord, rightAccessible := binarySearch(kdTree, x, middle+1, end, !compareLat, trans, edges)

		if !middleAccessible && !leftAccessible && !rightAccessible {
			return middle, middleCoord, middleAccessible
		}

		// Infinity is used if a vertex/step it is not accessible as we know that at least one is accessible.
		distMiddle := math.Inf(1)
		distRecursionLeft := math.Inf(1)
		distRecursionRight := math.Inf(1)
		if middleAccessible {
			distMiddle, _ = e.To(x.Lat, x.Lng, middleCoord.Lat, middleCoord.Lng)
		}
		if leftAccessible {
			distRecursionLeft, _ = e.To(x.Lat, x.Lng, leftCoord.Lat, leftCoord.Lng)
		}
		if rightAccessible {
			distRecursionRight, _ = e.To(x.Lat, x.Lng, rightCoord.Lat, rightCoord.Lng)
		}

		if distRecursionLeft < distRecursionRight {
			if distRecursionLeft < distMiddle {
				return leftRecIndex, leftCoord, leftAccessible
			}
			return middle, middleCoord, middleAccessible
		}
		if distRecursionRight < distMiddle {
			return rightRecIndex, rightCoord, rightAccessible
		}
		return middle, middleCoord, middleAccessible
	}

	var left bool
	if compareLat {
		left = x.Lat < middleCoord.Lat
	} else {
		left = x.Lng < middleCoord.Lng
	}
	if left {
		// stop if there is nothing left of the middle
		if middle == start {
			return middle, middleCoord, middleAccessible
		}

		// recursion on the left half
		recIndex, recCoord, recAccessible := binarySearch(kdTree, x, start, middle-1, !compareLat, trans, edges)

		// compare middle and result from the left
		distMiddle, _ := e.To(x.Lat, x.Lng, middleCoord.Lat, middleCoord.Lng)
		distRecursion, _ := e.To(x.Lat, x.Lng, recCoord.Lat, recCoord.Lng)
		if !recAccessible || distMiddle < distRecursion {
			return middle, middleCoord, middleAccessible
		}
		return recIndex, recCoord, recAccessible
	}
	// stop if there is nothing right of the middle
	if middle == end {
		return middle, middleCoord, middleAccessible
	}

	// recursion on the right half
	recIndex, recCoord, recAccessible := binarySearch(kdTree, x, middle+1, end, !compareLat, trans, edges)

	// compare middle and result from the right
	distMiddle, _ := e.To(x.Lat, x.Lng, middleCoord.Lat, middleCoord.Lng)
	distRecursion, _ := e.To(x.Lat, x.Lng, recCoord.Lat, recCoord.Lng)
	if !recAccessible || distMiddle < distRecursion {
		return middle, middleCoord, middleAccessible
	}
	return recIndex, recCoord, recAccessible
}

// decodeCoordinate returns the coordinate of the encoded vertex/step and if it is accessible by the
// given transport mode
func decodeCoordinate(t *KdTree, i int, trans graph.Transport, edges *[]graph.Edge) (geo.Coordinate, bool) {
	g := t.Graph
	ec := t.EncodedStep(i)
	coord := geo.DecodeCoordinate(t.EncodedCoordinates[2*i], t.EncodedCoordinates[2*i+1])

	vertexIndex := ec >> (EdgeOffsetBits + StepOffsetBits)
	edgeOffset := (ec >> StepOffsetBits) & MaxEdgeOffset
	stepOffset := ec & MaxStepOffset
	vertex := graph.Vertex(vertexIndex)

	if edgeOffset == MaxEdgeOffset && stepOffset == MaxStepOffset {
		// it is a vertex and not a step
		return coord, g.VertexAccessible(vertex, trans)
	}

	var edge graph.Edge
	var edgeAccessible bool
	switch t := g.(type) {
	case *graph.GraphFile:
		(*edges) = t.VertexRawEdges(vertex, *edges)
		edge = (*edges)[edgeOffset]
		edgeAccessible = t.EdgeAccessible(edge, trans)
	case *graph.OverlayGraphFile:
		(*edges) = t.VertexRawEdges(vertex, *edges)
		edge = (*edges)[edgeOffset]
		edgeAccessible = t.EdgeAccessible(edge, trans)
	default:
		panic("unexpected graph implementation")
	}

	return coord, edgeAccessible
}

// decodeWays returns one or two partital edges that are therefore called ways. Even for a vertex a
// way is returned so that later code only has to consider ways. The other cases are explained below.
func decodeWays(g graph.Graph, ec uint64, forward bool, trans graph.Transport, edges *[]graph.Edge, steps *[]geo.Coordinate) []graph.Way {
	vertexIndex := ec >> (EdgeOffsetBits + StepOffsetBits)
	edgeOffset := (ec >> StepOffsetBits) & MaxEdgeOffset
	offset := ec & MaxStepOffset
	vertex := graph.Vertex(vertexIndex)

	if edgeOffset == MaxEdgeOffset && offset == MaxStepOffset {
		// The easy case, where we hit some vertex exactly.
		w := make([]graph.Way, 1)
		target := g.VertexCoordinate(vertex)
		w[0] = graph.Way{Length: 0, Vertex: vertex, Steps: nil, Target: target}
		return w
	}

	var edge graph.Edge
	oneway := false
	switch t := g.(type) {
	case *graph.GraphFile:
		(*edges) = t.VertexRawEdges(vertex, *edges)
		edge = (*edges)[edgeOffset]
		oneway = alg.GetBit(t.Oneway, uint(edge))
	case *graph.OverlayGraphFile:
		(*edges) = t.VertexRawEdges(vertex, *edges)
		edge = (*edges)[edgeOffset]
		oneway = alg.GetBit(t.Oneway, uint(edge))
	default:
		panic("unexpected graph implementation")
	}
	if trans == graph.Foot {
		oneway = false
	}

	t1 := vertex                       // start vertex
	t2 := g.EdgeOpposite(edge, vertex) // end vertex

	// now we can allocate the way corresponding to (edge,offset),
	// but there are three cases to consider:
	// - if the way is bidirectional we have to compute both directions,
	//   if forward == true the from the offset two both endpoints,
	//   and the reverse otherwise
	// - if the way is unidirectional then we have to compute the way
	//   from the StartPoint to offset if forward == false
	// - otherwise we have to compute the way from offset to the EndPoint
	// Strictly speaking only the second case needs an additional binary
	// search in the form of edge.StartPoint, but let's keep this simple
	// for now.
	(*steps) = g.EdgeSteps(edge, vertex, *steps)
	s := *steps

	b1 := make([]geo.Coordinate, len(s[:offset]))
	b2 := make([]geo.Coordinate, len(s[offset+1:]))
	copy(b1, s[:offset])
	copy(b2, s[offset+1:])
	l1 := geo.StepLength(s[:offset+1])
	l2 := geo.StepLength(s[offset:])
	t1Coord := g.VertexCoordinate(t1)
	t2Coord := g.VertexCoordinate(t2)
	d1, _ := e.To(t1Coord.Lat, t1Coord.Lng, s[0].Lat, s[0].Lng)
	d2, _ := e.To(t2Coord.Lat, t2Coord.Lng, s[len(s)-1].Lat, s[len(s)-1].Lng)
	l1 += d1
	l2 += d2
	target := s[offset]

	if !forward {
		reverse(b2)
	} else {
		reverse(b1)
	}

	var w []graph.Way
	if !oneway {
		w = make([]graph.Way, 2) // bidirectional
		w[0] = graph.Way{Length: l1, Vertex: t1, Steps: b1, Forward: forward, Target: target}
		w[1] = graph.Way{Length: l2, Vertex: t2, Steps: b2, Forward: forward, Target: target}
	} else {
		w = make([]graph.Way, 1) // one way
		if forward {
			w[0] = graph.Way{Length: l2, Vertex: t2, Steps: b2, Forward: forward, Target: target}
		} else {
			w[0] = graph.Way{Length: l1, Vertex: t1, Steps: b1, Forward: forward, Target: target}
		}
	}
	return w
}

func reverse(steps []geo.Coordinate) {
	for i, j := 0, len(steps)-1; i < j; i, j = i+1, j-1 {
		steps[i], steps[j] = steps[j], steps[i]
	}
}
<commit_msg>added linear search for debugging<commit_after>package kdtree

import (
	"alg"
	"ellipsoid"
	"errors"
	"fmt"
	"geo"
	"graph"
	"log"
	"math"
	"mm"
	"path"
)

var (
	e             ellipsoid.Ellipsoid
	clusterKdTree ClusterKdTree
)

func init() {
	e = ellipsoid.Init("WGS84", ellipsoid.Degrees, ellipsoid.Meter, ellipsoid.Longitude_is_symmetric, ellipsoid.Bearing_is_symmetric)
}

func LoadKdTree(clusterGraph *graph.ClusterGraph, base string) error {
	// Load the k-d tree of all clusters
	clusterKdTrees := make([]*KdTree, len(clusterGraph.Cluster))
	for i, g := range clusterGraph.Cluster {
		clusterDir := path.Join(base, fmt.Sprintf("/cluster%d", i+1))
		var encodedSteps []uint64
		var encodedCoordinates []int32
		err := mm.Open(path.Join(clusterDir, "kdtree.ftf"), &encodedSteps)
		if err != nil {
			return err
		}
		err = mm.Open(path.Join(clusterDir, "coordinates.ftf"), &encodedCoordinates)
		if err != nil {
			return err
		}
		clusterKdTrees[i] = &KdTree{Graph: g, EncodedSteps: encodedSteps, EncodedCoordinates: encodedCoordinates}
	}

	// Load the k-d tree of the overlay graph
	var encodedSteps []uint64
	var encodedCoordinates []int32
	err := mm.Open(path.Join(base, "/overlay/kdtree.ftf"), &encodedSteps)
	if err != nil {
		return err
	}
	err = mm.Open(path.Join(base, "/overlay/coordinates.ftf"), &encodedCoordinates)
	if err != nil {
		return err
	}
	overlayKdTree := &KdTree{Graph: clusterGraph.Overlay, EncodedSteps: encodedSteps, EncodedCoordinates: encodedCoordinates}

	// Load the bounding boxes of the clusters
	var bboxesFile []int32
	err = mm.Open(path.Join(base, "bboxes.ftf"), &bboxesFile)
	if err != nil {
		return err
	}
	if len(bboxesFile)/4 != clusterGraph.Overlay.ClusterCount() {
		return errors.New("size of bboxes file does not match cluster count")
	}
	bboxes := make([]geo.BBox, len(bboxesFile)/4)
	for i, _ := range bboxes {
		bboxes[i] = geo.DecodeBBox(bboxesFile[4*i : 4*i+4])
	}

	clusterKdTree = ClusterKdTree{Overlay: overlayKdTree, Cluster: clusterKdTrees, BBoxes: bboxes}
	return nil
}

// NearestNeighbor returns -1 if the way is on the overlay graph
// No fail strategy: a nearest point on the overlay graph is always returned if no point
// is found in the clusters.
func NearestNeighbor(x geo.Coordinate, forward bool, trans graph.Transport) (int, []graph.Way) {
	edges := []graph.Edge(nil)
	steps := []geo.Coordinate(nil)

	// first search on the overlay graph
	overlay := clusterKdTree.Overlay
	bestStepIndex, coordOverlay, foundPoint := binarySearch(overlay, x, 0, overlay.EncodedStepLen()-1,
		true /* compareLat */, trans, &edges)
	minDistance, _ := e.To(x.Lat, x.Lng, coordOverlay.Lat, coordOverlay.Lng)

	// for debugging
	bestCoord := coordOverlay

	// then search on all clusters where the point is inside the bounding box of the cluster
	clusterIndex := -1
	for i, b := range clusterKdTree.BBoxes {
		if b.Contains(x) {
			kdTree := clusterKdTree.Cluster[i]
			stepIndex, coord, ok := binarySearch(kdTree, x, 0, kdTree.EncodedStepLen()-1, true /* compareLat */, trans, &edges)
			dist, _ := e.To(x.Lat, x.Lng, coord.Lat, coord.Lng)

			if ok && (!foundPoint || dist < minDistance) {
				foundPoint = true
				minDistance = dist
				bestStepIndex = stepIndex
				clusterIndex = i

				// for debugging
				bestCoord = coord
			}
		}
	}

	// for debugging: linear search
	minD := math.Inf(1)
	minI := -1
	minCluster := -1
	var minC geo.Coordinate
	for i, b := range clusterKdTree.BBoxes {
		if b.Contains(x) {
			kdTree := clusterKdTree.Cluster[i]
			for j := 0; j < kdTree.EncodedStepLen(); j++ {
				c, oki := decodeCoordinate(kdTree, j, trans, &edges)
				dd, _ := e.To(x.Lat, x.Lng, c.Lat, c.Lng)
				if oki && dd < minD {
					minD = dd
					minI = j
					minC = c
					minCluster = i
				}
			}
		}
	}
	fmt.Printf("nearest neighbor for %v\n", x)
	fmt.Printf("binary search: min distance: %v at %v in cluster %v  %v\n", minDistance, bestStepIndex, clusterIndex, bestCoord)
	fmt.Printf("linear search: min distance: %v at %v in cluster %v  %v\n", minD, minI, minCluster, minC)

	if clusterIndex >= 0 {
		kdTree := clusterKdTree.Cluster[clusterIndex]
		return clusterIndex, decodeWays(kdTree.Graph, kdTree.EncodedStep(bestStepIndex), forward, trans, &edges, &steps)
	}
	log.Printf("no matching bounding box found for (%v, %v)", x.Lat, x.Lng)
	return clusterIndex, decodeWays(overlay.Graph, overlay.EncodedStep(bestStepIndex), forward, trans, &edges, &steps)
}

// binarySearch in one k-d tree. The index, the coordinate, and if the returned step/vertex
// is accessible are returned.
func binarySearch(kdTree *KdTree, x geo.Coordinate, start, end int, compareLat bool,
	trans graph.Transport, edges *[]graph.Edge) (int, geo.Coordinate, bool) {

	if end-start <= 0 {
		startCoord, startAccessible := decodeCoordinate(kdTree, start, trans, edges)
		return start, startCoord, startAccessible
	}

	middle := (end-start)/2 + start

	// exact hit
	middleCoord, middleAccessible := decodeCoordinate(kdTree, middle, trans, edges)
	if middleAccessible && x.Lat == middleCoord.Lat && x.Lng == middleCoord.Lng {
		return middle, middleCoord, middleAccessible
	}

	// corner case where the nearest point can be on both sides of the middle
	if !middleAccessible || (compareLat && x.Lat == middleCoord.Lat) || (!compareLat && x.Lng == middleCoord.Lng) {
		// recursion on both halfs
		leftRecIndex, leftCoord, leftAccessible := binarySearch(kdTree, x, start, middle-1, !compareLat, trans, edges)
		rightRecIndex, rightCoord, rightAccessible := binarySearch(kdTree, x, middle+1, end, !compareLat, trans, edges)

		if !middleAccessible && !leftAccessible && !rightAccessible {
			return middle, middleCoord, middleAccessible
		}

		// Infinity is used if a vertex/step it is not accessible as we know that at least one is accessible.
		distMiddle := math.Inf(1)
		distRecursionLeft := math.Inf(1)
		distRecursionRight := math.Inf(1)
		if middleAccessible {
			distMiddle, _ = e.To(x.Lat, x.Lng, middleCoord.Lat, middleCoord.Lng)
		}
		if leftAccessible {
			distRecursionLeft, _ = e.To(x.Lat, x.Lng, leftCoord.Lat, leftCoord.Lng)
		}
		if rightAccessible {
			distRecursionRight, _ = e.To(x.Lat, x.Lng, rightCoord.Lat, rightCoord.Lng)
		}

		if distRecursionLeft < distRecursionRight {
			if distRecursionLeft < distMiddle {
				return leftRecIndex, leftCoord, leftAccessible
			}
			return middle, middleCoord, middleAccessible
		}
		if distRecursionRight < distMiddle {
			return rightRecIndex, rightCoord, rightAccessible
		}
		return middle, middleCoord, middleAccessible
	}

	var left bool
	if compareLat {
		left = x.Lat < middleCoord.Lat
	} else {
		left = x.Lng < middleCoord.Lng
	}
	if left {
		// stop if there is nothing left of the middle
		if middle == start {
			return middle, middleCoord, middleAccessible
		}

		// recursion on the left half
		recIndex, recCoord, recAccessible := binarySearch(kdTree, x, start, middle-1, !compareLat, trans, edges)

		// compare middle and result from the left
		distMiddle, _ := e.To(x.Lat, x.Lng, middleCoord.Lat, middleCoord.Lng)
		distRecursion, _ := e.To(x.Lat, x.Lng, recCoord.Lat, recCoord.Lng)
		if !recAccessible || distMiddle < distRecursion {
			return middle, middleCoord, middleAccessible
		}
		return recIndex, recCoord, recAccessible
	}
	// stop if there is nothing right of the middle
	if middle == end {
		return middle, middleCoord, middleAccessible
	}

	// recursion on the right half
	recIndex, recCoord, recAccessible := binarySearch(kdTree, x, middle+1, end, !compareLat, trans, edges)

	// compare middle and result from the right
	distMiddle, _ := e.To(x.Lat, x.Lng, middleCoord.Lat, middleCoord.Lng)
	distRecursion, _ := e.To(x.Lat, x.Lng, recCoord.Lat, recCoord.Lng)
	if !recAccessible || distMiddle < distRecursion {
		return middle, middleCoord, middleAccessible
	}
	return recIndex, recCoord, recAccessible
}

// decodeCoordinate returns the coordinate of the encoded vertex/step and if it is accessible by the
// given transport mode
func decodeCoordinate(t *KdTree, i int, trans graph.Transport, edges *[]graph.Edge) (geo.Coordinate, bool) {
	g := t.Graph
	ec := t.EncodedStep(i)
	coord := geo.DecodeCoordinate(t.EncodedCoordinates[2*i], t.EncodedCoordinates[2*i+1])

	vertexIndex := ec >> (EdgeOffsetBits + StepOffsetBits)
	edgeOffset := (ec >> StepOffsetBits) & MaxEdgeOffset
	stepOffset := ec & MaxStepOffset
	vertex := graph.Vertex(vertexIndex)

	if edgeOffset == MaxEdgeOffset && stepOffset == MaxStepOffset {
		// it is a vertex and not a step
		return coord, g.VertexAccessible(vertex, trans)
	}

	var edge graph.Edge
	var edgeAccessible bool
	switch t := g.(type) {
	case *graph.GraphFile:
		(*edges) = t.VertexRawEdges(vertex, *edges)
		edge = (*edges)[edgeOffset]
		edgeAccessible = t.EdgeAccessible(edge, trans)
	case *graph.OverlayGraphFile:
		(*edges) = t.VertexRawEdges(vertex, *edges)
		edge = (*edges)[edgeOffset]
		edgeAccessible = t.EdgeAccessible(edge, trans)
	default:
		panic("unexpected graph implementation")
	}

	return coord, edgeAccessible
}

// decodeWays returns one or two partital edges that are therefore called ways. Even for a vertex a
// way is returned so that later code only has to consider ways. The other cases are explained below.
func decodeWays(g graph.Graph, ec uint64, forward bool, trans graph.Transport, edges *[]graph.Edge, steps *[]geo.Coordinate) []graph.Way {
	vertexIndex := ec >> (EdgeOffsetBits + StepOffsetBits)
	edgeOffset := (ec >> StepOffsetBits) & MaxEdgeOffset
	offset := ec & MaxStepOffset
	vertex := graph.Vertex(vertexIndex)

	if edgeOffset == MaxEdgeOffset && offset == MaxStepOffset {
		// The easy case, where we hit some vertex exactly.
		w := make([]graph.Way, 1)
		target := g.VertexCoordinate(vertex)
		w[0] = graph.Way{Length: 0, Vertex: vertex, Steps: nil, Target: target}
		return w
	}

	var edge graph.Edge
	oneway := false
	switch t := g.(type) {
	case *graph.GraphFile:
		(*edges) = t.VertexRawEdges(vertex, *edges)
		edge = (*edges)[edgeOffset]
		oneway = alg.GetBit(t.Oneway, uint(edge))
	case *graph.OverlayGraphFile:
		(*edges) = t.VertexRawEdges(vertex, *edges)
		edge = (*edges)[edgeOffset]
		oneway = alg.GetBit(t.Oneway, uint(edge))
	default:
		panic("unexpected graph implementation")
	}
	if trans == graph.Foot {
		oneway = false
	}

	t1 := vertex                       // start vertex
	t2 := g.EdgeOpposite(edge, vertex) // end vertex

	// now we can allocate the way corresponding to (edge,offset),
	// but there are three cases to consider:
	// - if the way is bidirectional we have to compute both directions,
	//   if forward == true the from the offset two both endpoints,
	//   and the reverse otherwise
	// - if the way is unidirectional then we have to compute the way
	//   from the StartPoint to offset if forward == false
	// - otherwise we have to compute the way from offset to the EndPoint
	// Strictly speaking only the second case needs an additional binary
	// search in the form of edge.StartPoint, but let's keep this simple
	// for now.
	(*steps) = g.EdgeSteps(edge, vertex, *steps)
	s := *steps

	b1 := make([]geo.Coordinate, len(s[:offset]))
	b2 := make([]geo.Coordinate, len(s[offset+1:]))
	copy(b1, s[:offset])
	copy(b2, s[offset+1:])
	l1 := geo.StepLength(s[:offset+1])
	l2 := geo.StepLength(s[offset:])
	t1Coord := g.VertexCoordinate(t1)
	t2Coord := g.VertexCoordinate(t2)
	d1, _ := e.To(t1Coord.Lat, t1Coord.Lng, s[0].Lat, s[0].Lng)
	d2, _ := e.To(t2Coord.Lat, t2Coord.Lng, s[len(s)-1].Lat, s[len(s)-1].Lng)
	l1 += d1
	l2 += d2
	target := s[offset]

	if !forward {
		reverse(b2)
	} else {
		reverse(b1)
	}

	var w []graph.Way
	if !oneway {
		w = make([]graph.Way, 2) // bidirectional
		w[0] = graph.Way{Length: l1, Vertex: t1, Steps: b1, Forward: forward, Target: target}
		w[1] = graph.Way{Length: l2, Vertex: t2, Steps: b2, Forward: forward, Target: target}
	} else {
		w = make([]graph.Way, 1) // one way
		if forward {
			w[0] = graph.Way{Length: l2, Vertex: t2, Steps: b2, Forward: forward, Target: target}
		} else {
			w[0] = graph.Way{Length: l1, Vertex: t1, Steps: b1, Forward: forward, Target: target}
		}
	}
	return w
}

func reverse(steps []geo.Coordinate) {
	for i, j := 0, len(steps)-1; i < j; i, j = i+1, j-1 {
		steps[i], steps[j] = steps[j], steps[i]
	}
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"os"
	"testing"

	"github.com/aws/aws-sdk-go/service/servicequotas"
	"github.com/hashicorp/terraform/helper/resource"
)

// This resource different than many since quotas are pre-existing
// and the resource is only designed to help with increases.
// In the basic case, we test that the resource can match the existing quota
// without unexpected changes.
func TestAccAwsServiceQuotasServiceQuota_basic(t *testing.T) {
	dataSourceName := "data.aws_servicequotas_service_quota.test"
	resourceName := "aws_servicequotas_service_quota.test"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t); testAccPreCheckAWSServiceQuotas(t) },
		Providers:    testAccProviders,
		CheckDestroy: nil,
		Steps: []resource.TestStep{
			{
				Config: testAccAwsServiceQuotasServiceQuotaConfigSameValue("L-F678F1CE", "vpc"),
				Check: resource.ComposeTestCheckFunc(
					resource.TestCheckResourceAttrPair(resourceName, "adjustable", dataSourceName, "adjustable"),
					resource.TestCheckResourceAttrPair(resourceName, "arn", dataSourceName, "arn"),
					resource.TestCheckResourceAttrPair(resourceName, "default_value", dataSourceName, "default_value"),
					resource.TestCheckResourceAttrPair(resourceName, "quota_code", dataSourceName, "quota_code"),
					resource.TestCheckResourceAttrPair(resourceName, "quota_name", dataSourceName, "quota_name"),
					resource.TestCheckResourceAttrPair(resourceName, "service_code", dataSourceName, "service_code"),
					resource.TestCheckResourceAttrPair(resourceName, "service_name", dataSourceName, "service_name"),
					resource.TestCheckResourceAttrPair(resourceName, "value", dataSourceName, "value"),
				),
			},
			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func TestAccAwsServiceQuotasServiceQuota_Value_IncreaseOnCreate(t *testing.T) {
	quotaCode := os.Getenv("SERVICEQUOTAS_INCREASE_ON_CREATE_QUOTA_CODE")
	if quotaCode == "" {
		t.Skip(
			"Environment variable SERVICEQUOTAS_INCREASE_ON_CREATE_QUOTA_CODE is not set. " +
				"WARNING: This test will submit a real service quota increase!")
	}

	serviceCode := os.Getenv("SERVICEQUOTAS_INCREASE_ON_CREATE_SERVICE_CODE")
	if serviceCode == "" {
		t.Skip(
			"Environment variable SERVICEQUOTAS_INCREASE_ON_CREATE_SERVICE_CODE is not set. " +
				"WARNING: This test will submit a real service quota increase!")
	}

	value := os.Getenv("SERVICEQUOTAS_INCREASE_ON_CREATE_VALUE")
	if value == "" {
		t.Skip(
			"Environment variable SERVICEQUOTAS_INCREASE_ON_CREATE_VALUE is not set. " +
				"WARNING: This test will submit a real service quota increase!")
	}

	resourceName := "aws_servicequotas_service_quota.test"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t); testAccPreCheckAWSServiceQuotas(t) },
		Providers:    testAccProviders,
		CheckDestroy: nil,
		Steps: []resource.TestStep{
			{
				Config: testAccAwsServiceQuotasServiceQuotaConfigValue(quotaCode, serviceCode, value),
				Check: resource.ComposeTestCheckFunc(
					resource.TestCheckResourceAttr(resourceName, "quota_code", quotaCode),
					resource.TestCheckResourceAttr(resourceName, "service_code", serviceCode),
					resource.TestCheckResourceAttr(resourceName, "value", value),
				),
			},
		},
	})
}

func TestAccAwsServiceQuotasServiceQuota_Value_IncreaseOnUpdate(t *testing.T) {
	quotaCode := os.Getenv("SERVICEQUOTAS_INCREASE_ON_UPDATE_QUOTA_CODE")
	if quotaCode == "" {
		t.Skip(
			"Environment variable SERVICEQUOTAS_INCREASE_ON_UPDATE_QUOTA_CODE is not set. " +
				"WARNING: This test will submit a real service quota increase!")
	}

	serviceCode := os.Getenv("SERVICEQUOTAS_INCREASE_ON_UPDATE_SERVICE_CODE")
	if serviceCode == "" {
		t.Skip(
			"Environment variable SERVICEQUOTAS_INCREASE_ON_UPDATE_SERVICE_CODE is not set. " +
				"WARNING: This test will submit a real service quota increase!")
	}

	value := os.Getenv("SERVICEQUOTAS_INCREASE_ON_UPDATE_VALUE")
	if value == "" {
		t.Skip(
			"Environment variable SERVICEQUOTAS_INCREASE_ON_UPDATE_VALUE is not set. " +
				"WARNING: This test will submit a real service quota increase!")
	}

	dataSourceName := "aws_servicequotas_service_quota.test"
	resourceName := "aws_servicequotas_service_quota.test"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t); testAccPreCheckAWSServiceQuotas(t) },
		Providers:    testAccProviders,
		CheckDestroy: nil,
		Steps: []resource.TestStep{
			{
				Config: testAccAwsServiceQuotasServiceQuotaConfigSameValue(quotaCode, serviceCode),
				Check: resource.ComposeTestCheckFunc(
					resource.TestCheckResourceAttr(resourceName, "quota_code", quotaCode),
					resource.TestCheckResourceAttr(resourceName, "service_code", serviceCode),
					resource.TestCheckResourceAttrPair(resourceName, "value", dataSourceName, "value"),
				),
			},
			{
				Config: testAccAwsServiceQuotasServiceQuotaConfigValue(quotaCode, serviceCode, value),
				Check: resource.ComposeTestCheckFunc(
					resource.TestCheckResourceAttr(resourceName, "quota_code", quotaCode),
					resource.TestCheckResourceAttr(resourceName, "service_code", serviceCode),
					resource.TestCheckResourceAttr(resourceName, "value", value),
				),
			},
		},
	})
}

func testAccPreCheckAWSServiceQuotas(t *testing.T) {
	conn := testAccProvider.Meta().(*AWSClient).servicequotasconn

	input := &servicequotas.ListServicesInput{}

	_, err := conn.ListServices(input)

	if testAccPreCheckSkipError(err) {
		t.Skipf("skipping acceptance testing: %s", err)
	}

	if err != nil {
		t.Fatalf("unexpected PreCheck error: %s", err)
	}
}

func testAccAwsServiceQuotasServiceQuotaConfigSameValue(quotaCode, serviceCode string) string {
	return fmt.Sprintf(`
data "aws_servicequotas_service_quota" "test" {
  quota_code   = %[1]q
  service_code = %[2]q
}

resource "aws_servicequotas_service_quota" "test" {
  quota_code   = "${data.aws_servicequotas_service_quota.test.quota_code}"
  service_code = "${data.aws_servicequotas_service_quota.test.service_code}"
  value        = "${data.aws_servicequotas_service_quota.test.value}"
}
`, quotaCode, serviceCode)
}

func testAccAwsServiceQuotasServiceQuotaConfigValue(quotaCode, serviceCode, value string) string {
	return fmt.Sprintf(`
resource "aws_servicequotas_service_quota" "test" {
  quota_code   = %[1]q
  service_code = %[2]q
  value        = %[3]s
}
`, quotaCode, serviceCode, value)
}
<commit_msg>Update aws/resource_aws_servicequotas_service_quota_test.go<commit_after>package aws

import (
	"fmt"
	"os"
	"testing"

	"github.com/aws/aws-sdk-go/service/servicequotas"
	"github.com/hashicorp/terraform/helper/resource"
)

// This resource is different than many since quotas are pre-existing
// and the resource is only designed to help with increases.
// In the basic case, we test that the resource can match the existing quota
// without unexpected changes.
func TestAccAwsServiceQuotasServiceQuota_basic(t *testing.T) {
	dataSourceName := "data.aws_servicequotas_service_quota.test"
	resourceName := "aws_servicequotas_service_quota.test"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t); testAccPreCheckAWSServiceQuotas(t) },
		Providers:    testAccProviders,
		CheckDestroy: nil,
		Steps: []resource.TestStep{
			{
				Config: testAccAwsServiceQuotasServiceQuotaConfigSameValue("L-F678F1CE", "vpc"),
				Check: resource.ComposeTestCheckFunc(
					resource.TestCheckResourceAttrPair(resourceName, "adjustable", dataSourceName, "adjustable"),
					resource.TestCheckResourceAttrPair(resourceName, "arn", dataSourceName, "arn"),
					resource.TestCheckResourceAttrPair(resourceName, "default_value", dataSourceName, "default_value"),
					resource.TestCheckResourceAttrPair(resourceName, "quota_code", dataSourceName, "quota_code"),
					resource.TestCheckResourceAttrPair(resourceName, "quota_name", dataSourceName, "quota_name"),
					resource.TestCheckResourceAttrPair(resourceName, "service_code", dataSourceName, "service_code"),
					resource.TestCheckResourceAttrPair(resourceName, "service_name", dataSourceName, "service_name"),
					resource.TestCheckResourceAttrPair(resourceName, "value", dataSourceName, "value"),
				),
			},
			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func TestAccAwsServiceQuotasServiceQuota_Value_IncreaseOnCreate(t *testing.T) {
	quotaCode := os.Getenv("SERVICEQUOTAS_INCREASE_ON_CREATE_QUOTA_CODE")
	if quotaCode == "" {
		t.Skip(
			"Environment variable SERVICEQUOTAS_INCREASE_ON_CREATE_QUOTA_CODE is not set. " +
				"WARNING: This test will submit a real service quota increase!")
	}

	serviceCode := os.Getenv("SERVICEQUOTAS_INCREASE_ON_CREATE_SERVICE_CODE")
	if serviceCode == "" {
		t.Skip(
			"Environment variable SERVICEQUOTAS_INCREASE_ON_CREATE_SERVICE_CODE is not set. " +
				"WARNING: This test will submit a real service quota increase!")
	}

	value := os.Getenv("SERVICEQUOTAS_INCREASE_ON_CREATE_VALUE")
	if value == "" {
		t.Skip(
			"Environment variable SERVICEQUOTAS_INCREASE_ON_CREATE_VALUE is not set. " +
				"WARNING: This test will submit a real service quota increase!")
	}

	resourceName := "aws_servicequotas_service_quota.test"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t); testAccPreCheckAWSServiceQuotas(t) },
		Providers:    testAccProviders,
		CheckDestroy: nil,
		Steps: []resource.TestStep{
			{
				Config: testAccAwsServiceQuotasServiceQuotaConfigValue(quotaCode, serviceCode, value),
				Check: resource.ComposeTestCheckFunc(
					resource.TestCheckResourceAttr(resourceName, "quota_code", quotaCode),
					resource.TestCheckResourceAttr(resourceName, "service_code", serviceCode),
					resource.TestCheckResourceAttr(resourceName, "value", value),
				),
			},
		},
	})
}

func TestAccAwsServiceQuotasServiceQuota_Value_IncreaseOnUpdate(t *testing.T) {
	quotaCode := os.Getenv("SERVICEQUOTAS_INCREASE_ON_UPDATE_QUOTA_CODE")
	if quotaCode == "" {
		t.Skip(
			"Environment variable SERVICEQUOTAS_INCREASE_ON_UPDATE_QUOTA_CODE is not set. " +
				"WARNING: This test will submit a real service quota increase!")
	}

	serviceCode := os.Getenv("SERVICEQUOTAS_INCREASE_ON_UPDATE_SERVICE_CODE")
	if serviceCode == "" {
		t.Skip(
			"Environment variable SERVICEQUOTAS_INCREASE_ON_UPDATE_SERVICE_CODE is not set. " +
				"WARNING: This test will submit a real service quota increase!")
	}

	value := os.Getenv("SERVICEQUOTAS_INCREASE_ON_UPDATE_VALUE")
	if value == "" {
		t.Skip(
			"Environment variable SERVICEQUOTAS_INCREASE_ON_UPDATE_VALUE is not set. " +
				"WARNING: This test will submit a real service quota increase!")
	}

	dataSourceName := "aws_servicequotas_service_quota.test"
	resourceName := "aws_servicequotas_service_quota.test"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t); testAccPreCheckAWSServiceQuotas(t) },
		Providers:    testAccProviders,
		CheckDestroy: nil,
		Steps: []resource.TestStep{
			{
				Config: testAccAwsServiceQuotasServiceQuotaConfigSameValue(quotaCode, serviceCode),
				Check: resource.ComposeTestCheckFunc(
					resource.TestCheckResourceAttr(resourceName, "quota_code", quotaCode),
					resource.TestCheckResourceAttr(resourceName, "service_code", serviceCode),
					resource.TestCheckResourceAttrPair(resourceName, "value", dataSourceName, "value"),
				),
			},
			{
				Config: testAccAwsServiceQuotasServiceQuotaConfigValue(quotaCode, serviceCode, value),
				Check: resource.ComposeTestCheckFunc(
					resource.TestCheckResourceAttr(resourceName, "quota_code", quotaCode),
					resource.TestCheckResourceAttr(resourceName, "service_code", serviceCode),
					resource.TestCheckResourceAttr(resourceName, "value", value),
				),
			},
		},
	})
}

func testAccPreCheckAWSServiceQuotas(t *testing.T) {
	conn := testAccProvider.Meta().(*AWSClient).servicequotasconn

	input := &servicequotas.ListServicesInput{}

	_, err := conn.ListServices(input)

	if testAccPreCheckSkipError(err) {
		t.Skipf("skipping acceptance testing: %s", err)
	}

	if err != nil {
		t.Fatalf("unexpected PreCheck error: %s", err)
	}
}

func testAccAwsServiceQuotasServiceQuotaConfigSameValue(quotaCode, serviceCode string) string {
	return fmt.Sprintf(`
data "aws_servicequotas_service_quota" "test" {
  quota_code   = %[1]q
  service_code = %[2]q
}

resource "aws_servicequotas_service_quota" "test" {
  quota_code   = "${data.aws_servicequotas_service_quota.test.quota_code}"
  service_code = "${data.aws_servicequotas_service_quota.test.service_code}"
  value        = "${data.aws_servicequotas_service_quota.test.value}"
}
`, quotaCode, serviceCode)
}

func testAccAwsServiceQuotasServiceQuotaConfigValue(quotaCode, serviceCode, value string) string {
	return fmt.Sprintf(`
resource "aws_servicequotas_service_quota" "test" {
  quota_code   = %[1]q
  service_code = %[2]q
  value        = %[3]s
}
`, quotaCode, serviceCode, value)
}
<|endoftext|>


<commit_before>// Copyright © 2016 Brian Kidney <bkidney@briankidney.ca>
//
// 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 utils

import (
	"encoding/gob"
	"log"
	"os"

	"github.com/bkidney/NBClassify/utils"
)

func loadTrainingData(datafile string) (trainingData utils.TallyCount) {

	file, err := os.Open(datafile + ".gob")
	if err != nil {
		panic(err)
	}
	defer file.Close()

	dataDec := gob.NewDecoder(file)
	err = dataDec.Decode(&trainingData)
	if err != nil {
		log.Fatal("decode error:", err)
	}

	//	trainingData.Print()

	return trainingData
}
<commit_msg>Fixes circular import.<commit_after>// Copyright © 2016 Brian Kidney <bkidney@briankidney.ca>
//
// 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 utils

import (
	"encoding/gob"
	"log"
	"os"
)

func LoadTrainingData(datafile string) (trainingData TallyCount) {

	file, err := os.Open(datafile + ".gob")
	if err != nil {
		panic(err)
	}
	defer file.Close()

	dataDec := gob.NewDecoder(file)
	err = dataDec.Decode(&trainingData)
	if err != nil {
		log.Fatal("decode error:", err)
	}

	//	trainingData.Print()

	return trainingData
}
<|endoftext|>


<commit_before>// Copyright 2012, 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package charm_test

import (
	"io/ioutil"
	gc "launchpad.net/gocheck"
	corecharm "launchpad.net/juju-core/charm"
	"launchpad.net/juju-core/testing"
	"launchpad.net/juju-core/worker/uniter/charm"
	"os"
	"path/filepath"
)

type DeployerSuite struct {
	testing.GitSuite
}

var _ = gc.Suite(&DeployerSuite{})

func (s *DeployerSuite) TestUnsetCharm(c *gc.C) {
	d := charm.NewDeployer(filepath.Join(c.MkDir(), "deployer"))
	err := d.Deploy(charm.NewGitDir(c.MkDir()))
	c.Assert(err, gc.ErrorMatches, "charm deployment failed: no charm set")
}

func (s *DeployerSuite) TestInstall(c *gc.C) {
	// Install.
	d := charm.NewDeployer(filepath.Join(c.MkDir(), "deployer"))
	bun := s.bundle(c, func(path string) {
		err := ioutil.WriteFile(filepath.Join(path, "some-file"), []byte("hello"), 0644)
		c.Assert(err, gc.IsNil)
	})
	err := d.Stage(bun, corecharm.MustParseURL("cs:s/c-1"))
	c.Assert(err, gc.IsNil)
	s.checkCleanup(c, d)

	target := charm.NewGitDir(filepath.Join(c.MkDir(), "target"))
	err = d.Deploy(target)
	c.Assert(err, gc.IsNil)
	s.checkCleanup(c, d)

	// Check content.
	data, err := ioutil.ReadFile(filepath.Join(target.Path(), "some-file"))
	c.Assert(err, gc.IsNil)
	c.Assert(string(data), gc.Equals, "hello")
	url, err := charm.ReadCharmURL(target)
	c.Assert(err, gc.IsNil)
	c.Assert(url, gc.DeepEquals, corecharm.MustParseURL("cs:s/c-1"))
	lines, err := target.Log()
	c.Assert(err, gc.IsNil)
	c.Assert(lines, gc.HasLen, 2)
	c.Assert(lines[0], gc.Matches, `[0-9a-f]{7} Deployed charm "cs:s/c-1".`)
	c.Assert(lines[1], gc.Matches, `[0-9a-f]{7} Imported charm "cs:s/c-1" from ".*".`)
}

func (s *DeployerSuite) TestUpgrade(c *gc.C) {
	// Install.
	d := charm.NewDeployer(filepath.Join(c.MkDir(), "deployer"))
	bun1 := s.bundle(c, func(path string) {
		err := ioutil.WriteFile(filepath.Join(path, "some-file"), []byte("hello"), 0644)
		c.Assert(err, gc.IsNil)
		err = os.Symlink("./some-file", filepath.Join(path, "a-symlink"))
		c.Assert(err, gc.IsNil)
	})
	err := d.Stage(bun1, corecharm.MustParseURL("cs:s/c-1"))
	c.Assert(err, gc.IsNil)
	target := charm.NewGitDir(filepath.Join(c.MkDir(), "target"))
	err = d.Deploy(target)
	c.Assert(err, gc.IsNil)

	// Upgrade.
	bun2 := s.bundle(c, func(path string) {
		err := ioutil.WriteFile(filepath.Join(path, "some-file"), []byte("goodbye"), 0644)
		c.Assert(err, gc.IsNil)
		err = ioutil.WriteFile(filepath.Join(path, "a-symlink"), []byte("not any more!"), 0644)
		c.Assert(err, gc.IsNil)
	})
	err = d.Stage(bun2, corecharm.MustParseURL("cs:s/c-2"))
	c.Assert(err, gc.IsNil)
	s.checkCleanup(c, d)

	err = d.Deploy(target)
	c.Assert(err, gc.IsNil)
	s.checkCleanup(c, d)

	// Check content.
	data, err := ioutil.ReadFile(filepath.Join(target.Path(), "some-file"))
	c.Assert(err, gc.IsNil)
	c.Assert(string(data), gc.Equals, "goodbye")
	data, err = ioutil.ReadFile(filepath.Join(target.Path(), "a-symlink"))
	c.Assert(err, gc.IsNil)
	c.Assert(string(data), gc.Equals, "not any more!")
	url, err := charm.ReadCharmURL(target)
	c.Assert(err, gc.IsNil)
	c.Assert(url, gc.DeepEquals, corecharm.MustParseURL("cs:s/c-2"))
	lines, err := target.Log()
	c.Assert(err, gc.IsNil)
	c.Assert(lines, gc.HasLen, 5)
	c.Assert(lines[0], gc.Matches, `[0-9a-f]{7} Upgraded charm to "cs:s/c-2".`)
}

func (s *DeployerSuite) TestConflict(c *gc.C) {
	// Install.
	d := charm.NewDeployer(filepath.Join(c.MkDir(), "deployer"))
	bun1 := s.bundle(c, func(path string) {
		err := ioutil.WriteFile(filepath.Join(path, "some-file"), []byte("hello"), 0644)
		c.Assert(err, gc.IsNil)
	})
	err := d.Stage(bun1, corecharm.MustParseURL("cs:s/c-1"))
	c.Assert(err, gc.IsNil)
	target := charm.NewGitDir(filepath.Join(c.MkDir(), "target"))
	err = d.Deploy(target)
	c.Assert(err, gc.IsNil)

	// Mess up target.
	err = ioutil.WriteFile(filepath.Join(target.Path(), "some-file"), []byte("mu!"), 0644)
	c.Assert(err, gc.IsNil)

	// Upgrade.
	bun2 := s.bundle(c, func(path string) {
		err := ioutil.WriteFile(filepath.Join(path, "some-file"), []byte("goodbye"), 0644)
		c.Assert(err, gc.IsNil)
	})
	err = d.Stage(bun2, corecharm.MustParseURL("cs:s/c-2"))
	c.Assert(err, gc.IsNil)
	err = d.Deploy(target)
	c.Assert(err, gc.Equals, charm.ErrConflict)
	s.checkCleanup(c, d)

	// Check state.
	conflicted, err := target.Conflicted()
	c.Assert(err, gc.IsNil)
	c.Assert(conflicted, gc.Equals, true)

	// Revert and check initial content.
	err = target.Revert()
	c.Assert(err, gc.IsNil)
	data, err := ioutil.ReadFile(filepath.Join(target.Path(), "some-file"))
	c.Assert(err, gc.IsNil)
	c.Assert(string(data), gc.Equals, "mu!")
	conflicted, err = target.Conflicted()
	c.Assert(err, gc.IsNil)
	c.Assert(conflicted, gc.Equals, false)

	// Try to upgrade again.
	err = d.Deploy(target)
	c.Assert(err, gc.Equals, charm.ErrConflict)
	conflicted, err = target.Conflicted()
	c.Assert(err, gc.IsNil)
	c.Assert(conflicted, gc.Equals, true)
	s.checkCleanup(c, d)

	// And again.
	err = d.Deploy(target)
	c.Assert(err, gc.Equals, charm.ErrConflict)
	conflicted, err = target.Conflicted()
	c.Assert(err, gc.IsNil)
	c.Assert(conflicted, gc.Equals, true)
	s.checkCleanup(c, d)

	// Manually resolve, and commit.
	err = ioutil.WriteFile(filepath.Join(target.Path(), "some-file"), []byte("nu!"), 0644)
	c.Assert(err, gc.IsNil)
	err = target.Snapshotf("user resolved conflicts")
	c.Assert(err, gc.IsNil)
	conflicted, err = target.Conflicted()
	c.Assert(err, gc.IsNil)
	c.Assert(conflicted, gc.Equals, false)

	// Try a final upgrade to the same charm and check it doesn't write anything
	// except the upgrade log line.
	err = d.Deploy(target)
	c.Assert(err, gc.IsNil)
	s.checkCleanup(c, d)

	data, err = ioutil.ReadFile(filepath.Join(target.Path(), "some-file"))
	c.Assert(err, gc.IsNil)
	c.Assert(string(data), gc.Equals, "nu!")
	conflicted, err = target.Conflicted()
	c.Assert(err, gc.IsNil)
	c.Assert(conflicted, gc.Equals, false)
	lines, err := target.Log()
	c.Assert(err, gc.IsNil)
	c.Assert(lines[0], gc.Matches, `[0-9a-f]{7} Upgraded charm to "cs:s/c-2".`)
}

func (s *DeployerSuite) bundle(c *gc.C, customize func(path string)) *corecharm.Bundle {
	base := c.MkDir()
	dirpath := testing.Charms.ClonedDirPath(base, "dummy")
	customize(dirpath)
	dir, err := corecharm.ReadDir(dirpath)
	c.Assert(err, gc.IsNil)
	bunpath := filepath.Join(base, "bundle")
	file, err := os.Create(bunpath)
	c.Assert(err, gc.IsNil)
	defer file.Close()
	err = dir.BundleTo(file)
	c.Assert(err, gc.IsNil)
	bun, err := corecharm.ReadBundle(bunpath)
	c.Assert(err, gc.IsNil)
	return bun
}

func (s *DeployerSuite) checkCleanup(c *gc.C, d *charm.Deployer) {
	// Only one update dir should exist and be pointed to by the 'current'
	// symlink since extra ones should have been cleaned up by
	// cleanupOrphans.
	updateDirs, err := filepath.Glob(filepath.Join(d.Path(), "update-*"))
	c.Assert(err, gc.IsNil)
	c.Assert(updateDirs, gc.HasLen, 1)
	current, err := os.Readlink(d.Current().Path())
	c.Assert(err, gc.IsNil)
	c.Assert(updateDirs[0], gc.Equals, current)

	// No install dirs should be left behind since the one created is
	// renamed to the target path.
	installDirs, err := filepath.Glob(filepath.Join(d.Path(), "install-*"))
	c.Assert(err, gc.IsNil)
	c.Assert(installDirs, gc.HasLen, 0)
}
<commit_msg>- Make bundle and checkCleanup be standalone functions since they don't depend on DeployerSuite in any way.<commit_after>// Copyright 2012, 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package charm_test

import (
	"io/ioutil"
	gc "launchpad.net/gocheck"
	corecharm "launchpad.net/juju-core/charm"
	"launchpad.net/juju-core/testing"
	"launchpad.net/juju-core/worker/uniter/charm"
	"os"
	"path/filepath"
)

type DeployerSuite struct {
	testing.GitSuite
}

var _ = gc.Suite(&DeployerSuite{})

func (s *DeployerSuite) TestUnsetCharm(c *gc.C) {
	d := charm.NewDeployer(filepath.Join(c.MkDir(), "deployer"))
	err := d.Deploy(charm.NewGitDir(c.MkDir()))
	c.Assert(err, gc.ErrorMatches, "charm deployment failed: no charm set")
}

func (s *DeployerSuite) TestInstall(c *gc.C) {
	// Install.
	d := charm.NewDeployer(filepath.Join(c.MkDir(), "deployer"))
	bun := bundle(c, func(path string) {
		err := ioutil.WriteFile(filepath.Join(path, "some-file"), []byte("hello"), 0644)
		c.Assert(err, gc.IsNil)
	})
	err := d.Stage(bun, corecharm.MustParseURL("cs:s/c-1"))
	c.Assert(err, gc.IsNil)
	checkCleanup(c, d)

	target := charm.NewGitDir(filepath.Join(c.MkDir(), "target"))
	err = d.Deploy(target)
	c.Assert(err, gc.IsNil)
	checkCleanup(c, d)

	// Check content.
	data, err := ioutil.ReadFile(filepath.Join(target.Path(), "some-file"))
	c.Assert(err, gc.IsNil)
	c.Assert(string(data), gc.Equals, "hello")
	url, err := charm.ReadCharmURL(target)
	c.Assert(err, gc.IsNil)
	c.Assert(url, gc.DeepEquals, corecharm.MustParseURL("cs:s/c-1"))
	lines, err := target.Log()
	c.Assert(err, gc.IsNil)
	c.Assert(lines, gc.HasLen, 2)
	c.Assert(lines[0], gc.Matches, `[0-9a-f]{7} Deployed charm "cs:s/c-1".`)
	c.Assert(lines[1], gc.Matches, `[0-9a-f]{7} Imported charm "cs:s/c-1" from ".*".`)
}

func (s *DeployerSuite) TestUpgrade(c *gc.C) {
	// Install.
	d := charm.NewDeployer(filepath.Join(c.MkDir(), "deployer"))
	bun1 := bundle(c, func(path string) {
		err := ioutil.WriteFile(filepath.Join(path, "some-file"), []byte("hello"), 0644)
		c.Assert(err, gc.IsNil)
		err = os.Symlink("./some-file", filepath.Join(path, "a-symlink"))
		c.Assert(err, gc.IsNil)
	})
	err := d.Stage(bun1, corecharm.MustParseURL("cs:s/c-1"))
	c.Assert(err, gc.IsNil)
	target := charm.NewGitDir(filepath.Join(c.MkDir(), "target"))
	err = d.Deploy(target)
	c.Assert(err, gc.IsNil)

	// Upgrade.
	bun2 := bundle(c, func(path string) {
		err := ioutil.WriteFile(filepath.Join(path, "some-file"), []byte("goodbye"), 0644)
		c.Assert(err, gc.IsNil)
		err = ioutil.WriteFile(filepath.Join(path, "a-symlink"), []byte("not any more!"), 0644)
		c.Assert(err, gc.IsNil)
	})
	err = d.Stage(bun2, corecharm.MustParseURL("cs:s/c-2"))
	c.Assert(err, gc.IsNil)
	checkCleanup(c, d)

	err = d.Deploy(target)
	c.Assert(err, gc.IsNil)
	checkCleanup(c, d)

	// Check content.
	data, err := ioutil.ReadFile(filepath.Join(target.Path(), "some-file"))
	c.Assert(err, gc.IsNil)
	c.Assert(string(data), gc.Equals, "goodbye")
	data, err = ioutil.ReadFile(filepath.Join(target.Path(), "a-symlink"))
	c.Assert(err, gc.IsNil)
	c.Assert(string(data), gc.Equals, "not any more!")
	url, err := charm.ReadCharmURL(target)
	c.Assert(err, gc.IsNil)
	c.Assert(url, gc.DeepEquals, corecharm.MustParseURL("cs:s/c-2"))
	lines, err := target.Log()
	c.Assert(err, gc.IsNil)
	c.Assert(lines, gc.HasLen, 5)
	c.Assert(lines[0], gc.Matches, `[0-9a-f]{7} Upgraded charm to "cs:s/c-2".`)
}

func (s *DeployerSuite) TestConflict(c *gc.C) {
	// Install.
	d := charm.NewDeployer(filepath.Join(c.MkDir(), "deployer"))
	bun1 := bundle(c, func(path string) {
		err := ioutil.WriteFile(filepath.Join(path, "some-file"), []byte("hello"), 0644)
		c.Assert(err, gc.IsNil)
	})
	err := d.Stage(bun1, corecharm.MustParseURL("cs:s/c-1"))
	c.Assert(err, gc.IsNil)
	target := charm.NewGitDir(filepath.Join(c.MkDir(), "target"))
	err = d.Deploy(target)
	c.Assert(err, gc.IsNil)

	// Mess up target.
	err = ioutil.WriteFile(filepath.Join(target.Path(), "some-file"), []byte("mu!"), 0644)
	c.Assert(err, gc.IsNil)

	// Upgrade.
	bun2 := bundle(c, func(path string) {
		err := ioutil.WriteFile(filepath.Join(path, "some-file"), []byte("goodbye"), 0644)
		c.Assert(err, gc.IsNil)
	})
	err = d.Stage(bun2, corecharm.MustParseURL("cs:s/c-2"))
	c.Assert(err, gc.IsNil)
	err = d.Deploy(target)
	c.Assert(err, gc.Equals, charm.ErrConflict)
	checkCleanup(c, d)

	// Check state.
	conflicted, err := target.Conflicted()
	c.Assert(err, gc.IsNil)
	c.Assert(conflicted, gc.Equals, true)

	// Revert and check initial content.
	err = target.Revert()
	c.Assert(err, gc.IsNil)
	data, err := ioutil.ReadFile(filepath.Join(target.Path(), "some-file"))
	c.Assert(err, gc.IsNil)
	c.Assert(string(data), gc.Equals, "mu!")
	conflicted, err = target.Conflicted()
	c.Assert(err, gc.IsNil)
	c.Assert(conflicted, gc.Equals, false)

	// Try to upgrade again.
	err = d.Deploy(target)
	c.Assert(err, gc.Equals, charm.ErrConflict)
	conflicted, err = target.Conflicted()
	c.Assert(err, gc.IsNil)
	c.Assert(conflicted, gc.Equals, true)
	checkCleanup(c, d)

	// And again.
	err = d.Deploy(target)
	c.Assert(err, gc.Equals, charm.ErrConflict)
	conflicted, err = target.Conflicted()
	c.Assert(err, gc.IsNil)
	c.Assert(conflicted, gc.Equals, true)
	checkCleanup(c, d)

	// Manually resolve, and commit.
	err = ioutil.WriteFile(filepath.Join(target.Path(), "some-file"), []byte("nu!"), 0644)
	c.Assert(err, gc.IsNil)
	err = target.Snapshotf("user resolved conflicts")
	c.Assert(err, gc.IsNil)
	conflicted, err = target.Conflicted()
	c.Assert(err, gc.IsNil)
	c.Assert(conflicted, gc.Equals, false)

	// Try a final upgrade to the same charm and check it doesn't write anything
	// except the upgrade log line.
	err = d.Deploy(target)
	c.Assert(err, gc.IsNil)
	checkCleanup(c, d)

	data, err = ioutil.ReadFile(filepath.Join(target.Path(), "some-file"))
	c.Assert(err, gc.IsNil)
	c.Assert(string(data), gc.Equals, "nu!")
	conflicted, err = target.Conflicted()
	c.Assert(err, gc.IsNil)
	c.Assert(conflicted, gc.Equals, false)
	lines, err := target.Log()
	c.Assert(err, gc.IsNil)
	c.Assert(lines[0], gc.Matches, `[0-9a-f]{7} Upgraded charm to "cs:s/c-2".`)
}

func bundle(c *gc.C, customize func(path string)) *corecharm.Bundle {
	base := c.MkDir()
	dirpath := testing.Charms.ClonedDirPath(base, "dummy")
	customize(dirpath)
	dir, err := corecharm.ReadDir(dirpath)
	c.Assert(err, gc.IsNil)
	bunpath := filepath.Join(base, "bundle")
	file, err := os.Create(bunpath)
	c.Assert(err, gc.IsNil)
	defer file.Close()
	err = dir.BundleTo(file)
	c.Assert(err, gc.IsNil)
	bun, err := corecharm.ReadBundle(bunpath)
	c.Assert(err, gc.IsNil)
	return bun
}

func checkCleanup(c *gc.C, d *charm.Deployer) {
	// Only one update dir should exist and be pointed to by the 'current'
	// symlink since extra ones should have been cleaned up by
	// cleanupOrphans.
	updateDirs, err := filepath.Glob(filepath.Join(d.Path(), "update-*"))
	c.Assert(err, gc.IsNil)
	c.Assert(updateDirs, gc.HasLen, 1)
	current, err := os.Readlink(d.Current().Path())
	c.Assert(err, gc.IsNil)
	c.Assert(updateDirs[0], gc.Equals, current)

	// No install dirs should be left behind since the one created is
	// renamed to the target path.
	installDirs, err := filepath.Glob(filepath.Join(d.Path(), "install-*"))
	c.Assert(err, gc.IsNil)
	c.Assert(installDirs, gc.HasLen, 0)
}
<|endoftext|>