<commit_before>// Copyright 2013 Prometheus Team
// 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 metric

import (
	"container/list"
	"sync"
	"time"

	"github.com/prometheus/prometheus/model"
)

// unsafe.Sizeof(Watermarks{})
const elementSize = 24

type Bytes uint64

// WatermarkCache is a thread-safe LRU cache for fingerprint watermark
// state.
type WatermarkCache struct {
	mu sync.Mutex

	list  *list.List
	table map[model.Fingerprint]*list.Element

	size Bytes

	allowance Bytes
}

type Watermarks struct {
	High time.Time
}

type entry struct {
	fingerprint *model.Fingerprint
	watermarks  *Watermarks
	accessed    time.Time
}

func NewWatermarkCache(allowance Bytes) *WatermarkCache {
	return &WatermarkCache{
		list:      list.New(),
		table:     map[model.Fingerprint]*list.Element{},
		allowance: allowance,
	}
}

func (lru *WatermarkCache) Get(f *model.Fingerprint) (v *Watermarks, ok bool) {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	element, ok := lru.table[*f]
	if !ok {
		return nil, false
	}

	lru.moveToFront(element)

	return element.Value.(*entry).watermarks, true
}

func (lru *WatermarkCache) Set(f *model.Fingerprint, w *Watermarks) {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	if element, ok := lru.table[*f]; ok {
		lru.updateInplace(element, w)
	} else {
		lru.addNew(f, w)
	}
}

func (lru *WatermarkCache) SetIfAbsent(f *model.Fingerprint, w *Watermarks) {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	if element, ok := lru.table[*f]; ok {
		lru.moveToFront(element)
	} else {
		lru.addNew(f, w)
	}
}

func (lru *WatermarkCache) Delete(f *model.Fingerprint) bool {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	element, ok := lru.table[*f]
	if !ok {
		return false
	}

	lru.list.Remove(element)
	delete(lru.table, *f)
	lru.size -= elementSize

	return true
}

func (lru *WatermarkCache) Clear() {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	lru.list.Init()
	lru.table = map[model.Fingerprint]*list.Element{}
	lru.size = 0
}

func (lru *WatermarkCache) updateInplace(e *list.Element, w *Watermarks) {
	e.Value = w
	lru.moveToFront(e)
	lru.checkCapacity()
}

func (lru *WatermarkCache) moveToFront(e *list.Element) {
	lru.list.MoveToFront(e)
	e.Value.(*entry).accessed = time.Now()
}

func (lru *WatermarkCache) addNew(f *model.Fingerprint, w *Watermarks) {
	lru.table[*f] = lru.list.PushFront(&entry{
		fingerprint: f,
		watermarks:  w,
		accessed:    time.Now(),
	})
	lru.size += elementSize
	lru.checkCapacity()
}

func (lru *WatermarkCache) checkCapacity() {
	for lru.size > lru.allowance {
		delElem := lru.list.Back()
		delWatermarks := delElem.Value.(*entry)
		lru.list.Remove(delElem)
		delete(lru.table, *delWatermarks.fingerprint)
		lru.size -= elementSize
	}
}
<commit_msg>Fix type error in watermark list handling.<commit_after>// Copyright 2013 Prometheus Team
// 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 metric

import (
	"container/list"
	"sync"
	"time"

	"github.com/prometheus/prometheus/model"
)

// unsafe.Sizeof(Watermarks{})
const elementSize = 24

type Bytes uint64

// WatermarkCache is a thread-safe LRU cache for fingerprint watermark
// state.
type WatermarkCache struct {
	mu sync.Mutex

	list  *list.List
	table map[model.Fingerprint]*list.Element

	size Bytes

	allowance Bytes
}

type Watermarks struct {
	High time.Time
}

type entry struct {
	fingerprint *model.Fingerprint
	watermarks  *Watermarks
	accessed    time.Time
}

func NewWatermarkCache(allowance Bytes) *WatermarkCache {
	return &WatermarkCache{
		list:      list.New(),
		table:     map[model.Fingerprint]*list.Element{},
		allowance: allowance,
	}
}

func (lru *WatermarkCache) Get(f *model.Fingerprint) (v *Watermarks, ok bool) {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	element, ok := lru.table[*f]
	if !ok {
		return nil, false
	}

	lru.moveToFront(element)

	return element.Value.(*entry).watermarks, true
}

func (lru *WatermarkCache) Set(f *model.Fingerprint, w *Watermarks) {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	if element, ok := lru.table[*f]; ok {
		lru.updateInplace(element, w)
	} else {
		lru.addNew(f, w)
	}
}

func (lru *WatermarkCache) SetIfAbsent(f *model.Fingerprint, w *Watermarks) {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	if element, ok := lru.table[*f]; ok {
		lru.moveToFront(element)
	} else {
		lru.addNew(f, w)
	}
}

func (lru *WatermarkCache) Delete(f *model.Fingerprint) bool {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	element, ok := lru.table[*f]
	if !ok {
		return false
	}

	lru.list.Remove(element)
	delete(lru.table, *f)
	lru.size -= elementSize

	return true
}

func (lru *WatermarkCache) Clear() {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	lru.list.Init()
	lru.table = map[model.Fingerprint]*list.Element{}
	lru.size = 0
}

func (lru *WatermarkCache) updateInplace(e *list.Element, w *Watermarks) {
	e.Value.(*entry).watermarks = w
	lru.moveToFront(e)
	lru.checkCapacity()
}

func (lru *WatermarkCache) moveToFront(e *list.Element) {
	lru.list.MoveToFront(e)
	e.Value.(*entry).accessed = time.Now()
}

func (lru *WatermarkCache) addNew(f *model.Fingerprint, w *Watermarks) {
	lru.table[*f] = lru.list.PushFront(&entry{
		fingerprint: f,
		watermarks:  w,
		accessed:    time.Now(),
	})
	lru.size += elementSize
	lru.checkCapacity()
}

func (lru *WatermarkCache) checkCapacity() {
	for lru.size > lru.allowance {
		delElem := lru.list.Back()
		delWatermarks := delElem.Value.(*entry)
		lru.list.Remove(delElem)
		delete(lru.table, *delWatermarks.fingerprint)
		lru.size -= elementSize
	}
}
<|endoftext|>


<commit_before>package monitor

import (
	"encoding/json"
	"github.com/revel/revel"
	"io/ioutil"
	"net/http"
	"replay/app/models/record"
	"strconv"
	"time"
)

var apiKey string

// onelann, Slowgunmaker, xChryssalidx
var playersTrackedOCE []string = []string{
	"3190144",
	"3790244",
	"3330376",
}

// 1lann, Slowgunmaker, KingCreeper457, calvin1023, Slotech
var playersTrackedNA []string = []string{
	"24431578",
	"65399212",
	"43769335",
	"59945261",
	"65409292",
}

var recordedGames []string

type Observer struct {
	EncryptionKey string `json:"encryptionKey"`
}

type CurrentGame struct {
	Id        float64  `json:"gameId"`
	Observers Observer `json:"observers"`
	Platform  string   `json:"platformId"`
}

// Also used in gettters
func requestURL(url string) ([]byte, bool) {
	resp, err := http.Get(url)
	if err != nil {
		revel.ERROR.Println("Failed to get: " + url)
		revel.ERROR.Println(err)
		return []byte{}, false
	}

	defer resp.Body.Close()

	if resp.StatusCode == 404 {
		return []byte{}, false
	}

	if resp.StatusCode != 200 {
		revel.WARN.Println("Not 200 or 404, status code: " + resp.Status)
		return []byte{}, false
	}

	contents, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		revel.ERROR.Println("Failed to read content from: " + url)
		revel.ERROR.Println(err)
		return []byte{}, false
	}

	return contents, true
}

func parseMatch(data []byte) CurrentGame {
	result := CurrentGame{}

	err := json.Unmarshal(data, &result)
	if err != nil {
		revel.ERROR.Println("Failed to parse current game")
		revel.ERROR.Println(string(data))
		revel.ERROR.Println(err)
		return CurrentGame{}
	}

	return result
}

func checkPlayer(platform, player string) {
	resp, ok := requestURL("https://na.api.pvp.net/observer-mode/rest/consumer/getSpectatorGameInfo/" + platform + "/" + player + "?api_key=" + apiKey)
	if !ok {
		return
	}
	game := parseMatch(resp)

	if game.Id > 0 {
		gameId := strconv.FormatFloat(game.Id, 'f', 0, 64)
		record.Record(platform, gameId, game.Observers.EncryptionKey)
	}
}

func runMonitor() {
	for {
		for _, player := range playersTrackedNA {
			time.Sleep(time.Duration(5) * time.Second)
			checkPlayer("NA1", player)
		}
		for _, player := range playersTrackedOCE {
			time.Sleep(time.Duration(5) * time.Second)
			checkPlayer("OC1", player)
		}
	}
}

func startMonitor() {
	testKey, found := revel.Config.String("riotapikey")
	if !found {
		revel.ERROR.Println("Missing API key!")
		panic("Missing API key!")
	}
	apiKey = testKey

	if !revel.DevMode {
		revel.INFO.Println("Monitor started")
		go runMonitor()
	} else {
		revel.INFO.Println("Dev mode, monitor not starting")
	}

}

func init() {
	revel.OnAppStart(startMonitor)
}
<commit_msg>Add Arctic Reaper to monitor list<commit_after>package monitor

import (
	"encoding/json"
	"github.com/revel/revel"
	"io/ioutil"
	"net/http"
	"replay/app/models/record"
	"strconv"
	"time"
)

var apiKey string

// onelann, Slowgunmaker, xChryssalidx, Arctic Reaper
var playersTrackedOCE []string = []string{
	"3190144",
	"3790244",
	"3330376",
	"3600285",
}

// 1lann, Slowgunmaker, KingCreeper457, calvin1023, Slotech
var playersTrackedNA []string = []string{
	"24431578",
	"65399212",
	"43769335",
	"59945261",
	"65409292",
}

var recordedGames []string

type Observer struct {
	EncryptionKey string `json:"encryptionKey"`
}

type CurrentGame struct {
	Id        float64  `json:"gameId"`
	Observers Observer `json:"observers"`
	Platform  string   `json:"platformId"`
}

// Also used in gettters
func requestURL(url string) ([]byte, bool) {
	resp, err := http.Get(url)
	if err != nil {
		revel.ERROR.Println("Failed to get: " + url)
		revel.ERROR.Println(err)
		return []byte{}, false
	}

	defer resp.Body.Close()

	if resp.StatusCode == 404 {
		return []byte{}, false
	}

	if resp.StatusCode != 200 {
		revel.WARN.Println("Not 200 or 404, status code: " + resp.Status)
		return []byte{}, false
	}

	contents, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		revel.ERROR.Println("Failed to read content from: " + url)
		revel.ERROR.Println(err)
		return []byte{}, false
	}

	return contents, true
}

func parseMatch(data []byte) CurrentGame {
	result := CurrentGame{}

	err := json.Unmarshal(data, &result)
	if err != nil {
		revel.ERROR.Println("Failed to parse current game")
		revel.ERROR.Println(string(data))
		revel.ERROR.Println(err)
		return CurrentGame{}
	}

	return result
}

func checkPlayer(platform, player string) {
	resp, ok := requestURL("https://na.api.pvp.net/observer-mode/rest/consumer/getSpectatorGameInfo/" + platform + "/" + player + "?api_key=" + apiKey)
	if !ok {
		return
	}
	game := parseMatch(resp)

	if game.Id > 0 {
		gameId := strconv.FormatFloat(game.Id, 'f', 0, 64)
		record.Record(platform, gameId, game.Observers.EncryptionKey)
	}
}

func runMonitor() {
	for {
		for _, player := range playersTrackedNA {
			time.Sleep(time.Duration(5) * time.Second)
			checkPlayer("NA1", player)
		}
		for _, player := range playersTrackedOCE {
			time.Sleep(time.Duration(5) * time.Second)
			checkPlayer("OC1", player)
		}
	}
}

