<commit_before>package redis

import (
	"github.com/weisd/cache"
	"testing"
)

func TestRedisCache(t *testing.T) {
	var err error
	c, err := cache.New(cache.Options{Adapter: "redis", AdapterConfig: `{"Addr":":6379"}`, Section: "test"})
	if err != nil {
		t.Fatal(err)
	}

	err = c.Put("da", "weisd", 300)
	if err != nil {
		t.Fatal(err)
	}

	res := c.Get("da")

	if res != "weisd" {
		t.Fatal("sdf")
	}

	t.Log("ok")
	t.Log("test", res)

	err = c.Tags([]string{"dd"}).Put("da", "weisd", 300)
	if err != nil {
		t.Fatal(err)
	}
	res = c.Tags([]string{"dd"}).Get("da")

	if res != "weisd" {
		t.Fatal("not weisd")
	}

	t.Log("ok")
	t.Log("dd", res)

	err = c.Tags([]string{"aa"}).Put("aa", "aaa", 300)
	if err != nil {
		t.Fatal(err)
	}

	err = c.Tags([]string{"aa"}).Put("bb", "bbb", 300)
	if err != nil {
		t.Fatal(err)
	}

	res = c.Tags([]string{"aa"}).Get("aa")

	if res != "aaa" {
		t.Fatal("not aaa")
	}

	t.Log("ok")
	t.Log("aa", res)

	err = c.Tags([]string{"aa"}).Flush()
	if err != nil {
		t.Fatal(err)
	}

	res = c.Tags([]string{"aa"}).Get("aa")
	if res != "" {
		t.Fatal("flush faield")
	}

	res = c.Tags([]string{"aa"}).Get("bb")
	if res != "" {
		t.Fatal("flush faield")
	}

	res = c.Tags([]string{"dd"}).Get("da")
	if res != "weisd" {
		t.Fatal("not weisd")
	}

	t.Log("ok")

	c.Flush()

	res = c.Get("da")
	if res != "" {
		t.Fatal("flush failed")
	}

	t.Log("get dd da", res)

}
<commit_msg>Update redis_test.go<commit_after>package redis

import (
	"github.com/vodka-contrib/cache"
	"testing"
)

func TestRedisCache(t *testing.T) {
	var err error
	c, err := cache.New(cache.Options{Adapter: "redis", AdapterConfig: `{"Addr":":6379"}`, Section: "test"})
	if err != nil {
		t.Fatal(err)
	}

	err = c.Put("da", "weisd", 300)
	if err != nil {
		t.Fatal(err)
	}

	res := c.Get("da")

	if res != "weisd" {
		t.Fatal("sdf")
	}

	t.Log("ok")
	t.Log("test", res)

	err = c.Tags([]string{"dd"}).Put("da", "weisd", 300)
	if err != nil {
		t.Fatal(err)
	}
	res = c.Tags([]string{"dd"}).Get("da")

	if res != "weisd" {
		t.Fatal("not weisd")
	}

	t.Log("ok")
	t.Log("dd", res)

	err = c.Tags([]string{"aa"}).Put("aa", "aaa", 300)
	if err != nil {
		t.Fatal(err)
	}

	err = c.Tags([]string{"aa"}).Put("bb", "bbb", 300)
	if err != nil {
		t.Fatal(err)
	}

	res = c.Tags([]string{"aa"}).Get("aa")

	if res != "aaa" {
		t.Fatal("not aaa")
	}

	t.Log("ok")
	t.Log("aa", res)

	err = c.Tags([]string{"aa"}).Flush()
	if err != nil {
		t.Fatal(err)
	}

	res = c.Tags([]string{"aa"}).Get("aa")
	if res != "" {
		t.Fatal("flush faield")
	}

	res = c.Tags([]string{"aa"}).Get("bb")
	if res != "" {
		t.Fatal("flush faield")
	}

	res = c.Tags([]string{"dd"}).Get("da")
	if res != "weisd" {
		t.Fatal("not weisd")
	}

	t.Log("ok")

	c.Flush()

	res = c.Get("da")
	if res != "" {
		t.Fatal("flush failed")
	}

	t.Log("get dd da", res)

}
<|endoftext|>


<commit_before>package server

import (
	"fmt"
	"github.com/siddontang/go-log/log"
	"github.com/siddontang/ledisdb/ledis"
	"io"
	"net/http"
	"strconv"
	"strings"

	"encoding/json"
	"github.com/ugorji/go/codec"
	"gopkg.in/mgo.v2/bson"
)

var allowedContentTypes = map[string]struct{}{
	"json":    struct{}{},
	"bson":    struct{}{},
	"msgpack": struct{}{},
}

type httpClient struct {
	app *App
	db  *ledis.DB
	ldb *ledis.Ledis

	resp responseWriter
	req  *requestContext
}

type httpWriter struct {
	contentType string
	cmd         string
	w           http.ResponseWriter
}

// http context

func newClientHTTP(app *App, w http.ResponseWriter, r *http.Request) {
	var err error
	c := new(httpClient)
	c.app = app
	c.ldb = app.ldb
	c.db, err = c.ldb.Select(0)
	if err != nil {
		w.Write([]byte(err.Error()))
		return
	}

	c.req, err = c.makeRequest(app, r, w)
	if err != nil {
		w.Write([]byte(err.Error()))
		return
	}
	c.req.perform()
}

func (c *httpClient) addr(r *http.Request) string {
	addr := r.Header.Get("X-Forwarded-For")
	if addr == "" {
		addr = r.Header.Get("X-Real-IP")
		if addr == "" {
			addr = r.Header.Get("Remote-Addr")
		}
	}
	return addr
}

func (c *httpClient) makeRequest(app *App, r *http.Request, w http.ResponseWriter) (*requestContext, error) {
	var err error

	db, cmd, argsStr, contentType := c.parseReqPath(r)

	c.db, err = app.ldb.Select(db)
	if err != nil {
		return nil, err
	}

	contentType = strings.ToLower(contentType)

	if _, ok := allowedContentTypes[contentType]; !ok {
		return nil, fmt.Errorf("unsupported content type: '%s', only json, bson, msgpack are supported", contentType)
	}

	req := newRequestContext(app)
	args := make([][]byte, len(argsStr))
	for i, arg := range argsStr {
		args[i] = []byte(arg)
	}

	req.cmd = strings.ToLower(cmd)
	req.args = args
	req.remoteAddr = c.addr(r)
	req.resp = &httpWriter{contentType, cmd, w}
	return req, nil
}

func (c *httpClient) parseReqPath(r *http.Request) (db int, cmd string, args []string, contentType string) {

	contentType = r.FormValue("type")
	if contentType == "" {
		contentType = "json"
	}

	substrings := strings.Split(strings.TrimLeft(r.URL.Path, "/"), "/")
	if len(substrings) == 1 {
		return 0, substrings[0], substrings[1:], contentType
	}
	db, err := strconv.Atoi(substrings[0])
	if err != nil {
		cmd = substrings[0]
		args = substrings[1:]
	} else {
		cmd = substrings[1]
		args = substrings[2:]
	}

	return
}

// http writer

func (w *httpWriter) genericWrite(result interface{}) {

	m := map[string]interface{}{
		w.cmd: result,
	}
	switch w.contentType {
	case "json":
		writeJSON(&m, w.w)
	case "bson":
		writeBSON(&m, w.w)
	case "msgpack":
		writeMsgPack(&m, w.w)
	default:
		log.Error("invalid content type %s", w.contentType)
	}
}

func (w *httpWriter) writeError(err error) {
	result := [2]interface{}{
		false,
		fmt.Sprintf("ERR %s", err.Error()),
	}
	w.genericWrite(result)
}

func (w *httpWriter) writeStatus(status string) {
	var success bool
	if status == OK || status == PONG {
		success = true
	}
	w.genericWrite([]interface{}{success, status})
}

func (w *httpWriter) writeInteger(n int64) {
	w.genericWrite(n)
}

func (w *httpWriter) writeBulk(b []byte) {
	if b == nil {
		w.genericWrite(nil)
	} else {
		w.genericWrite(ledis.String(b))
	}
}

func (w *httpWriter) writeArray(lst []interface{}) {
	w.genericWrite(lst)
}

func (w *httpWriter) writeSliceArray(lst [][]byte) {
	arr := make([]interface{}, len(lst))
	for i, elem := range lst {
		if elem == nil {
			arr[i] = nil
		} else {
			arr[i] = ledis.String(elem)
		}
	}
	w.genericWrite(arr)
}

func (w *httpWriter) writeFVPairArray(lst []ledis.FVPair) {
	m := make(map[string]string)
	for _, elem := range lst {
		m[ledis.String(elem.Field)] = ledis.String(elem.Value)
	}
	w.genericWrite(m)
}

func (w *httpWriter) writeScorePairArray(lst []ledis.ScorePair, withScores bool) {
	var arr []string
	if withScores {
		arr = make([]string, 2*len(lst))
		for i, data := range lst {
			arr[2*i] = ledis.String(data.Member)
			arr[2*i+1] = strconv.FormatInt(data.Score, 10)
		}
	} else {
		arr = make([]string, len(lst))
		for i, data := range lst {
			arr[i] = ledis.String(data.Member)
		}
	}
	w.genericWrite(arr)
}

func (w *httpWriter) writeBulkFrom(n int64, rb io.Reader) {
	w.writeError(fmt.Errorf("unsuport"))
}

func (w *httpWriter) flush() {

}

func writeJSON(resutl interface{}, w http.ResponseWriter) {
	buf, err := json.Marshal(resutl)
	if err != nil {
		log.Error(err.Error())
		return
	}

	w.Header().Set("Content-type", "application/json; charset=utf-8")
	w.Header().Set("Content-Length", strconv.Itoa(len(buf)))

	_, err = w.Write(buf)
	if err != nil {
		log.Error(err.Error())
	}
}

func writeBSON(result interface{}, w http.ResponseWriter) {
	buf, err := bson.Marshal(result)
	if err != nil {
		log.Error(err.Error())
		return
	}

	w.Header().Set("Content-type", "application/octet-stream")
	w.Header().Set("Content-Length", strconv.Itoa(len(buf)))

	_, err = w.Write(buf)
	if err != nil {
		log.Error(err.Error())
	}
}

func writeMsgPack(result interface{}, w http.ResponseWriter) {
	w.Header().Set("Content-type", "application/octet-stream")

	var mh codec.MsgpackHandle
	enc := codec.NewEncoder(w, &mh)
	if err := enc.Encode(result); err != nil {
		log.Error(err.Error())
	}
}
<commit_msg>http interface: not support cmds of repl<commit_after>package server

import (
	"fmt"
	"github.com/siddontang/go-log/log"
	"github.com/siddontang/ledisdb/ledis"
	"io"
	"net/http"
	"strconv"
	"strings"

	"encoding/json"
	"github.com/ugorji/go/codec"
	"gopkg.in/mgo.v2/bson"
)

var allowedContentTypes = map[string]struct{}{
	"json":    struct{}{},
	"bson":    struct{}{},
	"msgpack": struct{}{},
}

type httpClient struct {
	app *App
	db  *ledis.DB
	ldb *ledis.Ledis

	resp responseWriter
	req  *requestContext
}

type httpWriter struct {
	contentType string
	cmd         string
	w           http.ResponseWriter
}

func newClientHTTP(app *App, w http.ResponseWriter, r *http.Request) {
	var err error
	c := new(httpClient)
	c.app = app
	c.ldb = app.ldb
	c.db, err = c.ldb.Select(0)
	if err != nil {
		w.Write([]byte(err.Error()))
		return
	}

	c.req, err = c.makeRequest(app, r, w)
	if err != nil {
		w.Write([]byte(err.Error()))
		return
	}
	c.req.perform()
}

func (c *httpClient) addr(r *http.Request) string {
	addr := r.Header.Get("X-Forwarded-For")
	if addr == "" {
		addr = r.Header.Get("X-Real-IP")
		if addr == "" {
			addr = r.Header.Get("Remote-Addr")
		}
	}
	return addr
}

func (c *httpClient) makeRequest(app *App, r *http.Request, w http.ResponseWriter) (*requestContext, error) {
	var err error

	db, cmd, argsStr, contentType := c.parseReqPath(r)

	c.db, err = app.ldb.Select(db)
	if err != nil {
		return nil, err
	}

	contentType = strings.ToLower(contentType)

	if _, ok := allowedContentTypes[contentType]; !ok {
		return nil, fmt.Errorf("unsupported content type: '%s', only json, bson, msgpack are supported", contentType)
	}

	req := newRequestContext(app)
	args := make([][]byte, len(argsStr))
	for i, arg := range argsStr {
		args[i] = []byte(arg)
	}

	req.cmd = strings.ToLower(cmd)

	if req.cmd == "slaveof" || req.cmd == "fullsync" || req.cmd == "sync" {
		return nil, fmt.Errorf("unsupported command: '%s'", cmd)
	}

	req.remoteAddr = c.addr(r)
	req.resp = &httpWriter{contentType, cmd, w}
	return req, nil
}

func (c *httpClient) parseReqPath(r *http.Request) (db int, cmd string, args []string, contentType string) {

	contentType = r.FormValue("type")
	if contentType == "" {
		contentType = "json"
	}

	substrings := strings.Split(strings.TrimLeft(r.URL.Path, "/"), "/")
	if len(substrings) == 1 {
		return 0, substrings[0], substrings[1:], contentType
	}
	db, err := strconv.Atoi(substrings[0])
	if err != nil {
		cmd = substrings[0]
		args = substrings[1:]
	} else {
		cmd = substrings[1]
		args = substrings[2:]
	}

	return
}

// http writer

func (w *httpWriter) genericWrite(result interface{}) {

	m := map[string]interface{}{
		w.cmd: result,
	}
	switch w.contentType {
	case "json":
		writeJSON(&m, w.w)
	case "bson":
		writeBSON(&m, w.w)
	case "msgpack":
		writeMsgPack(&m, w.w)
	default:
		log.Error("invalid content type %s", w.contentType)
	}
}

func (w *httpWriter) writeError(err error) {
	result := [2]interface{}{
		false,
		fmt.Sprintf("ERR %s", err.Error()),
	}
	w.genericWrite(result)
}

func (w *httpWriter) writeStatus(status string) {
	var success bool
	if status == OK || status == PONG {
		success = true
	}
	w.genericWrite([]interface{}{success, status})
}

func (w *httpWriter) writeInteger(n int64) {
	w.genericWrite(n)
}

func (w *httpWriter) writeBulk(b []byte) {
	if b == nil {
		w.genericWrite(nil)
	} else {
		w.genericWrite(ledis.String(b))
	}
}

func (w *httpWriter) writeArray(lst []interface{}) {
	w.genericWrite(lst)
}

func (w *httpWriter) writeSliceArray(lst [][]byte) {
	arr := make([]interface{}, len(lst))
	for i, elem := range lst {
		if elem == nil {
			arr[i] = nil
		} else {
			arr[i] = ledis.String(elem)
		}
	}
	w.genericWrite(arr)
}

func (w *httpWriter) writeFVPairArray(lst []ledis.FVPair) {
	m := make(map[string]string)
	for _, elem := range lst {
		m[ledis.String(elem.Field)] = ledis.String(elem.Value)
	}
	w.genericWrite(m)
}

func (w *httpWriter) writeScorePairArray(lst []ledis.ScorePair, withScores bool) {
	var arr []string
	if withScores {
		arr = make([]string, 2*len(lst))
		for i, data := range lst {
			arr[2*i] = ledis.String(data.Member)
			arr[2*i+1] = strconv.FormatInt(data.Score, 10)
		}
	} else {
		arr = make([]string, len(lst))
		for i, data := range lst {
			arr[i] = ledis.String(data.Member)
		}
	}
	w.genericWrite(arr)
}

func (w *httpWriter) writeBulkFrom(n int64, rb io.Reader) {
	w.writeError(fmt.Errorf("unsuport"))
}

func (w *httpWriter) flush() {

}

func writeJSON(resutl interface{}, w http.ResponseWriter) {
	buf, err := json.Marshal(resutl)
	if err != nil {
		log.Error(err.Error())
		return
	}

	w.Header().Set("Content-type", "application/json; charset=utf-8")
	w.Header().Set("Content-Length", strconv.Itoa(len(buf)))

	_, err = w.Write(buf)
	if err != nil {
		log.Error(err.Error())
	}
}

func writeBSON(result interface{}, w http.ResponseWriter) {
	buf, err := bson.Marshal(result)
	if err != nil {
		log.Error(err.Error())
		return
	}

	w.Header().Set("Content-type", "application/octet-stream")
	w.Header().Set("Content-Length", strconv.Itoa(len(buf)))

	_, err = w.Write(buf)
	if err != nil {
		log.Error(err.Error())
	}
}

func writeMsgPack(result interface{}, w http.ResponseWriter) {
	w.Header().Set("Content-type", "application/octet-stream")

	var mh codec.MsgpackHandle
	enc := codec.NewEncoder(w, &mh)
	if err := enc.Encode(result); err != nil {
		log.Error(err.Error())
	}
}
<|endoftext|>


<commit_before>package medias

import (
	"errors"
	"fmt"
	"reflect"
)
/**
The global attributes for a Media
 */
type Media struct {
	ID      int    `json:"id"`
	Name    string `json:"name"`
	Styles []string `json:"styles"`
	Components []MediaPlugin `json:"components"`
}

type MediaConfig struct {
	Styles []string `json:"styles"`
}

/**
Properties and configuration for a plugin used in the media
 */
type MediaPlugin struct {
	ComponentName       string `json:"componentName"`
	EltName    string `json:"eltName"`
	Files      []string `json:"files"`
	PropValues map[string]interface{} `json:"propValues"` //MediaPluginProps `json:"propValues"`
}

/**
Because we don't know what will compounds the props for a plugin, we use a map[string] interface{}
 */
type MediaPluginProps struct {
	X map[string]interface{} `json:"-"` //map[string]string
}

func SetField(obj interface{}, name string, value interface{}) error {
	structValue := reflect.ValueOf(obj).Elem()
	structFieldValue := structValue.FieldByName(name)

	if !structFieldValue.IsValid() {
		return fmt.Errorf("No such field: %s in obj", name)
	}

	if !structFieldValue.CanSet() {
		return fmt.Errorf("Cannot set %s field value", name)
	}

	structFieldType := structFieldValue.Type()
	val := reflect.ValueOf(value)
	if structFieldType != val.Type() {
		return errors.New("Provided value type didn't match obj field type")
	}

	structFieldValue.Set(val)
	return nil
}

func (s *Media) FillStruct(m map[string]interface{}) error {
	for k, v := range m {
		err := SetField(s, k, v)
		if err != nil {
			return err
		}
	}
	return nil
}<commit_msg>[Fix] New format<commit_after>package medias

import (
	"errors"
	"fmt"
	"reflect"
)

/**
The global attributes for a Media
 */
type Media struct {
	ID          string `json:"id"`
	Name        string `json:"name"`
	Description string `json:"description"`
	Rows        int `json:"rows"`
	Cols        int `json:"cols"`
	Styles      []string `json:"styles-var"`
	Plugins     []MediaPlugin `json:"plugins"`
}

/**
Properties and configuration for a plugin used in the media
 */
type MediaPlugin struct {
	InstanceId string `json:"instanceId"`
	Name       string `json:"name"`
	FrontEnd   MediaPluginFrontEnd `json:"front-end"`
	BackEnd    MediaPluginBackEnd `json:"back-end"`
}

type MediaPluginFrontEnd struct {
	Files   []string `json:"files"`
	EltName string `json:"eltName"`
	X       int `json:"x"`
	Y       int `json:"y"`
	Rows    int `json:"rows"`
	Cols    int `json:"cols"`
	Props   map[string]interface{} `json:"props"`
}

type MediaPluginBackEnd struct {
	Ports []int `json:"ports"`
	Props map[string]interface{} `json:"props"`
}

/**
Because we don't know what will compounds the props for a plugin, we use a map[string] interface{}
 */
type MediaPluginProps struct {
	X map[string]interface{} `json:"-"` //map[string]string
}

func SetField(obj interface{}, name string, value interface{}) error {
	structValue := reflect.ValueOf(obj).Elem()
	structFieldValue := structValue.FieldByName(name)

	if !structFieldValue.IsValid() {
		return fmt.Errorf("No such field: %s in obj", name)
	}

	if !structFieldValue.CanSet() {
		return fmt.Errorf("Cannot set %s field value", name)
	}

	structFieldType := structFieldValue.Type()
	val := reflect.ValueOf(value)
	if structFieldType != val.Type() {
		return errors.New("Provided value type didn't match obj field type")
	}

	structFieldValue.Set(val)
	return nil
}

func (s *Media) FillStruct(m map[string]interface{}) error {
	for k, v := range m {
		err := SetField(s, k, v)
		if err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package fs

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"sync"

	"github.com/pkg/errors"
)

var (
	bufferPool = &sync.Pool{
		New: func() interface{} {
			return make([]byte, 32*1024)
		},
	}
)

// CopyDir copies the directory from src to dst.
// Most efficient copy of files is attempted.
func CopyDir(dst, src string) error {
	inodes := map[uint64]string{}
	return copyDirectory(dst, src, inodes)
}

func copyDirectory(dst, src string, inodes map[uint64]string) error {
	stat, err := os.Stat(src)
	if err != nil {
		return errors.Wrapf(err, "failed to stat %s", src)
	}
	if !stat.IsDir() {
		return errors.Errorf("source is not directory")
	}

	if st, err := os.Stat(dst); err != nil {
		if err := os.Mkdir(dst, stat.Mode()); err != nil {
			return errors.Wrapf(err, "failed to mkdir %s", dst)
		}
	} else if !st.IsDir() {
		return errors.Errorf("cannot copy to non-directory: %s", dst)
	} else {
		if err := os.Chmod(dst, stat.Mode()); err != nil {
			return errors.Wrapf(err, "failed to chmod on %s", dst)
		}
	}

	fis, err := ioutil.ReadDir(src)
	if err != nil {
		return errors.Wrapf(err, "failed to read %s", src)
	}

	if err := copyFileInfo(stat, dst); err != nil {
		return errors.Wrapf(err, "failed to copy file info for %s", dst)
	}

	for _, fi := range fis {
		source := filepath.Join(src, fi.Name())
		target := filepath.Join(dst, fi.Name())

		switch {
		case fi.IsDir():
			if err := copyDirectory(target, source, inodes); err != nil {
				return err
			}
			continue
		case (fi.Mode() & os.ModeType) == 0:
			link, err := GetLinkSource(target, fi, inodes)
			if err != nil {
				return errors.Wrap(err, "failed to get hardlink")
			}
			if link != "" {
				if err := os.Link(link, target); err != nil {
					return errors.Wrap(err, "failed to create hard link")
				}
			} else if err := copyFile(source, target); err != nil {
				return errors.Wrap(err, "failed to copy files")
			}
		case (fi.Mode() & os.ModeSymlink) == os.ModeSymlink:
			link, err := os.Readlink(source)
			if err != nil {
				return errors.Wrapf(err, "failed to read link: %s", source)
			}
			if err := os.Symlink(link, target); err != nil {
				return errors.Wrapf(err, "failed to create symlink: %s", target)
			}
		case (fi.Mode() & os.ModeDevice) == os.ModeDevice:
			if err := copyDevice(target, fi); err != nil {
				return errors.Wrapf(err, "failed to create device")
			}
		default:
			// TODO: Support pipes and sockets
			return errors.Wrapf(err, "unsupported mode %s", fi.Mode())
		}
		if err := copyFileInfo(fi, target); err != nil {
			return errors.Wrap(err, "failed to copy file info")
		}

		if err := copyXAttrs(target, source); err != nil {
			return errors.Wrap(err, "failed to copy xattrs")
		}
	}

	return nil
}

func copyFile(source, target string) error {
	src, err := os.Open(source)
	if err != nil {
		return errors.Wrapf(err, "failed to open source %s", err)
	}
	defer src.Close()
	tgt, err := os.Create(target)
	if err != nil {
		return errors.Wrapf(err, "failed to open target %s", err)
	}
	defer tgt.Close()

	return copyFileContent(tgt, src)
}
<commit_msg>fix copyFile error message<commit_after>package fs

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"sync"

	"github.com/pkg/errors"
)

var (
	bufferPool = &sync.Pool{
		New: func() interface{} {
			return make([]byte, 32*1024)
		},
	}
)

// CopyDir copies the directory from src to dst.
// Most efficient copy of files is attempted.
func CopyDir(dst, src string) error {
	inodes := map[uint64]string{}
	return copyDirectory(dst, src, inodes)
}