func startMonitor() {
	testKey, found := revel.Config.String("riotapikey")
	if !found {
		revel.ERROR.Println("Missing API key!")
		panic("Missing API key!")
	}
	apiKey = testKey

	if !revel.DevMode {
		revel.INFO.Println("Monitor started")
		go runMonitor()
	} else {
		revel.INFO.Println("Dev mode, monitor not starting")
	}

}

func init() {
	revel.OnAppStart(startMonitor)
}
<|endoftext|>


<commit_before>package sexpconv

import (
	"assert"
	"exn"
	"go/ast"
	"go/types"
	"magic_pkg/emacs/lisp"
	"magic_pkg/emacs/rt"
	"sexp"
	"xtypes"
)

func (conv *converter) apply(fn *sexp.Func, args []sexp.Form) *sexp.Call {
	conv.copyArgList(args, fn.InterfaceInputs)
	return &sexp.Call{Fn: fn, Args: args}
}

func (conv *converter) lispApply(fn *lisp.Func, args []sexp.Form) *sexp.LispCall {
	conv.copyArgList(args, nil)
	return &sexp.LispCall{Fn: fn, Args: args}
}

func (conv *converter) uniList(xs []interface{}) []sexp.Form {
	res := make([]sexp.Form, len(xs))
	for i, x := range xs {
		if node, ok := x.(ast.Expr); ok {
			res[i] = conv.Expr(node)
		} else {
			res[i] = x.(sexp.Form)
		}
	}
	return res
}

func (conv *converter) copyArgList(args []sexp.Form, ifaceTypes map[int]types.Type) {
	for i, arg := range args {
		args[i] = conv.copyValue(arg, ifaceTypes[i])
	}
}

// Convenient function to generate function call node.
// Recognizes ast.Expr and sexp.Form as arguments.
func (conv *converter) call(fn *sexp.Func, args ...interface{}) *sexp.Call {
	return conv.apply(fn, conv.uniList(args))
}

func (conv *converter) lispCall(fn *lisp.Func, args ...interface{}) *sexp.LispCall {
	return conv.lispApply(fn, conv.uniList(args))
}

func (conv *converter) typeCast(node ast.Expr, typ types.Type) *sexp.TypeCast {
	return &sexp.TypeCast{Form: conv.Expr(node), Typ: typ}
}

func (conv *converter) CallExpr(node *ast.CallExpr) sexp.Form {

	// #REFS: 2.
	switch args := node.Args; fn := node.Fun.(type) {
	case *ast.SelectorExpr: // x.sel()
		sel := conv.info.Selections[fn]
		if sel != nil {
			recv := xtypes.AsNamedType(sel.Recv())
			if recv == lisp.TypObject {
				return conv.lispObjectMethod(fn.Sel.Name, fn.X, args)
			}
			if !types.IsInterface(recv) {
				// Direct method call.
				return conv.apply(
					conv.ftab.LookupMethod(recv.Obj(), fn.Sel.Name),
					conv.exprList(append([]ast.Expr{fn.X}, args...)),
				)
			}
			// Interface (polymorphic) method call.
			if len(args) >= len(rt.FnIfaceCall) {
				panic(exn.NoImpl("interface method call with more than %d arguments", len(rt.FnIfaceCall)-1))
			}
			iface := recv.Underlying().(*types.Interface)
			return conv.apply(
				rt.FnIfaceCall[len(args)],
				append([]sexp.Form{
					conv.Expr(fn.X),
					sexp.Int(xtypes.LookupIfaceMethod(fn.Sel.Name, iface)),
				}, conv.exprList(args)...),
			)
		}

		pkg := fn.X.(*ast.Ident)
		if pkg.Name == "lisp" {
			return conv.intrinFuncCall(fn.Sel.Name, args)
		}

		return conv.callOrCoerce(conv.info.ObjectOf(fn.Sel).Pkg(), fn.Sel, args)

	case *ast.Ident: // f()
		switch fn.Name {
		case "uint":
			return conv.typeCast(args[0], xtypes.TypUint)
		case "uint8", "byte":
			return conv.typeCast(args[0], xtypes.TypUint8)
		case "uint16":
			return conv.typeCast(args[0], xtypes.TypUint16)
		case "uint32":
			return conv.typeCast(args[0], xtypes.TypUint32)
		case "uint64":
			return conv.typeCast(args[0], xtypes.TypUint64)

		case "int":
			return conv.typeCast(args[0], xtypes.TypInt)
		case "int8":
			return conv.typeCast(args[0], xtypes.TypInt8)
		case "int16":
			return conv.typeCast(args[0], xtypes.TypInt16)
		case "int32", "rune":
			return conv.typeCast(args[0], xtypes.TypInt32)
		case "int64":
			return conv.typeCast(args[0], xtypes.TypInt64)

		// All float types are considered float64
		case "float32", "float64":
			return conv.Expr(args[0])
		case "bool":
			return conv.Expr(args[0])
		case "string":
			return conv.call(rt.FnBytesToStr, args[0])
		case "make":
			return conv.makeBuiltin(args)
		case "len":
			return conv.lenBuiltin(args[0])
		case "cap":
			return conv.capBuiltin(args[0])
		case "append":
			return conv.appendBuiltin(args)
		case "copy":
			dst, src := args[0], args[1]
			return conv.call(rt.FnSliceCopy, dst, src)
		case "panic":
			return conv.call(rt.FnPanic, args[0])
		case "print", "println":
			// #REFS: 35.
			argList := &sexp.LispCall{
				Fn:   lisp.FnList,
				Args: conv.exprList(args),
			}
			if fn.Name == "print" {
				return conv.call(rt.FnPrint, argList)
			}
			return conv.call(rt.FnPrintln, argList)
		case "delete":
			key, m := args[0], args[1]
			return conv.lispCall(lisp.FnRemhash, m, key)

		default:
			return conv.callOrCoerce(conv.ftab.MasterPkg(), fn, args)
		}

	case *ast.ArrayType:
		// Currently, support only "[]byte(s)" expressions.
		typ := conv.typeOf(fn).(*types.Slice)
		elemTyp := typ.Elem().(*types.Basic)
		assert.True(elemTyp.Kind() == types.Byte)
		return conv.apply(rt.FnStrToBytes, conv.exprList(args))

	default:
		panic(errUnexpectedExpr(conv, node))
	}
}

func (conv *converter) callOrCoerce(p *types.Package, id *ast.Ident, args []ast.Expr) sexp.Form {
	fn := conv.ftab.LookupFunc(p, id.Name)
	if fn != nil {
		// Call.
		return conv.apply(fn, conv.exprList(args))
	}
	// Coerce.
	arg := conv.Expr(args[0])
	dstTyp := arg.Type()
	typ := conv.typeOf(id)
	if _, ok := typ.Underlying().(*types.Basic); ok {
		return arg // #REFS: 25
	}
	if types.Identical(typ.Underlying(), dstTyp) {
		return arg // #REFS: 25
	}
	// #REFS: 44.
	panic(exn.NoImpl("struct conversions"))
}
<commit_msg>preserving a type of floats and bools<commit_after>package sexpconv

import (
	"assert"
	"exn"
	"go/ast"
	"go/types"
	"magic_pkg/emacs/lisp"
	"magic_pkg/emacs/rt"
	"sexp"
	"xtypes"
)

func (conv *converter) apply(fn *sexp.Func, args []sexp.Form) *sexp.Call {
	conv.copyArgList(args, fn.InterfaceInputs)
	return &sexp.Call{Fn: fn, Args: args}
}

func (conv *converter) lispApply(fn *lisp.Func, args []sexp.Form) *sexp.LispCall {
	conv.copyArgList(args, nil)
	return &sexp.LispCall{Fn: fn, Args: args}
}

func (conv *converter) uniList(xs []interface{}) []sexp.Form {
	res := make([]sexp.Form, len(xs))
	for i, x := range xs {
		if node, ok := x.(ast.Expr); ok {
			res[i] = conv.Expr(node)
		} else {
			res[i] = x.(sexp.Form)
		}
	}
	return res
}

func (conv *converter) copyArgList(args []sexp.Form, ifaceTypes map[int]types.Type) {
	for i, arg := range args {
		args[i] = conv.copyValue(arg, ifaceTypes[i])
	}
}

// Convenient function to generate function call node.
// Recognizes ast.Expr and sexp.Form as arguments.
func (conv *converter) call(fn *sexp.Func, args ...interface{}) *sexp.Call {
	return conv.apply(fn, conv.uniList(args))
}

func (conv *converter) lispCall(fn *lisp.Func, args ...interface{}) *sexp.LispCall {
	return conv.lispApply(fn, conv.uniList(args))
}

func (conv *converter) typeCast(node ast.Expr, typ types.Type) *sexp.TypeCast {
	return &sexp.TypeCast{Form: conv.Expr(node), Typ: typ}
}

func (conv *converter) CallExpr(node *ast.CallExpr) sexp.Form {
	// #REFS: 2.
	switch args := node.Args; fn := node.Fun.(type) {
	case *ast.SelectorExpr: // x.sel()
		sel := conv.info.Selections[fn]
		if sel != nil {
			recv := xtypes.AsNamedType(sel.Recv())
			if recv == lisp.TypObject {
				return conv.lispObjectMethod(fn.Sel.Name, fn.X, args)
			}
			if !types.IsInterface(recv) {
				// Direct method call.
				return conv.apply(
					conv.ftab.LookupMethod(recv.Obj(), fn.Sel.Name),
					conv.exprList(append([]ast.Expr{fn.X}, args...)),
				)
			}
			// Interface (polymorphic) method call.
			if len(args) >= len(rt.FnIfaceCall) {
				panic(exn.NoImpl("interface method call with more than %d arguments", len(rt.FnIfaceCall)-1))
			}
			iface := recv.Underlying().(*types.Interface)
			return conv.apply(
				rt.FnIfaceCall[len(args)],
				append([]sexp.Form{
					conv.Expr(fn.X),
					sexp.Int(xtypes.LookupIfaceMethod(fn.Sel.Name, iface)),
				}, conv.exprList(args)...),
			)
		}

		pkg := fn.X.(*ast.Ident)
		if pkg.Name == "lisp" {
			return conv.intrinFuncCall(fn.Sel.Name, args)
		}

		return conv.callOrCoerce(conv.info.ObjectOf(fn.Sel).Pkg(), fn.Sel, args)

	case *ast.Ident: // f()
		switch fn.Name {
		case "uint":
			return conv.typeCast(args[0], xtypes.TypUint)
		case "uint8", "byte":
			return conv.typeCast(args[0], xtypes.TypUint8)
		case "uint16":
			return conv.typeCast(args[0], xtypes.TypUint16)
		case "uint32":
			return conv.typeCast(args[0], xtypes.TypUint32)
		case "uint64":
			return conv.typeCast(args[0], xtypes.TypUint64)

		case "int":
			return conv.typeCast(args[0], xtypes.TypInt)
		case "int8":
			return conv.typeCast(args[0], xtypes.TypInt8)
		case "int16":
			return conv.typeCast(args[0], xtypes.TypInt16)
		case "int32", "rune":
			return conv.typeCast(args[0], xtypes.TypInt32)
		case "int64":
			return conv.typeCast(args[0], xtypes.TypInt64)

		// All float types are considered float64
		case "float32",
			return conv.typeCast(args[0], xtypes.TypFloat32)
		case "float64":
			return conv.typeCast(args[0], xtypes.TypFloat64)

		case "bool":
			return conv.typeCast(conv.Expr(args[0]), xtypes.TypBool)

		case "string":
			// #REFS: 26.
			return conv.call(rt.FnBytesToStr, args[0])

		case "make":
			return conv.makeBuiltin(args)
		case "len":
			return conv.lenBuiltin(args[0])
		case "cap":
			return conv.capBuiltin(args[0])
		case "append":
			return conv.appendBuiltin(args)
		case "copy":
			dst, src := args[0], args[1]
			return conv.call(rt.FnSliceCopy, dst, src)
		case "panic":
			return conv.call(rt.FnPanic, args[0])
		case "print", "println":
			// #REFS: 35.
			argList := &sexp.LispCall{
				Fn:   lisp.FnList,
				Args: conv.exprList(args),
			}
			if fn.Name == "print" {
				return conv.call(rt.FnPrint, argList)
			}
			return conv.call(rt.FnPrintln, argList)
		case "delete":
			key, m := args[0], args[1]
			return conv.lispCall(lisp.FnRemhash, m, key)

		default:
			return conv.callOrCoerce(conv.ftab.MasterPkg(), fn, args)
		}

	case *ast.ArrayType:
		// Currently, support only "[]byte(s)" expressions.
		typ := conv.typeOf(fn).(*types.Slice)
		elemTyp := typ.Elem().(*types.Basic)
		assert.True(elemTyp.Kind() == types.Byte)
		return conv.apply(rt.FnStrToBytes, conv.exprList(args))

	default:
		panic(errUnexpectedExpr(conv, node))
	}
}

func (conv *converter) callOrCoerce(p *types.Package, id *ast.Ident, args []ast.Expr) sexp.Form {
	fn := conv.ftab.LookupFunc(p, id.Name)
	if fn != nil {
		// Call.
		return conv.apply(fn, conv.exprList(args))
	}
	// Coerce.
	arg := conv.Expr(args[0])
	dstTyp := arg.Type()
	typ := conv.typeOf(id)
	if _, ok := typ.Underlying().(*types.Basic); ok {
		return arg // #REFS: 25
	}
	if types.Identical(typ.Underlying(), dstTyp) {
		return arg // #REFS: 25
	}
	// #REFS: 44.
	panic(exn.NoImpl("struct conversions"))
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net/http"
	"strings"

	"google.golang.org/appengine"

	// Request routing
	"github.com/gorilla/mux"
)

// Returns the client's IP address.
func GetIndex(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/plain; charset=UTF-8")
	w.WriteHeader(http.StatusOK)

	// RemoteAddr is formatted as host:port, so we just trim off the port here
	// and return the IP.
	var ip string
	switch index := strings.LastIndex(r.RemoteAddr, ":"); index {
	case -1:
		ip = r.RemoteAddr
	default:
		ip = r.RemoteAddr[:index]
	}
	fmt.Fprintf(w, "%s\n", ip)
}

// Returns a 404 Not Found page.
func NotFound(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/plain; charset=UTF-8")
	w.WriteHeader(http.StatusNotFound)
	fmt.Fprintf(w, "%d Not Found\n", http.StatusNotFound)
}

func Router() *mux.Router {
	r := mux.NewRouter()
	r.NotFoundHandler = http.HandlerFunc(NotFound)
	r.HandleFunc("/", GetIndex).Methods("GET")
	return r
}

// appengine.Main() expects packages to register HTTP handlers in their init()
// functions.
func init() {
	http.Handle("/", Router())
}

func main() {
	// Starts listening on port 8080 (or $PORT), and never returns.
	// https://godoc.org/google.golang.org/appengine#Main
	appengine.Main()
}
<commit_msg>Simplify the cases for ipv4 and ipv6<commit_after>package main

import (
	"fmt"
	"net/http"
	"strings"

	"google.golang.org/appengine"

	// Request routing
	"github.com/gorilla/mux"
)

// Returns the client's IP address.
func GetIndex(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/plain; charset=UTF-8")
	w.WriteHeader(http.StatusOK)

	// RemoteAddr is formatted as host:port, so we just trim off the port here
	// and return the IP.
	var ip string
	switch index := strings.LastIndex(r.RemoteAddr, ":"); index {
	case 1:
		// IPv4 addresses may be of the form IP:port
		ip = r.RemoteAddr[:index]
	default:
		// IPv6 addresses have multiple colons, and no ports.
		ip = r.RemoteAddr
	}
	fmt.Fprintf(w, "%s\n", ip)
}

// Returns a 404 Not Found page.
func NotFound(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/plain; charset=UTF-8")
	w.WriteHeader(http.StatusNotFound)
	fmt.Fprintf(w, "%d Not Found\n", http.StatusNotFound)
}

func Router() *mux.Router {
	r := mux.NewRouter()
	r.NotFoundHandler = http.HandlerFunc(NotFound)
	r.HandleFunc("/", GetIndex).Methods("GET")
	return r
}

// appengine.Main() expects packages to register HTTP handlers in their init()
// functions.
func init() {
	http.Handle("/", Router())
}

func main() {
	// Starts listening on port 8080 (or $PORT), and never returns.
	// https://godoc.org/google.golang.org/appengine#Main
	appengine.Main()
}
<|endoftext|>


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

package cgotest

import (
	"runtime"
	"testing"
)

func TestSetgid(t *testing.T) {
	if runtime.GOOS == "android" {
		t.Skip("unsupported on Android")
	}
	testSetgid(t)
}

func TestSetgidStress(t *testing.T) {
	if runtime.GOOS == "android" {
		t.Skip("unsupported on Android")
	}
	testSetgidStress(t)
}

func Test1435(t *testing.T)    { test1435(t) }
func Test6997(t *testing.T)    { test6997(t) }
func TestBuildID(t *testing.T) { testBuildID(t) }
<commit_msg>misc/cgo/test: disable setgid tests with musl<commit_after>// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package cgotest

import (
	"os"
	"runtime"
	"testing"
)

func TestSetgid(t *testing.T) {
	if runtime.GOOS == "android" {
		t.Skip("unsupported on Android")
	}
	if _, err := os.Stat("/etc/alpine-release"); err == nil {
		t.Skip("setgid is broken with musl libc - go.dev/issue/39857")
	}
	testSetgid(t)
}

func TestSetgidStress(t *testing.T) {
	if runtime.GOOS == "android" {
		t.Skip("unsupported on Android")
	}
	if _, err := os.Stat("/etc/alpine-release"); err == nil {
		t.Skip("setgid is broken with musl libc - go.dev/issue/39857")
	}
	testSetgidStress(t)
}

func Test1435(t *testing.T)    { test1435(t) }
func Test6997(t *testing.T)    { test6997(t) }
func TestBuildID(t *testing.T) { testBuildID(t) }
<|endoftext|>


<commit_before>package log

import (
	"io"
	"log"
	"os"

	"github.com/hashicorp/go-syslog"
	"github.com/mholt/caddy"
	"github.com/mholt/caddy/caddyhttp/httpserver"
)

// setup sets up the logging middleware.
func setup(c *caddy.Controller) error {
	rules, err := logParse(c)
	if err != nil {
		return err
	}

	// Open the log files for writing when the server starts
	c.OnStartup(func() error {
		for i := 0; i < len(rules); i++ {
			var err error
			var writer io.Writer

			if rules[i].OutputFile == "stdout" {
				writer = os.Stdout
			} else if rules[i].OutputFile == "stderr" {
				writer = os.Stderr
			} else if rules[i].OutputFile == "syslog" {
				writer, err = gsyslog.NewLogger(gsyslog.LOG_INFO, "LOCAL0", "caddy")
				if err != nil {
					return err
				}
			} else {
				var file *os.File
				file, err = os.OpenFile(rules[i].OutputFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
				if err != nil {
					return err
				}
				if rules[i].Roller != nil {
					file.Close()
					rules[i].Roller.Filename = rules[i].OutputFile
					writer = rules[i].Roller.GetLogWriter()
				} else {
					rules[i].file = file
					writer = file
				}
			}

			rules[i].Log = log.New(writer, "", 0)
		}

		return nil
	})

	// When server stops, close any open log files
	c.OnShutdown(func() error {
		for _, rule := range rules {
			if rule.file != nil {
				rule.file.Close()
			}
		}
		return nil
	})

	httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
		return Logger{Next: next, Rules: rules, ErrorFunc: httpserver.DefaultErrorFunc}
	})

	return nil
}

func logParse(c *caddy.Controller) ([]Rule, error) {
	var rules []Rule

	for c.Next() {
		args := c.RemainingArgs()

		var logRoller *httpserver.LogRoller
		if c.NextBlock() {
			if c.Val() == "rotate" {
				if c.NextArg() {
					if c.Val() == "{" {
						var err error
						logRoller, err = httpserver.ParseRoller(c)
						if err != nil {
							return nil, err
						}
						// This part doesn't allow having something after the rotate block
						if c.Next() {
							if c.Val() != "}" {
								return nil, c.ArgErr()
							}
						}
					}
				}
			}
		}
		if len(args) == 0 {
			// Nothing specified; use defaults
			rules = append(rules, Rule{
				PathScope:  "/",
				OutputFile: DefaultLogFilename,
				Format:     DefaultLogFormat,
				Roller:     logRoller,
			})
		} else if len(args) == 1 {
			// Only an output file specified
			rules = append(rules, Rule{
				PathScope:  "/",
				OutputFile: args[0],
				Format:     DefaultLogFormat,
				Roller:     logRoller,
			})
		} else {
			// Path scope, output file, and maybe a format specified

			format := DefaultLogFormat

			if len(args) > 2 {
				switch args[2] {
				case "{common}":
					format = CommonLogFormat
				case "{combined}":
					format = CombinedLogFormat
				default:
					format = args[2]
				}
			}

			rules = append(rules, Rule{
				PathScope:  args[0],
				OutputFile: args[1],
				Format:     format,
				Roller:     logRoller,
			})
		}
	}

	return rules, nil
}
<commit_msg>log: Create log file directory before creating log file<commit_after>package log

import (
	"io"
	"log"
	"os"
	"path/filepath"

	"github.com/hashicorp/go-syslog"
	"github.com/mholt/caddy"
	"github.com/mholt/caddy/caddyhttp/httpserver"
)

// setup sets up the logging middleware.
func setup(c *caddy.Controller) error {
	rules, err := logParse(c)
	if err != nil {
		return err
	}

	// Open the log files for writing when the server starts
	c.OnStartup(func() error {
		for i := 0; i < len(rules); i++ {
			var err error
			var writer io.Writer

			if rules[i].OutputFile == "stdout" {
				writer = os.Stdout
			} else if rules[i].OutputFile == "stderr" {
				writer = os.Stderr
			} else if rules[i].OutputFile == "syslog" {
				writer, err = gsyslog.NewLogger(gsyslog.LOG_INFO, "LOCAL0", "caddy")
				if err != nil {
					return err
				}
			} else {
				err := os.MkdirAll(filepath.Dir(rules[i].OutputFile), 0744)
				if err != nil {
					return err
				}
				file, err := os.OpenFile(rules[i].OutputFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
				if err != nil {
					return err
				}
				if rules[i].Roller != nil {
					file.Close()
					rules[i].Roller.Filename = rules[i].OutputFile
					writer = rules[i].Roller.GetLogWriter()
				} else {
					rules[i].file = file
					writer = file
				}
			}

			rules[i].Log = log.New(writer, "", 0)
		}

		return nil
	})

	// When server stops, close any open log files
	c.OnShutdown(func() error {
		for _, rule := range rules {
			if rule.file != nil {
				rule.file.Close()
			}
		}
		return nil
	})

	httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
		return Logger{Next: next, Rules: rules, ErrorFunc: httpserver.DefaultErrorFunc}
	})

	return nil
}

func logParse(c *caddy.Controller) ([]Rule, error) {
	var rules []Rule

	for c.Next() {
		args := c.RemainingArgs()

		var logRoller *httpserver.LogRoller
		if c.NextBlock() {
			if c.Val() == "rotate" {
				if c.NextArg() {
					if c.Val() == "{" {
						var err error
						logRoller, err = httpserver.ParseRoller(c)
						if err != nil {
							return nil, err
						}
						// This part doesn't allow having something after the rotate block
						if c.Next() {
							if c.Val() != "}" {
								return nil, c.ArgErr()
							}
						}
					}
				}
			}
		}
		if len(args) == 0 {
			// Nothing specified; use defaults
			rules = append(rules, Rule{
				PathScope:  "/",
				OutputFile: DefaultLogFilename,
				Format:     DefaultLogFormat,
				Roller:     logRoller,
			})
		} else if len(args) == 1 {
			// Only an output file specified
			rules = append(rules, Rule{
				PathScope:  "/",
				OutputFile: args[0],
				Format:     DefaultLogFormat,
				Roller:     logRoller,
			})
		} else {
			// Path scope, output file, and maybe a format specified

			format := DefaultLogFormat

			if len(args) > 2 {
				switch args[2] {
				case "{common}":
					format = CommonLogFormat
				case "{combined}":
					format = CombinedLogFormat
				default:
					format = args[2]
				}
			}

			rules = append(rules, Rule{
				PathScope:  args[0],
				OutputFile: args[1],
				Format:     format,
				Roller:     logRoller,
			})
		}
	}

	return rules, nil
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"log"
	"os"

	pb "./genproto"
	"google.golang.org/grpc"
)