func copyDirectory(dst, src string, inodes map[uint64]string) error {
	stat, err := os.Stat(src)
	if err != nil {
		return errors.Wrapf(err, "failed to stat %s", src)
	}
	if !stat.IsDir() {
		return errors.Errorf("source is not directory")
	}

	if st, err := os.Stat(dst); err != nil {
		if err := os.Mkdir(dst, stat.Mode()); err != nil {
			return errors.Wrapf(err, "failed to mkdir %s", dst)
		}
	} else if !st.IsDir() {
		return errors.Errorf("cannot copy to non-directory: %s", dst)
	} else {
		if err := os.Chmod(dst, stat.Mode()); err != nil {
			return errors.Wrapf(err, "failed to chmod on %s", dst)
		}
	}

	fis, err := ioutil.ReadDir(src)
	if err != nil {
		return errors.Wrapf(err, "failed to read %s", src)
	}

	if err := copyFileInfo(stat, dst); err != nil {
		return errors.Wrapf(err, "failed to copy file info for %s", dst)
	}

	for _, fi := range fis {
		source := filepath.Join(src, fi.Name())
		target := filepath.Join(dst, fi.Name())

		switch {
		case fi.IsDir():
			if err := copyDirectory(target, source, inodes); err != nil {
				return err
			}
			continue
		case (fi.Mode() & os.ModeType) == 0:
			link, err := GetLinkSource(target, fi, inodes)
			if err != nil {
				return errors.Wrap(err, "failed to get hardlink")
			}
			if link != "" {
				if err := os.Link(link, target); err != nil {
					return errors.Wrap(err, "failed to create hard link")
				}
			} else if err := copyFile(source, target); err != nil {
				return errors.Wrap(err, "failed to copy files")
			}
		case (fi.Mode() & os.ModeSymlink) == os.ModeSymlink:
			link, err := os.Readlink(source)
			if err != nil {
				return errors.Wrapf(err, "failed to read link: %s", source)
			}
			if err := os.Symlink(link, target); err != nil {
				return errors.Wrapf(err, "failed to create symlink: %s", target)
			}
		case (fi.Mode() & os.ModeDevice) == os.ModeDevice:
			if err := copyDevice(target, fi); err != nil {
				return errors.Wrapf(err, "failed to create device")
			}
		default:
			// TODO: Support pipes and sockets
			return errors.Wrapf(err, "unsupported mode %s", fi.Mode())
		}
		if err := copyFileInfo(fi, target); err != nil {
			return errors.Wrap(err, "failed to copy file info")
		}

		if err := copyXAttrs(target, source); err != nil {
			return errors.Wrap(err, "failed to copy xattrs")
		}
	}

	return nil
}

func copyFile(source, target string) error {
	src, err := os.Open(source)
	if err != nil {
		return errors.Wrapf(err, "failed to open source %s", source)
	}
	defer src.Close()
	tgt, err := os.Create(target)
	if err != nil {
		return errors.Wrapf(err, "failed to open target %s", target)
	}
	defer tgt.Close()

	return copyFileContent(tgt, src)
}
<|endoftext|>


<commit_before>package dap

import (
	"errors"
	"strings"

	"getmelange.com/dap/wire"

	"airdispat.ch/identity"
	"airdispat.ch/message"
	"code.google.com/p/goprotobuf/proto"
)

const codePrefix = "DAP-"

type Delegate interface {
	// Account
	Register(addr string, keys map[string][]byte) error
	Unregister(addr string, keys map[string][]byte) error
	// Message
	GetMessages(since uint64, owner string, context bool) ([]*ResponseMessage, error)
	PublishMessage(name string, to []string, author string, message *message.EncryptedMessage, alerted bool) error
	UpdateMessage(name string, author string, message *message.EncryptedMessage) error
	// Data
	GetData(owner string, key string) ([]byte, error)
	SetData(owner string, key string, data []byte) error
}

type Handler struct {
	Key      *identity.Identity
	Delegate Delegate
}

// Handle Type
func (h *Handler) HandlesType(typ string) bool {
	return strings.HasPrefix(typ, codePrefix)
}

// Handle the DAP Request
func (h *Handler) HandleMessage(typ string, data []byte, head message.Header) ([]message.Message, error) {
	// I love that Golang doesn't have Generics. I promise!
	switch typ {
	case wire.RegisterCode:
		// Handle Registration
		unmarsh := &wire.Register{}
		err := proto.Unmarshal(data, unmarsh)
		if err != nil {
			return nil, err
		}
		return h.Register(unmarsh, head)
	case wire.UnregisterCode:
		// Handle Unregistration
		unmarsh := &wire.Unregister{}
		err := proto.Unmarshal(data, unmarsh)
		if err != nil {
			return nil, err
		}
		return h.Unregister(unmarsh, head)
	case wire.DownloadMessagesCode:
		// Handle DownloadMessages
		unmarsh := &wire.DownloadMessages{}
		err := proto.Unmarshal(data, unmarsh)
		if err != nil {
			return nil, err
		}
		return h.DownloadMessages(unmarsh, head)
	case wire.PublishMessageCode:
		// Handle PublishMessage
		unmarsh := &wire.PublishMessage{}
		err := proto.Unmarshal(data, unmarsh)
		if err != nil {
			return nil, err
		}
		return h.PublishMessage(unmarsh, head)
	case wire.UpdateMessageCode:
		// Handle UpdateMessage
		unmarsh := &wire.UpdateMessage{}
		err := proto.Unmarshal(data, unmarsh)
		if err != nil {
			return nil, err
		}
		return h.UpdateMessage(unmarsh, head)
	case wire.DataCode:
		// Handle Data
		unmarsh := &wire.Data{}
		err := proto.Unmarshal(data, unmarsh)
		if err != nil {
			return nil, err
		}
		return h.Data(unmarsh, head)
	case wire.GetDataCode:
		// Handle GetData
		unmarsh := &wire.GetData{}
		err := proto.Unmarshal(data, unmarsh)
		if err != nil {
			return nil, err
		}
		return h.GetData(unmarsh, head)
	}
	return nil, errors.New("Cannot handle type. That shouldn't happen.")
}

// Register a User on the Delegate
func (h *Handler) Register(r *wire.Register, head message.Header) ([]message.Message, error) {
	data := make(map[string][]byte)
	for _, v := range r.GetKeys() {
		data[v.GetKey()] = v.GetData()
	}
	err := h.Delegate.Register(head.From.String(), data)
	if err != nil {
		return nil, err
	}
	return CreateResponse(0, "OK", h.Key.Address, head.From), nil
}

// Unregister a User on the Delegate
func (h *Handler) Unregister(r *wire.Unregister, head message.Header) ([]message.Message, error) {
	data := make(map[string][]byte)
	for _, v := range r.GetKeys() {
		data[v.GetKey()] = v.GetData()
	}
	err := h.Delegate.Unregister(head.From.String(), data)
	if err != nil {
		return nil, err
	}
	return CreateResponse(0, "OK", h.Key.Address, head.From), nil
}

// Return all Messages received after `since` in sequence.
func (h *Handler) DownloadMessages(r *wire.DownloadMessages, head message.Header) ([]message.Message, error) {
	responses, err := h.Delegate.GetMessages(r.GetSince(), head.From.String(), r.GetContext())
	if err != nil {
		return nil, err
	}

	out := make([]message.Message, len(responses))
	for i, v := range responses {
		out[i] = v
	}

	return CreateResponse(0, "OK", h.Key.Address, head.From, out...), nil
}

// Publish a message on Delegate.
func (h *Handler) PublishMessage(r *wire.PublishMessage, head message.Header) ([]message.Message, error) {
	msg, err := message.CreateEncryptedMessageFromBytes(r.GetData())
	if err != nil {
		return nil, err
	}

	// Name, To, Author, Message
	err = h.Delegate.PublishMessage(r.GetName(), r.GetTo(), head.From.String(), msg, r.GetAlert())
	if err != nil {
		return nil, err
	}

	return CreateResponse(0, "OK", h.Key.Address, head.From), nil
}

// Update a message on Delegate.
func (h *Handler) UpdateMessage(r *wire.UpdateMessage, head message.Header) ([]message.Message, error) {
	msg, err := message.CreateEncryptedMessageFromBytes(r.GetData())
	if err != nil {
		return nil, err
	}

	// Name, To, Author, Message
	err = h.Delegate.UpdateMessage(r.GetName(), head.From.String(), msg)
	if err != nil {
		return nil, err
	}

	return CreateResponse(0, "OK", h.Key.Address, head.From), nil
}

// Set Data
func (h *Handler) Data(r *wire.Data, head message.Header) ([]message.Message, error) {
	err := h.Delegate.SetData(head.From.String(), r.GetKey(), r.GetData())
	if err != nil {
		return nil, err
	}

	return CreateResponse(0, "OK", h.Key.Address, head.From), nil
}

// Get Data
func (h *Handler) GetData(r *wire.GetData, head message.Header) ([]message.Message, error) {
	data, err := h.Delegate.GetData(head.From.String(), r.GetKey())
	if err != nil {
		return nil, err
	}

	return CreateDataResponse(0, "OK", h.Key.Address, head.From, data), nil
}
<commit_msg>Implemented DAP Hash-As-You-Go<commit_after>package dap

import (
	"bytes"
	"errors"
	"hash"
	"io"
	"net"
	"strings"

	"getmelange.com/dap/wire"

	"crypto/sha256"

	"airdispat.ch/identity"
	"airdispat.ch/message"
	"code.google.com/p/goprotobuf/proto"
)

const codePrefix = "DAP-"

type Delegate interface {
	// Account
	Register(addr string, keys map[string][]byte) error
	Unregister(addr string, keys map[string][]byte) error
	// Message
	GetMessages(since uint64, owner string, context bool) ([]*ResponseMessage, error)
	PublishMessage(name string, to []string, author string, message *message.EncryptedMessage, alerted bool) error
	UpdateMessage(name string, author string, message *message.EncryptedMessage) error
	// AD Data
	PublishDataMessage(name string, to []string, author string, message *message.EncryptedMessage, length uint64, r ReadVerifier) error
	// Data
	GetData(owner string, key string) ([]byte, error)
	SetData(owner string, key string, data []byte) error
}

type ReadVerifier interface {
	io.Reader
	Verify() bool
}

type Handler struct {
	Key      *identity.Identity
	Delegate Delegate
}

// Handle Type
func (h *Handler) HandlesType(typ string) bool {
	return strings.HasPrefix(typ, codePrefix)
}

// Handle the DAP Request
func (h *Handler) HandleMessage(typ string, data []byte, head message.Header, conn net.Conn) ([]message.Message, error) {
	// I love that Golang doesn't have Generics. I promise!
	switch typ {
	case wire.RegisterCode:
		// Handle Registration
		unmarsh := &wire.Register{}
		err := proto.Unmarshal(data, unmarsh)
		if err != nil {
			return nil, err
		}
		return h.Register(unmarsh, head)
	case wire.UnregisterCode:
		// Handle Unregistration
		unmarsh := &wire.Unregister{}
		err := proto.Unmarshal(data, unmarsh)
		if err != nil {
			return nil, err
		}
		return h.Unregister(unmarsh, head)
	case wire.DownloadMessagesCode:
		// Handle DownloadMessages
		unmarsh := &wire.DownloadMessages{}
		err := proto.Unmarshal(data, unmarsh)
		if err != nil {
			return nil, err
		}
		return h.DownloadMessages(unmarsh, head)
	case wire.PublishMessageCode:
		// Handle PublishMessage
		unmarsh := &wire.PublishMessage{}
		err := proto.Unmarshal(data, unmarsh)
		if err != nil {
			return nil, err
		}
		return h.PublishMessage(unmarsh, head)
	case wire.UpdateMessageCode:
		// Handle UpdateMessage
		unmarsh := &wire.UpdateMessage{}
		err := proto.Unmarshal(data, unmarsh)
		if err != nil {
			return nil, err
		}
		return h.UpdateMessage(unmarsh, head)
	case wire.PublishDataMessageCode:
		// Handle PublishDataMessage
		unmarsh := &wire.PublishDataMessage{}
		err := proto.Unmarshal(data, unmarsh)
		if err != nil {
			return nil, err
		}
		return h.PublishDataMessage(unmarsh, head, conn)
	case wire.DataCode:
		// Handle Data
		unmarsh := &wire.Data{}
		err := proto.Unmarshal(data, unmarsh)
		if err != nil {
			return nil, err
		}
		return h.Data(unmarsh, head)
	case wire.GetDataCode:
		// Handle GetData
		unmarsh := &wire.GetData{}
		err := proto.Unmarshal(data, unmarsh)
		if err != nil {
			return nil, err
		}
		return h.GetData(unmarsh, head)
	}
	return nil, errors.New("Cannot handle type. That shouldn't happen.")
}

// Register a User on the Delegate
func (h *Handler) Register(r *wire.Register, head message.Header) ([]message.Message, error) {
	data := make(map[string][]byte)
	for _, v := range r.GetKeys() {
		data[v.GetKey()] = v.GetData()
	}
	err := h.Delegate.Register(head.From.String(), data)
	if err != nil {
		return nil, err
	}
	return CreateResponse(0, "OK", h.Key.Address, head.From), nil
}

// Unregister a User on the Delegate
func (h *Handler) Unregister(r *wire.Unregister, head message.Header) ([]message.Message, error) {
	data := make(map[string][]byte)
	for _, v := range r.GetKeys() {
		data[v.GetKey()] = v.GetData()
	}
	err := h.Delegate.Unregister(head.From.String(), data)
	if err != nil {
		return nil, err
	}
	return CreateResponse(0, "OK", h.Key.Address, head.From), nil
}

// Return all Messages received after `since` in sequence.
func (h *Handler) DownloadMessages(r *wire.DownloadMessages, head message.Header) ([]message.Message, error) {
	responses, err := h.Delegate.GetMessages(r.GetSince(), head.From.String(), r.GetContext())
	if err != nil {
		return nil, err
	}

	out := make([]message.Message, len(responses))
	for i, v := range responses {
		out[i] = v
	}

	return CreateResponse(0, "OK", h.Key.Address, head.From, out...), nil
}