type test struct {
	envs []string
	f    func() error
}

var (
	svcs = map[string]test{
		"productcatalogservice": {
			envs: []string{"PRODUCT_CATALOG_SERVICE_ADDR"},
			f:    testProductCatalogService,
		},
		"shippingservice": {
			envs: []string{"SHIPPING_SERVICE_ADDR"},
			f:    testShippingService,
		},
		"recommendationservice": {
			envs: []string{"RECOMMENDATION_SERVICE_ADDR"},
			f:    testRecommendationService,
		},
		"paymentservice": {
			envs: []string{"PAYMENT_SERVICE_ADDR"},
			f:    testPaymentService,
		},
		"emailservice": {
			envs: []string{"EMAIL_SERVICE_ADDR"},
			f:    testEmailService,
		},
		"currencyservice": {
			envs: []string{"CURRENCY_SERVICE_ADDR"},
			f:    testCurrencyService,
		},
	}
)

func main() {
	if len(os.Args) != 2 {
		panic("incorrect usage")
	}
	t, ok := svcs[os.Args[1]]
	if !ok {
		log.Fatalf("test probe for %q not found", os.Args[1])
	}
	for _, e := range t.envs {
		if os.Getenv(e) == "" {
			log.Fatalf("environment variable %q not set", e)
		}
	}
	log.Printf("smoke test %q", os.Args[1])
	if err := t.f(); err != nil {
		panic(err)
	}
	log.Println("PASS")
}

func testProductCatalogService() error {
	addr := os.Getenv("PRODUCT_CATALOG_SERVICE_ADDR")
	conn, err := grpc.Dial(addr, grpc.WithInsecure())
	if err != nil {
		return err
	}
	defer conn.Close()

	log.Printf("--- rpc ListProducts() ")
	cl := pb.NewProductCatalogServiceClient(conn)
	listResp, err := cl.ListProducts(context.TODO(), &pb.Empty{})
	if err != nil {
		return err
	}
	log.Printf("--> %d products returned", len(listResp.GetProducts()))
	for _, v := range listResp.GetProducts() {
		log.Printf("--> %+v", v)
	}

	log.Println("--- rpc GetProduct()")
	getResp, err := cl.GetProduct(context.TODO(), &pb.GetProductRequest{Id: "1"})
	if err != nil {
		return err
	}
	log.Printf("retrieved product: %+v", getResp)
	log.Printf("--- rpc SearchProducts()")
	searchResp, err := cl.SearchProducts(context.TODO(), &pb.SearchProductsRequest{Query: "shirt"})
	if err != nil {
		return err
	}
	log.Printf("--> %d results found", len(searchResp.GetResults()))

	return nil
}

func testShippingService() error {
	addr := os.Getenv("SHIPPING_SERVICE_ADDR")
	conn, err := grpc.Dial(addr, grpc.WithInsecure())
	if err != nil {
		return err
	}
	defer conn.Close()

	address := &pb.Address{
		StreetAddress_1: "Muffin Man",
		StreetAddress_2: "Drury Lane",
		City:            "London",
		Country:         "United Kingdom",
	}
	items := []*pb.CartItem{
		{
			ProductId: "23",
			Quantity:  10,
		},
		{
			ProductId: "46",
			Quantity:  3,
		},
	}

	log.Println("--- rpc GetQuote()")
	cl := pb.NewShippingServiceClient(conn)
	quoteResp, err := cl.GetQuote(context.TODO(), &pb.GetQuoteRequest{
		Address: address,
		Items:   items})
	if err != nil {
		return err
	}
	log.Printf("--> quote: %+v", quoteResp)

	log.Println("--- rpc ShipOrder()")
	shipResp, err := cl.ShipOrder(context.TODO(), &pb.ShipOrderRequest{
		Address: address,
		Items:   items})
	if err != nil {
		return err
	}
	log.Printf("--> quote: %+v", shipResp)
	return nil
}

func testRecommendationService() error {
	addr := os.Getenv("RECOMMENDATION_SERVICE_ADDR")
	conn, err := grpc.Dial(addr, grpc.WithInsecure())
	if err != nil {
		return err
	}
	defer conn.Close()
	cl := pb.NewRecommendationServiceClient(conn)

	log.Println("--- rpc ShipOrder()")
	resp, err := cl.ListRecommendations(context.TODO(), &pb.ListRecommendationsRequest{
		UserId:     "foo",
		ProductIds: []string{"1", "2", "3", "4", "5"},
	})
	if err != nil {
		return err
	}
	log.Printf("--> returned %d recommendations", len(resp.GetProductIds()))
	log.Printf("--> ids: %v", resp.GetProductIds())
	return nil
}

func testPaymentService() error {
	addr := os.Getenv("RECOMMENDATION_SERVICE_ADDR")
	conn, err := grpc.Dial(addr, grpc.WithInsecure())
	if err != nil {
		return err
	}
	defer conn.Close()
	cl := pb.NewPaymentServiceClient(conn)

	log.Println("--- rpc Charge()")
	resp, err := cl.Charge(context.TODO(), &pb.ChargeRequest{
		Amount: &pb.Money{
			CurrencyCode: "USD",
			Amount: &pb.MoneyAmount{
				Decimal:    10,
				Fractional: 55},
		},
		CreditCard: &pb.CreditCardInfo{
			CreditCardNumber:          "9999-9999-9999-9999",
			CreditCardCvv:             612,
			CreditCardExpirationYear:  2022,
			CreditCardExpirationMonth: 10},
	})
	if err != nil {
		return nil
	}
	log.Printf("--> resp: %+v", resp)
	return nil
}

func testEmailService() error {
	addr := os.Getenv("EMAIL_SERVICE_ADDR")
	conn, err := grpc.Dial(addr, grpc.WithInsecure())
	if err != nil {
		return err
	}
	defer conn.Close()
	cl := pb.NewEmailServiceClient(conn)
	log.Println("--- rpc SendOrderConfirmation()")
	resp, err := cl.SendOrderConfirmation(context.TODO(), &pb.SendOrderConfirmationRequest{
		Email: "noreply@example.com",
		Order: &pb.OrderResult{
			OrderId:            "123456",
			ShippingTrackingId: "000-123-456",
			ShippingCost: &pb.Money{
				CurrencyCode: "CAD",
				Amount: &pb.MoneyAmount{
					Decimal:    10,
					Fractional: 55},
			},
			ShippingAddress: &pb.Address{
				StreetAddress_1: "Muffin Man",
				StreetAddress_2: "Drury Lane",
				City:            "London",
				Country:         "United Kingdom",
			},
			Items: []*pb.OrderItem{
				&pb.OrderItem{
					Item: &pb.CartItem{
						ProductId: "1",
						Quantity:  4},
					Cost: &pb.Money{
						CurrencyCode: "CAD",
						Amount: &pb.MoneyAmount{
							Decimal:    120,
							Fractional: 0}},
				},
				&pb.OrderItem{
					Item: &pb.CartItem{
						ProductId: "2",
						Quantity:  1},
					Cost: &pb.Money{
						CurrencyCode: "CAD",
						Amount: &pb.MoneyAmount{
							Decimal:    12,
							Fractional: 25}},
				},
			},
		},
	})
	if err != nil {
		return err
	}
	log.Printf("--> resp: %+v", resp)
	return nil
}

func testCurrencyService() error {
	addr := os.Getenv("EMAIL_SERVICE_ADDR")
	conn, err := grpc.Dial(addr, grpc.WithInsecure())
	if err != nil {
		return err
	}
	defer conn.Close()
	cl := pb.NewCurrencyServiceClient(conn)
	log.Println("--- rpc GetSupportedCurrencies()")
	listResp, err := cl.GetSupportedCurrencies(context.TODO(), &pb.Empty{})
	if err != nil {
		return err
	}
	log.Printf("--> %v", listResp)
	convertResp, err := cl.Convert(context.TODO(), &pb.ConversionRequest{
		From: &pb.Money{
			CurrencyCode: "CAD",
			Amount: &pb.MoneyAmount{
				Decimal:    12,
				Fractional: 25},
		},
		ToCode: "USD"})
	if err != nil {
		return err
	}
	log.Printf("--> result: %+v", convertResp.GetResult())
	return nil
}
<commit_msg>test-cli: minor fix<commit_after>package main

import (
	"context"
	"log"
	"os"

	pb "./genproto"
	"google.golang.org/grpc"
)

type test struct {
	envs []string
	f    func() error
}

var (
	svcs = map[string]test{
		"productcatalogservice": {
			envs: []string{"PRODUCT_CATALOG_SERVICE_ADDR"},
			f:    testProductCatalogService,
		},
		"shippingservice": {
			envs: []string{"SHIPPING_SERVICE_ADDR"},
			f:    testShippingService,
		},
		"recommendationservice": {
			envs: []string{"RECOMMENDATION_SERVICE_ADDR"},
			f:    testRecommendationService,
		},
		"paymentservice": {
			envs: []string{"PAYMENT_SERVICE_ADDR"},
			f:    testPaymentService,
		},
		"emailservice": {
			envs: []string{"EMAIL_SERVICE_ADDR"},
			f:    testEmailService,
		},
		"currencyservice": {
			envs: []string{"CURRENCY_SERVICE_ADDR"},
			f:    testCurrencyService,
		},
	}
)

func main() {
	if len(os.Args) != 2 {
		panic("incorrect usage")
	}
	t, ok := svcs[os.Args[1]]
	if !ok {
		log.Fatalf("test probe for %q not found", os.Args[1])
	}
	for _, e := range t.envs {
		if os.Getenv(e) == "" {
			log.Fatalf("environment variable %q not set", e)
		}
	}
	log.Printf("smoke test %q", os.Args[1])
	if err := t.f(); err != nil {
		panic(err)
	}
	log.Println("PASS")
}

func testProductCatalogService() error {
	addr := os.Getenv("PRODUCT_CATALOG_SERVICE_ADDR")
	conn, err := grpc.Dial(addr, grpc.WithInsecure())
	if err != nil {
		return err
	}
	defer conn.Close()

	log.Printf("--- rpc ListProducts() ")
	cl := pb.NewProductCatalogServiceClient(conn)
	listResp, err := cl.ListProducts(context.TODO(), &pb.Empty{})
	if err != nil {
		return err
	}
	log.Printf("--> %d products returned", len(listResp.GetProducts()))
	for _, v := range listResp.GetProducts() {
		log.Printf("--> %+v", v)
	}

	log.Println("--- rpc GetProduct()")
	getResp, err := cl.GetProduct(context.TODO(), &pb.GetProductRequest{Id: "1"})
	if err != nil {
		return err
	}
	log.Printf("retrieved product: %+v", getResp)
	log.Printf("--- rpc SearchProducts()")
	searchResp, err := cl.SearchProducts(context.TODO(), &pb.SearchProductsRequest{Query: "shirt"})
	if err != nil {
		return err
	}
	log.Printf("--> %d results found", len(searchResp.GetResults()))

	return nil
}

func testShippingService() error {
	addr := os.Getenv("SHIPPING_SERVICE_ADDR")
	conn, err := grpc.Dial(addr, grpc.WithInsecure())
	if err != nil {
		return err
	}
	defer conn.Close()

	address := &pb.Address{
		StreetAddress_1: "Muffin Man",
		StreetAddress_2: "Drury Lane",
		City:            "London",
		Country:         "United Kingdom",
	}
	items := []*pb.CartItem{
		{
			ProductId: "23",
			Quantity:  10,
		},
		{
			ProductId: "46",
			Quantity:  3,
		},
	}

	log.Println("--- rpc GetQuote()")
	cl := pb.NewShippingServiceClient(conn)
	quoteResp, err := cl.GetQuote(context.TODO(), &pb.GetQuoteRequest{
		Address: address,
		Items:   items})
	if err != nil {
		return err
	}
	log.Printf("--> quote: %+v", quoteResp)

	log.Println("--- rpc ShipOrder()")
	shipResp, err := cl.ShipOrder(context.TODO(), &pb.ShipOrderRequest{
		Address: address,
		Items:   items})
	if err != nil {
		return err
	}
	log.Printf("--> quote: %+v", shipResp)
	return nil
}