// Publish a message on Delegate.
func (h *Handler) PublishMessage(r *wire.PublishMessage, head message.Header) ([]message.Message, error) {
	msg, err := message.CreateEncryptedMessageFromBytes(r.GetData())
	if err != nil {
		return nil, err
	}

	// Name, To, Author, Message
	err = h.Delegate.PublishMessage(r.GetName(), r.GetTo(), head.From.String(), msg, r.GetAlert())
	if err != nil {
		return nil, err
	}

	return CreateResponse(0, "OK", h.Key.Address, head.From), nil
}

// Update a message on Delegate.
func (h *Handler) UpdateMessage(r *wire.UpdateMessage, head message.Header) ([]message.Message, error) {
	msg, err := message.CreateEncryptedMessageFromBytes(r.GetData())
	if err != nil {
		return nil, err
	}

	// Name, To, Author, Message
	err = h.Delegate.UpdateMessage(r.GetName(), head.From.String(), msg)
	if err != nil {
		return nil, err
	}

	return CreateResponse(0, "OK", h.Key.Address, head.From), nil
}

type dataReader struct {
	io.Reader

	expectedHash []byte
	runningHash  hash.Hash
}

func createDataReader(r io.Reader, length int64, hash []byte) *dataReader {
	newHash := sha256.New()
	return &dataReader{
		Reader:       io.TeeReader(io.LimitReader(r, length), newHash),
		expectedHash: hash,
		runningHash:  newHash,
	}
}

func (d *dataReader) Verify() bool {
	return bytes.Equal(d.runningHash.Sum(nil), d.expectedHash)
}

// Publish a message on Delegate.
func (h *Handler) PublishDataMessage(r *wire.PublishDataMessage, head message.Header, conn net.Conn) ([]message.Message, error) {
	msg, err := message.CreateEncryptedMessageFromBytes(r.GetHeader())
	if err != nil {
		return nil, err
	}

	// Name, To, Author, Message
	err = h.Delegate.PublishDataMessage(
		r.GetName(),
		r.GetTo(),
		head.From.String(),
		msg,
		r.GetLength(),
		createDataReader(conn, int64(r.GetLength()), r.GetHash()))
	if err != nil {
		return nil, err
	}

	return CreateResponse(0, "OK", h.Key.Address, head.From), nil
}

// Set Data
func (h *Handler) Data(r *wire.Data, head message.Header) ([]message.Message, error) {
	err := h.Delegate.SetData(head.From.String(), r.GetKey(), r.GetData())
	if err != nil {
		return nil, err
	}

	return CreateResponse(0, "OK", h.Key.Address, head.From), nil
}

// Get Data
func (h *Handler) GetData(r *wire.GetData, head message.Header) ([]message.Message, error) {
	data, err := h.Delegate.GetData(head.From.String(), r.GetKey())
	if err != nil {
		return nil, err
	}

	return CreateDataResponse(0, "OK", h.Key.Address, head.From, data), nil
}
<|endoftext|>


<commit_before>package server

import (
	"testing"
)

func Test_StartPconnSrv(t *testing.T) {
	if e := StartPconnSrv(); e != nil { //try a unit test on function
		t.Error("start server failed...") // 如果不是如预期的那么就报错
	} else {
		t.Log("testing passed") //记录一些你期望记录的信息
	}
}
<commit_msg>Remove test<commit_after>package server

import (
	"testing"
)

func Test_StartPconnSrv(t *testing.T) {
	// if e := StartPconnSrv(); e != nil { //try a unit test on function
	// 	t.Error("start server failed...") // 如果不是如预期的那么就报错
	// } else {
	// 	t.Log("testing passed") //记录一些你期望记录的信息
	// }
}
<|endoftext|>


<commit_before>package data

type LedgerEntrySlice []LedgerEntry

type Index uint64

type leBase struct {
	hashable
	LedgerEntryType LedgerEntryType `json:",omitempty"`
	LedgerIndex     *Hash256        `json:",omitempty"`
}

type AccountRootFields struct {
	Flags             *LedgerEntryFlag `json:",omitempty"`
	Account           *Account         `json:",omitempty"`
	Sequence          *uint32          `json:",omitempty"`
	Balance           *Value           `json:",omitempty"`
	OwnerCount        *uint32          `json:",omitempty"`
	PreviousTxnID     *Hash256         `json:",omitempty"`
	PreviousTxnLgrSeq *uint32          `json:",omitempty"`
	AccountTxnID      *Hash256         `json:",omitempty"`
	RegularKey        *RegularKey      `json:",omitempty"`
	EmailHash         *Hash128         `json:",omitempty"`
	WalletLocator     *Hash256         `json:",omitempty"`
	WalletSize        *uint32          `json:",omitempty"`
	MessageKey        *PublicKey       `json:",omitempty"`
	TransferRate      *uint32          `json:",omitempty"`
	Domain            *VariableLength  `json:",omitempty"`
	Signers           *VariableLength  `json:",omitempty"`
}

type AccountRoot struct {
	leBase
	AccountRootFields
}

type RippleStateFields struct {
	Flags             *LedgerEntryFlag `json:",omitempty"`
	LowLimit          *Amount          `json:",omitempty"`
	HighLimit         *Amount          `json:",omitempty"`
	PreviousTxnID     *Hash256         `json:",omitempty"`
	PreviousTxnLgrSeq *uint32          `json:",omitempty"`
	Balance           *Amount          `json:",omitempty"`
	LowNode           *Index           `json:",omitempty"`
	HighNode          *Index           `json:",omitempty"`
	LowQualityIn      *uint32          `json:",omitempty"`
	LowQualityOut     *uint32          `json:",omitempty"`
	HighQualityIn     *uint32          `json:",omitempty"`
	HighQualityOut    *uint32          `json:",omitempty"`
}

type RippleState struct {
	leBase
	RippleStateFields
}

type RippleStateOutcome struct {
}

type OfferFields struct {
	Flags             *LedgerEntryFlag `json:",omitempty"`
	Account           *Account         `json:",omitempty"`
	Sequence          *uint32          `json:",omitempty"`
	TakerPays         *Amount          `json:",omitempty"`
	TakerGets         *Amount          `json:",omitempty"`
	BookDirectory     *Hash256         `json:",omitempty"`
	BookNode          *Index           `json:",omitempty"`
	OwnerNode         *Index           `json:",omitempty"`
	PreviousTxnID     *Hash256         `json:",omitempty"`
	PreviousTxnLgrSeq *uint32          `json:",omitempty"`
	Expiration        *uint32          `json:",omitempty"`
}

type Offer struct {
	leBase
	OfferFields
}

type OfferOutcome struct {
	Account *Account
	Paid    *Amount
	Got     *Amount
}

type DirectoryFields struct {
	Flags             *LedgerEntryFlag `json:",omitempty"`
	RootIndex         *Hash256         `json:",omitempty"`
	Indexes           *Vector256       `json:",omitempty"`
	Owner             *Account         `json:",omitempty"`
	TakerPaysCurrency *Hash160         `json:",omitempty"`
	TakerPaysIssuer   *Hash160         `json:",omitempty"`
	TakerGetsCurrency *Hash160         `json:",omitempty"`
	TakerGetsIssuer   *Hash160         `json:",omitempty"`
	ExchangeRate      *Index           `json:",omitempty"`
	IndexNext         *Index           `json:",omitempty"`
	IndexPrevious     *Index           `json:",omitempty"`
}

type Directory struct {
	leBase
	DirectoryFields
}

type LedgerHashesFields struct {
	Flags               *LedgerEntryFlag `json:",omitempty"`
	FirstLedgerSequence uint32
	LastLedgerSequence  uint32
	Hashes              Vector256
}

type LedgerHashes struct {
	leBase
	LedgerHashesFields
}

type AmendmentsFields struct {
	Flags      *LedgerEntryFlag `json:",omitempty"`
	Amendments Hash256
}

type Amendments struct {
	leBase
	AmendmentsFields
}

type FeeSettingFields struct {
	Flags             *LedgerEntryFlag `json:",omitempty"`
	BaseFee           uint64
	ReferenceFeeUnits uint32
	ReserveBase       uint32
	ReserveIncrement  uint32
}

type FeeSetting struct {
	leBase
	FeeSettingFields
}

func (le *leBase) GetType() string {
	return ledgerEntryNames[le.LedgerEntryType]
}

func (le *leBase) GetLedgerEntryType() LedgerEntryType {
	return le.LedgerEntryType
}
<commit_msg>Expiration is RippleTime<commit_after>package data

type LedgerEntrySlice []LedgerEntry

type Index uint64

type leBase struct {
	hashable
	LedgerEntryType LedgerEntryType `json:",omitempty"`
	LedgerIndex     *Hash256        `json:",omitempty"`
}

type AccountRootFields struct {
	Flags             *LedgerEntryFlag `json:",omitempty"`
	Account           *Account         `json:",omitempty"`
	Sequence          *uint32          `json:",omitempty"`
	Balance           *Value           `json:",omitempty"`
	OwnerCount        *uint32          `json:",omitempty"`
	PreviousTxnID     *Hash256         `json:",omitempty"`
	PreviousTxnLgrSeq *uint32          `json:",omitempty"`
	AccountTxnID      *Hash256         `json:",omitempty"`
	RegularKey        *RegularKey      `json:",omitempty"`
	EmailHash         *Hash128         `json:",omitempty"`
	WalletLocator     *Hash256         `json:",omitempty"`
	WalletSize        *uint32          `json:",omitempty"`
	MessageKey        *PublicKey       `json:",omitempty"`
	TransferRate      *uint32          `json:",omitempty"`
	Domain            *VariableLength  `json:",omitempty"`
	Signers           *VariableLength  `json:",omitempty"`
}

type AccountRoot struct {
	leBase
	AccountRootFields
}

type RippleStateFields struct {
	Flags             *LedgerEntryFlag `json:",omitempty"`
	LowLimit          *Amount          `json:",omitempty"`
	HighLimit         *Amount          `json:",omitempty"`
	PreviousTxnID     *Hash256         `json:",omitempty"`
	PreviousTxnLgrSeq *uint32          `json:",omitempty"`
	Balance           *Amount          `json:",omitempty"`
	LowNode           *Index           `json:",omitempty"`
	HighNode          *Index           `json:",omitempty"`
	LowQualityIn      *uint32          `json:",omitempty"`
	LowQualityOut     *uint32          `json:",omitempty"`
	HighQualityIn     *uint32          `json:",omitempty"`
	HighQualityOut    *uint32          `json:",omitempty"`
}

type RippleState struct {
	leBase
	RippleStateFields
}

type RippleStateOutcome struct {
}

type OfferFields struct {
	Flags             *LedgerEntryFlag `json:",omitempty"`
	Account           *Account         `json:",omitempty"`
	Sequence          *uint32          `json:",omitempty"`
	TakerPays         *Amount          `json:",omitempty"`
	TakerGets         *Amount          `json:",omitempty"`
	BookDirectory     *Hash256         `json:",omitempty"`
	BookNode          *Index           `json:",omitempty"`
	OwnerNode         *Index           `json:",omitempty"`
	PreviousTxnID     *Hash256         `json:",omitempty"`
	PreviousTxnLgrSeq *uint32          `json:",omitempty"`
	Expiration        *RippleTime      `json:",omitempty"`
}

type Offer struct {
	leBase
	OfferFields
}

type OfferOutcome struct {
	Account *Account
	Paid    *Amount
	Got     *Amount
}

type DirectoryFields struct {
	Flags             *LedgerEntryFlag `json:",omitempty"`
	RootIndex         *Hash256         `json:",omitempty"`
	Indexes           *Vector256       `json:",omitempty"`
	Owner             *Account         `json:",omitempty"`
	TakerPaysCurrency *Hash160         `json:",omitempty"`
	TakerPaysIssuer   *Hash160         `json:",omitempty"`
	TakerGetsCurrency *Hash160         `json:",omitempty"`
	TakerGetsIssuer   *Hash160         `json:",omitempty"`
	ExchangeRate      *Index           `json:",omitempty"`
	IndexNext         *Index           `json:",omitempty"`
	IndexPrevious     *Index           `json:",omitempty"`
}

type Directory struct {
	leBase
	DirectoryFields
}

type LedgerHashesFields struct {
	Flags               *LedgerEntryFlag `json:",omitempty"`
	FirstLedgerSequence uint32
	LastLedgerSequence  uint32
	Hashes              Vector256
}

type LedgerHashes struct {
	leBase
	LedgerHashesFields
}

type AmendmentsFields struct {
	Flags      *LedgerEntryFlag `json:",omitempty"`
	Amendments Hash256
}

type Amendments struct {
	leBase
	AmendmentsFields
}

type FeeSettingFields struct {
	Flags             *LedgerEntryFlag `json:",omitempty"`
	BaseFee           uint64
	ReferenceFeeUnits uint32
	ReserveBase       uint32
	ReserveIncrement  uint32
}

type FeeSetting struct {
	leBase
	FeeSettingFields
}

func (le *leBase) GetType() string {
	return ledgerEntryNames[le.LedgerEntryType]
}