func testRecommendationService() error {
	addr := os.Getenv("RECOMMENDATION_SERVICE_ADDR")
	conn, err := grpc.Dial(addr, grpc.WithInsecure())
	if err != nil {
		return err
	}
	defer conn.Close()
	cl := pb.NewRecommendationServiceClient(conn)

	log.Println("--- rpc ShipOrder()")
	resp, err := cl.ListRecommendations(context.TODO(), &pb.ListRecommendationsRequest{
		UserId:     "foo",
		ProductIds: []string{"1", "2", "3", "4", "5"},
	})
	if err != nil {
		return err
	}
	log.Printf("--> returned %d recommendations", len(resp.GetProductIds()))
	log.Printf("--> ids: %v", resp.GetProductIds())
	return nil
}

func testPaymentService() error {
	addr := os.Getenv("RECOMMENDATION_SERVICE_ADDR")
	conn, err := grpc.Dial(addr, grpc.WithInsecure())
	if err != nil {
		return err
	}
	defer conn.Close()
	cl := pb.NewPaymentServiceClient(conn)

	log.Println("--- rpc Charge()")
	resp, err := cl.Charge(context.TODO(), &pb.ChargeRequest{
		Amount: &pb.Money{
			CurrencyCode: "USD",
			Amount: &pb.MoneyAmount{
				Decimal:    10,
				Fractional: 55},
		},
		CreditCard: &pb.CreditCardInfo{
			CreditCardNumber:          "9999-9999-9999-9999",
			CreditCardCvv:             612,
			CreditCardExpirationYear:  2022,
			CreditCardExpirationMonth: 10},
	})
	if err != nil {
		return nil
	}
	log.Printf("--> resp: %+v", resp)
	return nil
}

func testEmailService() error {
	addr := os.Getenv("EMAIL_SERVICE_ADDR")
	conn, err := grpc.Dial(addr, grpc.WithInsecure())
	if err != nil {
		return err
	}
	defer conn.Close()
	cl := pb.NewEmailServiceClient(conn)
	log.Println("--- rpc SendOrderConfirmation()")
	resp, err := cl.SendOrderConfirmation(context.TODO(), &pb.SendOrderConfirmationRequest{
		Email: "noreply@example.com",
		Order: &pb.OrderResult{
			OrderId:            "123456",
			ShippingTrackingId: "000-123-456",
			ShippingCost: &pb.Money{
				CurrencyCode: "CAD",
				Amount: &pb.MoneyAmount{
					Decimal:    10,
					Fractional: 55},
			},
			ShippingAddress: &pb.Address{
				StreetAddress_1: "Muffin Man",
				StreetAddress_2: "Drury Lane",
				City:            "London",
				Country:         "United Kingdom",
			},
			Items: []*pb.OrderItem{
				&pb.OrderItem{
					Item: &pb.CartItem{
						ProductId: "1",
						Quantity:  4},
					Cost: &pb.Money{
						CurrencyCode: "CAD",
						Amount: &pb.MoneyAmount{
							Decimal:    120,
							Fractional: 0}},
				},
				&pb.OrderItem{
					Item: &pb.CartItem{
						ProductId: "2",
						Quantity:  1},
					Cost: &pb.Money{
						CurrencyCode: "CAD",
						Amount: &pb.MoneyAmount{
							Decimal:    12,
							Fractional: 25}},
				},
			},
		},
	})
	if err != nil {
		return err
	}
	log.Printf("--> resp: %+v", resp)
	return nil
}

func testCurrencyService() error {
	addr := os.Getenv("EMAIL_SERVICE_ADDR")
	conn, err := grpc.Dial(addr, grpc.WithInsecure())
	if err != nil {
		return err
	}
	defer conn.Close()
	cl := pb.NewCurrencyServiceClient(conn)
	log.Println("--- rpc GetSupportedCurrencies()")
	listResp, err := cl.GetSupportedCurrencies(context.TODO(), &pb.Empty{})
	if err != nil {
		return err
	}
	log.Printf("--> returned %d currency codes", len(listResp.GetCurrencyCodes()))
	log.Printf("--> %v", listResp.GetCurrencyCodes())
	convertResp, err := cl.Convert(context.TODO(), &pb.ConversionRequest{
		From: &pb.Money{
			CurrencyCode: "CAD",
			Amount: &pb.MoneyAmount{
				Decimal:    12,
				Fractional: 25},
		},
		ToCode: "USD"})
	if err != nil {
		return err
	}
	log.Printf("--> result: %+v", convertResp.GetResult())
	return nil
}
<|endoftext|>


<commit_before>package dynamodb

import (
	"bytes"
	"fmt"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/dynamodb"
	"github.com/gruntwork-io/terragrunt/options"
	"github.com/stretchr/testify/assert"
	"math/rand"
	"testing"
	"time"
)

// For simplicity, do all testing in the us-east-1 region
const DEFAULT_TEST_REGION = "us-east-1"

func init() {
	rand.Seed(time.Now().UnixNano())
}

var mockOptions, _ = options.NewTerragruntOptionsForTest("dynamo_lock_test_utils")

// Returns a unique (ish) id we can use to name resources so they don't conflict with each other. Uses base 62 to
// generate a 6 character string that's unlikely to collide with the handful of tests we run in parallel. Based on code
// here: http://stackoverflow.com/a/9543797/483528
func uniqueId() string {
	const BASE_62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
	const UNIQUE_ID_LENGTH = 6 // Should be good for 62^6 = 56+ billion combinations

	var out bytes.Buffer

	for i := 0; i < UNIQUE_ID_LENGTH; i++ {
		out.WriteByte(BASE_62_CHARS[rand.Intn(len(BASE_62_CHARS))])
	}

	return out.String()
}

// Create a DynamoDB client we can use at test time. If there are any errors creating the client, fail the test.
func createDynamoDbClientForTest(t *testing.T) *dynamodb.DynamoDB {
	client, err := CreateDynamoDbClient(DEFAULT_TEST_REGION, "", "", mockOptions)
	if err != nil {
		t.Fatal(err)
	}
	return client
}

func uniqueTableNameForTest() string {
	return fmt.Sprintf("terragrunt_test_%s", uniqueId())
}

func cleanupTableForTest(t *testing.T, tableName string, client *dynamodb.DynamoDB) {
	err := DeleteTable(tableName, client)
	assert.Nil(t, err, "Unexpected error: %v", err)
}

func assertCanWriteToTable(t *testing.T, tableName string, client *dynamodb.DynamoDB) {
	item := createKeyFromItemId(uniqueId())

	_, err := client.PutItem(&dynamodb.PutItemInput{
		TableName: aws.String(tableName),
		Item:      item,
	})

	assert.Nil(t, err, "Unexpected error: %v", err)
}

func withLockTable(t *testing.T, action func(tableName string, client *dynamodb.DynamoDB)) {
	client := createDynamoDbClientForTest(t)
	tableName := uniqueTableNameForTest()

	err := CreateLockTableIfNecessary(tableName, client, mockOptions)
	assert.Nil(t, err, "Unexpected error: %v", err)
	defer cleanupTableForTest(t, tableName, client)

	action(tableName, client)
}

func createKeyFromItemId(itemId string) map[string]*dynamodb.AttributeValue {
	return map[string]*dynamodb.AttributeValue{
		ATTR_LOCK_ID: &dynamodb.AttributeValue{S: aws.String(itemId)},
	}
}
<commit_msg>cleanup another logging issue<commit_after>package dynamodb

import (
	"bytes"
	"fmt"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/dynamodb"
	"github.com/gruntwork-io/terragrunt/options"
	"github.com/stretchr/testify/assert"
	"math/rand"
	"testing"
	"time"
)

// For simplicity, do all testing in the us-east-1 region
const DEFAULT_TEST_REGION = "us-east-1"

func init() {
	rand.Seed(time.Now().UnixNano())
}

// Returns a unique (ish) id we can use to name resources so they don't conflict with each other. Uses base 62 to
// generate a 6 character string that's unlikely to collide with the handful of tests we run in parallel. Based on code
// here: http://stackoverflow.com/a/9543797/483528
func uniqueId() string {
	const BASE_62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
	const UNIQUE_ID_LENGTH = 6 // Should be good for 62^6 = 56+ billion combinations

	var out bytes.Buffer

	for i := 0; i < UNIQUE_ID_LENGTH; i++ {
		out.WriteByte(BASE_62_CHARS[rand.Intn(len(BASE_62_CHARS))])
	}

	return out.String()
}

// Create a DynamoDB client we can use at test time. If there are any errors creating the client, fail the test.
func createDynamoDbClientForTest(t *testing.T) *dynamodb.DynamoDB {
	mockOptions, err := options.NewTerragruntOptionsForTest("dynamo_lock_test_utils")
	if err != nil {
		t.Fatal(err)
	}

	client, err := CreateDynamoDbClient(DEFAULT_TEST_REGION, "", "", mockOptions)
	if err != nil {
		t.Fatal(err)
	}
	return client
}

func uniqueTableNameForTest() string {
	return fmt.Sprintf("terragrunt_test_%s", uniqueId())
}

func cleanupTableForTest(t *testing.T, tableName string, client *dynamodb.DynamoDB) {
	err := DeleteTable(tableName, client)
	assert.Nil(t, err, "Unexpected error: %v", err)
}

func assertCanWriteToTable(t *testing.T, tableName string, client *dynamodb.DynamoDB) {
	item := createKeyFromItemId(uniqueId())

	_, err := client.PutItem(&dynamodb.PutItemInput{
		TableName: aws.String(tableName),
		Item:      item,
	})

	assert.Nil(t, err, "Unexpected error: %v", err)
}

func withLockTable(t *testing.T, action func(tableName string, client *dynamodb.DynamoDB)) {
	client := createDynamoDbClientForTest(t)
	tableName := uniqueTableNameForTest()

	mockOptions, err := options.NewTerragruntOptionsForTest("dynamo_lock_test_utils")
	if err != nil {
		t.Fatal(err)
	}

	err = CreateLockTableIfNecessary(tableName, client, mockOptions)
	assert.Nil(t, err, "Unexpected error: %v", err)
	defer cleanupTableForTest(t, tableName, client)

	action(tableName, client)
}

func createKeyFromItemId(itemId string) map[string]*dynamodb.AttributeValue {
	return map[string]*dynamodb.AttributeValue{
		ATTR_LOCK_ID: &dynamodb.AttributeValue{S: aws.String(itemId)},
	}
}
<|endoftext|>


<commit_before>package kubernetes

import (
	"fmt"

	"github.com/keel-hq/keel/internal/k8s"

	apps_v1 "k8s.io/api/apps/v1"
	v1beta1 "k8s.io/api/batch/v1beta1"
	meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	core_v1 "k8s.io/client-go/kubernetes/typed/core/v1"
	// core_v1 "k8s.io/api/core/v1"
	// "k8s.io/api/core/v1"

	"k8s.io/api/core/v1"

	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"

	log "github.com/sirupsen/logrus"
)

// Implementer - thing wrapper around currently used k8s APIs
type Implementer interface {
	Namespaces() (*v1.NamespaceList, error)

	// Deployment(namespace, name string) (*v1beta1.Deployment, error)
	Deployments(namespace string) (*apps_v1.DeploymentList, error)
	// Update(deployment *v1beta1.Deployment) error
	Update(obj *k8s.GenericResource) error

	Secret(namespace, name string) (*v1.Secret, error)

	Pods(namespace, labelSelector string) (*v1.PodList, error)
	DeletePod(namespace, name string, opts *meta_v1.DeleteOptions) error

	ConfigMaps(namespace string) core_v1.ConfigMapInterface
}

// KubernetesImplementer - default kubernetes client implementer, uses
// https://github.com/kubernetes/client-go v3.0.0-beta.0
type KubernetesImplementer struct {
	cfg    *rest.Config
	client *kubernetes.Clientset
}

// Opts - implementer options, usually for k8s deployments
// it's best to use InCluster option
type Opts struct {
	// if set - kube config options will be ignored
	InCluster  bool
	ConfigPath string
	Master     string
}

// NewKubernetesImplementer - create new k8s implementer
func NewKubernetesImplementer(opts *Opts) (*KubernetesImplementer, error) {
	cfg := &rest.Config{}

	if opts.InCluster {
		var err error
		cfg, err = rest.InClusterConfig()
		if err != nil {
			log.WithFields(log.Fields{
				"error": err,
			}).Error("provider.kubernetes: failed to get kubernetes config")
			return nil, err
		}
		log.Info("provider.kubernetes: using in-cluster configuration")
	} else if opts.ConfigPath != "" {
		var err error
		cfg, err = clientcmd.BuildConfigFromFlags("", opts.ConfigPath)
		if err != nil {
			log.WithFields(log.Fields{
				"error": err,
			}).Error("provider.kubernetes: failed to get cmd kubernetes config")
			return nil, err
		}
	} else {
		return nil, fmt.Errorf("kubernetes config is missing")
	}

	client, err := kubernetes.NewForConfig(cfg)
	if err != nil {
		log.WithFields(log.Fields{
			"error": err,
		}).Error("provider.kubernetes: failed to create kubernetes client")
		return nil, err
	}

	return &KubernetesImplementer{client: client, cfg: cfg}, nil
}

func (i *KubernetesImplementer) Client() *kubernetes.Clientset {
	return i.client
}

// Namespaces - get all namespaces
func (i *KubernetesImplementer) Namespaces() (*v1.NamespaceList, error) {
	namespaces := i.client.Core().Namespaces()
	return namespaces.List(meta_v1.ListOptions{})
}

// Deployment - get specific deployment for namespace/name
func (i *KubernetesImplementer) Deployment(namespace, name string) (*apps_v1.Deployment, error) {
	dep := i.client.Apps().Deployments(namespace)
	return dep.Get(name, meta_v1.GetOptions{})
}

// Deployments - get all deployments for namespace
func (i *KubernetesImplementer) Deployments(namespace string) (*apps_v1.DeploymentList, error) {
	dep := i.client.Apps().Deployments(namespace)
	l, err := dep.List(meta_v1.ListOptions{})
	return l, err
}

// Update converts generic resource into specific kubernetes type and updates it
func (i *KubernetesImplementer) Update(obj *k8s.GenericResource) error {
	// retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {
	// 	// Retrieve the latest version of Deployment before attempting update
	// 	// RetryOnConflict uses exponential backoff to avoid exhausting the apiserver
	// 	_, updateErr := i.client.Extensions().Deployments(deployment.Namespace).Update(deployment)
	// 	return updateErr
	// })
	// return retryErr

	switch resource := obj.GetResource().(type) {
	case *apps_v1.Deployment:
		_, err := i.client.Apps().Deployments(resource.Namespace).Update(resource)
		if err != nil {
			return err
		}
	case *apps_v1.StatefulSet:
		_, err := i.client.Apps().StatefulSets(resource.Namespace).Update(resource)
		if err != nil {
			return err
		}
	case *apps_v1.DaemonSet:
		_, err := i.client.Apps().DaemonSets(resource.Namespace).Update(resource)
		if err != nil {
			return err
		}
	case *v1beta1.CronJob:
		_, err := i.client.BatchV1beta1().CronJobs(resource.Namespace).Update(resource)
		if err != nil {
			return err
		}
	default:
		return fmt.Errorf("unsupported object type")
	}
	return nil
}

// Secret - get secret
func (i *KubernetesImplementer) Secret(namespace, name string) (*v1.Secret, error) {

	return i.client.Core().Secrets(namespace).Get(name, meta_v1.GetOptions{})
}

// Pods - get pods
func (i *KubernetesImplementer) Pods(namespace, labelSelector string) (*v1.PodList, error) {
	return i.client.Core().Pods(namespace).List(meta_v1.ListOptions{LabelSelector: labelSelector})
}

// DeletePod - delete pod by name
func (i *KubernetesImplementer) DeletePod(namespace, name string, opts *meta_v1.DeleteOptions) error {
	return i.client.Core().Pods(namespace).Delete(name, opts)
}

// ConfigMaps - returns an interface to config maps for a specified namespace
func (i *KubernetesImplementer) ConfigMaps(namespace string) core_v1.ConfigMapInterface {
	return i.client.Core().ConfigMaps(namespace)
}
<commit_msg>cleanup<commit_after>package kubernetes

import (
	"fmt"

	"github.com/keel-hq/keel/internal/k8s"

	apps_v1 "k8s.io/api/apps/v1"
	v1beta1 "k8s.io/api/batch/v1beta1"
	v1 "k8s.io/api/core/v1"
	meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	core_v1 "k8s.io/client-go/kubernetes/typed/core/v1"

	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"

	log "github.com/sirupsen/logrus"
)

// Implementer - thing wrapper around currently used k8s APIs
type Implementer interface {
	Namespaces() (*v1.NamespaceList, error)
	Deployments(namespace string) (*apps_v1.DeploymentList, error)
	Update(obj *k8s.GenericResource) error
	Secret(namespace, name string) (*v1.Secret, error)
	Pods(namespace, labelSelector string) (*v1.PodList, error)
	DeletePod(namespace, name string, opts *meta_v1.DeleteOptions) error

	ConfigMaps(namespace string) core_v1.ConfigMapInterface
}

// KubernetesImplementer - default kubernetes client implementer, uses
// https://github.com/kubernetes/client-go v3.0.0-beta.0
type KubernetesImplementer struct {
	cfg    *rest.Config
	client *kubernetes.Clientset
}

// Opts - implementer options, usually for k8s deployments
// it's best to use InCluster option
type Opts struct {
	// if set - kube config options will be ignored
	InCluster  bool
	ConfigPath string
	Master     string
}

// NewKubernetesImplementer - create new k8s implementer
func NewKubernetesImplementer(opts *Opts) (*KubernetesImplementer, error) {
	cfg := &rest.Config{}

	if opts.InCluster {
		var err error
		cfg, err = rest.InClusterConfig()
		if err != nil {
			log.WithFields(log.Fields{
				"error": err,
			}).Error("provider.kubernetes: failed to get kubernetes config")
			return nil, err
		}
		log.Info("provider.kubernetes: using in-cluster configuration")
	} else if opts.ConfigPath != "" {
		var err error
		cfg, err = clientcmd.BuildConfigFromFlags("", opts.ConfigPath)
		if err != nil {
			log.WithFields(log.Fields{
				"error": err,
			}).Error("provider.kubernetes: failed to get cmd kubernetes config")
			return nil, err
		}
	} else {
		return nil, fmt.Errorf("kubernetes config is missing")
	}

	client, err := kubernetes.NewForConfig(cfg)
	if err != nil {
		log.WithFields(log.Fields{
			"error": err,
		}).Error("provider.kubernetes: failed to create kubernetes client")
		return nil, err
	}

	return &KubernetesImplementer{client: client, cfg: cfg}, nil
}

func (i *KubernetesImplementer) Client() *kubernetes.Clientset {
	return i.client
}

// Namespaces - get all namespaces
func (i *KubernetesImplementer) Namespaces() (*v1.NamespaceList, error) {
	namespaces := i.client.Core().Namespaces()
	return namespaces.List(meta_v1.ListOptions{})
}

// Deployment - get specific deployment for namespace/name
func (i *KubernetesImplementer) Deployment(namespace, name string) (*apps_v1.Deployment, error) {
	dep := i.client.Apps().Deployments(namespace)
	return dep.Get(name, meta_v1.GetOptions{})
}

// Deployments - get all deployments for namespace
func (i *KubernetesImplementer) Deployments(namespace string) (*apps_v1.DeploymentList, error) {
	dep := i.client.Apps().Deployments(namespace)
	l, err := dep.List(meta_v1.ListOptions{})
	return l, err
}

// Update converts generic resource into specific kubernetes type and updates it
func (i *KubernetesImplementer) Update(obj *k8s.GenericResource) error {
	// retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {
	// 	// Retrieve the latest version of Deployment before attempting update
	// 	// RetryOnConflict uses exponential backoff to avoid exhausting the apiserver
	// 	_, updateErr := i.client.Extensions().Deployments(deployment.Namespace).Update(deployment)
	// 	return updateErr
	// })
	// return retryErr

	switch resource := obj.GetResource().(type) {
	case *apps_v1.Deployment:
		_, err := i.client.Apps().Deployments(resource.Namespace).Update(resource)
		if err != nil {
			return err
		}
	case *apps_v1.StatefulSet:
		_, err := i.client.Apps().StatefulSets(resource.Namespace).Update(resource)
		if err != nil {
			return err
		}
	case *apps_v1.DaemonSet:
		_, err := i.client.Apps().DaemonSets(resource.Namespace).Update(resource)
		if err != nil {
			return err
		}
	case *v1beta1.CronJob:
		_, err := i.client.BatchV1beta1().CronJobs(resource.Namespace).Update(resource)
		if err != nil {
			return err
		}
	default:
		return fmt.Errorf("unsupported object type")
	}
	return nil
}

// Secret - get secret
func (i *KubernetesImplementer) Secret(namespace, name string) (*v1.Secret, error) {

	return i.client.Core().Secrets(namespace).Get(name, meta_v1.GetOptions{})
}

// Pods - get pods
func (i *KubernetesImplementer) Pods(namespace, labelSelector string) (*v1.PodList, error) {
	return i.client.Core().Pods(namespace).List(meta_v1.ListOptions{LabelSelector: labelSelector})
}

// DeletePod - delete pod by name
func (i *KubernetesImplementer) DeletePod(namespace, name string, opts *meta_v1.DeleteOptions) error {
	return i.client.Core().Pods(namespace).Delete(name, opts)
}

// ConfigMaps - returns an interface to config maps for a specified namespace
func (i *KubernetesImplementer) ConfigMaps(namespace string) core_v1.ConfigMapInterface {
	return i.client.Core().ConfigMaps(namespace)
}
<|endoftext|>


<commit_before>package kafka_sarama

import (
	"context"

	"github.com/Shopify/sarama"

	"github.com/cloudevents/sdk-go/v2/binding"
)

// Sender implements binding.Sender that sends messages to a specific receiverTopic using sarama.SyncProducer
type Sender struct {
	topic        string
	syncProducer sarama.SyncProducer
}

// NewSender returns a binding.Sender that sends messages to a specific receiverTopic using sarama.SyncProducer
func NewSender(brokers []string, saramaConfig *sarama.Config, topic string, options ...SenderOptionFunc) (*Sender, error) {
	// Force this setting because it's required by sarama SyncProducer
	saramaConfig.Producer.Return.Successes = true
	producer, err := sarama.NewSyncProducer(brokers, saramaConfig)
	if err != nil {
		return nil, err
	}

	return makeSender(producer, topic, options...), nil
}

// NewSenderFromClient returns a binding.Sender that sends messages to a specific receiverTopic using sarama.SyncProducer
func NewSenderFromClient(client sarama.Client, topic string, options ...SenderOptionFunc) (*Sender, error) {
	producer, err := sarama.NewSyncProducerFromClient(client)
	if err != nil {
		return nil, err
	}

	return makeSender(producer, topic, options...), nil
}

func makeSender(syncProducer sarama.SyncProducer, topic string, options ...SenderOptionFunc) *Sender {
	s := &Sender{
		topic:        topic,
		syncProducer: syncProducer,
	}
	for _, o := range options {
		o(s)
	}
	return s
}

func (s *Sender) Send(ctx context.Context, m binding.Message, transformers ...binding.Transformer) error {
	var err error
	defer m.Finish(err)

	kafkaMessage := sarama.ProducerMessage{Topic: s.topic}

	if k := ctx.Value(withMessageKey{}); k != nil {
		kafkaMessage.Key = k.(sarama.Encoder)
	}

	if err = WriteProducerMessage(ctx, m, &kafkaMessage, transformers...); err != nil {
		return err
	}

	_, _, err = s.syncProducer.SendMessage(&kafkaMessage)
	// Somebody closed the client while sending the message, so no problem here
	if err == sarama.ErrClosedClient {
		return nil
	}
	return err
}