func (le *leBase) GetLedgerEntryType() LedgerEntryType {
	return le.LedgerEntryType
}
<|endoftext|>


<commit_before>package goes

// StaticEndpointDiscoverer is used for connecting to a single node
type StaticEndpointDiscoverer struct {
	IPAddress string
	Port      int
}

// Discover will just use the given ip address and port to connect to a single node
func (discoverer *StaticEndpointDiscoverer) Discover() (MemberInfo, error) {
	return MemberInfo{
		ExternalTCPIP:   discoverer.IPAddress,
		ExternalTCPPort: discoverer.Port,
	}, nil
}
<commit_msg>Remove static endpoint discoverer<commit_after><|endoftext|>


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

package server

import (
	"math/rand"
	"net"
	"os"
	"strings"
	"testing"
	"time"

	"github.com/coreos/etcd/clientv3"
	. "github.com/pingcap/check"
	"github.com/pingcap/kvproto/pkg/pdpb"
)

func TestServer(t *testing.T) {
	TestingT(t)
}

type cleanupFunc func()

func newTestServer(c *C) (*Server, cleanUpFunc) {
	cfg := NewTestSingleConfig()

	svr, err := NewServer(cfg)
	c.Assert(err, IsNil)

	cleanup := func() {
		svr.Close()
		cleanServer(svr.cfg)
	}

	return svr, cleanup
}

var stripUnix = strings.NewReplacer("unix://", "")

func cleanServer(cfg *Config) {
	// Clean data directory
	os.RemoveAll(cfg.DataDir)

	// Clean unix sockets
	os.Remove(stripUnix.Replace(cfg.PeerUrls))
	os.Remove(stripUnix.Replace(cfg.ClientUrls))
	os.Remove(stripUnix.Replace(cfg.AdvertisePeerUrls))
	os.Remove(stripUnix.Replace(cfg.AdvertiseClientUrls))
}

func newMultiTestServers(c *C, count int) ([]*Server, cleanupFunc) {
	svrs := make([]*Server, 0, count)
	cfgs := NewTestMultiConfig(count)

	ch := make(chan *Server, count)
	for i := 0; i < count; i++ {
		cfg := cfgs[i]

		go func() {
			svr, err := NewServer(cfg)
			c.Assert(err, IsNil)
			ch <- svr
		}()
	}

	for i := 0; i < count; i++ {
		svr := <-ch
		go svr.Run()
		svrs = append(svrs, svr)
	}

	mustWaitLeader(c, svrs)

	cleanup := func() {
		for _, svr := range svrs {
			svr.Close()
		}

		for _, cfg := range cfgs {
			cleanServer(cfg)
		}
	}

	return svrs, cleanup
}

func mustWaitLeader(c *C, svrs []*Server) *Server {
	for i := 0; i < 500; i++ {
		for _, s := range svrs {
			if s.IsLeader() {
				return s
			}
		}
		time.Sleep(100 * time.Millisecond)
	}
	c.Fatal("no leader")
	return nil
}

func mustRPCCall(c *C, conn net.Conn, req *pdpb.Request) *pdpb.Response {
	resp, err := rpcCall(conn, uint64(rand.Int63()), req)
	c.Assert(err, IsNil)
	c.Assert(resp, NotNil)
	return resp
}

var _ = Suite(&testLeaderServerSuite{})

type testLeaderServerSuite struct {
	client     *clientv3.Client
	svrs       map[string]*Server
	leaderPath string
}

func (s *testLeaderServerSuite) SetUpSuite(c *C) {
	s.svrs = make(map[string]*Server)

	cfgs := NewTestMultiConfig(3)

	ch := make(chan *Server, 3)
	for i := 0; i < 3; i++ {
		cfg := cfgs[i]

		go func() {
			svr, err := NewServer(cfg)
			c.Assert(err, IsNil)
			ch <- svr
		}()
	}

	for i := 0; i < 3; i++ {
		svr := <-ch
		s.svrs[svr.GetAddr()] = svr
		s.leaderPath = svr.getLeaderPath()
	}

	s.setUpClient(c)
}

func (s *testLeaderServerSuite) TearDownSuite(c *C) {
	s.client.Close()

	for _, svr := range s.svrs {
		svr.Close()
		cleanServer(svr.cfg)
	}
}

func (s *testLeaderServerSuite) setUpClient(c *C) {
	endpoints := make([]string, 0, 3)

	for _, svr := range s.svrs {
		endpoints = append(endpoints, svr.GetEndpoints()...)
	}

	var err error
	s.client, err = clientv3.New(clientv3.Config{
		Endpoints:   endpoints,
		DialTimeout: 3 * time.Second,
	})
	c.Assert(err, IsNil)
}

func (s *testLeaderServerSuite) TestLeader(c *C) {
	for _, svr := range s.svrs {
		go svr.Run()
	}

	leader1 := mustGetLeader(c, s.client, s.leaderPath)
	svr, ok := s.svrs[leader1.GetAddr()]
	c.Assert(ok, IsTrue)
	svr.Close()
	delete(s.svrs, leader1.GetAddr())

	// wait leader changes
	for i := 0; i < 50; i++ {
		leader, _ := getLeader(s.client, s.leaderPath)
		if leader != nil && leader.GetAddr() != leader1.GetAddr() {
			break
		}

		time.Sleep(500 * time.Millisecond)
	}

	leader2 := mustGetLeader(c, s.client, s.leaderPath)
	c.Assert(leader1.GetAddr(), Not(Equals), leader2.GetAddr())
}
<commit_msg>fix server test.<commit_after>// Copyright 2016 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

package server

import (
	"math/rand"
	"net"
	"os"
	"strings"
	"testing"
	"time"

	"github.com/coreos/etcd/clientv3"
	. "github.com/pingcap/check"
	"github.com/pingcap/kvproto/pkg/pdpb"
)

func TestServer(t *testing.T) {
	TestingT(t)
}

type cleanupFunc func()

func newTestServer(c *C) (*Server, cleanUpFunc) {
	cfg := NewTestSingleConfig()

	svr, err := NewServer(cfg)
	c.Assert(err, IsNil)

	cleanup := func() {
		svr.Close()
		cleanServer(svr.cfg)
	}

	return svr, cleanup
}

var stripUnix = strings.NewReplacer("unix://", "")

func cleanServer(cfg *Config) {
	// Clean data directory
	os.RemoveAll(cfg.DataDir)

	// Clean unix sockets
	os.Remove(stripUnix.Replace(cfg.PeerUrls))
	os.Remove(stripUnix.Replace(cfg.ClientUrls))
	os.Remove(stripUnix.Replace(cfg.AdvertisePeerUrls))
	os.Remove(stripUnix.Replace(cfg.AdvertiseClientUrls))
}

func newMultiTestServers(c *C, count int) ([]*Server, cleanupFunc) {
	svrs := make([]*Server, 0, count)
	cfgs := NewTestMultiConfig(count)

	ch := make(chan *Server, count)
	for i := 0; i < count; i++ {
		cfg := cfgs[i]

		go func() {
			svr, err := NewServer(cfg)
			c.Assert(err, IsNil)
			ch <- svr
		}()
	}

	for i := 0; i < count; i++ {
		svr := <-ch
		go svr.Run()
		svrs = append(svrs, svr)
	}

	mustWaitLeader(c, svrs)

	cleanup := func() {
		for _, svr := range svrs {
			svr.Close()
		}

		for _, cfg := range cfgs {
			cleanServer(cfg)
		}
	}

	return svrs, cleanup
}

func mustWaitLeader(c *C, svrs []*Server) *Server {
	for i := 0; i < 500; i++ {
		for _, s := range svrs {
			if s.IsLeader() {
				return s
			}
		}
		time.Sleep(100 * time.Millisecond)
	}
	c.Fatal("no leader")
	return nil
}

func mustRPCCall(c *C, conn net.Conn, req *pdpb.Request) *pdpb.Response {
	resp, err := rpcCall(conn, uint64(rand.Int63()), req)
	c.Assert(err, IsNil)
	c.Assert(resp, NotNil)
	return resp
}

var _ = Suite(&testLeaderServerSuite{})

type testLeaderServerSuite struct {
	client     *clientv3.Client
	svrs       map[string]*Server
	leaderPath string
}

func (s *testLeaderServerSuite) SetUpSuite(c *C) {
	s.svrs = make(map[string]*Server)

	cfgs := NewTestMultiConfig(3)

	ch := make(chan *Server, 3)
	for i := 0; i < 3; i++ {
		cfg := cfgs[i]

		go func() {
			svr, err := NewServer(cfg)
			c.Assert(err, IsNil)
			ch <- svr
		}()
	}

	for i := 0; i < 3; i++ {
		svr := <-ch
		s.svrs[svr.GetAddr()] = svr
		s.leaderPath = svr.getLeaderPath()
	}

	s.setUpClient(c)
}

func (s *testLeaderServerSuite) TearDownSuite(c *C) {
	s.client.Close()

	for _, svr := range s.svrs {
		svr.Close()
		cleanServer(svr.cfg)
	}
}

func (s *testLeaderServerSuite) setUpClient(c *C) {
	endpoints := make([]string, 0, 3)

	for _, svr := range s.svrs {
		endpoints = append(endpoints, svr.GetEndpoints()...)
	}

	var err error
	s.client, err = clientv3.New(clientv3.Config{
		Endpoints:   endpoints,
		DialTimeout: 3 * time.Second,
	})
	c.Assert(err, IsNil)
}

func (s *testLeaderServerSuite) TestLeader(c *C) {
	for _, svr := range s.svrs {
		go svr.Run()
	}

	leader1 := mustGetLeader(c, s.client, s.leaderPath)
	svr, ok := s.svrs[leader1.GetAddr()]
	c.Assert(ok, IsTrue)
	svr.Close()
	delete(s.svrs, leader1.GetAddr())

	// Create a client without the leader1's endpoints.
	endpoints := make([]string, 0, 2)
	for _, svr := range s.svrs {
		endpoints = append(endpoints, svr.GetEndpoints()...)
	}
	client, err := clientv3.New(clientv3.Config{
		Endpoints:   endpoints,
		DialTimeout: 3 * time.Second,
	})
	c.Assert(err, IsNil)
	defer client.Close()

	// wait leader changes
	for i := 0; i < 50; i++ {
		leader, _ := getLeader(client, s.leaderPath)
		if leader != nil && leader.GetAddr() != leader1.GetAddr() {
			break
		}

		time.Sleep(500 * time.Millisecond)
	}

	leader2 := mustGetLeader(c, client, s.leaderPath)
	c.Assert(leader1.GetAddr(), Not(Equals), leader2.GetAddr())
}
<|endoftext|>


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

package server

import (
	assert "github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/suite"
	"github.com/venicegeo/pz-workflow/common"
	"github.com/venicegeo/pz-gocommon"
	loggerPkg "github.com/venicegeo/pz-logger/client"
	uuidgenPkg "github.com/venicegeo/pz-uuidgen/client"
	"log"
	"testing"
	"net/http"
	"bytes"
	"encoding/json"
	"io/ioutil"
	"fmt"
	"time"
)

type ServerTester struct {
	suite.Suite
	sys *piazza.System
	url string
}

func (suite *ServerTester) SetupSuite() {
	t := suite.T()
	assert := assert.New(t)

	config, err := piazza.NewConfig(piazza.PzWorkflow, piazza.ConfigModeTest)
	if err != nil {
		log.Fatal(err)
	}

	sys, err := piazza.NewSystem(config)
	if err != nil {
		log.Fatal(err)
	}

	theLogger, err := loggerPkg.NewMockLoggerService(sys)
	if err != nil {
		log.Fatal(err)
	}

	theUuidgen, err := uuidgenPkg.NewMockUuidGenService(sys)
	if err != nil {
		log.Fatal(err)
	}

	routes, err := CreateHandlers(sys, theLogger, theUuidgen)
	if err != nil {
		log.Fatal(err)
	}

	_ = sys.StartServer(routes)

	suite.sys = sys

	suite.url = fmt.Sprintf("http://%s/v1", sys.Config.GetBindToAddress())

	assert.Len(sys.Services, 4)
}

func (suite *ServerTester) TearDownSuite() {
	//TODO: kill the go routine running the server
}

func TestRunSuite(t *testing.T) {
	s := new(ServerTester)
	suite.Run(t, s)
}

func (suite *ServerTester) Post(path string, body interface{}) interface{} {
	t := suite.T()
	assert := assert.New(t)

	bodyBytes, err := json.Marshal(body)
	assert.NoError(err)

	resp, err := http.Post(suite.url + path, piazza.ContentTypeJSON, bytes.NewBuffer(bodyBytes))
	assert.NoError(err)
	assert.NotNil(resp)
	assert.Equal(http.StatusCreated, resp.StatusCode)

	defer resp.Body.Close()
	data, err := ioutil.ReadAll(resp.Body)
	assert.NoError(err)

	var result interface{}
	err = json.Unmarshal(data, &result)
	assert.NoError(err)

	return result
}