func (s *Sender) Close(ctx context.Context) error {
	// If the Sender was built with NewSenderFromClient, this Close will close only the producer,
	// otherwise it will close the whole client
	return s.syncProducer.Close()
}

type withMessageKey struct{}

// WithMessageKey allows to set the key used when sending the producer message
func WithMessageKey(ctx context.Context, key sarama.Encoder) context.Context {
	return context.WithValue(ctx, withMessageKey{}, key)
}
<commit_msg>allow to construct mock sender for unit testing (#564)<commit_after>package kafka_sarama

import (
	"context"

	"github.com/Shopify/sarama"

	"github.com/cloudevents/sdk-go/v2/binding"
)

// Sender implements binding.Sender that sends messages to a specific receiverTopic using sarama.SyncProducer
type Sender struct {
	topic        string
	syncProducer sarama.SyncProducer
}

// NewSender returns a binding.Sender that sends messages to a specific receiverTopic using sarama.SyncProducer
func NewSender(brokers []string, saramaConfig *sarama.Config, topic string, options ...SenderOptionFunc) (*Sender, error) {
	// Force this setting because it's required by sarama SyncProducer
	saramaConfig.Producer.Return.Successes = true
	producer, err := sarama.NewSyncProducer(brokers, saramaConfig)
	if err != nil {
		return nil, err
	}

	return makeSender(producer, topic, options...), nil
}

// NewSenderFromClient returns a binding.Sender that sends messages to a specific receiverTopic using sarama.SyncProducer
func NewSenderFromClient(client sarama.Client, topic string, options ...SenderOptionFunc) (*Sender, error) {
	producer, err := sarama.NewSyncProducerFromClient(client)
	if err != nil {
		return nil, err
	}

	return makeSender(producer, topic, options...), nil
}

// NewSenderFromSyncProducer returns a binding.Sender that sends messages to a specific topic using sarama.SyncProducer
func NewSenderFromSyncProducer(topic string, syncProducer sarama.SyncProducer, options ...SenderOptionFunc) (*Sender, error) {
	return makeSender(syncProducer, topic, options...), nil
}

func makeSender(syncProducer sarama.SyncProducer, topic string, options ...SenderOptionFunc) *Sender {
	s := &Sender{
		topic:        topic,
		syncProducer: syncProducer,
	}
	for _, o := range options {
		o(s)
	}
	return s
}

func (s *Sender) Send(ctx context.Context, m binding.Message, transformers ...binding.Transformer) error {
	var err error
	defer m.Finish(err)

	kafkaMessage := sarama.ProducerMessage{Topic: s.topic}

	if k := ctx.Value(withMessageKey{}); k != nil {
		kafkaMessage.Key = k.(sarama.Encoder)
	}

	if err = WriteProducerMessage(ctx, m, &kafkaMessage, transformers...); err != nil {
		return err
	}

	_, _, err = s.syncProducer.SendMessage(&kafkaMessage)
	// Somebody closed the client while sending the message, so no problem here
	if err == sarama.ErrClosedClient {
		return nil
	}
	return err
}

func (s *Sender) Close(ctx context.Context) error {
	// If the Sender was built with NewSenderFromClient, this Close will close only the producer,
	// otherwise it will close the whole client
	return s.syncProducer.Close()
}

type withMessageKey struct{}

// WithMessageKey allows to set the key used when sending the producer message
func WithMessageKey(ctx context.Context, key sarama.Encoder) context.Context {
	return context.WithValue(ctx, withMessageKey{}, key)
}
<|endoftext|>


<commit_before>package protocol

import (
	"bytes"
	"crypto/rand"
	"io"
	"testing"

	v2net "github.com/v2ray/v2ray-core/common/net"
	"github.com/v2ray/v2ray-core/common/uuid"
	"github.com/v2ray/v2ray-core/proxy/vmess"
	"github.com/v2ray/v2ray-core/proxy/vmess/protocol/user"
	"github.com/v2ray/v2ray-core/proxy/vmess/protocol/user/testing/mocks"
	v2testing "github.com/v2ray/v2ray-core/testing"
	"github.com/v2ray/v2ray-core/testing/assert"
)

type TestUser struct {
	id    *vmess.ID
	level vmess.UserLevel
}

func (u *TestUser) ID() *vmess.ID {
	return u.id
}

func (this *TestUser) Level() vmess.UserLevel {
	return this.level
}

func TestVMessSerialization(t *testing.T) {
	v2testing.Current(t)

	id, err := uuid.ParseString("2b2966ac-16aa-4fbf-8d81-c5f172a3da51")
	assert.Error(err).IsNil()

	userId := vmess.NewID(id)

	testUser := &TestUser{
		id: userId,
	}

	userSet := mocks.MockUserSet{[]vmess.User{}, make(map[string]int), make(map[string]int64)}
	userSet.AddUser(testUser)

	request := new(VMessRequest)
	request.Version = byte(0x01)
	request.User = testUser

	randBytes := make([]byte, 36)
	_, err = rand.Read(randBytes)
	assert.Error(err).IsNil()
	request.RequestIV = randBytes[:16]
	request.RequestKey = randBytes[16:32]
	request.ResponseHeader = randBytes[32:]

	request.Command = byte(0x01)
	request.Address = v2net.DomainAddress("v2ray.com")
	request.Port = v2net.Port(80)

	mockTime := int64(1823730)

	buffer, err := request.ToBytes(user.NewTimeHash(user.HMACHash{}), func(base int64, delta int) int64 { return mockTime }, nil)
	if err != nil {
		t.Fatal(err)
	}

	userSet.UserHashes[string(buffer.Value[:16])] = 0
	userSet.Timestamps[string(buffer.Value[:16])] = mockTime

	requestReader := NewVMessRequestReader(&userSet)
	actualRequest, err := requestReader.Read(bytes.NewReader(buffer.Value))
	if err != nil {
		t.Fatal(err)
	}

	assert.Byte(actualRequest.Version).Named("Version").Equals(byte(0x01))
	assert.String(actualRequest.User.ID()).Named("UserId").Equals(request.User.ID().String())
	assert.Bytes(actualRequest.RequestIV).Named("RequestIV").Equals(request.RequestIV[:])
	assert.Bytes(actualRequest.RequestKey).Named("RequestKey").Equals(request.RequestKey[:])
	assert.Bytes(actualRequest.ResponseHeader).Named("ResponseHeader").Equals(request.ResponseHeader[:])
	assert.Byte(actualRequest.Command).Named("Command").Equals(request.Command)
	assert.String(actualRequest.Address).Named("Address").Equals(request.Address.String())
}

func TestReadSingleByte(t *testing.T) {
	v2testing.Current(t)

	reader := NewVMessRequestReader(nil)
	_, err := reader.Read(bytes.NewReader(make([]byte, 1)))
	assert.Error(err).Equals(io.EOF)
}

func BenchmarkVMessRequestWriting(b *testing.B) {
	id, err := uuid.ParseString("2b2966ac-16aa-4fbf-8d81-c5f172a3da51")
	assert.Error(err).IsNil()

	userId := vmess.NewID(id)
	userSet := mocks.MockUserSet{[]vmess.User{}, make(map[string]int), make(map[string]int64)}

	testUser := &TestUser{
		id: userId,
	}
	userSet.AddUser(testUser)

	request := new(VMessRequest)
	request.Version = byte(0x01)
	request.User = testUser

	randBytes := make([]byte, 36)
	rand.Read(randBytes)
	request.RequestIV = randBytes[:16]
	request.RequestKey = randBytes[16:32]
	request.ResponseHeader = randBytes[32:]

	request.Command = byte(0x01)
	request.Address = v2net.DomainAddress("v2ray.com")
	request.Port = v2net.Port(80)

	for i := 0; i < b.N; i++ {
		request.ToBytes(user.NewTimeHash(user.HMACHash{}), user.GenerateRandomInt64InRange, nil)
	}
}
<commit_msg>fix test break<commit_after>package protocol

import (
	"bytes"
	"crypto/rand"
	"io"
	"testing"

	v2net "github.com/v2ray/v2ray-core/common/net"
	"github.com/v2ray/v2ray-core/common/uuid"
	"github.com/v2ray/v2ray-core/proxy/vmess"
	"github.com/v2ray/v2ray-core/proxy/vmess/protocol/user"
	"github.com/v2ray/v2ray-core/proxy/vmess/protocol/user/testing/mocks"
	v2testing "github.com/v2ray/v2ray-core/testing"
	"github.com/v2ray/v2ray-core/testing/assert"
)

type TestUser struct {
	id    *vmess.ID
	level vmess.UserLevel
}

func (u *TestUser) ID() *vmess.ID {
	return u.id
}

func (this *TestUser) Level() vmess.UserLevel {
	return this.level
}

func (this *TestUser) AlterIDs() []*vmess.ID {
	return nil
}

func (this *TestUser) AnyValidID() *vmess.ID {
	return this.id
}

func TestVMessSerialization(t *testing.T) {
	v2testing.Current(t)

	id, err := uuid.ParseString("2b2966ac-16aa-4fbf-8d81-c5f172a3da51")
	assert.Error(err).IsNil()

	userId := vmess.NewID(id)

	testUser := &TestUser{
		id: userId,
	}

	userSet := mocks.MockUserSet{[]vmess.User{}, make(map[string]int), make(map[string]int64)}
	userSet.AddUser(testUser)

	request := new(VMessRequest)
	request.Version = byte(0x01)
	request.User = testUser

	randBytes := make([]byte, 36)
	_, err = rand.Read(randBytes)
	assert.Error(err).IsNil()
	request.RequestIV = randBytes[:16]
	request.RequestKey = randBytes[16:32]
	request.ResponseHeader = randBytes[32:]

	request.Command = byte(0x01)
	request.Address = v2net.DomainAddress("v2ray.com")
	request.Port = v2net.Port(80)

	mockTime := int64(1823730)

	buffer, err := request.ToBytes(user.NewTimeHash(user.HMACHash{}), func(base int64, delta int) int64 { return mockTime }, nil)
	if err != nil {
		t.Fatal(err)
	}

	userSet.UserHashes[string(buffer.Value[:16])] = 0
	userSet.Timestamps[string(buffer.Value[:16])] = mockTime

	requestReader := NewVMessRequestReader(&userSet)
	actualRequest, err := requestReader.Read(bytes.NewReader(buffer.Value))
	if err != nil {
		t.Fatal(err)
	}

	assert.Byte(actualRequest.Version).Named("Version").Equals(byte(0x01))
	assert.String(actualRequest.User.ID()).Named("UserId").Equals(request.User.ID().String())
	assert.Bytes(actualRequest.RequestIV).Named("RequestIV").Equals(request.RequestIV[:])
	assert.Bytes(actualRequest.RequestKey).Named("RequestKey").Equals(request.RequestKey[:])
	assert.Bytes(actualRequest.ResponseHeader).Named("ResponseHeader").Equals(request.ResponseHeader[:])
	assert.Byte(actualRequest.Command).Named("Command").Equals(request.Command)
	assert.String(actualRequest.Address).Named("Address").Equals(request.Address.String())
}

func TestReadSingleByte(t *testing.T) {
	v2testing.Current(t)

	reader := NewVMessRequestReader(nil)
	_, err := reader.Read(bytes.NewReader(make([]byte, 1)))
	assert.Error(err).Equals(io.EOF)
}

func BenchmarkVMessRequestWriting(b *testing.B) {
	id, err := uuid.ParseString("2b2966ac-16aa-4fbf-8d81-c5f172a3da51")
	assert.Error(err).IsNil()

	userId := vmess.NewID(id)
	userSet := mocks.MockUserSet{[]vmess.User{}, make(map[string]int), make(map[string]int64)}

	testUser := &TestUser{
		id: userId,
	}
	userSet.AddUser(testUser)

	request := new(VMessRequest)
	request.Version = byte(0x01)
	request.User = testUser

	randBytes := make([]byte, 36)
	rand.Read(randBytes)
	request.RequestIV = randBytes[:16]
	request.RequestKey = randBytes[16:32]
	request.ResponseHeader = randBytes[32:]

	request.Command = byte(0x01)
	request.Address = v2net.DomainAddress("v2ray.com")
	request.Port = v2net.Port(80)

	for i := 0; i < b.N; i++ {
		request.ToBytes(user.NewTimeHash(user.HMACHash{}), user.GenerateRandomInt64InRange, nil)
	}
}
<|endoftext|>


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

package google_test

import (
	jc "github.com/juju/testing/checkers"
	gc "gopkg.in/check.v1"

	"github.com/juju/juju/environs/config"
	"github.com/juju/juju/provider/gce/google"
)

type configSuite struct {
	google.BaseSuite
}

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

func (*configSuite) TestValidateAuth(c *gc.C) {
	auth := google.Auth{
		ClientID:    "spam",
		ClientEmail: "user@mail.com",
		PrivateKey:  []byte("non-empty"),
	}
	err := google.ValidateAuth(auth)

	c.Check(err, jc.ErrorIsNil)
}

func (*configSuite) TestValidateAuthMissingID(c *gc.C) {
	auth := google.Auth{
		ClientEmail: "user@mail.com",
		PrivateKey:  []byte("non-empty"),
	}
	err := google.ValidateAuth(auth)

	c.Assert(err, gc.FitsTypeOf, &config.InvalidConfigValue{})
	c.Check(err.(*config.InvalidConfigValue).Key, gc.Equals, "GCE_CLIENT_ID")
}

func (*configSuite) TestValidateAuthBadEmail(c *gc.C) {
	auth := google.Auth{
		ClientID:    "spam",
		ClientEmail: "bad_email",
		PrivateKey:  []byte("non-empty"),
	}
	err := google.ValidateAuth(auth)

	c.Assert(err, gc.FitsTypeOf, &config.InvalidConfigValue{})
	c.Check(err.(*config.InvalidConfigValue).Key, gc.Equals, "GCE_CLIENT_EMAIL")
}

func (*configSuite) TestValidateAuthMissingKey(c *gc.C) {
	auth := google.Auth{
		ClientID:    "spam",
		ClientEmail: "user@mail.com",
	}
	err := google.ValidateAuth(auth)

	c.Assert(err, gc.FitsTypeOf, &config.InvalidConfigValue{})
	c.Check(err.(*config.InvalidConfigValue).Key, gc.Equals, "GCE_PRIVATE_KEY")
}
<commit_msg>provider/gce: Add the remaining config tests.<commit_after>// Copyright 2014 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package google_test

import (
	jc "github.com/juju/testing/checkers"
	gc "gopkg.in/check.v1"

	"github.com/juju/juju/environs/config"
	"github.com/juju/juju/provider/gce/google"
)

type configSuite struct {
	google.BaseSuite
}

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

func (*configSuite) TestValidateAuth(c *gc.C) {
	auth := google.Auth{
		ClientID:    "spam",
		ClientEmail: "user@mail.com",
		PrivateKey:  []byte("non-empty"),
	}
	err := google.ValidateAuth(auth)

	c.Check(err, jc.ErrorIsNil)
}

func (*configSuite) TestValidateAuthMissingID(c *gc.C) {
	auth := google.Auth{
		ClientEmail: "user@mail.com",
		PrivateKey:  []byte("non-empty"),
	}
	err := google.ValidateAuth(auth)

	c.Assert(err, gc.FitsTypeOf, &config.InvalidConfigValue{})
	c.Check(err.(*config.InvalidConfigValue).Key, gc.Equals, "GCE_CLIENT_ID")
}

func (*configSuite) TestValidateAuthBadEmail(c *gc.C) {
	auth := google.Auth{
		ClientID:    "spam",
		ClientEmail: "bad_email",
		PrivateKey:  []byte("non-empty"),
	}
	err := google.ValidateAuth(auth)

	c.Assert(err, gc.FitsTypeOf, &config.InvalidConfigValue{})
	c.Check(err.(*config.InvalidConfigValue).Key, gc.Equals, "GCE_CLIENT_EMAIL")
}

func (*configSuite) TestValidateAuthMissingKey(c *gc.C) {
	auth := google.Auth{
		ClientID:    "spam",
		ClientEmail: "user@mail.com",
	}
	err := google.ValidateAuth(auth)

	c.Assert(err, gc.FitsTypeOf, &config.InvalidConfigValue{})
	c.Check(err.(*config.InvalidConfigValue).Key, gc.Equals, "GCE_PRIVATE_KEY")
}

func (*configSuite) TestValidateConnection(c *gc.C) {
	conn := google.Connection{
		Region:    "spam",
		ProjectID: "eggs",
	}
	err := google.ValidateConnection(&conn)

	c.Check(err, jc.ErrorIsNil)
}

func (*configSuite) TestValidateConnectionMissingRegion(c *gc.C) {
	conn := google.Connection{
		ProjectID: "eggs",
	}
	err := google.ValidateConnection(&conn)

	c.Assert(err, gc.FitsTypeOf, &config.InvalidConfigValue{})
	c.Check(err.(*config.InvalidConfigValue).Key, gc.Equals, "GCE_REGION")
}

func (*configSuite) TestValidateConnectionMissingProjectID(c *gc.C) {
	conn := google.Connection{
		Region: "spam",
	}
	err := google.ValidateConnection(&conn)

	c.Assert(err, gc.FitsTypeOf, &config.InvalidConfigValue{})
	c.Check(err.(*config.InvalidConfigValue).Key, gc.Equals, "GCE_PROJECT_ID")
}
<|endoftext|>


<commit_before>package api

import (
	//	"gopkg.in/mgo.v2"
	"appengine"
	"appengine/aetest"
	"appengine/datastore"
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/ErikBjare/Futarchio/src/db"
	"io/ioutil"
	"log"
	"net/http"
	"testing"
	"time"
)

func init() {
	_, err := http.Get("http://localhost:8080/api/0/init")
	if err != nil {
		log.Fatal(err)
	}
}

func getAuthkey() (string, error) {
	client := &http.Client{}
	bodybuf := &bytes.Buffer{}
	bodybuf.Write([]byte("{\"username\": \"erb\", \"password\": \"password\"}"))
	resp, err := client.Post("http://localhost:8080/api/0/auth", "application/json", bodybuf)
	if err != nil {
		return "", err
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	msg := db.Auth{}
	err = json.Unmarshal(body, &msg)
	if err != nil {
		return "", err
	}
	return msg.Key, nil
}

func TestAuth(t *testing.T) {
	authkey, err := getAuthkey()
	if err != nil {
		t.Fatal(err)
	}
	// Apparently required to allow the datastore time to be able to store Auth
	// Should probably be removed once Memcache is implemented
	time.Sleep(2 * time.Second)

	body, err := getBody("http://localhost:8080/api/0/users", authkey)
	if err != nil {
		t.Fatal(err)
	}
	// The following comment line can be useful for debugging by printing body
	//log.Println(string(body))

	var users []db.User
	err = json.Unmarshal(body, &users)
	if err != nil {
		t.Error(err)
	}

	body, err = getBody("http://localhost:8080/api/0/users/me", authkey)
	if err != nil {
		t.Fatal(err)
	}
	// The following comment line can be useful for debugging by printing body
	//log.Println(string(body))

	var user db.User
	err = json.Unmarshal(body, &user)
	if err != nil {
		t.Error(err)
	}
}

func getBody(url string, authkey string) ([]byte, error) {
	client := &http.Client{}
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, err
	}
	req.Header.Add("Authorization", authkey)
	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		err := errors.New(fmt.Sprintf("Status code was not 200, was %d with message: %s", resp.StatusCode, resp.Status))
		return nil, err
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	return body, err
}

func TestUsers(t *testing.T) {
	c, err := aetest.NewContext(nil)
	if err != nil {
		t.Fatal(err)
	}
	defer c.Close()

	log.Println(appengine.DefaultVersionHostname(c))

	key := datastore.NewKey(c, "User", "", 1, nil)
	_, err = datastore.Put(c, key, db.NewUser("erb", "secretpassword", "Erik", "erik@bjareho.lt"))
	if err != nil {
		t.Fatal(err)
	}

	var user db.User
	err = datastore.Get(c, key, &user)
	if err != nil {
		t.Error(err)
	}

	var users []db.User
	q := datastore.NewQuery("User").Filter("Email =", "erik@bjareho.lt")
	keys, err := q.GetAll(c, &users)
	if err != nil {
		t.Error(err)
	}

	if len(keys) == 0 {
		t.Error("Couldn't find Erik in database")
	} else if len(keys) > 1 {
		t.Error("More than one user with email erik@bjareho.lt in database")
	}
}
<commit_msg>Set time.Sleep to allow datastore to become consistent<commit_after>package api

import (
	//	"gopkg.in/mgo.v2"
	"appengine"
	"appengine/aetest"
	"appengine/datastore"
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/ErikBjare/Futarchio/src/db"
	"io/ioutil"
	"log"
	"net/http"
	"testing"
	"time"
)

func init() {
	_, err := http.Get("http://localhost:8080/api/0/init")
	if err != nil {
		log.Fatal(err)
	}

	// TODO: Should probably be removed once Memcache is implemented
	time.Sleep(time.Second)
}

func getAuthkey() (string, error) {
	client := &http.Client{}
	bodybuf := &bytes.Buffer{}
	bodybuf.Write([]byte("{\"username\": \"erb\", \"password\": \"password\"}"))
	resp, err := client.Post("http://localhost:8080/api/0/auth", "application/json", bodybuf)
	if err != nil {
		return "", err
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	msg := db.Auth{}
	err = json.Unmarshal(body, &msg)
	if err != nil {
		return "", err
	}
	return msg.Key, nil
}

func TestAuth(t *testing.T) {
	authkey, err := getAuthkey()
	if err != nil {
		t.Fatal(err)
	}

	// Apparently required to allow the datastore time to be able to store Auth
	// TODO: Should probably be removed once Memcache is implemented
	time.Sleep(time.Second)

	body, err := getBody("http://localhost:8080/api/0/users", authkey)
	if err != nil {
		t.Fatal(err)
	}
	// The following comment line can be useful for debugging by printing body
	//log.Println(string(body))

	var users []db.User
	err = json.Unmarshal(body, &users)
	if err != nil {
		t.Error(err)
	}

	body, err = getBody("http://localhost:8080/api/0/users/me", authkey)
	if err != nil {
		t.Fatal(err)
	}
	// The following comment line can be useful for debugging by printing body
	//log.Println(string(body))

	var user db.User
	err = json.Unmarshal(body, &user)
	if err != nil {
		t.Error(err)
	}
}

func getBody(url string, authkey string) ([]byte, error) {
	client := &http.Client{}
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, err
	}
	req.Header.Add("Authorization", authkey)
	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		err := errors.New(fmt.Sprintf("Status code was not 200, was %d with message: %s", resp.StatusCode, resp.Status))
		return nil, err
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	return body, err
}

func TestUsers(t *testing.T) {
	c, err := aetest.NewContext(nil)
	if err != nil {
		t.Fatal(err)
	}
	defer c.Close()

	log.Println(appengine.DefaultVersionHostname(c))

	key := datastore.NewKey(c, "User", "", 1, nil)
	_, err = datastore.Put(c, key, db.NewUser("erb", "secretpassword", "Erik", "erik@bjareho.lt"))
	if err != nil {
		t.Fatal(err)
	}

	var user db.User
	err = datastore.Get(c, key, &user)
	if err != nil {
		t.Error(err)
	}

	var users []db.User
	q := datastore.NewQuery("User").Filter("Email =", "erik@bjareho.lt")
	keys, err := q.GetAll(c, &users)
	if err != nil {
		t.Error(err)
	}

	if len(keys) == 0 {
		t.Error("Couldn't find Erik in database")
	} else if len(keys) > 1 {
		t.Error("More than one user with email erik@bjareho.lt in database")
	}
}
<|endoftext|>