func (suite *ServerTester) Get(path string) interface{} {
	t := suite.T()
	assert := assert.New(t)

	resp, err := http.Get(suite.url + path)
	assert.NoError(err)
	assert.NotNil(resp)

	defer resp.Body.Close()
	data, err := ioutil.ReadAll(resp.Body)
	assert.NoError(err)

	var result interface{}
	err = json.Unmarshal(data, &result)
	assert.NoError(err)

	return result
}

//---------------------------------------------------------------------------

func (suite *ServerTester) TestOne() {

	t := suite.T()
	assert := assert.New(t)

	var err error
	//var idResponse *common.WorkflowIdResponse

	var eventTypeName = "EventTypeA"

	var et1Id common.Ident
	{
		mapping := map[string]piazza.MappingElementTypeName{
			"num":  piazza.MappingElementTypeInteger,
			"str": piazza.MappingElementTypeString,
		}

		eventType := &common.EventType{Name: eventTypeName, Mapping: mapping}

		resp := suite.Post("/eventtypes", eventType)

		resp2 := &common.WorkflowIdResponse{}
		err = common.SuperConvert(resp, resp2)
		assert.NoError(err)

		et1Id = resp2.ID
	}

	var t1Id common.Ident
	{
		x1 := &common.Trigger{
			Title: "the x1 trigger",
			Condition: common.Condition{
				EventType: et1Id,
				Query: map[string]interface{}{
					"query": map[string]interface{}{
						"match": map[string]interface{}{
							"num": 17,
						},
					},
				},
			},
			Job: common.Job{
				Task: "the x1 task",
			},
		}

		resp := suite.Post("/triggers", x1)
		resp2 := &common.WorkflowIdResponse{}
		err = common.SuperConvert(resp, resp2)
		assert.NoError(err)

		t1Id = resp2.ID
	}

	var e1Id common.Ident
	{
		// will cause trigger TRG1
		e1 := &common.Event{
			EventType: et1Id,
			Date: time.Now(),
			Data: map[string]interface{}{
				"num": 17,
				"str": "quick",
			},
		}

		resp := suite.Post("/events/" + eventTypeName, e1)
		resp2 := &common.WorkflowIdResponse{}
		err = common.SuperConvert(resp, resp2)
		assert.NoError(err)

		e1Id = resp2.ID
	}

	{
		// will cause no triggers
		e1 := &common.Event{
			EventType: et1Id,
			Date: time.Now(),
			Data: map[string]interface{}{
				"num": 18,
				"str": "brown",
			},
		}

		resp := suite.Post("/events/" + eventTypeName, e1)
		resp2 := &common.WorkflowIdResponse{}
		err = common.SuperConvert(resp, resp2)
		assert.NoError(err)
	}

	{
		resp := suite.Get("/alerts")

		var alerts []common.Alert
		common.SuperConvert(resp, &alerts)
		assert.Len(alerts, 1)

		alert0 := alerts[0]
		assert.EqualValues(e1Id, alert0.EventId)
		assert.EqualValues(t1Id, alert0.TriggerId)
	}
}
<commit_msg>Added a foo unit test<commit_after>// Copyright 2016, RadiantBlue Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package server

import (
	assert "github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/suite"
	"github.com/venicegeo/pz-workflow/common"
	"github.com/venicegeo/pz-gocommon"
	loggerPkg "github.com/venicegeo/pz-logger/client"
	uuidgenPkg "github.com/venicegeo/pz-uuidgen/client"
	"log"
	"testing"
	"net/http"
	"bytes"
	"encoding/json"
	"io/ioutil"
	"fmt"
	"time"
)

type ServerTester struct {
	suite.Suite
	sys *piazza.System
	url string
}

func (suite *ServerTester) SetupSuite() {
	t := suite.T()
	assert := assert.New(t)

	config, err := piazza.NewConfig(piazza.PzWorkflow, piazza.ConfigModeTest)
	if err != nil {
		log.Fatal(err)
	}

	sys, err := piazza.NewSystem(config)
	if err != nil {
		log.Fatal(err)
	}

	theLogger, err := loggerPkg.NewMockLoggerService(sys)
	if err != nil {
		log.Fatal(err)
	}

	theUuidgen, err := uuidgenPkg.NewMockUuidGenService(sys)
	if err != nil {
		log.Fatal(err)
	}

	routes, err := CreateHandlers(sys, theLogger, theUuidgen)
	if err != nil {
		log.Fatal(err)
	}

	_ = sys.StartServer(routes)

	suite.sys = sys

	suite.url = fmt.Sprintf("http://%s/v1", sys.Config.GetBindToAddress())

	assert.Len(sys.Services, 4)
}

func (suite *ServerTester) TearDownSuite() {
	//TODO: kill the go routine running the server
}

func TestRunSuite(t *testing.T) {
	s := new(ServerTester)
	suite.Run(t, s)
}

func (suite *ServerTester) Post(path string, body interface{}) interface{} {
	t := suite.T()
	assert := assert.New(t)

	bodyBytes, err := json.Marshal(body)
	assert.NoError(err)

	resp, err := http.Post(suite.url + path, piazza.ContentTypeJSON, bytes.NewBuffer(bodyBytes))
	assert.NoError(err)
	assert.NotNil(resp)
	assert.Equal(http.StatusCreated, resp.StatusCode)

	defer resp.Body.Close()
	data, err := ioutil.ReadAll(resp.Body)
	assert.NoError(err)

	var result interface{}
	err = json.Unmarshal(data, &result)
	assert.NoError(err)

	return result
}

func (suite *ServerTester) Get(path string) interface{} {
	t := suite.T()
	assert := assert.New(t)

	resp, err := http.Get(suite.url + path)
	assert.NoError(err)
	assert.NotNil(resp)

	defer resp.Body.Close()
	data, err := ioutil.ReadAll(resp.Body)
	assert.NoError(err)

	var result interface{}
	err = json.Unmarshal(data, &result)
	assert.NoError(err)

	return result
}

//---------------------------------------------------------------------------

func (suite *ServerTester) TestOne() {

	t := suite.T()
	assert := assert.New(t)

	var err error
	//var idResponse *common.WorkflowIdResponse

	var eventTypeName = "EventTypeA"

	var et1Id common.Ident
	{
		mapping := map[string]piazza.MappingElementTypeName{
			"num":  piazza.MappingElementTypeInteger,
			"str": piazza.MappingElementTypeString,
		}

		eventType := &common.EventType{Name: eventTypeName, Mapping: mapping}

		resp := suite.Post("/eventtypes", eventType)

		resp2 := &common.WorkflowIdResponse{}
		err = common.SuperConvert(resp, resp2)
		assert.NoError(err)

		et1Id = resp2.ID
	}

	var t1Id common.Ident
	{
		x1 := &common.Trigger{
			Title: "the x1 trigger",
			Condition: common.Condition{
				EventType: et1Id,
				Query: map[string]interface{}{
					"query": map[string]interface{}{
						"match": map[string]interface{}{
							"num": 17,
						},
					},
				},
			},
			Job: common.Job{
				Task: "the x1 task",
			},
		}

		resp := suite.Post("/triggers", x1)
		resp2 := &common.WorkflowIdResponse{}
		err = common.SuperConvert(resp, resp2)
		assert.NoError(err)

		t1Id = resp2.ID
	}

	var e1Id common.Ident
	{
		// will cause trigger TRG1
		e1 := &common.Event{
			EventType: et1Id,
			Date: time.Now(),
			Data: map[string]interface{}{
				"num": 17,
				"str": "quick",
			},
		}

		resp := suite.Post("/events/" + eventTypeName, e1)
		resp2 := &common.WorkflowIdResponse{}
		err = common.SuperConvert(resp, resp2)
		assert.NoError(err)

		e1Id = resp2.ID
	}

	{
		// will cause no triggers
		e1 := &common.Event{
			EventType: et1Id,
			Date: time.Now(),
			Data: map[string]interface{}{
				"num": 18,
				"str": "brown",
			},
		}

		resp := suite.Post("/events/" + eventTypeName, e1)
		resp2 := &common.WorkflowIdResponse{}
		err = common.SuperConvert(resp, resp2)
		assert.NoError(err)
	}

	{
		resp := suite.Get("/alerts")

		var alerts []common.Alert
		common.SuperConvert(resp, &alerts)
		assert.Len(alerts, 1)

		alert0 := alerts[0]
		assert.EqualValues(e1Id, alert0.EventId)
		assert.EqualValues(t1Id, alert0.TriggerId)
	}
}

func (suite *ServerTester) TestTwo() {
	t := suite.T()
	assert := assert.New(t)
	assert.Equal(17, 10 + 7)
}

<|endoftext|>


<commit_before>package api

// NetworksPost represents the fields of a new LXD network
//
// API extension: network
type NetworksPost struct {
	NetworkPut `yaml:",inline"`

	Managed bool   `json:"managed" yaml:"managed"`
	Name    string `json:"name" yaml:"name"`
	Type    string `json:"type" yaml:"type"`
}

// NetworkPost represents the fields required to rename a LXD network
//
// API extension: network
type NetworkPost struct {
	Name string `json:"name" yaml:"name"`
}

// NetworkPut represents the modifiable fields of a LXD network
//
// API extension: network
type NetworkPut struct {
	Config map[string]string `json:"config" yaml:"config"`

	// API extension: entity_description
	Description string `json:"description" yaml:"description"`
}

// Network represents a LXD network
type Network struct {
	NetworkPut `yaml:",inline"`

	Name   string   `json:"name" yaml:"name"`
	Type   string   `json:"type" yaml:"type"`
	UsedBy []string `json:"used_by" yaml:"used_by"`

	// API extension: network
	Managed bool `json:"managed" yaml:"managed"`

	// API extension: clustering
	Status    string   `json:"status" yaml:"status"`
	Locations []string `json:"locations" yaml:"locations"`
}

// Writable converts a full Network struct into a NetworkPut struct (filters read-only fields)
func (network *Network) Writable() NetworkPut {
	return network.NetworkPut
}

// NetworkLease represents a DHCP lease
//
// API extension: network_leases
type NetworkLease struct {
	Hostname string `json:"hostname" yaml:"hostname"`
	Hwaddr   string `json:"hwaddr" yaml:"hwaddr"`
	Address  string `json:"address" yaml:"address"`
	Type     string `json:"type" yaml:"type"`
}

// NetworkState represents the network state
type NetworkState struct {
	Addresses []NetworkStateAddress `json:"addresses" yaml:"addresses"`
	Counters  NetworkStateCounters  `json:"counters" yaml:"counters"`
	Hwaddr    string                `json:"hwaddr" yaml:"hwaddr"`
	Mtu       int                   `json:"mtu" yaml:"mtu"`
	State     string                `json:"state" yaml:"state"`
	Type      string                `json:"type" yaml:"type"`
}

// NetworkStateAddress represents a network address
type NetworkStateAddress struct {
	Family  string `json:"family" yaml:"family"`
	Address string `json:"address" yaml:"address"`
	Netmask string `json:"netmask" yaml:"netmask"`
	Scope   string `json:"scope" yaml:"scope"`
}

// NetworkStateCounters represents packet counters
type NetworkStateCounters struct {
	BytesReceived   int64 `json:"bytes_received" yaml:"bytes_received"`
	BytesSent       int64 `json:"bytes_sent" yaml:"bytes_sent"`
	PacketsReceived int64 `json:"packets_received" yaml:"packets_received"`
	PacketsSent     int64 `json:"packets_sent" yaml:"packets_sent"`
}
<commit_msg>shared/api: Add Location to NetworkLeases<commit_after>package api

// NetworksPost represents the fields of a new LXD network
//
// API extension: network
type NetworksPost struct {
	NetworkPut `yaml:",inline"`

	Managed bool   `json:"managed" yaml:"managed"`
	Name    string `json:"name" yaml:"name"`
	Type    string `json:"type" yaml:"type"`
}

// NetworkPost represents the fields required to rename a LXD network
//
// API extension: network
type NetworkPost struct {
	Name string `json:"name" yaml:"name"`
}

// NetworkPut represents the modifiable fields of a LXD network
//
// API extension: network
type NetworkPut struct {
	Config map[string]string `json:"config" yaml:"config"`

	// API extension: entity_description
	Description string `json:"description" yaml:"description"`
}

// Network represents a LXD network
type Network struct {
	NetworkPut `yaml:",inline"`

	Name   string   `json:"name" yaml:"name"`
	Type   string   `json:"type" yaml:"type"`
	UsedBy []string `json:"used_by" yaml:"used_by"`

	// API extension: network
	Managed bool `json:"managed" yaml:"managed"`

	// API extension: clustering
	Status    string   `json:"status" yaml:"status"`
	Locations []string `json:"locations" yaml:"locations"`
}

// Writable converts a full Network struct into a NetworkPut struct (filters read-only fields)
func (network *Network) Writable() NetworkPut {
	return network.NetworkPut
}

// NetworkLease represents a DHCP lease
//
// API extension: network_leases
type NetworkLease struct {
	Hostname string `json:"hostname" yaml:"hostname"`
	Hwaddr   string `json:"hwaddr" yaml:"hwaddr"`
	Address  string `json:"address" yaml:"address"`
	Type     string `json:"type" yaml:"type"`

	// API extension: network_leases_location
	Location string `json:"location" yaml:"location"`
}

// NetworkState represents the network state
type NetworkState struct {
	Addresses []NetworkStateAddress `json:"addresses" yaml:"addresses"`
	Counters  NetworkStateCounters  `json:"counters" yaml:"counters"`
	Hwaddr    string                `json:"hwaddr" yaml:"hwaddr"`
	Mtu       int                   `json:"mtu" yaml:"mtu"`
	State     string                `json:"state" yaml:"state"`
	Type      string                `json:"type" yaml:"type"`
}

// NetworkStateAddress represents a network address
type NetworkStateAddress struct {
	Family  string `json:"family" yaml:"family"`
	Address string `json:"address" yaml:"address"`
	Netmask string `json:"netmask" yaml:"netmask"`
	Scope   string `json:"scope" yaml:"scope"`
}

// NetworkStateCounters represents packet counters
type NetworkStateCounters struct {
	BytesReceived   int64 `json:"bytes_received" yaml:"bytes_received"`
	BytesSent       int64 `json:"bytes_sent" yaml:"bytes_sent"`
	PacketsReceived int64 `json:"packets_received" yaml:"packets_received"`
	PacketsSent     int64 `json:"packets_sent" yaml:"packets_sent"`
}
<|endoftext|>


<commit_before>package cancel

import (
	"context"
	"fmt"
	"net/http"
	"sync"
)

// HTTPRequestCanceller tracks a cancelable operation
type HTTPRequestCanceller struct {
	reqCancel map[*http.Request]context.CancelFunc
	lock      sync.Mutex
}

// NewHTTPRequestCanceller returns a new HTTPRequestCanceller struct
func NewHTTPRequestCanceller() *HTTPRequestCanceller {
	c := HTTPRequestCanceller{}

	c.lock.Lock()
	c.reqCancel = make(map[*http.Request]context.CancelFunc)
	c.lock.Unlock()

	return &c
}

// Cancelable indicates whether there are operations that support cancellation
func (c *HTTPRequestCanceller) Cancelable() bool {
	c.lock.Lock()
	length := len(c.reqCancel)
	c.lock.Unlock()

	return length > 0
}

// Cancel will attempt to cancel all ongoing operations
func (c *HTTPRequestCanceller) Cancel() error {
	if !c.Cancelable() {
		return fmt.Errorf("This operation can't be canceled at this time")
	}

	c.lock.Lock()
	for req, cancel := range c.reqCancel {
		cancel()
		delete(c.reqCancel, req)
	}
	c.lock.Unlock()

	return nil
}

// CancelableDownload performs an http request and allows for it to be canceled at any time
func CancelableDownload(c *HTTPRequestCanceller, client *http.Client, req *http.Request) (*http.Response, chan bool, error) {
	chDone := make(chan bool)
	ctx, cancel := context.WithCancel(req.Context())
	req = req.WithContext(ctx)
	if c != nil {
		c.lock.Lock()
		c.reqCancel[req] = cancel
		c.lock.Unlock()
	}

	go func() {
		<-chDone
		if c != nil {
			c.lock.Lock()
			cancel()
			delete(c.reqCancel, req)
			c.lock.Unlock()
		}
	}()

	resp, err := client.Do(req)
	if err != nil {
		close(chDone)
		return nil, nil, err
	}

	return resp, chDone, nil
}
<commit_msg>shared/cancel: Ends all comments with a full-stop.<commit_after>package cancel

import (
	"context"
	"fmt"
	"net/http"
	"sync"
)

// HTTPRequestCanceller tracks a cancelable operation.
type HTTPRequestCanceller struct {
	reqCancel map[*http.Request]context.CancelFunc
	lock      sync.Mutex
}

// NewHTTPRequestCanceller returns a new HTTPRequestCanceller struct.
func NewHTTPRequestCanceller() *HTTPRequestCanceller {
	c := HTTPRequestCanceller{}

	c.lock.Lock()
	c.reqCancel = make(map[*http.Request]context.CancelFunc)
	c.lock.Unlock()

	return &c
}

// Cancelable indicates whether there are operations that support cancellation.
func (c *HTTPRequestCanceller) Cancelable() bool {
	c.lock.Lock()
	length := len(c.reqCancel)
	c.lock.Unlock()

	return length > 0
}

// Cancel will attempt to cancel all ongoing operations.
func (c *HTTPRequestCanceller) Cancel() error {
	if !c.Cancelable() {
		return fmt.Errorf("This operation can't be canceled at this time")
	}

	c.lock.Lock()
	for req, cancel := range c.reqCancel {
		cancel()
		delete(c.reqCancel, req)
	}
	c.lock.Unlock()

	return nil
}

// CancelableDownload performs an http request and allows for it to be canceled at any time.
func CancelableDownload(c *HTTPRequestCanceller, client *http.Client, req *http.Request) (*http.Response, chan bool, error) {
	chDone := make(chan bool)
	ctx, cancel := context.WithCancel(req.Context())
	req = req.WithContext(ctx)
	if c != nil {
		c.lock.Lock()
		c.reqCancel[req] = cancel
		c.lock.Unlock()
	}

	go func() {
		<-chDone
		if c != nil {
			c.lock.Lock()
			cancel()
			delete(c.reqCancel, req)
			c.lock.Unlock()
		}
	}()

	resp, err := client.Do(req)
	if err != nil {
		close(chDone)
		return nil, nil, err
	}

	return resp, chDone, nil
}
<|endoftext|>


<commit_before>package ratelimiter

import (
	"testing"
	"time"
)

func TestPour(t *testing.T) {
	bucket := NewLeakyBucket(60, time.Second)
	bucket.Lastupdate = time.Unix(0, 0)

	bucket.Now = func() time.Time { return time.Unix(1, 0) }

	if bucket.Pour(61) {
		t.Error("Expected false")
	}

	if !bucket.Pour(10) {
		t.Error("Expected true")
	}

	if !bucket.Pour(49) {
		t.Error("Expected true")
	}

	if bucket.Pour(2) {
		t.Error("Expected false")
	}

	bucket.Now = func() time.Time { return time.Unix(61, 0) }
	if !bucket.Pour(60) {
		t.Error("Expected true")
	}

	if bucket.Pour(1) {
		t.Error("Expected false")
	}

	bucket.Now = func() time.Time { return time.Unix(70, 0) }

	if !bucket.Pour(1) {
		t.Error("Expected true")
	}

}

func TestTimeSinceLastUpdate(t *testing.T) {
	bucket := NewLeakyBucket(60, time.Second)
	bucket.Now = func() time.Time { return time.Unix(1, 0) }
	bucket.Pour(1)
	bucket.Now = func() time.Time { return time.Unix(2, 0) }

	sinceLast := bucket.TimeSinceLastUpdate()
	if sinceLast != time.Second*1 {
		t.Error("Expected time since last update to be less than 1 second, got %d", sinceLast)
	}
}

func TestTimeToDrain(t *testing.T) {
	bucket := NewLeakyBucket(60, time.Second)
	bucket.Now = func() time.Time { return time.Unix(1, 0) }
	bucket.Pour(10)

	if bucket.TimeToDrain() != time.Second*10 {
		t.Error("Time to drain should be 10 seconds")
	}

	bucket.Now = func() time.Time { return time.Unix(2, 0) }

	if bucket.TimeToDrain() != time.Second*9 {
		t.Error("Time to drain should be 9 seconds")
	}
}
<commit_msg>Use errorf if using a format string<commit_after>package ratelimiter

import (
	"testing"
	"time"
)

func TestPour(t *testing.T) {
	bucket := NewLeakyBucket(60, time.Second)
	bucket.Lastupdate = time.Unix(0, 0)

	bucket.Now = func() time.Time { return time.Unix(1, 0) }

	if bucket.Pour(61) {
		t.Error("Expected false")
	}

	if !bucket.Pour(10) {
		t.Error("Expected true")
	}

	if !bucket.Pour(49) {
		t.Error("Expected true")
	}

	if bucket.Pour(2) {
		t.Error("Expected false")
	}

	bucket.Now = func() time.Time { return time.Unix(61, 0) }
	if !bucket.Pour(60) {
		t.Error("Expected true")
	}

	if bucket.Pour(1) {
		t.Error("Expected false")
	}

	bucket.Now = func() time.Time { return time.Unix(70, 0) }

	if !bucket.Pour(1) {
		t.Error("Expected true")
	}

}

func TestTimeSinceLastUpdate(t *testing.T) {
	bucket := NewLeakyBucket(60, time.Second)
	bucket.Now = func() time.Time { return time.Unix(1, 0) }
	bucket.Pour(1)
	bucket.Now = func() time.Time { return time.Unix(2, 0) }

	sinceLast := bucket.TimeSinceLastUpdate()
	if sinceLast != time.Second*1 {
		t.Errorf("Expected time since last update to be less than 1 second, got %d", sinceLast)
	}
}

func TestTimeToDrain(t *testing.T) {
	bucket := NewLeakyBucket(60, time.Second)
	bucket.Now = func() time.Time { return time.Unix(1, 0) }
	bucket.Pour(10)

	if bucket.TimeToDrain() != time.Second*10 {
		t.Error("Time to drain should be 10 seconds")
	}

	bucket.Now = func() time.Time { return time.Unix(2, 0) }

	if bucket.TimeToDrain() != time.Second*9 {
		t.Error("Time to drain should be 9 seconds")
	}
}
<|endoftext|>


<commit_before>// Code generated by protoc-gen-gogo.
// source: metric.proto
// DO NOT EDIT!

package events

import proto "code.google.com/p/gogoprotobuf/proto"
import math "math"

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = math.Inf

// / A ValueMetric indicates the value of a metric at an instant in time.
type ValueMetric struct {
	Name             *string  `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
	Value            *float64 `protobuf:"fixed64,2,req,name=value" json:"value,omitempty"`
	Unit             *string  `protobuf:"bytes,3,req,name=unit" json:"unit,omitempty"`
	XXX_unrecognized []byte   `json:"-"`
}

func (m *ValueMetric) Reset()         { *m = ValueMetric{} }
func (m *ValueMetric) String() string { return proto.CompactTextString(m) }
func (*ValueMetric) ProtoMessage()    {}

func (m *ValueMetric) GetName() string {
	if m != nil && m.Name != nil {
		return *m.Name
	}
	return ""
}

func (m *ValueMetric) GetValue() float64 {
	if m != nil && m.Value != nil {
		return *m.Value
	}
	return 0
}

func (m *ValueMetric) GetUnit() string {
	if m != nil && m.Unit != nil {
		return *m.Unit
	}
	return ""
}

// / A CounterEvent represents the increment of a counter. It contains only the change in the value; it is the responsibility of downstream consumers to maintain the value of the counter.
type CounterEvent struct {
	Name             *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
	Delta            *uint64 `protobuf:"varint,2,req,name=delta" json:"delta,omitempty"`
	XXX_unrecognized []byte  `json:"-"`
}

func (m *CounterEvent) Reset()         { *m = CounterEvent{} }
func (m *CounterEvent) String() string { return proto.CompactTextString(m) }
func (*CounterEvent) ProtoMessage()    {}

func (m *CounterEvent) GetName() string {
	if m != nil && m.Name != nil {
		return *m.Name
	}
	return ""
}

func (m *CounterEvent) GetDelta() uint64 {
	if m != nil && m.Delta != nil {
		return *m.Delta
	}
	return 0
}

// / A ContainerMetric records resource usage of an app in a container.
type ContainerMetric struct {
	ApplicationId    *string  `protobuf:"bytes,1,req,name=applicationId" json:"applicationId,omitempty"`
	InstanceIndex    *int32   `protobuf:"varint,2,req,name=instanceIndex" json:"instanceIndex,omitempty"`
	CpuPercentage    *float64 `protobuf:"fixed64,3,req,name=cpuPercentage" json:"cpuPercentage,omitempty"`
	MemoryBytes      *uint64  `protobuf:"varint,4,req,name=memoryBytes" json:"memoryBytes,omitempty"`
	DiskBytes        *uint64  `protobuf:"varint,5,req,name=diskBytes" json:"diskBytes,omitempty"`
	XXX_unrecognized []byte   `json:"-"`
}

func (m *ContainerMetric) Reset()         { *m = ContainerMetric{} }
func (m *ContainerMetric) String() string { return proto.CompactTextString(m) }
func (*ContainerMetric) ProtoMessage()    {}

func (m *ContainerMetric) GetApplicationId() string {
	if m != nil && m.ApplicationId != nil {
		return *m.ApplicationId
	}
	return ""
}

func (m *ContainerMetric) GetInstanceIndex() int32 {
	if m != nil && m.InstanceIndex != nil {
		return *m.InstanceIndex
	}
	return 0
}

func (m *ContainerMetric) GetCpuPercentage() float64 {
	if m != nil && m.CpuPercentage != nil {
		return *m.CpuPercentage
	}
	return 0
}

func (m *ContainerMetric) GetMemoryBytes() uint64 {
	if m != nil && m.MemoryBytes != nil {
		return *m.MemoryBytes
	}
	return 0
}

func (m *ContainerMetric) GetDiskBytes() uint64 {
	if m != nil && m.DiskBytes != nil {
		return *m.DiskBytes
	}
	return 0
}

func init() {
}
<commit_msg>Update with Total field on CounterEvent<commit_after>// Code generated by protoc-gen-gogo.
// source: metric.proto
// DO NOT EDIT!

package events

import proto "code.google.com/p/gogoprotobuf/proto"
import math "math"

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = math.Inf

// / A ValueMetric indicates the value of a metric at an instant in time.
type ValueMetric struct {
	Name             *string  `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
	Value            *float64 `protobuf:"fixed64,2,req,name=value" json:"value,omitempty"`
	Unit             *string  `protobuf:"bytes,3,req,name=unit" json:"unit,omitempty"`
	XXX_unrecognized []byte   `json:"-"`
}

func (m *ValueMetric) Reset()         { *m = ValueMetric{} }
func (m *ValueMetric) String() string { return proto.CompactTextString(m) }
func (*ValueMetric) ProtoMessage()    {}

func (m *ValueMetric) GetName() string {
	if m != nil && m.Name != nil {
		return *m.Name
	}
	return ""
}

func (m *ValueMetric) GetValue() float64 {
	if m != nil && m.Value != nil {
		return *m.Value
	}
	return 0
}

func (m *ValueMetric) GetUnit() string {
	if m != nil && m.Unit != nil {
		return *m.Unit
	}
	return ""
}

// / A CounterEvent represents the increment of a counter. It contains only the change in the value; it is the responsibility of downstream consumers to maintain the value of the counter.
type CounterEvent struct {
	Name             *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
	Delta            *uint64 `protobuf:"varint,2,req,name=delta" json:"delta,omitempty"`
	Total            *uint64 `protobuf:"varint,3,opt,name=total" json:"total,omitempty"`
	XXX_unrecognized []byte  `json:"-"`
}

func (m *CounterEvent) Reset()         { *m = CounterEvent{} }
func (m *CounterEvent) String() string { return proto.CompactTextString(m) }
func (*CounterEvent) ProtoMessage()    {}

func (m *CounterEvent) GetName() string {
	if m != nil && m.Name != nil {
		return *m.Name
	}
	return ""
}

func (m *CounterEvent) GetDelta() uint64 {
	if m != nil && m.Delta != nil {
		return *m.Delta
	}
	return 0
}

func (m *CounterEvent) GetTotal() uint64 {
	if m != nil && m.Total != nil {
		return *m.Total
	}
	return 0
}

// / A ContainerMetric records resource usage of an app in a container.
type ContainerMetric struct {
	ApplicationId    *string  `protobuf:"bytes,1,req,name=applicationId" json:"applicationId,omitempty"`
	InstanceIndex    *int32   `protobuf:"varint,2,req,name=instanceIndex" json:"instanceIndex,omitempty"`
	CpuPercentage    *float64 `protobuf:"fixed64,3,req,name=cpuPercentage" json:"cpuPercentage,omitempty"`
	MemoryBytes      *uint64  `protobuf:"varint,4,req,name=memoryBytes" json:"memoryBytes,omitempty"`
	DiskBytes        *uint64  `protobuf:"varint,5,req,name=diskBytes" json:"diskBytes,omitempty"`
	XXX_unrecognized []byte   `json:"-"`
}

func (m *ContainerMetric) Reset()         { *m = ContainerMetric{} }
func (m *ContainerMetric) String() string { return proto.CompactTextString(m) }
func (*ContainerMetric) ProtoMessage()    {}

func (m *ContainerMetric) GetApplicationId() string {
	if m != nil && m.ApplicationId != nil {
		return *m.ApplicationId
	}
	return ""
}

func (m *ContainerMetric) GetInstanceIndex() int32 {
	if m != nil && m.InstanceIndex != nil {
		return *m.InstanceIndex
	}
	return 0
}

func (m *ContainerMetric) GetCpuPercentage() float64 {
	if m != nil && m.CpuPercentage != nil {
		return *m.CpuPercentage
	}
	return 0
}

func (m *ContainerMetric) GetMemoryBytes() uint64 {
	if m != nil && m.MemoryBytes != nil {
		return *m.MemoryBytes
	}
	return 0
}

func (m *ContainerMetric) GetDiskBytes() uint64 {
	if m != nil && m.DiskBytes != nil {
		return *m.DiskBytes
	}
	return 0
}

func init() {
}
<|endoftext|>


<commit_before>package aws

import (
	"testing"

	"github.com/hashicorp/terraform/helper/resource"
)

func TestAccAWSElasticacheCluster_importBasic(t *testing.T) {
	resourceName := "aws_elasticache_cluster.bar"

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSElasticacheClusterDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSElasticacheClusterConfig,
			},

			resource.TestStep{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}
<commit_msg>provider/aws: Set AWS region in elasticache cluster import test<commit_after>package aws

import (
	"os"
	"testing"

	"github.com/hashicorp/terraform/helper/resource"
)

func TestAccAWSElasticacheCluster_importBasic(t *testing.T) {
	oldvar := os.Getenv("AWS_DEFAULT_REGION")
	os.Setenv("AWS_DEFAULT_REGION", "us-east-1")
	defer os.Setenv("AWS_DEFAULT_REGION", oldvar)

	resourceName := "aws_elasticache_cluster.bar"

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSElasticacheClusterDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSElasticacheClusterConfig,
			},

			resource.TestStep{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}
<|endoftext|>


<commit_before>package facebook

import (
	"encoding/json"
	"fmt"
	"github.com/go-errors/errors"
	"net/http"
	"sourcegraph.com/sourcegraph/go-selenium"
	"strings"
)

type Facebook struct {
	// Intentionally empty.
}

const (
	authURL             = "https://www.facebook.com/dialog/oauth?client_id=%v&redirect_uri=%v&scope=public_profile,email"
	exchangeURL         = "https://graph.facebook.com/v2.3/oauth/access_token?client_id=%v&redirect_uri=%v&client_secret=%v&code=%v"
	emailFieldName      = "email"
	passwordFieldName   = "pass"
	loginButtonName     = "login"
	authorizeButtonName = "__CONFIRM__"
	tokenDivID          = "token"
)

func NewFacebook() *Facebook {
	return &Facebook{}
}

func (f *Facebook) GetName() string {
	return "facebook"
}

func (f *Facebook) HandleRedirect(r *http.Request) (string, error) {
	if token := r.URL.Query().Get("code"); len(token) > 0 {
		return token, nil
	} else {
		return "", errors.Errorf("Missing 'code' query string parameter in request '%s'.", r.URL)
	}
}

func (f *Facebook) Authenticate(webDriver selenium.WebDriver, appID, appSecret, username, password, redirectURL string) (string, error) {
	// Load FB auth page.
	if err := webDriver.Get(fmt.Sprintf(authURL, appID, redirectURL)); err != nil {
		return "", errors.Wrap(err, 0)
	}

	// Fill e-mail and password fields, click "Login".
	element, err := webDriver.FindElement(selenium.ByName, emailFieldName)
	if err != nil {
		return "", errors.Wrap(err, 0)
	}
	if err := element.SendKeys(username); err != nil {
		return "", errors.Wrap(err, 0)
	}
	element, err = webDriver.FindElement(selenium.ByName, passwordFieldName)
	if err != nil {
		return "", errors.Wrap(err, 0)
	}
	if err := element.SendKeys(password); err != nil {
		return "", errors.Wrap(err, 0)
	}
	element, err = webDriver.FindElement(selenium.ByName, loginButtonName)
	if err != nil {
		return "", errors.Wrap(err, 0)
	}
	if err := element.Click(); err != nil {
		return "", errors.Wrap(err, 0)
	}

	// If needed, click authorize the app. If the app is already authorized, just continue.
	element, err = webDriver.FindElement(selenium.ByName, authorizeButtonName)
	if err == nil {
		if err := element.Click(); err != nil {
			return "", errors.Wrap(err, 0)
		}
	} else {
		if url, _ := webDriver.CurrentURL(); !strings.HasPrefix(url, redirectURL) {
			return "", errors.Wrap(err, 0)
		}
	}

	// Extract code token from the redirect page.
	element, err = webDriver.FindElement(selenium.ById, tokenDivID)
	if err != nil {
		return "", errors.Wrap(err, 0)
	}
	code, err := element.Text()
	if err != nil {
		return "", errors.Wrap(err, 0)
	}

	// Exchange the code for a OAuth token using the secret app id.
	resp, err := http.Get(fmt.Sprintf(exchangeURL, appID, redirectURL, appSecret, code))
	if err != nil {
		return "", errors.Wrap(err, 0)
	}
	if resp.StatusCode != http.StatusOK {
		return "", errors.Errorf("Token exchange request failed with status %v.", resp.StatusCode)
	}
	exchangeResp := make(map[string]interface{})
	if err := json.NewDecoder(resp.Body).Decode(&exchangeResp); err != nil {
		return "", errors.Wrap(err, 0)
	}

	return exchangeResp["access_token"].(string), nil
}
<commit_msg>Fix Facebook auth.<commit_after>package facebook

import (
	"encoding/json"
	"fmt"
	"github.com/go-errors/errors"
	"net/http"
	"sourcegraph.com/sourcegraph/go-selenium"
	"strings"
)

type Facebook struct {
	// Intentionally empty.
}

const (
	authURL             = "https://www.facebook.com/dialog/oauth?client_id=%v&redirect_uri=%v&scope=public_profile,email"
	exchangeURL         = "https://graph.facebook.com/v2.3/oauth/access_token?client_id=%v&redirect_uri=%v&client_secret=%v&code=%v"
	emailFieldName      = "email"
	passwordFieldName   = "pass"
	loginButtonID = "u_0_2"
	authorizeButtonName = "__CONFIRM__"
	tokenDivID          = "token"
)

func NewFacebook() *Facebook {
	return &Facebook{}
}

func (f *Facebook) GetName() string {
	return "facebook"
}

func (f *Facebook) HandleRedirect(r *http.Request) (string, error) {
	if token := r.URL.Query().Get("code"); len(token) > 0 {
		return token, nil
	} else {
		return "", errors.Errorf("Missing 'code' query string parameter in request '%s'.", r.URL)
	}
}

func (f *Facebook) Authenticate(webDriver selenium.WebDriver, appID, appSecret, username, password, redirectURL string) (string, error) {
	// Load FB auth page.
	if err := webDriver.Get(fmt.Sprintf(authURL, appID, redirectURL)); err != nil {
		return "", errors.Wrap(err, 0)
	}

	// Fill e-mail and password fields, click "Login".
	element, err := webDriver.FindElement(selenium.ByName, emailFieldName)
	if err != nil {
		return "", errors.Wrap(err, 0)
	}
	if err := element.SendKeys(username); err != nil {
		return "", errors.Wrap(err, 0)
	}
	element, err = webDriver.FindElement(selenium.ByName, passwordFieldName)
	if err != nil {
		return "", errors.Wrap(err, 0)
	}
	if err := element.SendKeys(password); err != nil {
		return "", errors.Wrap(err, 0)
	}
	element, err = webDriver.FindElement(selenium.ById, loginButtonID)
	if err != nil {
		return "", errors.Wrap(err, 0)
	}
	if err := element.Click(); err != nil {
		return "", errors.Wrap(err, 0)
	}

	// If needed, click authorize the app. If the app is already authorized, just continue.
	element, err = webDriver.FindElement(selenium.ByName, authorizeButtonName)
	if err == nil {
		if err := element.Click(); err != nil {
			return "", errors.Wrap(err, 0)
		}
	} else {
		if url, _ := webDriver.CurrentURL(); !strings.HasPrefix(url, redirectURL) {
			return "", errors.Wrap(err, 0)
		}
	}

	// Extract code token from the redirect page.
	element, err = webDriver.FindElement(selenium.ById, tokenDivID)
	if err != nil {
		return "", errors.Wrap(err, 0)
	}
	code, err := element.Text()
	if err != nil {
		return "", errors.Wrap(err, 0)
	}

	// Exchange the code for a OAuth token using the secret app id.
	resp, err := http.Get(fmt.Sprintf(exchangeURL, appID, redirectURL, appSecret, code))
	if err != nil {
		return "", errors.Wrap(err, 0)
	}
	if resp.StatusCode != http.StatusOK {
		return "", errors.Errorf("Token exchange request failed with status %v.", resp.StatusCode)
	}
	exchangeResp := make(map[string]interface{})
	if err := json.NewDecoder(resp.Body).Decode(&exchangeResp); err != nil {
		return "", errors.Wrap(err, 0)
	}

	return exchangeResp["access_token"].(string), nil
}
<|endoftext|>