<commit_before>package lfucache

import (
	"container/list"
	"errors"
)

// Cache is a LFU cache structure.
type Cache struct {
	capacity      int
	length        int
	frequencyList *frequencyNode
	index         map[string]*node
	evictedChans  list.List
	stats         Statistics
}

// Current item counts and operation counters.
type Statistics struct {
	LenFreq0    int // Number of items at frequency zero, i.e Inserted but not Accessed
	Inserts     int // Number of Insert()s
	Hits        int // Number of hits (Access() to item)
	Misses      int // Number of misses (Access() to non-existant key)
	Evictions   int // Number of evictions (due to size constraints on Insert(), or EvictIf() calls)
	Deletes     int // Number of Delete()s.
	FreqListLen int // Current length of frequency list, i.e. the number of distinct usage levels
}

type frequencyNode struct {
	usage    int
	prev     *frequencyNode
	next     *frequencyNode
	nodeList *node
}

type node struct {
	key    string
	value  interface{}
	parent *frequencyNode
	next   *node
	prev   *node
}

var (
	zeroSizeCache = errors.New("create zero-sized cache")
	emptyLfu      = errors.New("lfu on empty cache")
)

// New initializes a new LFU Cache structure.
func New(capacity int) *Cache {
	if capacity == 0 {
		panic(zeroSizeCache)
	}

	c := Cache{}
	c.capacity = capacity
	c.index = make(map[string]*node, capacity)
	c.frequencyList = &frequencyNode{}
	return &c
}

// Resize the cache to a new capacity. When shrinking, items may get evicted.
func (c *Cache) Resize(capacity int) {
	c.capacity = capacity
	for c.length > c.capacity {
		c.evict(c.lfu())
	}
}

// Insert inserts an item into the cache. If the key already exists, the
// existing item is evicted and the new one inserted.
func (c *Cache) Insert(key string, value interface{}) {
	c.check()

	if n, ok := c.index[key]; ok {
		c.evict(n)
	}

	if c.length == c.capacity {
		c.evict(c.lfu())
	}

	n := &node{}
	n.key = key
	n.value = value
	c.index[key] = n
	c.moveNodeToFn(n, c.frequencyList)
	c.length++
	c.stats.Inserts++

	c.check()
}

// Delete deletes an item from the cache and returns true. Does nothing and
// returns false if the key was not present in the cache.
func (c *Cache) Delete(key string) bool {
	c.check()

	n, ok := c.index[key]
	if ok {
		c.deleteNode(n)
		c.stats.Deletes++
	}

	c.check()

	return ok
}

// Access an item in the cache. Returns "value, ok" similar to map indexing.
// Increases the item's use count.
func (c *Cache) Access(key string) (interface{}, bool) {
	c.check()

	n, ok := c.index[key]
	if !ok {
		c.stats.Misses++
		return nil, false
	}

	nextUsage := n.parent.usage + 1
	var nextFn *frequencyNode
	if n.parent.next == nil || n.parent.next.usage != nextUsage {
		nextFn = c.newFrequencyNode(nextUsage, n.parent, n.parent.next)
	} else {
		nextFn = n.parent.next
	}

	c.moveNodeToFn(n, nextFn)
	c.stats.Hits++

	c.check()

	return n.value, true
}

// Len returns the number of items currently stored in the cache.
func (c *Cache) Len() int {
	return c.length
}

// Cap returns the maximum number of items the cache will hold.
func (c *Cache) Cap() int {
	return c.capacity
}

// Statistics returns the cache statistics.
func (c *Cache) Statistics() Statistics {
	c.check()

	c.stats.LenFreq0 = c.items0()
	c.stats.FreqListLen = c.numFrequencyNodes()
	return c.stats
}

// Evictions registers a channel used to report items that get evicted from
// the cache.  Only items evicted due to LFU or EvictIf() will be sent on the
// channel, not items removed by calling Delete(). The channel must be
// unregistered using UnregisterEvictions() prior to ceasing reads in order to
// avoid deadlocking evictions.
func (c *Cache) Evictions(e chan<- interface{}) {
	c.check()

	c.evictedChans.PushBack(e)
}

// UnregisterEvictions removes the channel from the list of channels to be
// notified on item eviction.  Must be called when there is no longer a reader
// for the channel in question.
func (c *Cache) UnregisterEvictions(e chan<- interface{}) {
	c.check()

	for el := c.evictedChans.Front(); el != nil; el = el.Next() {
		if el.Value.(chan<- interface{}) == e {
			c.evictedChans.Remove(el)
			return
		}
	}
}

// EvictIf applies test to each item in the cache and evicts it if the test
// returns true.  Returns the number of items that was evicted.
func (c *Cache) EvictIf(test func(interface{}) bool) int {
	c.check()

	cnt := 0
	for _, n := range c.index {
		if test(n.value) {
			c.evict(n)
			cnt++
		}
	}

	c.check()

	return cnt
}

func (c *Cache) items0() int {
	cnt := 0
	for n := c.frequencyList.nodeList; n != nil; n = n.next {
		cnt++
	}
	return cnt
}

func (c *Cache) evict(n *node) {
	for c := c.evictedChans.Front(); c != nil; c = c.Next() {
		c.Value.(chan<- interface{}) <- n.value
	}
	c.deleteNode(n)
	c.stats.Evictions++
}

func (c *Cache) deleteNode(n *node) {
	if n.prev != nil {
		n.prev.next = n.next
	}

	if n.next != nil {
		n.next.prev = n.prev
	}

	fn := n.parent
	if fn.nodeList == n {
		fn.nodeList = n.next
	}

	// Delete empty non-head frequency node
	if fn.usage != 0 && fn.nodeList == nil {
		c.deleteFrequencyNode(fn)
	}

	delete(c.index, n.key)
	c.length--
}

func (c *Cache) lfu() *node {
	for fn := c.frequencyList; fn != nil; fn = fn.next {
		if fn.nodeList != nil {
			return fn.nodeList
		}
	}

	panic(emptyLfu)
}

func (c *Cache) newFrequencyNode(usage int, prev, next *frequencyNode) *frequencyNode {
	fn := &frequencyNode{usage, prev, next, nil}
	if fn.prev != nil {
		fn.prev.next = fn
	}
	if fn.next != nil {
		fn.next.prev = fn
	}
	return fn
}

func (c *Cache) deleteFrequencyNode(fn *frequencyNode) {
	if fn.next != nil {
		fn.next.prev = fn.prev
	}

	if fn.prev != nil {
		fn.prev.next = fn.next
	}
}

func (c *Cache) moveNodeToFn(n *node, fn *frequencyNode) {
	if n.prev != nil {
		n.prev.next = n.next
	}

	if n.next != nil {
		n.next.prev = n.prev
	}

	if n.parent != nil {
		if n.parent.nodeList == n {
			n.parent.nodeList = n.next
		}
		if n.parent.nodeList == nil && n.parent.usage != 0 {
			c.deleteFrequencyNode(n.parent)
		}
	}

	n.prev = nil
	n.next = nil

	n.parent = fn
	if fn.nodeList != nil {
		n.next = fn.nodeList
		n.next.prev = n
	}
	fn.nodeList = n
}

func (c *Cache) numFrequencyNodes() int {
	count := 0
	for fn := c.frequencyList; fn != nil; fn = fn.next {
		count++
	}
	return count
}
<commit_msg>Minor refactorings<commit_after>package lfucache

import (
	"container/list"
	"errors"
)

// Cache is a LFU cache structure.
type Cache struct {
	capacity      int
	length        int
	frequencyList *frequencyNode
	index         map[string]*node
	evictedChans  list.List
	stats         Statistics
}

// Current item counts and operation counters.
type Statistics struct {
	LenFreq0    int // Number of items at frequency zero, i.e Inserted but not Accessed
	Inserts     int // Number of Insert()s
	Hits        int // Number of hits (Access() to item)
	Misses      int // Number of misses (Access() to non-existant key)
	Evictions   int // Number of evictions (due to size constraints on Insert(), or EvictIf() calls)
	Deletes     int // Number of Delete()s.
	FreqListLen int // Current length of frequency list, i.e. the number of distinct usage levels
}

type frequencyNode struct {
	usage    int
	prev     *frequencyNode
	next     *frequencyNode
	nodeList *node
}

type node struct {
	key    string
	value  interface{}
	parent *frequencyNode
	next   *node
	prev   *node
}

var (
	zeroSizeCache = errors.New("create zero-sized cache")
	emptyLfu      = errors.New("lfu on empty cache")
)

// New initializes a new LFU Cache structure.
func New(capacity int) *Cache {
	if capacity == 0 {
		panic(zeroSizeCache)
	}

	c := Cache{}
	c.capacity = capacity
	c.index = make(map[string]*node, capacity)
	c.frequencyList = &frequencyNode{}
	return &c
}

// Resize the cache to a new capacity. When shrinking, items may get evicted.
func (c *Cache) Resize(capacity int) {
	c.capacity = capacity
	for c.length > c.capacity {
		c.evict(c.lfu())
	}
}

// Insert inserts an item into the cache. If the key already exists, the
// existing item is evicted and the new one inserted.
func (c *Cache) Insert(key string, value interface{}) {
	c.check()

	if n, ok := c.index[key]; ok {
		c.evict(n)
	}

	if c.length == c.capacity {
		c.evict(c.lfu())
	}

	n := &node{key: key, value: value}
	c.index[key] = n
	c.moveNodeToFn(n, c.frequencyList)
	c.length++
	c.stats.Inserts++

	c.check()
}

// Delete deletes an item from the cache and returns true. Does nothing and
// returns false if the key was not present in the cache.
func (c *Cache) Delete(key string) bool {
	c.check()

	n, ok := c.index[key]
	if ok {
		c.deleteNode(n)
		c.stats.Deletes++
	}

	c.check()

	return ok
}

// Access an item in the cache. Returns "value, ok" similar to map indexing.
// Increases the item's use count.
func (c *Cache) Access(key string) (interface{}, bool) {
	c.check()

	n, ok := c.index[key]
	if !ok {
		c.stats.Misses++
		return nil, false
	}

	nextUsage := n.parent.usage + 1
	var nextFn *frequencyNode
	if n.parent.next == nil || n.parent.next.usage != nextUsage {
		nextFn = c.newFrequencyNode(nextUsage, n.parent)
	} else {
		nextFn = n.parent.next
	}

	c.moveNodeToFn(n, nextFn)
	c.stats.Hits++

	c.check()

	return n.value, true
}

// Len returns the number of items currently stored in the cache.
func (c *Cache) Len() int {
	return c.length
}

// Cap returns the maximum number of items the cache will hold.
func (c *Cache) Cap() int {
	return c.capacity
}

// Statistics returns the cache statistics.
func (c *Cache) Statistics() Statistics {
	c.check()

	c.stats.LenFreq0 = c.items0()
	c.stats.FreqListLen = c.numFrequencyNodes()
	return c.stats
}

// Evictions registers a channel used to report items that get evicted from
// the cache.  Only items evicted due to LFU or EvictIf() will be sent on the
// channel, not items removed by calling Delete(). The channel must be
// unregistered using UnregisterEvictions() prior to ceasing reads in order to
// avoid deadlocking evictions.
func (c *Cache) Evictions(e chan<- interface{}) {
	c.check()

	c.evictedChans.PushBack(e)
}

// UnregisterEvictions removes the channel from the list of channels to be
// notified on item eviction.  Must be called when there is no longer a reader
// for the channel in question.
func (c *Cache) UnregisterEvictions(e chan<- interface{}) {
	c.check()

	for el := c.evictedChans.Front(); el != nil; el = el.Next() {
		if el.Value.(chan<- interface{}) == e {
			c.evictedChans.Remove(el)
			return
		}
	}
}

// EvictIf applies test to each item in the cache and evicts it if the test
// returns true.  Returns the number of items that was evicted.
func (c *Cache) EvictIf(test func(interface{}) bool) int {
	c.check()

	cnt := 0
	for _, n := range c.index {
		if test(n.value) {
			c.evict(n)
			cnt++
		}
	}

	c.check()

	return cnt
}

func (c *Cache) items0() int {
	cnt := 0
	for n := c.frequencyList.nodeList; n != nil; n = n.next {
		cnt++
	}
	return cnt
}

func (c *Cache) evict(n *node) {
	for c := c.evictedChans.Front(); c != nil; c = c.Next() {
		c.Value.(chan<- interface{}) <- n.value
	}
	c.deleteNode(n)
	c.stats.Evictions++
}

func (c *Cache) deleteNode(n *node) {
	if n.prev != nil {
		n.prev.next = n.next
	}

	if n.next != nil {
		n.next.prev = n.prev
	}

	fn := n.parent
	if fn.nodeList == n {
		fn.nodeList = n.next
	}

	if fn.usage != 0 && fn.nodeList == nil {
		c.deleteFrequencyNode(fn)
	}

	delete(c.index, n.key)
	c.length--
}

func (c *Cache) lfu() *node {
	for fn := c.frequencyList; fn != nil; fn = fn.next {
		if fn.nodeList != nil {
			return fn.nodeList
		}
	}

	panic(emptyLfu)
}

func (c *Cache) newFrequencyNode(usage int, parent *frequencyNode) *frequencyNode {
	fn := &frequencyNode{usage, parent, parent.next, nil}

	if fn.next != nil {
		fn.next.prev = fn
	}

	parent.next = fn

	return fn
}

func (c *Cache) deleteFrequencyNode(fn *frequencyNode) {
	if fn.next != nil {
		fn.next.prev = fn.prev
	}

	fn.prev.next = fn.next
}

func (c *Cache) moveNodeToFn(n *node, fn *frequencyNode) {
	if n.prev != nil {
		n.prev.next = n.next
	}

	if n.next != nil {
		n.next.prev = n.prev
	}

	if n.parent != nil {
		if n.parent.nodeList == n {
			n.parent.nodeList = n.next
		}
		if n.parent.nodeList == nil && n.parent.usage != 0 {
			c.deleteFrequencyNode(n.parent)
		}
	}

	n.prev = nil
	n.next = nil

	n.parent = fn
	if fn.nodeList != nil {
		n.next = fn.nodeList
		n.next.prev = n
	}

	fn.nodeList = n
}

func (c *Cache) numFrequencyNodes() int {
	count := 0
	for fn := c.frequencyList; fn != nil; fn = fn.next {
		count++
	}
	return count
}
<|endoftext|>


<commit_before><commit_msg>added abort error<commit_after><|endoftext|>


<commit_before>package gowsev

import (
	"golang.org/x/net/websocket"
)

type evMessage struct {
	id      uint64
	message []byte
}

type evConn struct {
	id                uint64
	conn              *websocket.Conn
	writerMessageChan chan []byte
	writerCloseChan   chan struct{}
}

type evNewConn struct {
	conn              *websocket.Conn
	writerMessageChan chan []byte
	writerCloseChan   chan struct{}
}

var globalNewConnChan chan *evNewConn

type EvContext struct {
	handler           *Handler
	idCounter         uint64
	conns             map[uint64]evConn
	readerMessageChan chan evMessage
	readerCloseChan   chan uint64
	timeout           int // milliseconds
}

func makeContext(handler *Handler) EvContext {
	return EvContext{handler, 0, make(map[uint64]evConn), make(chan evMessage), make(chan uint64), 1000}
}

<commit_msg>context public methods<commit_after>package gowsev

import (
	"time"
	"golang.org/x/net/websocket"
)

type evMessage struct {
	id      uint64
	message []byte
}

type evConn struct {
	id                uint64
	conn              *websocket.Conn
	writerMessageChan chan []byte
	writerCloseChan   chan struct{}
}

type evNewConn struct {
	conn              *websocket.Conn
	writerMessageChan chan []byte
	writerCloseChan   chan struct{}
}

var globalNewConnChan chan *evNewConn

type EvContext struct {
	handler           *Handler
	idCounter         uint64
	conns             map[uint64]evConn
	readerMessageChan chan evMessage
	readerCloseChan   chan uint64
	timeout           time.Duration // int64 nanoseconds
}

func makeContext(handler *Handler) EvContext {
	return EvContext{handler, 0, make(map[uint64]evConn), make(chan evMessage), make(chan uint64), 1000}
}

func (context *EvContext) GetTimeout() time.Duration {
	return context.timeout
}

func (context *EvContext) SetTimeout(timeout time.Duration) {
	context.timeout = timeout
}

func (context *EvContext) AddConn(conn *websocket.Conn) {
	go writer(conn)
}

func (context *EvContext) ListenAndServe(port string) {

}

<|endoftext|>


<commit_before>package fire

import (
	"net/http"

	"github.com/256dpi/fire/coal"

	"github.com/256dpi/jsonapi"
	"gopkg.in/mgo.v2/bson"
)

// An Operation indicates the purpose of a yield to a callback in the processing
// flow of an API request by a controller. These operations may occur multiple
// times during a single request.
type Operation int

// All the available operations.
const (
	_ Operation = iota

	// The list operation will used to authorize the loading of multiple
	// resources from a collection.
	//
	// Note: This operation is also used to load related resources.
	List

	// The find operation will be used to authorize the loading of a specific
	// resource from a collection.
	//
	// Note: This operation is also used to load a specific related resource.
	Find

	// The create operation will be used to authorize and validate the creation
	// of a new resource in a collection.
	Create

	// The update operation will be used to authorize the loading and validate
	// the updating of a specific resource in a collection.
	//
	// Note: Updates can include attributes, relationships or both.
	Update

	// The delete operation will be used to authorize the loading and validate
	// the deletion of a specific resource in a collection.
	Delete

	// The collection action operation will be used to authorize the execution
	// of a callback for a collection action.
	CollectionAction

	// The resource action operation will be used to authorize the execution
	// of a callback for a resource action.
	ResourceAction
)

// Read will return true when this operations does only read data.
func (o Operation) Read() bool {
	return o == List || o == Find
}

// Write will return true when this operation does write data.
func (o Operation) Write() bool {
	return o == Create || o == Update || o == Delete
}

// Action will return true when this operation is a collection or resource action.
func (o Operation) Action() bool {
	return o == CollectionAction || o == ResourceAction
}

// String returns the name of the operation.
func (o Operation) String() string {
	switch o {
	case List:
		return "List"
	case Find:
		return "Find"
	case Create:
		return "Create"
	case Update:
		return "Update"
	case Delete:
		return "Delete"
	case CollectionAction:
		return "CollectionAction"
	case ResourceAction:
		return "ResourceAction"
	}

	return ""
}

// A Context provides useful contextual information.
type Context struct {
	// The current operation in process (read only).
	Operation Operation

	// The query that will be used during an List, Find, Update, Delete or
	// ResourceAction operation to select a list of models or a specific model.
	//
	// On Find, Update and Delete operations, the "_id" key is preset to the
	// resource id, while on forwarded List operations a relationship filter is
	// preset.
	Selector bson.M

	// The query that will be used during an List, Find, Update, Delete or
	// ResourceAction operation to further filter the selection of a list of
	// models or a specific model.
	//
	// On List operations, attribute filters are preset.
	Filter bson.M

	// The Model that will be saved during Create, updated during Update or
	// deleted during Delete.
	Model coal.Model

	// The sorting that will be used during List.
	Sorting []string

	// The filtered fields if at least one is available.
	Fields []string

	// The document that will be written to the client during List, Find, Create
	// and partially Update. The JSON API endpoints which modify a resources
	// relationships do only respond with a header as no other information should
	// be changed.
	//
	// Note: The document will be set before notifiers are run.
	Response *jsonapi.Document

	// The store that is used to retrieve and persist the model (read only).
	Store *coal.SubStore

	// The underlying JSON-API request (read only).
	JSONAPIRequest *jsonapi.Request

	// The underlying HTTP request (read only).
	//
	// Note: The path is not updated when a controller forwards a request to
	// another controller.
	HTTPRequest *http.Request

	// The underlying HTTP response writer. The response writer should only be
	// used during collection or resource actions to write a response or to set
	// custom headers.
	ResponseWriter http.ResponseWriter

	// The Controller that is managing the request (read only).
	Controller *Controller

	// The Group that received the request (read only).
	Group *Group

	// The Tracer used to tracer code execution (read only).
	Tracer *Tracer

	original coal.Model
}

// Query returns the composite query of Selector and Filter.
func (c *Context) Query() bson.M {
	return bson.M{
		"$and": []bson.M{c.Selector, c.Filter},
	}
}

// Original will return the stored version of the model. This method is intended
// to be used to calculate the changed fields during an Update operation. Any
// returned error is already marked as fatal. This function will cache and reuse
// loaded models between multiple callbacks.
//
// Note: The method will panic if being used during any other operation than Update.
func (c *Context) Original() (coal.Model, error) {
	// begin trace
	c.Tracer.Push("fire/Context.Original")

	// check operation
	if c.Operation != Update {
		panic("fire: the original can only be loaded during an update operation")
	}

	// return cached model
	if c.original != nil {
		c.Tracer.Pop()
		return c.original, nil
	}

	// create a new model
	m := c.Model.Meta().Make()

	// read original document
	c.Tracer.Push("mgo/Query.One")
	c.Tracer.Tag("id", c.Model.ID())
	err := c.Store.C(c.Model).FindId(c.Model.ID()).One(m)
	if err != nil {
		return nil, err
	}
	c.Tracer.Pop()

	// cache model
	c.original = coal.Init(m)

	// finish trace
	c.Tracer.Pop()

	return c.original, nil
}
<commit_msg>added clarifications<commit_after>package fire

import (
	"net/http"

	"github.com/256dpi/fire/coal"

	"github.com/256dpi/jsonapi"
	"gopkg.in/mgo.v2/bson"
)

// An Operation indicates the purpose of a yield to a callback in the processing
// flow of an API request by a controller. These operations may occur multiple
// times during a single request.
type Operation int

// All the available operations.
const (
	_ Operation = iota

	// The list operation will used to authorize the loading of multiple
	// resources from a collection.
	//
	// Note: This operation is also used to load related resources.
	List

	// The find operation will be used to authorize the loading of a specific
	// resource from a collection.
	//
	// Note: This operation is also used to load a specific related resource.
	Find

	// The create operation will be used to authorize and validate the creation
	// of a new resource in a collection.
	Create

	// The update operation will be used to authorize the loading and validate
	// the updating of a specific resource in a collection.
	//
	// Note: Updates can include attributes, relationships or both.
	Update

	// The delete operation will be used to authorize the loading and validate
	// the deletion of a specific resource in a collection.
	Delete

	// The collection action operation will be used to authorize the execution
	// of a callback for a collection action.
	CollectionAction

	// The resource action operation will be used to authorize the execution
	// of a callback for a resource action.
	ResourceAction
)

// Read will return true when this operations does only read data.
func (o Operation) Read() bool {
	return o == List || o == Find
}

// Write will return true when this operation does write data.
func (o Operation) Write() bool {
	return o == Create || o == Update || o == Delete
}

// Action will return true when this operation is a collection or resource action.
func (o Operation) Action() bool {
	return o == CollectionAction || o == ResourceAction
}

// String returns the name of the operation.
func (o Operation) String() string {
	switch o {
	case List:
		return "List"
	case Find:
		return "Find"
	case Create:
		return "Create"
	case Update:
		return "Update"
	case Delete:
		return "Delete"
	case CollectionAction:
		return "CollectionAction"
	case ResourceAction:
		return "ResourceAction"
	}

	return ""
}

// A Context provides useful contextual information.
type Context struct {
	// The current operation in process (read only).
	Operation Operation

	// The query that will be used during an List, Find, Update, Delete or
	// ResourceAction operation to select a list of models or a specific model.
	//
	// On Find, Update and Delete operations, the "_id" key is preset to the
	// resource id, while on forwarded List operations the relationship filter
	// is preset.
	Selector bson.M

	// The query that will be used during an List, Find, Update, Delete or
	// ResourceAction operation to further filter the selection of a list of
	// models or a specific model.
	//
	// On List operations, attribute and relationship filters are preset.
	Filter bson.M

	// The Model that will be saved during Create, updated during Update or
	// deleted during Delete.
	Model coal.Model

	// The sorting that will be used during List.
	Sorting []string

	// The filtered fields if at least one is available.
	Fields []string

	// The document that will be written to the client during List, Find, Create
	// and Update.
	//
	// Note: The document will be set before notifiers are run.
	Response *jsonapi.Document

	// The store that is used to retrieve and persist the model (read only).
	Store *coal.SubStore

	// The underlying JSON-API request (read only).
	JSONAPIRequest *jsonapi.Request

	// The underlying HTTP request (read only).
	//
	// Note: The path is not updated when a controller forwards a request to
	// a related controller.
	HTTPRequest *http.Request

	// The underlying HTTP response writer. The response writer should only be
	// used during collection or resource actions to write a custom response.
	ResponseWriter http.ResponseWriter

	// The Controller that is managing the request (read only).
	Controller *Controller

	// The Group that received the request (read only).
	Group *Group

	// The Tracer used to tracer code execution (read only).
	Tracer *Tracer

	original coal.Model
}

// Query returns the composite query of Selector and Filter.
func (c *Context) Query() bson.M {
	return bson.M{
		"$and": []bson.M{c.Selector, c.Filter},
	}
}

// Original will return the stored version of the model. This method is intended
// to be used to calculate the changed fields during an Update operation. Any
// returned error is already marked as fatal. This function will cache and reuse
// loaded models between multiple callbacks.
//
// Note: The method will panic if being used during any other operation than Update.
func (c *Context) Original() (coal.Model, error) {
	// begin trace
	c.Tracer.Push("fire/Context.Original")

	// check operation
	if c.Operation != Update {
		panic("fire: the original can only be loaded during an update operation")
	}

	// return cached model
	if c.original != nil {
		c.Tracer.Pop()
		return c.original, nil
	}

	// create a new model
	m := c.Model.Meta().Make()

	// read original document
	c.Tracer.Push("mgo/Query.One")
	c.Tracer.Tag("id", c.Model.ID())
	err := c.Store.C(c.Model).FindId(c.Model.ID()).One(m)
	if err != nil {
		return nil, err
	}
	c.Tracer.Pop()

	// cache model
	c.original = coal.Init(m)

	// finish trace
	c.Tracer.Pop()

	return c.original, nil
}
<|endoftext|>


<commit_before>package fauxgl

import (
	"image"
	"image/draw"
	"math"
	"runtime"
	"sync"
)

type Context struct {
	Width        int
	Height       int
	ColorBuffer  *image.NRGBA
	DepthBuffer  []float64
	screenMatrix Matrix
	locks        []sync.Mutex
}

func NewContext(width, height int) *Context {
	dc := &Context{}
	dc.Width = width
	dc.Height = height
	dc.ColorBuffer = image.NewNRGBA(image.Rect(0, 0, width, height))
	dc.DepthBuffer = make([]float64, width*height)
	dc.screenMatrix = Screen(width, height)
	dc.locks = make([]sync.Mutex, 256)
	dc.ClearDepthBuffer()
	return dc
}

func (dc *Context) Image() image.Image {
	return dc.ColorBuffer
}

func (dc *Context) ClearColorBuffer(color Vector) {
	im := dc.ColorBuffer
	src := image.NewUniform(color.NRGBA())
	draw.Draw(im, im.Bounds(), src, image.ZP, draw.Src)
}

func (dc *Context) ClearDepthBuffer() {
	for i := range dc.DepthBuffer {
		dc.DepthBuffer[i] = math.MaxFloat64
	}
}

func (dc *Context) rasterize(v1, v2, v3 Vertex, s1, s2, s3 Vector, shader Shader) {
	min := s1.Min(s2.Min(s3)).Floor()
	max := s1.Max(s2.Max(s3)).Ceil()
	x1 := int(min.X)
	x2 := int(max.X)
	y1 := int(min.Y)
	y2 := int(max.Y)
	ra := 1 / ((s3.X-s1.X)*(s2.Y-s1.Y) - (s3.Y-s1.Y)*(s2.X-s1.X))
	r1 := 1 / v1.Output.W
	r2 := 1 / v2.Output.W
	r3 := 1 / v3.Output.W
	for y := y1; y <= y2; y++ {
		for x := x1; x <= x2; x++ {
			p := Vector{float64(x) + 0.5, float64(y) + 0.5, 0}
			bx := (p.X-s2.X)*(s3.Y-s2.Y) - (p.Y-s2.Y)*(s3.X-s2.X)
			if bx < 0 {
				continue
			}
			by := (p.X-s3.X)*(s1.Y-s3.Y) - (p.Y-s3.Y)*(s1.X-s3.X)
			if by < 0 {
				continue
			}
			bz := (p.X-s1.X)*(s2.Y-s1.Y) - (p.Y-s1.Y)*(s2.X-s1.X)
			if bz < 0 {
				continue
			}
			bx *= ra
			by *= ra
			bz *= ra
			z := bx*s1.Z + by*s2.Z + bz*s3.Z
			i := y*dc.Width + x
			if z >= dc.DepthBuffer[i] { // completely safe?
				continue
			}
			b := VectorW{bx * r1, by * r2, bz * r3, 0}
			b.W = 1 / (b.X + b.Y + b.Z)
			v := InterpolateVertexes(v1, v2, v3, b)
			color := shader.Fragment(v)
			if color == Discard {
				continue
			}
			c := color.NRGBA()
			lock := &dc.locks[(x+y)&255]
			lock.Lock()
			if z < dc.DepthBuffer[i] {
				dc.DepthBuffer[i] = z
				dc.ColorBuffer.SetNRGBA(x, y, c)
			}
			lock.Unlock()
		}
	}
}

func (dc *Context) drawClipped(v1, v2, v3 Vertex, shader Shader) {
	ndc1 := v1.Output.DivScalar(v1.Output.W).Vector()
	ndc2 := v2.Output.DivScalar(v2.Output.W).Vector()
	ndc3 := v3.Output.DivScalar(v3.Output.W).Vector()

	// back face culling
	var sum float64
	sum += (ndc2.X - ndc1.X) * (ndc2.Y + ndc1.Y)
	sum += (ndc3.X - ndc2.X) * (ndc3.Y + ndc2.Y)
	sum += (ndc1.X - ndc3.X) * (ndc1.Y + ndc3.Y)
	if sum >= 0 {
		return
	}

	s1 := dc.screenMatrix.MulPosition(ndc1)
	s2 := dc.screenMatrix.MulPosition(ndc2)
	s3 := dc.screenMatrix.MulPosition(ndc3)
	dc.rasterize(v1, v2, v3, s1, s2, s3, shader)
}

func (dc *Context) DrawTriangle(t *Triangle, shader Shader) {
	v1 := shader.Vertex(t.V1)
	v2 := shader.Vertex(t.V2)
	v3 := shader.Vertex(t.V3)
	if v1.Outside() || v2.Outside() || v3.Outside() {
		triangles := ClipTriangle(NewTriangle(v1, v2, v3))
		for _, t := range triangles {
			dc.drawClipped(t.V1, t.V2, t.V3, shader)
		}
	} else {
		dc.drawClipped(v1, v2, v3, shader)
	}
}

func (dc *Context) DrawTriangles(triangles []*Triangle, shader Shader) {
	wn := runtime.NumCPU()
	done := make(chan bool, wn)
	for wi := 0; wi < wn; wi++ {
		go func(wi int) {
			for i, t := range triangles {
				if i%wn == wi {
					dc.DrawTriangle(t, shader)
				}
			}
			done <- true
		}(wi)
	}
	for wi := 0; wi < wn; wi++ {
		<-done
	}
}

func (dc *Context) DrawMesh(mesh *Mesh, shader Shader) {
	dc.DrawTriangles(mesh.Triangles, shader)
}
<commit_msg>forward differencing rasterization<commit_after>package fauxgl

import (
	"image"
	"image/draw"
	"math"
	"runtime"
	"sync"
)

type Context struct {
	Width        int
	Height       int
	ColorBuffer  *image.NRGBA
	DepthBuffer  []float64
	screenMatrix Matrix
	locks        []sync.Mutex
}

func NewContext(width, height int) *Context {
	dc := &Context{}
	dc.Width = width
	dc.Height = height
	dc.ColorBuffer = image.NewNRGBA(image.Rect(0, 0, width, height))
	dc.DepthBuffer = make([]float64, width*height)
	dc.screenMatrix = Screen(width, height)
	dc.locks = make([]sync.Mutex, 256)
	dc.ClearDepthBuffer()
	return dc
}

func (dc *Context) Image() image.Image {
	return dc.ColorBuffer
}

func (dc *Context) ClearColorBuffer(color Vector) {
	im := dc.ColorBuffer
	src := image.NewUniform(color.NRGBA())
	draw.Draw(im, im.Bounds(), src, image.ZP, draw.Src)
}

func (dc *Context) ClearDepthBuffer() {
	for i := range dc.DepthBuffer {
		dc.DepthBuffer[i] = math.MaxFloat64
	}
}

func edge(a, b, c Vector) float64 {
	return (b.X-a.X)*(c.Y-a.Y) - (b.Y-a.Y)*(c.X-a.X)
}

func (dc *Context) rasterize(v0, v1, v2 Vertex, s0, s1, s2 Vector, shader Shader) {
	min := s0.Min(s1.Min(s2)).Floor()
	max := s0.Max(s1.Max(s2)).Ceil()
	x0 := int(min.X)
	x1 := int(max.X)
	y0 := int(min.Y)
	y1 := int(max.Y)
	p := Vector{float64(x0) + 0.5, float64(y0) + 0.5, 0}
	w00 := edge(s1, s2, p)
	w01 := edge(s2, s0, p)
	w02 := edge(s0, s1, p)
	a01 := s0.Y - s1.Y
	b01 := s1.X - s0.X
	a12 := s1.Y - s2.Y
	b12 := s2.X - s1.X
	a20 := s2.Y - s0.Y
	b20 := s0.X - s2.X
	ra := 1 / edge(s0, s1, s2)
	r0 := 1 / v0.Output.W
	r1 := 1 / v1.Output.W
	r2 := 1 / v2.Output.W
	for y := y0; y <= y1; y++ {
		w0 := w00
		w1 := w01
		w2 := w02
		for x := x0; x <= x1; x++ {
			b0 := w0 * ra
			b1 := w1 * ra
			b2 := w2 * ra
			w0 += a12
			w1 += a20
			w2 += a01
			if b0 < 0 || b1 < 0 || b2 < 0 {
				continue
			}
			z := b0*s0.Z + b1*s1.Z + b2*s2.Z
			i := y*dc.Width + x
			if z >= dc.DepthBuffer[i] { // completely safe?
				continue
			}
			b := VectorW{b0 * r0, b1 * r1, b2 * r2, 0}
			b.W = 1 / (b.X + b.Y + b.Z)
			v := InterpolateVertexes(v0, v1, v2, b)
			color := shader.Fragment(v)
			if color == Discard {
				continue
			}
			c := color.NRGBA()
			lock := &dc.locks[(x+y)&255]
			lock.Lock()
			if z < dc.DepthBuffer[i] {
				dc.DepthBuffer[i] = z
				dc.ColorBuffer.SetNRGBA(x, y, c)
			}
			lock.Unlock()
		}
		w00 += b12
		w01 += b20
		w02 += b01
	}
}

func (dc *Context) drawClipped(v0, v1, v2 Vertex, shader Shader) {
	ndc0 := v0.Output.DivScalar(v0.Output.W).Vector()
	ndc1 := v1.Output.DivScalar(v1.Output.W).Vector()
	ndc2 := v2.Output.DivScalar(v2.Output.W).Vector()

	// back face culling
	if (ndc1.X-ndc0.X)*(ndc2.Y-ndc0.Y)-(ndc2.X-ndc0.X)*(ndc1.Y-ndc0.Y) <= 0 {
		return
	}

	s0 := dc.screenMatrix.MulPosition(ndc0)
	s1 := dc.screenMatrix.MulPosition(ndc1)
	s2 := dc.screenMatrix.MulPosition(ndc2)
	dc.rasterize(v0, v1, v2, s0, s1, s2, shader)
}

func (dc *Context) DrawTriangle(t *Triangle, shader Shader) {
	v1 := shader.Vertex(t.V1)
	v2 := shader.Vertex(t.V2)
	v3 := shader.Vertex(t.V3)
	if v1.Outside() || v2.Outside() || v3.Outside() {
		triangles := ClipTriangle(NewTriangle(v1, v2, v3))
		for _, t := range triangles {
			dc.drawClipped(t.V1, t.V2, t.V3, shader)
		}
	} else {
		dc.drawClipped(v1, v2, v3, shader)
	}
}

func (dc *Context) DrawTriangles(triangles []*Triangle, shader Shader) {
	wn := runtime.NumCPU()
	done := make(chan bool, wn)
	for wi := 0; wi < wn; wi++ {
		go func(wi int) {
			for i, t := range triangles {
				if i%wn == wi {
					dc.DrawTriangle(t, shader)
				}
			}
			done <- true
		}(wi)
	}
	for wi := 0; wi < wn; wi++ {
		<-done
	}
}

func (dc *Context) DrawMesh(mesh *Mesh, shader Shader) {
	dc.DrawTriangles(mesh.Triangles, shader)
}
<|endoftext|>


<commit_before>/*
Copyright 2015 Rodrigo Rafael Monti Kochenburger

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 web

import (
	"net/http"

	"github.com/gostack/ctxinfo"

	"golang.org/x/net/context"
)

// ContextHandler is a extension of a http.Handler that also includes a context.Context object.
type ContextHandler interface {
	ServeHTTP(c context.Context, w http.ResponseWriter, req *http.Request)
}

// ContextHandlerFunc implements ServeHTTP for a function
type ContextHandlerFunc func(c context.Context, w http.ResponseWriter, req *http.Request)

// ServeHTTP implements the http.Handler interface for a function, calling itself
func (ch ContextHandlerFunc) ServeHTTP(c context.Context, w http.ResponseWriter, req *http.Request) {
	ch(c, w, req)
}

// ContextHandlerAdapter wraps a ContextHandler, returning an http.Handler that initializes a
// context allowing ContexHandler to be mounted on any net/http compatible library.
func ContextHandlerAdapter(ctx context.Context, ch ContextHandler) http.Handler {
	fn := func(w http.ResponseWriter, req *http.Request) {
		ch.ServeHTTP(ctxinfo.TxContext(ctx), w, req)
	}

	return http.HandlerFunc(fn)
}
<commit_msg>Add goji support<commit_after>/*
Copyright 2015 Rodrigo Rafael Monti Kochenburger

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 web

import (
	"net/http"

	"github.com/gostack/ctxinfo"
	"github.com/zenazn/goji/web"
	"golang.org/x/net/context"
)

// ContextHandler is a extension of a http.Handler that also includes a context.Context object.
type ContextHandler interface {
	ServeHTTP(c context.Context, w http.ResponseWriter, req *http.Request)
}

// ContextHandlerFunc implements ServeHTTP for a function
type ContextHandlerFunc func(c context.Context, w http.ResponseWriter, req *http.Request)

// ServeHTTP implements the http.Handler interface for a function, calling itself
func (ch ContextHandlerFunc) ServeHTTP(c context.Context, w http.ResponseWriter, req *http.Request) {
	ch(c, w, req)
}

// ContextHandlerAdapter wraps a ContextHandler, returning an http.Handler that initializes a
// context allowing ContexHandler to be mounted on any net/http compatible library.
func ContextHandlerAdapter(ctx context.Context, ch ContextHandler) http.Handler {
	fn := func(w http.ResponseWriter, req *http.Request) {
		ch.ServeHTTP(ctxinfo.TxContext(ctx), w, req)
	}

	return http.HandlerFunc(fn)
}

// ContextHandlerAdapter wraps a ContextHandler, returning an http.Handler that initializes a
// context allowing ContexHandler to be mounted on any net/http compatible library.
func GojiContextHandlerAdapter(ctx context.Context, ch ContextHandler) web.Handler {
	fn := func(c web.C, w http.ResponseWriter, req *http.Request) {
		ctx := ctxinfo.TxContext(ctx)
		ctx = context.WithValue(ctx, "github.com/gostack/web:goji", c.URLParams)
		ch.ServeHTTP(ctx, w, req)
	}

	return web.HandlerFunc(fn)
}

func GojiParam(ctx context.Context, key string) string {
	m := ctx.Value("github.com/gostack/web:goji").(map[string]string)
	return m[key]
}
<|endoftext|>


<commit_before>package command

import (
	"encoding/base64"
	"github.com/hashicorp/memberlist"
	"github.com/hashicorp/serf/client"
	"github.com/hashicorp/serf/command/agent"
	"github.com/hashicorp/serf/serf"
	"github.com/mitchellh/cli"
	"strings"
	"testing"
)

func testKeysCommandAgent(t *testing.T) *agent.Agent {
	key1, err := base64.StdEncoding.DecodeString("SNCg1bQSoCdGVlEx+TgfBw==")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	key2, err := base64.StdEncoding.DecodeString("vbitCcJNwNP4aEWHgofjMg==")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	keyring, err := memberlist.NewKeyring([][]byte{key1, key2}, key1)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	agentConf := agent.DefaultConfig()
	serfConf := serf.DefaultConfig()
	serfConf.MemberlistConfig.Keyring = keyring

	a1 := testAgentWithConfig(t, agentConf, serfConf)
	return a1
}

func TestKeysCommand_implements(t *testing.T) {
	var _ cli.Command = &KeysCommand{}
}

func TestKeysCommandRun_InstallKey(t *testing.T) {
	a1 := testKeysCommandAgent(t)
	defer a1.Shutdown()
	rpcAddr, ipc := testIPC(t, a1)
	defer ipc.Shutdown()

	ui := new(cli.MockUi)
	c := &KeysCommand{Ui: ui}

	rpcClient, err := client.NewRPCClient(rpcAddr)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	keys, _, err := rpcClient.ListKeys()
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	if _, ok := keys["jbuQMI4gMUeh1PPmKOtiBg=="]; ok {
		t.Fatalf("have test key")
	}

	args := []string{
		"-rpc-addr=" + rpcAddr,
		"-install", "jbuQMI4gMUeh1PPmKOtiBg==",
	}

	code := c.Run(args)
	if code != 0 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}

	if !strings.Contains(ui.OutputWriter.String(), "Successfully installed key") {
		t.Fatalf("bad: %#v", ui.OutputWriter.String())
	}

	keys, _, err = rpcClient.ListKeys()
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	if _, ok := keys["jbuQMI4gMUeh1PPmKOtiBg=="]; !ok {
		t.Fatalf("new key not found")
	}
}

func TestKeysCommandRun_UseKey(t *testing.T) {
	a1 := testKeysCommandAgent(t)
	defer a1.Shutdown()
	rpcAddr, ipc := testIPC(t, a1)
	defer ipc.Shutdown()

	ui := new(cli.MockUi)
	c := &KeysCommand{Ui: ui}

	// Trying to use a non-existent key returns 1
	args := []string{
		"-rpc-addr=" + rpcAddr,
		"-use", "eodFZZjm7pPwIZ0Miy7boQ==",
	}

	code := c.Run(args)
	if code != 1 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}

	// Using an existing key returns 0
	args = []string{
		"-rpc-addr=" + rpcAddr,
		"-use", "vbitCcJNwNP4aEWHgofjMg==",
	}

	code = c.Run(args)
	if code != 0 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}
}

func TestKeysCommandRun_RemoveKey(t *testing.T) {
	a1 := testKeysCommandAgent(t)
	defer a1.Shutdown()
	rpcAddr, ipc := testIPC(t, a1)
	defer ipc.Shutdown()

	ui := new(cli.MockUi)
	c := &KeysCommand{Ui: ui}

	rpcClient, err := client.NewRPCClient(rpcAddr)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	keys, _, err := rpcClient.ListKeys()
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	if len(keys) != 2 {
		t.Fatalf("expected 2 keys: %v", keys)
	}

	// Removing non-existing key still returns 0 (noop)
	args := []string{
		"-rpc-addr=" + rpcAddr,
		"-remove", "eodFZZjm7pPwIZ0Miy7boQ==",
	}

	code := c.Run(args)
	if code != 0 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}

	// Number of keys unchanged after noop command
	keys, _, err = rpcClient.ListKeys()
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	if len(keys) != 2 {
		t.Fatalf("expected 2 keys: %v", keys)
	}

	// Removing a primary key returns 1
	args = []string{
		"-rpc-addr=" + rpcAddr,
		"-remove", "SNCg1bQSoCdGVlEx+TgfBw==",
	}

	ui.ErrorWriter.Reset()
	code = c.Run(args)
	if code != 1 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}

	if !strings.Contains(ui.ErrorWriter.String(), "Error removing key") {
		t.Fatalf("bad: %#v", ui.OutputWriter.String())
	}

	// Removing a non-primary, existing key returns 0
	args = []string{
		"-rpc-addr=" + rpcAddr,
		"-remove", "vbitCcJNwNP4aEWHgofjMg==",
	}

	code = c.Run(args)
	if code != 0 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}

	// Key removed after successful -remove command
	keys, _, err = rpcClient.ListKeys()
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	if len(keys) != 1 {
		t.Fatalf("expected 2 keys: %v", keys)
	}
}

func TestKeysCommandRun_ListKeys(t *testing.T) {
	a1 := testKeysCommandAgent(t)
	defer a1.Shutdown()
	rpcAddr, ipc := testIPC(t, a1)
	defer ipc.Shutdown()

	ui := new(cli.MockUi)
	c := &KeysCommand{Ui: ui}

	// Trying to use a non-existent key returns 1
	args := []string{
		"-rpc-addr=" + rpcAddr,
		"-list",
	}

	code := c.Run(args)
	if code == 1 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}

	if !strings.Contains(ui.OutputWriter.String(), "SNCg1bQSoCdGVlEx+TgfBw==") {
		t.Fatalf("missing expected key")
	}

	if !strings.Contains(ui.OutputWriter.String(), "vbitCcJNwNP4aEWHgofjMg==") {
		t.Fatalf("missing expected key")
	}
}

func TestKeysCommandRun_BadOptions(t *testing.T) {
	a1 := testAgent(t)
	defer a1.Shutdown()
	rpcAddr, ipc := testIPC(t, a1)
	defer ipc.Shutdown()

	ui := new(cli.MockUi)
	c := &KeysCommand{Ui: ui}

	args := []string{
		"-rpc-addr=" + rpcAddr,
		"-install", "vbitCcJNwNP4aEWHgofjMg==",
		"-use", "vbitCcJNwNP4aEWHgofjMg==",
	}

	code := c.Run(args)
	if code != 1 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}

	args = []string{
		"-rpc-addr=" + rpcAddr,
		"-list",
		"-remove", "SNCg1bQSoCdGVlEx+TgfBw==",
	}

	code = c.Run(args)
	if code != 1 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}
}
<commit_msg>command: add tests for returning node errors during key operations<commit_after>package command

import (
	"encoding/base64"
	"github.com/hashicorp/memberlist"
	"github.com/hashicorp/serf/client"
	"github.com/hashicorp/serf/command/agent"
	"github.com/hashicorp/serf/serf"
	"github.com/mitchellh/cli"
	"strings"
	"testing"
)

func testKeysCommandAgent(t *testing.T) *agent.Agent {
	key1, err := base64.StdEncoding.DecodeString("SNCg1bQSoCdGVlEx+TgfBw==")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	key2, err := base64.StdEncoding.DecodeString("vbitCcJNwNP4aEWHgofjMg==")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	keyring, err := memberlist.NewKeyring([][]byte{key1, key2}, key1)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	agentConf := agent.DefaultConfig()
	serfConf := serf.DefaultConfig()
	serfConf.MemberlistConfig.Keyring = keyring

	a1 := testAgentWithConfig(t, agentConf, serfConf)
	return a1
}

func TestKeysCommand_implements(t *testing.T) {
	var _ cli.Command = &KeysCommand{}
}

func TestKeysCommandRun_InstallKey(t *testing.T) {
	a1 := testKeysCommandAgent(t)
	defer a1.Shutdown()
	rpcAddr, ipc := testIPC(t, a1)
	defer ipc.Shutdown()

	ui := new(cli.MockUi)
	c := &KeysCommand{Ui: ui}

	rpcClient, err := client.NewRPCClient(rpcAddr)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	keys, _, _, err := rpcClient.ListKeys()
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	if _, ok := keys["jbuQMI4gMUeh1PPmKOtiBg=="]; ok {
		t.Fatalf("have test key")
	}

	args := []string{
		"-rpc-addr=" + rpcAddr,
		"-install", "jbuQMI4gMUeh1PPmKOtiBg==",
	}

	code := c.Run(args)
	if code != 0 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}

	if !strings.Contains(ui.OutputWriter.String(), "Successfully installed key") {
		t.Fatalf("bad: %#v", ui.OutputWriter.String())
	}

	keys, _, _, err = rpcClient.ListKeys()
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	if _, ok := keys["jbuQMI4gMUeh1PPmKOtiBg=="]; !ok {
		t.Fatalf("new key not found")
	}
}

func TestKeysCommandRun_InstallKeyFailure(t *testing.T) {
	a1 := testAgent(t)
	defer a1.Shutdown()
	rpcAddr, ipc := testIPC(t, a1)
	defer ipc.Shutdown()

	ui := new(cli.MockUi)
	c := &KeysCommand{Ui: ui}

	// Trying to install with encryption disabled returns 1
	args := []string{
		"-rpc-addr=" + rpcAddr,
		"-install", "jbuQMI4gMUeh1PPmKOtiBg==",
	}

	code := c.Run(args)
	if code != 1 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}

	// Node errors appear in stderr
	if !strings.Contains(ui.ErrorWriter.String(), "not enabled") {
		t.Fatalf("expected empty keyring error")
	}
}

func TestKeysCommandRun_UseKey(t *testing.T) {
	a1 := testKeysCommandAgent(t)
	defer a1.Shutdown()
	rpcAddr, ipc := testIPC(t, a1)
	defer ipc.Shutdown()

	ui := new(cli.MockUi)
	c := &KeysCommand{Ui: ui}

	// Trying to use a non-existent key returns 1
	args := []string{
		"-rpc-addr=" + rpcAddr,
		"-use", "eodFZZjm7pPwIZ0Miy7boQ==",
	}

	code := c.Run(args)
	if code != 1 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}

	// Using an existing key returns 0
	args = []string{
		"-rpc-addr=" + rpcAddr,
		"-use", "vbitCcJNwNP4aEWHgofjMg==",
	}

	code = c.Run(args)
	if code != 0 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}
}

func TestKeysCommandRun_UseKeyFailure(t *testing.T) {
	a1 := testKeysCommandAgent(t)
	defer a1.Shutdown()
	rpcAddr, ipc := testIPC(t, a1)
	defer ipc.Shutdown()

	ui := new(cli.MockUi)
	c := &KeysCommand{Ui: ui}

	// Trying to use a key that doesn't exist returns 1
	args := []string{
		"-rpc-addr=" + rpcAddr,
		"-use", "jbuQMI4gMUeh1PPmKOtiBg==",
	}

	code := c.Run(args)
	if code != 1 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}

	// Node errors appear in stderr
	if !strings.Contains(ui.ErrorWriter.String(), "not in the keyring") {
		t.Fatalf("expected absent key error")
	}
}

func TestKeysCommandRun_RemoveKey(t *testing.T) {
	a1 := testKeysCommandAgent(t)
	defer a1.Shutdown()
	rpcAddr, ipc := testIPC(t, a1)
	defer ipc.Shutdown()

	ui := new(cli.MockUi)
	c := &KeysCommand{Ui: ui}

	rpcClient, err := client.NewRPCClient(rpcAddr)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	keys, _, _, err := rpcClient.ListKeys()
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	if len(keys) != 2 {
		t.Fatalf("expected 2 keys: %v", keys)
	}

	// Removing non-existing key still returns 0 (noop)
	args := []string{
		"-rpc-addr=" + rpcAddr,
		"-remove", "eodFZZjm7pPwIZ0Miy7boQ==",
	}

	code := c.Run(args)
	if code != 0 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}

	// Number of keys unchanged after noop command
	keys, _, _, err = rpcClient.ListKeys()
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	if len(keys) != 2 {
		t.Fatalf("expected 2 keys: %v", keys)
	}

	// Removing a primary key returns 1
	args = []string{
		"-rpc-addr=" + rpcAddr,
		"-remove", "SNCg1bQSoCdGVlEx+TgfBw==",
	}

	ui.ErrorWriter.Reset()
	code = c.Run(args)
	if code != 1 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}

	if !strings.Contains(ui.ErrorWriter.String(), "Error removing key") {
		t.Fatalf("bad: %#v", ui.OutputWriter.String())
	}

	// Removing a non-primary, existing key returns 0
	args = []string{
		"-rpc-addr=" + rpcAddr,
		"-remove", "vbitCcJNwNP4aEWHgofjMg==",
	}

	code = c.Run(args)
	if code != 0 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}

	// Key removed after successful -remove command
	keys, _, _, err = rpcClient.ListKeys()
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	if len(keys) != 1 {
		t.Fatalf("expected 2 keys: %v", keys)
	}
}

func TestKeysCommandRun_RemoveKeyFailure(t *testing.T) {
	a1 := testKeysCommandAgent(t)
	defer a1.Shutdown()
	rpcAddr, ipc := testIPC(t, a1)
	defer ipc.Shutdown()

	ui := new(cli.MockUi)
	c := &KeysCommand{Ui: ui}

	// Trying to remove the primary key returns 1
	args := []string{
		"-rpc-addr=" + rpcAddr,
		"-remove", "SNCg1bQSoCdGVlEx+TgfBw==",
	}

	code := c.Run(args)
	if code != 1 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}

	// Node errors appear in stderr
	if !strings.Contains(ui.ErrorWriter.String(), "not allowed") {
		t.Fatalf("expected primary key removal error")
	}
}

func TestKeysCommandRun_ListKeys(t *testing.T) {
	a1 := testKeysCommandAgent(t)
	defer a1.Shutdown()
	rpcAddr, ipc := testIPC(t, a1)
	defer ipc.Shutdown()

	ui := new(cli.MockUi)
	c := &KeysCommand{Ui: ui}

	args := []string{
		"-rpc-addr=" + rpcAddr,
		"-list",
	}

	code := c.Run(args)
	if code == 1 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}

	if !strings.Contains(ui.OutputWriter.String(), "SNCg1bQSoCdGVlEx+TgfBw==") {
		t.Fatalf("missing expected key")
	}

	if !strings.Contains(ui.OutputWriter.String(), "vbitCcJNwNP4aEWHgofjMg==") {
		t.Fatalf("missing expected key")
	}
}

func TestKeysCommandRun_ListKeysFailure(t *testing.T) {
	a1 := testAgent(t)
	defer a1.Shutdown()
	rpcAddr, ipc := testIPC(t, a1)
	defer ipc.Shutdown()

	ui := new(cli.MockUi)
	c := &KeysCommand{Ui: ui}

	// Trying to list keys with encryption disabled returns 1
	args := []string{
		"-rpc-addr=" + rpcAddr,
		"-list",
	}

	code := c.Run(args)
	if code != 1 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}

	if !strings.Contains(ui.ErrorWriter.String(), "not enabled") {
		t.Fatalf("expected empty keyring error")
	}
}

func TestKeysCommandRun_BadOptions(t *testing.T) {
	a1 := testAgent(t)
	defer a1.Shutdown()
	rpcAddr, ipc := testIPC(t, a1)
	defer ipc.Shutdown()

	ui := new(cli.MockUi)
	c := &KeysCommand{Ui: ui}

	args := []string{
		"-rpc-addr=" + rpcAddr,
		"-install", "vbitCcJNwNP4aEWHgofjMg==",
		"-use", "vbitCcJNwNP4aEWHgofjMg==",
	}

	code := c.Run(args)
	if code != 1 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}

	args = []string{
		"-rpc-addr=" + rpcAddr,
		"-list",
		"-remove", "SNCg1bQSoCdGVlEx+TgfBw==",
	}

	code = c.Run(args)
	if code != 1 {
		t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
	}
}
<|endoftext|>


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

// Package voyeur implements a concurrency-safe value that can be watched for
// changes.
package voyeur

import (
	"sync"
)

// Value represents a shared value that can be watched for changes. Methods on
// a Value may be called concurrently. The zero Value is
// ok to use, and is equivalent to a NewValue result
// with a nil initial value.
type Value struct {
	val     interface{}
	version int
	mu      sync.RWMutex
	wait    sync.Cond
	closed  bool
}

// NewValue creates a new Value holding the given initial value. If initial is
// nil, any watchers will wait until a value is set.
func NewValue(initial interface{}) *Value {
	v := new(Value)
	v.init()
	if initial != nil {
		v.val = initial
		v.version++
	}
	return v
}

func (v *Value) needsInit() bool {
	return v.wait.L == nil
}

func (v *Value) init() {
	if v.needsInit() {
		v.wait.L = v.mu.RLocker()
	}
}

// Set sets the shared value to val.
func (v *Value) Set(val interface{}) {
	v.mu.Lock()
	v.init()
	v.val = val
	v.version++
	v.mu.Unlock()
	v.wait.Broadcast()
}

// Close closes the Value, unblocking any outstanding watchers.  Close always
// returns nil.
func (v *Value) Close() error {
	v.mu.Lock()
	v.init()
	v.closed = true
	v.mu.Unlock()
	v.wait.Broadcast()
	return nil
}

// Closed reports whether the value has been closed.
func (v *Value) Closed() bool {
	v.mu.RLock()
	defer v.mu.RUnlock()
	return v.closed
}

// Get returns the current value.
func (v *Value) Get() interface{} {
	v.mu.RLock()
	defer v.mu.RUnlock()
	return v.val
}

// Watch returns a Watcher that can be used to watch for changes to the value.
func (v *Value) Watch() *Watcher {
	return &Watcher{value: v}
}

// Watcher represents a single watcher of a shared value.
type Watcher struct {
	value   *Value
	version int
	current interface{}
	closed  bool
}

// Next blocks until there is a new value to be retrieved from the value that is
// being watched. It also unblocks when the value or the Watcher itself is
// closed. Next returns false if the value or the Watcher itself have been
// closed.
func (w *Watcher) Next() bool {
	val := w.value
	val.mu.RLock()
	defer val.mu.RUnlock()
	if val.needsInit() {
		val.mu.RUnlock()
		val.mu.Lock()
		val.init()
		val.mu.Unlock()
		val.mu.RLock()
	}

	// We should never go around this loop more than twice.
	for {
		if w.version != val.version {
			w.version = val.version
			w.current = val.val
			return true
		}
		if val.closed || w.closed {
			return false
		}

		// Wait releases the lock until triggered and then reacquires the lock,
		// thus avoiding a deadlock.
		val.wait.Wait()
	}
}

// Close closes the Watcher without closing the underlying
// value. It may be called concurrently with Next.
func (w *Watcher) Close() {
	w.value.mu.Lock()
	w.value.init()
	w.closed = true
	w.value.mu.Unlock()
	w.value.wait.Broadcast()
}

// Value returns the last value that was retrieved from the watched Value by
// Next.
func (w *Watcher) Value() interface{} {
	return w.current
}
<commit_msg>worker/peergrouper: rationalise logging<commit_after>// Copyright 2012, 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

// Package voyeur implements a concurrency-safe value that can be watched for
// changes.
package voyeur

import (
	"sync"
)

// Value represents a shared value that can be watched for changes. Methods on
// a Value may be called concurrently. The zero Value is
// ok to use, and is equivalent to a NewValue result
// with a nil initial value.
type Value struct {
	val     interface{}
	version int
	mu      sync.RWMutex
	wait    sync.Cond
	closed  bool
}

// NewValue creates a new Value holding the given initial value. If initial is
// nil, any watchers will wait until a value is set.
func NewValue(initial interface{}) *Value {
	v := new(Value)
	v.init()
	if initial != nil {
		v.val = initial
		v.version++
	}
	return v
}

func (v *Value) needsInit() bool {
	return v.wait.L == nil
}

func (v *Value) init() {
	if v.needsInit() {
		v.wait.L = v.mu.RLocker()
	}
}

// Set sets the shared value to val.
func (v *Value) Set(val interface{}) {
	v.mu.Lock()
	v.init()
	v.val = val
	v.version++
	v.mu.Unlock()
	v.wait.Broadcast()
}

// Close closes the Value, unblocking any outstanding watchers.  Close always
// returns nil.
func (v *Value) Close() error {
	v.mu.Lock()
	v.init()
	v.closed = true
	v.mu.Unlock()
	v.wait.Broadcast()
	return nil
}

// Closed reports whether the value has been closed.
func (v *Value) Closed() bool {
	v.mu.RLock()
	defer v.mu.RUnlock()
	return v.closed
}

// Get returns the current value.
func (v *Value) Get() interface{} {
	v.mu.RLock()
	defer v.mu.RUnlock()
	return v.val
}

// Watch returns a Watcher that can be used to watch for changes to the value.
func (v *Value) Watch() *Watcher {
	return &Watcher{value: v}
}

// Watcher represents a single watcher of a shared value.
type Watcher struct {
	value   *Value
	version int
	current interface{}
	closed  bool
}

// Next blocks until there is a new value to be retrieved from the value that is
// being watched. It also unblocks when the value or the Watcher itself is
// closed. Next returns false if the value or the Watcher itself have been
// closed.
func (w *Watcher) Next() bool {
	val := w.value
	val.mu.RLock()
	defer val.mu.RUnlock()
	if val.needsInit() {
		val.mu.RUnlock()
		val.mu.Lock()
		val.init()
		val.mu.Unlock()
		val.mu.RLock()
	}

	// We can go around this loop a maximum of two times,
	// because the only thing that can cause a Wait to
	// return is for the condition to be triggered,
	// which can only happen if the value is set (causing
	// the version to increment) or it is closed
	// causing the closed flag to be set.
	// Both these cases will cause Next to return.
	for {
		if w.version != val.version {
			w.version = val.version
			w.current = val.val
			return true
		}
		if val.closed || w.closed {
			return false
		}

		// Wait releases the lock until triggered and then reacquires the lock,
		// thus avoiding a deadlock.
		val.wait.Wait()
	}
}

// Close closes the Watcher without closing the underlying
// value. It may be called concurrently with Next.
func (w *Watcher) Close() {
	w.value.mu.Lock()
	w.value.init()
	w.closed = true
	w.value.mu.Unlock()
	w.value.wait.Broadcast()
}

// Value returns the last value that was retrieved from the watched Value by
// Next.
func (w *Watcher) Value() interface{} {
	return w.current
}
<|endoftext|>


<commit_before>// Copyright 2014 Kelsey Hightower. All rights reserved.
// Use of this source code is governed by a BSD-style
// license found in the LICENSE file.

// Package memkv implements an in-memory key/value store.
package memkv

import (
	"errors"
	"path"
	"path/filepath"
	"sort"
	"strings"
	"sync"
)

var ErrNotExist = errors.New("key does not exist")
var ErrNoMatch = errors.New("no keys match")

type KeyError struct {
	Key string
	Err error
}

func (e *KeyError) Error() string {
	return e.Err.Error() + ": " + e.Key
}

// A Store represents an in-memory key-value store safe for
// concurrent access.
type Store struct {
	FuncMap map[string]interface{}
	sync.RWMutex
	m map[string]KVPair
}

// New creates and initializes a new Store.
func New() Store {
	s := Store{m: make(map[string]KVPair)}
	s.FuncMap = map[string]interface{}{
		"exists": s.Exists,
		"ls":     s.List,
		"lsdir":  s.ListDir,
		"get":    s.Get,
		"gets":   s.GetAll,
		"getv":   s.GetValue,
		"getvs":  s.GetAllValues,
	}
	return s
}

// Delete deletes the KVPair associated with key.
func (s Store) Del(key string) {
	s.Lock()
	delete(s.m, key)
	s.Unlock()
}

// Exists checks for the existence of key in the store.
func (s Store) Exists(key string) bool {
	_, err := s.Get(key)
	if err != nil {
		return false
	}
	return true
}

// Get gets the KVPair associated with key. If there is no KVPair
// associated with key, Get returns KVPair{}, ErrNotExist.
func (s Store) Get(key string) (KVPair, error) {
	s.RLock()
	kv, ok := s.m[key]
	s.RUnlock()
	if !ok {
		return kv, &KeyError{key, ErrNotExist}
	}
	return kv, nil
}

// GetValue gets the value associated with key. If there are no values
// associated with key, GetValue returns "", ErrNotExist.
func (s Store) GetValue(key string) (string, error) {
	kv, err := s.Get(key)
	if err != nil {
		return "", err
	}
	return kv.Value, nil
}

// GetAll returns a KVPair for all nodes with keys matching pattern.
// The syntax of patterns is the same as in filepath.Match.
func (s Store) GetAll(pattern string) (KVPairs, error) {
	ks := make(KVPairs, 0)
	s.RLock()
	defer s.RUnlock()
	for _, kv := range s.m {
		m, err := filepath.Match(pattern, kv.Key)
		if err != nil {
			return nil, err
		}
		if m {
			ks = append(ks, kv)
		}
	}
	if len(ks) == 0 {
		return ks, nil
	}
	sort.Sort(ks)
	return ks, nil
}

func (s Store) GetAllValues(pattern string) ([]string, error) {
	vs := make([]string, 0)
	ks, err := s.GetAll(pattern)
	if err != nil {
		return vs, err
	}
	if len(ks) == 0 {
		return vs, nil
	}
	for _, kv := range ks {
		vs = append(vs, kv.Value)
	}
	sort.Strings(vs)
	return vs, nil
}

func (s Store) List(filePath string) []string {
	vs := make([]string, 0)
	m := make(map[string]bool)
	s.RLock()
	defer s.RUnlock()
	for _, kv := range s.m {
		if kv.Key == filePath {
			m[path.Base(kv.Key)] = true
			continue
		}
		if strings.HasPrefix(kv.Key, filePath) {
			m[strings.Split(stripKey(kv.Key, filePath), "/")[0]] = true
		}
	}
	for k := range m {
		vs = append(vs, k)
	}
	sort.Strings(vs)
	return vs
}

func (s Store) ListDir(filePath string) []string {
	vs := make([]string, 0)
	m := make(map[string]bool)
	s.RLock()
	defer s.RUnlock()
	for _, kv := range s.m {
		if strings.HasPrefix(kv.Key, filePath) {
			items := strings.Split(stripKey(kv.Key, filePath), "/")
			if len(items) < 2 {
				continue
			}
			m[items[0]] = true
		}
	}
	for k := range m {
		vs = append(vs, k)
	}
	sort.Strings(vs)
	return vs
}

// Set sets the KVPair entry associated with key to value.
func (s Store) Set(key string, value string) {
	s.Lock()
	s.m[key] = KVPair{key, value}
	s.Unlock()
}

func (s Store) Purge() {
	s.Lock()
	for k := range s.m {
		delete(s.m, k)
	}
	s.Unlock()
}

func stripKey(key, prefix string) string {
	return strings.TrimPrefix(strings.TrimPrefix(key, prefix), "/")
}
<commit_msg>bump memkv to fix list and listdir bug<commit_after>// Copyright 2014 Kelsey Hightower. All rights reserved.
// Use of this source code is governed by a BSD-style
// license found in the LICENSE file.

// Package memkv implements an in-memory key/value store.
package memkv

import (
	"errors"
	"path"
	"path/filepath"
	"sort"
	"strings"
	"sync"
)

var ErrNotExist = errors.New("key does not exist")
var ErrNoMatch = errors.New("no keys match")

type KeyError struct {
	Key string
	Err error
}

func (e *KeyError) Error() string {
	return e.Err.Error() + ": " + e.Key
}

// A Store represents an in-memory key-value store safe for
// concurrent access.
type Store struct {
	FuncMap map[string]interface{}
	sync.RWMutex
	m map[string]KVPair
}

// New creates and initializes a new Store.
func New() Store {
	s := Store{m: make(map[string]KVPair)}
	s.FuncMap = map[string]interface{}{
		"exists": s.Exists,
		"ls":     s.List,
		"lsdir":  s.ListDir,
		"get":    s.Get,
		"gets":   s.GetAll,
		"getv":   s.GetValue,
		"getvs":  s.GetAllValues,
	}
	return s
}

// Delete deletes the KVPair associated with key.
func (s Store) Del(key string) {
	s.Lock()
	delete(s.m, key)
	s.Unlock()
}

// Exists checks for the existence of key in the store.
func (s Store) Exists(key string) bool {
	_, err := s.Get(key)
	if err != nil {
		return false
	}
	return true
}

// Get gets the KVPair associated with key. If there is no KVPair
// associated with key, Get returns KVPair{}, ErrNotExist.
func (s Store) Get(key string) (KVPair, error) {
	s.RLock()
	kv, ok := s.m[key]
	s.RUnlock()
	if !ok {
		return kv, &KeyError{key, ErrNotExist}
	}
	return kv, nil
}

// GetValue gets the value associated with key. If there are no values
// associated with key, GetValue returns "", ErrNotExist.
func (s Store) GetValue(key string) (string, error) {
	kv, err := s.Get(key)
	if err != nil {
		return "", err
	}
	return kv.Value, nil
}

// GetAll returns a KVPair for all nodes with keys matching pattern.
// The syntax of patterns is the same as in filepath.Match.
func (s Store) GetAll(pattern string) (KVPairs, error) {
	ks := make(KVPairs, 0)
	s.RLock()
	defer s.RUnlock()
	for _, kv := range s.m {
		m, err := filepath.Match(pattern, kv.Key)
		if err != nil {
			return nil, err
		}
		if m {
			ks = append(ks, kv)
		}
	}
	if len(ks) == 0 {
		return ks, nil
	}
	sort.Sort(ks)
	return ks, nil
}

func (s Store) GetAllValues(pattern string) ([]string, error) {
	vs := make([]string, 0)
	ks, err := s.GetAll(pattern)
	if err != nil {
		return vs, err
	}
	if len(ks) == 0 {
		return vs, nil
	}
	for _, kv := range ks {
		vs = append(vs, kv.Value)
	}
	sort.Strings(vs)
	return vs, nil
}

func (s Store) List(filePath string) []string {
	vs := make([]string, 0)
	m := make(map[string]bool)
	s.RLock()
	defer s.RUnlock()
	prefix := pathToTerms(path.Clean(filePath))
	for _, kv := range s.m {
		if kv.Key == filePath {
			m[path.Base(kv.Key)] = true
			continue
		}
		target := pathToTerms(path.Dir(kv.Key))
		if samePrefixTerms(target, prefix) {
			m[strings.Split(stripKey(kv.Key, filePath), "/")[0]] = true
		}
	}
	for k := range m {
		vs = append(vs, k)
	}
	sort.Strings(vs)
	return vs
}

func (s Store) ListDir(filePath string) []string {
	vs := make([]string, 0)
	m := make(map[string]bool)
	s.RLock()
	defer s.RUnlock()
	prefix := pathToTerms(path.Clean(filePath))
	for _, kv := range s.m {
		if strings.HasPrefix(kv.Key, filePath) {
			items := pathToTerms(path.Dir(kv.Key))
			if samePrefixTerms(prefix, items) && (len(items)-len(prefix) >= 1) {
				m[items[len(prefix):][0]] = true
			}
		}
	}
	for k := range m {
		vs = append(vs, k)
	}
	sort.Strings(vs)
	return vs
}

// Set sets the KVPair entry associated with key to value.
func (s Store) Set(key string, value string) {
	s.Lock()
	s.m[key] = KVPair{key, value}
	s.Unlock()
}

func (s Store) Purge() {
	s.Lock()
	for k := range s.m {
		delete(s.m, k)
	}
	s.Unlock()
}

func stripKey(key, prefix string) string {
	return strings.TrimPrefix(strings.TrimPrefix(key, prefix), "/")
}

func pathToTerms(filePath string) []string {
	return strings.Split(path.Clean(filePath), "/")
}

func samePrefixTerms(left, right []string) bool {
	l := len(left)
	if len(left) > len(right) {
		l = len(right)
	}
	for i := 0; i < l; i++ {
		if left[i] != right[i] {
			return false
		}
	}
	return true
}
<|endoftext|>


<commit_before>package db

import (
	"appengine/aetest"
	"appengine/datastore"
	"testing"
)

func TestPassword(t *testing.T) {
	pass := "123password!\"#¤"
	user := NewUser("erb", pass, "erik@bjareho.lt", "Erik")
	valid := user.CheckPassword(pass)
	if !valid {
		t.Fatal("Password check failed")
	}
}

func TestAuth(t *testing.T) {
	auth := NewAuth()
	// TODO: testing
	if auth.Key == "" {
		t.Fatal("Authkey was empty string")
	}
}

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

	user := NewUser("user", "pass", "name", "email")
	_ = NewYesNoPoll("title", "desc", "erb")
	pollkey := datastore.NewIncompleteKey(c, "Poll", nil)
	vote1, _, _ := NewYesNoVote(pollkey, user, true, 0)
	vote2, _, _ := NewYesNoVote(pollkey, user, false, 0)
	vote3, _, _ := newVote(pollkey, user, map[string]float32{"yes": 5, "no": 15}, 0)

	// TODO: Verify that polls are actually made by their creator
	// TODO: Test different levels of privacy

	if vote1.Weights()["yes"] != vote2.Weights()["no"] {
		t.Fatal("")
	}

	votes := []Vote{vote1, vote2, vote3}
	sumvotes := SumVotes(votes)
	shouldbe := map[string]float32{"yes": 1.25, "no": 1.75}
	for k := range sumvotes {
		if sumvotes[k] != shouldbe[k] {
			t.Fatal("SumVotes was wrong: ", sumvotes)
		}
	}
}
<commit_msg>Fixed tests<commit_after>package db

import (
	"appengine/aetest"
	"appengine/datastore"
	"testing"
)

func TestPassword(t *testing.T) {
	pass := "123password!\"#¤"
	user := NewUser("erb", pass, "erik@bjareho.lt", "Erik")
	valid := user.CheckPassword(pass)
	if !valid {
		t.Fatal("Password check failed")
	}
}

func TestAuth(t *testing.T) {
	auth := NewAuth()
	// TODO: testing
	if auth.Key == "" {
		t.Fatal("Authkey was empty string")
	}
}

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

	_ = NewUser("user", "pass", "name", "email")
	userkey := datastore.NewIncompleteKey(c, "User", nil)
	_ = NewYesNoPoll("title", "desc", "erb")
	pollkey := datastore.NewIncompleteKey(c, "Poll", nil)
	vote1, _, _ := NewYesNoVote(pollkey, userkey, true, 0)
	vote2, _, _ := NewYesNoVote(pollkey, userkey, false, 0)
	vote3, _, _ := newVote(pollkey, userkey, map[string]float32{"yes": 5, "no": 15}, 0)

	// TODO: Verify that polls are actually made by their creator
	// TODO: Test different levels of privacy

	if vote1.Weights()["yes"] != vote2.Weights()["no"] {
		t.Fatal("")
	}

	votes := []Vote{vote1, vote2, vote3}
	sumvotes := SumVotes(votes)
	shouldbe := map[string]float32{"yes": 1.25, "no": 1.75}
	for k := range sumvotes {
		if sumvotes[k] != shouldbe[k] {
			t.Fatal("SumVotes was wrong: ", sumvotes)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/coreos/go-semver/semver"
	"github.com/spf13/cobra"

	"arvika.subliminl.com/developers/devtool/release"
)

var (
	dockerTagCmd = &cobra.Command{
		Use:   "docker-tag",
		Short: "Get the docker tag for the current project",
		Long:  "Returns the image:tag for the current project",
		Run:   runDockerTag,
	}
)

func init() {
	mainCmd.AddCommand(dockerTagCmd)
}

func runDockerTag(cmd *cobra.Command, args []string) {
	info, err := release.GetProjectInfo()
	if err != nil {
		Quitf("%s\n", err)
	}
	version, err := semver.NewVersion(info.Version)
	if err != nil {
		Quitf("%s\n", err)
	}
	tag := version.String()
	if version.Metadata != "" {
		tag = "latest"
	}
	Printf("%s:%s", info.Name, tag)
}
<commit_msg>Added override for image name<commit_after>package main

import (
	"github.com/coreos/go-semver/semver"
	"github.com/spf13/cobra"

	"arvika.subliminl.com/developers/devtool/release"
)

var (
	dockerTagImage string
	dockerTagCmd   = &cobra.Command{
		Use:   "docker-tag",
		Short: "Get the docker tag for the current project",
		Long:  "Returns the image:tag for the current project",
		Run:   runDockerTag,
	}
)

func init() {
	dockerTagCmd.Flags().StringVarP(&dockerTagImage, "image", "i", "", "Docker image name")
	mainCmd.AddCommand(dockerTagCmd)
}

func runDockerTag(cmd *cobra.Command, args []string) {
	info, err := release.GetProjectInfo()
	if err != nil {
		Quitf("%s\n", err)
	}
	version, err := semver.NewVersion(info.Version)
	if err != nil {
		Quitf("%s\n", err)
	}
	tag := version.String()
	if version.Metadata != "" {
		tag = "latest"
	}
	if dockerTagImage == "" {
		dockerTagImage = info.Name
	}
	Printf("%s:%s", dockerTagImage, tag)
}
<|endoftext|>


<commit_before>// Copyright 2015 The gocui 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 main

import (
	"encoding/hex"
	"fmt"
	"io"
	"log"
	"os"
	"runtime"

	"github.com/jroimartin/gocui"
)

func main() {
	runtime.LockOSThread()

	g := gocui.NewGui()
	if err := g.Init(); err != nil {
		log.Fatalln(err)
	}
	defer g.Close()

	g.SetLayout(layout)
	if err := initKeybindings(g); err != nil {
		log.Fatalln(err)
	}
	g.ShowCursor = true

	err := g.MainLoop()
	if err != nil && err != gocui.Quit {
		log.Fatalln(err)
	}
}

func layout(g *gocui.Gui) error {
	maxX, _ := g.Size()

	if v, err := g.SetView("legend", maxX-23, 0, maxX-1, 5); err != nil {
		if err != gocui.ErrorUnkView {
			return err
		}
		fmt.Fprintln(v, "KEYBINDINGS")
		fmt.Fprintln(v, "↑ ↓: Seek input")
		fmt.Fprintln(v, "A: Enable autoscroll")
		fmt.Fprintln(v, "^C: Exit")
	}

	if v, err := g.SetView("stdin", 0, 0, 80, 35); err != nil {
		if err != gocui.ErrorUnkView {
			return err
		}
		if err := g.SetCurrentView("stdin"); err != nil {
			return err
		}
		dumper := hex.Dumper(v)
		if _, err := io.Copy(dumper, os.Stdin); err != nil {
			return err
		}
		v.Wrap = true
		v.Autoscroll = true
		v.Editable = true
	}

	return nil
}

func initKeybindings(g *gocui.Gui) error {
	if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
		return err
	}
	if err := g.SetKeybinding("stdin", 'a', gocui.ModNone, autoscroll); err != nil {
		return err
	}
	if err := g.SetKeybinding("stdin", gocui.KeyArrowUp, gocui.ModNone,
		func(g *gocui.Gui, v *gocui.View) error {
			scrollView(v, -1)
			return nil
		}); err != nil {
		return err
	}
	if err := g.SetKeybinding("stdin", gocui.KeyArrowDown, gocui.ModNone,
		func(g *gocui.Gui, v *gocui.View) error {
			scrollView(v, 1)
			return nil
		}); err != nil {
		return err
	}
	return nil
}

func quit(g *gocui.Gui, v *gocui.View) error {
	return gocui.Quit
}

func autoscroll(g *gocui.Gui, v *gocui.View) error {
	v.Autoscroll = true
	return nil
}

func scrollView(v *gocui.View, dy int) error {
	if v != nil {
		v.Autoscroll = false
		ox, oy := v.Origin()
		if err := v.SetOrigin(ox, oy+dy); err != nil {
			return err
		}
	}
	return nil
}
<commit_msg>_examples/stdin.go: Disable autoscroll and edition<commit_after>// Copyright 2015 The gocui 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 main

import (
	"encoding/hex"
	"fmt"
	"io"
	"log"
	"os"
	"runtime"

	"github.com/jroimartin/gocui"
)

func main() {
	runtime.LockOSThread()

	g := gocui.NewGui()
	if err := g.Init(); err != nil {
		log.Fatalln(err)
	}
	defer g.Close()

	g.SetLayout(layout)
	if err := initKeybindings(g); err != nil {
		log.Fatalln(err)
	}
	g.ShowCursor = true

	err := g.MainLoop()
	if err != nil && err != gocui.Quit {
		log.Fatalln(err)
	}
}

func layout(g *gocui.Gui) error {
	maxX, _ := g.Size()

	if v, err := g.SetView("legend", maxX-23, 0, maxX-1, 5); err != nil {
		if err != gocui.ErrorUnkView {
			return err
		}
		fmt.Fprintln(v, "KEYBINDINGS")
		fmt.Fprintln(v, "↑ ↓: Seek input")
		fmt.Fprintln(v, "A: Enable autoscroll")
		fmt.Fprintln(v, "^C: Exit")
	}

	if v, err := g.SetView("stdin", 0, 0, 80, 35); err != nil {
		if err != gocui.ErrorUnkView {
			return err
		}
		if err := g.SetCurrentView("stdin"); err != nil {
			return err
		}
		dumper := hex.Dumper(v)
		if _, err := io.Copy(dumper, os.Stdin); err != nil {
			return err
		}
		v.Wrap = true
	}

	return nil
}

func initKeybindings(g *gocui.Gui) error {
	if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
		return err
	}
	if err := g.SetKeybinding("stdin", 'a', gocui.ModNone, autoscroll); err != nil {
		return err
	}
	if err := g.SetKeybinding("stdin", gocui.KeyArrowUp, gocui.ModNone,
		func(g *gocui.Gui, v *gocui.View) error {
			scrollView(v, -1)
			return nil
		}); err != nil {
		return err
	}
	if err := g.SetKeybinding("stdin", gocui.KeyArrowDown, gocui.ModNone,
		func(g *gocui.Gui, v *gocui.View) error {
			scrollView(v, 1)
			return nil
		}); err != nil {
		return err
	}
	return nil
}

func quit(g *gocui.Gui, v *gocui.View) error {
	return gocui.Quit
}

func autoscroll(g *gocui.Gui, v *gocui.View) error {
	v.Autoscroll = true
	return nil
}

func scrollView(v *gocui.View, dy int) error {
	if v != nil {
		v.Autoscroll = false
		ox, oy := v.Origin()
		if err := v.SetOrigin(ox, oy+dy); err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package base

import (
	"fmt"
	"log"
	"strings"
	"testing"

	sgbucket "github.com/couchbase/sg-bucket"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func TestView(t *testing.T) {
	ForAllDataStores(t, func(t *testing.T, bucket sgbucket.DataStore) {

		ddocName := "testDDoc"
		viewName := "testView"
		//Create design doc and view
		view := sgbucket.ViewDef{
			Map: `function (doc, meta) { emit(doc.type, null); }`,
		}

		ddoc := &sgbucket.DesignDoc{
			Views: map[string]sgbucket.ViewDef{viewName: view},
		}

		err := bucket.PutDDoc(ddocName, ddoc)
		require.NoError(t, err)

		defer func() {
			err := bucket.DeleteDDoc(ddocName)
			if err != nil {
				log.Printf("Error removing design doc during test teardown")
			}
		}()

		// Put test docs
		err = bucket.Set("u1", 0, map[string]interface{}{"type": "Circle"})
		assert.NoError(t, err)
		err = bucket.Set("u2", 0, map[string]interface{}{"type": "Northern"})
		assert.NoError(t, err)
		err = bucket.Set("u3", 0, map[string]interface{}{"type": "District"})
		assert.NoError(t, err)

		// Confirm view availability
		ddocCheck, getErr := bucket.GetDDoc(ddocName)
		assert.NoError(t, getErr)
		assert.NotNil(t, ddocCheck)

		// wait for view readiness
		worker := func() (shouldRetry bool, err error, value interface{}) {
			viewParams := make(map[string]interface{})
			_, viewErr := bucket.View(ddocName, viewName, viewParams)
			if viewErr == nil {
				return false, nil, nil
			}
			if strings.Contains(viewErr.Error(), "view_undefined") {
				log.Printf("View undefined, retrying")
				return true, nil, nil
			}
			return false, viewErr, nil
		}

		description := fmt.Sprintf("Wait for view readiness")
		sleeper := CreateSleeperFunc(50, 100)
		viewErr, _ := RetryLoop(description, worker, sleeper)
		require.NoError(t, viewErr)

		// stale=false
		viewParams := make(map[string]interface{})
		viewParams[ViewQueryParamStale] = false
		result, viewErr := bucket.View(ddocName, viewName, viewParams)
		require.NoError(t, viewErr)
		assert.Equal(t, 3, len(result.Rows))

		// Limit
		viewParams[ViewQueryParamLimit] = 1
		result, viewErr = bucket.View(ddocName, viewName, viewParams)
		require.NoError(t, viewErr)
		require.Equal(t, 1, len(result.Rows))
		assert.Equal(t, "Circle", result.Rows[0].Key)

		// Startkey, Endkey
		delete(viewParams, ViewQueryParamLimit)
		viewParams[ViewQueryParamStartKey] = "District"
		viewParams[ViewQueryParamEndKey] = "Northern"
		result, viewErr = bucket.View(ddocName, viewName, viewParams)
		require.NoError(t, viewErr)
		require.Equal(t, 2, len(result.Rows))
		assert.Equal(t, "District", result.Rows[0].Key)
		assert.Equal(t, "Northern", result.Rows[1].Key)

		// InclusiveEnd=false
		viewParams[ViewQueryParamInclusiveEnd] = false
		result, viewErr = bucket.View(ddocName, viewName, viewParams)
		require.NoError(t, viewErr)
		assert.Equal(t, 1, len(result.Rows))
		assert.Equal(t, "District", result.Rows[0].Key)

		// Descending (CBS only)
		if !UnitTestUrlIsWalrus() {
			viewParams = make(map[string]interface{}) // clear previous
			viewParams[ViewQueryParamDescending] = true
			result, viewErr = bucket.View(ddocName, viewName, viewParams)
			require.NoError(t, viewErr)
			require.Equal(t, 3, len(result.Rows))
			assert.Equal(t, "Northern", result.Rows[0].Key)
		}

		// ...and skip (CBS only)
		if !UnitTestUrlIsWalrus() {
			viewParams[ViewQueryParamSkip] = 1
			result, viewErr = bucket.View(ddocName, viewName, viewParams)
			require.NoError(t, viewErr)
			require.Equal(t, 2, len(result.Rows))
			assert.Equal(t, "District", result.Rows[0].Key)
		}

		// Key and keys
		viewParams = make(map[string]interface{}) // clear previous
		viewParams[ViewQueryParamKey] = "District"
		result, viewErr = bucket.View(ddocName, viewName, viewParams)
		require.NoError(t, viewErr)
		require.Equal(t, 1, len(result.Rows))
		assert.Equal(t, "District", result.Rows[0].Key)

		viewParams[ViewQueryParamKey] = "Central"
		result, viewErr = bucket.View(ddocName, viewName, viewParams)
		require.NoError(t, viewErr)
		require.Equal(t, 0, len(result.Rows))

		delete(viewParams, ViewQueryParamKey)
		viewParams[ViewQueryParamKeys] = []interface{}{"Central", "Circle"}
		result, viewErr = bucket.View(ddocName, viewName, viewParams)
		require.NoError(t, viewErr)
		require.Equal(t, 1, len(result.Rows))
		assert.Equal(t, "Circle", result.Rows[0].Key)

		// ViewCustom

		// ViewQuery, Next
		viewQueryParams := make(map[string]interface{})
		iterator, viewQueryErr := bucket.ViewQuery(ddocName, viewName, viewQueryParams)
		require.NoError(t, viewQueryErr)
		var value interface{}
		rowCount := 0
		for iterator.Next(&value) {
			rowCount++
		}
		assert.Equal(t, 3, rowCount)

		// ViewQuery, NextBytes
		bytesIterator, viewQueryErr := bucket.ViewQuery(ddocName, viewName, viewQueryParams)
		require.NoError(t, viewQueryErr)
		rowCount = 0
		for {
			nextBytes := bytesIterator.NextBytes()
			if nextBytes == nil {
				break
			}
			rowCount++
		}
		assert.Equal(t, 3, rowCount)

	})
}
<commit_msg>CBG-1261 Retry test view readiness on any error (#4940)<commit_after>package base

import (
	"fmt"
	"log"
	"testing"

	sgbucket "github.com/couchbase/sg-bucket"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func TestView(t *testing.T) {
	ForAllDataStores(t, func(t *testing.T, bucket sgbucket.DataStore) {

		ddocName := "testDDoc"
		viewName := "testView"
		//Create design doc and view
		view := sgbucket.ViewDef{
			Map: `function (doc, meta) { emit(doc.type, null); }`,
		}

		ddoc := &sgbucket.DesignDoc{
			Views: map[string]sgbucket.ViewDef{viewName: view},
		}

		err := bucket.PutDDoc(ddocName, ddoc)
		require.NoError(t, err)

		defer func() {
			err := bucket.DeleteDDoc(ddocName)
			if err != nil {
				log.Printf("Error removing design doc during test teardown")
			}
		}()

		// Put test docs
		err = bucket.Set("u1", 0, map[string]interface{}{"type": "Circle"})
		assert.NoError(t, err)
		err = bucket.Set("u2", 0, map[string]interface{}{"type": "Northern"})
		assert.NoError(t, err)
		err = bucket.Set("u3", 0, map[string]interface{}{"type": "District"})
		assert.NoError(t, err)

		// Confirm view availability
		ddocCheck, getErr := bucket.GetDDoc(ddocName)
		assert.NoError(t, getErr)
		assert.NotNil(t, ddocCheck)

		// wait for view readiness
		worker := func() (shouldRetry bool, err error, value interface{}) {
			viewParams := make(map[string]interface{})
			_, viewErr := bucket.View(ddocName, viewName, viewParams)
			if viewErr == nil {
				return false, nil, nil
			}
			log.Printf("Unexpected error querying view for readiness, retrying: %v", err)
			return true, viewErr, nil
		}

		description := fmt.Sprintf("Wait for view readiness")
		sleeper := CreateSleeperFunc(50, 100)
		viewErr, _ := RetryLoop(description, worker, sleeper)
		require.NoError(t, viewErr)

		// stale=false
		viewParams := make(map[string]interface{})
		viewParams[ViewQueryParamStale] = false
		result, viewErr := bucket.View(ddocName, viewName, viewParams)
		require.NoError(t, viewErr)
		assert.Equal(t, 3, len(result.Rows))

		// Limit
		viewParams[ViewQueryParamLimit] = 1
		result, viewErr = bucket.View(ddocName, viewName, viewParams)
		require.NoError(t, viewErr)
		require.Equal(t, 1, len(result.Rows))
		assert.Equal(t, "Circle", result.Rows[0].Key)

		// Startkey, Endkey
		delete(viewParams, ViewQueryParamLimit)
		viewParams[ViewQueryParamStartKey] = "District"
		viewParams[ViewQueryParamEndKey] = "Northern"
		result, viewErr = bucket.View(ddocName, viewName, viewParams)
		require.NoError(t, viewErr)
		require.Equal(t, 2, len(result.Rows))
		assert.Equal(t, "District", result.Rows[0].Key)
		assert.Equal(t, "Northern", result.Rows[1].Key)

		// InclusiveEnd=false
		viewParams[ViewQueryParamInclusiveEnd] = false
		result, viewErr = bucket.View(ddocName, viewName, viewParams)
		require.NoError(t, viewErr)
		assert.Equal(t, 1, len(result.Rows))
		assert.Equal(t, "District", result.Rows[0].Key)

		// Descending (CBS only)
		if !UnitTestUrlIsWalrus() {
			viewParams = make(map[string]interface{}) // clear previous
			viewParams[ViewQueryParamDescending] = true
			result, viewErr = bucket.View(ddocName, viewName, viewParams)
			require.NoError(t, viewErr)
			require.Equal(t, 3, len(result.Rows))
			assert.Equal(t, "Northern", result.Rows[0].Key)
		}

		// ...and skip (CBS only)
		if !UnitTestUrlIsWalrus() {
			viewParams[ViewQueryParamSkip] = 1
			result, viewErr = bucket.View(ddocName, viewName, viewParams)
			require.NoError(t, viewErr)
			require.Equal(t, 2, len(result.Rows))
			assert.Equal(t, "District", result.Rows[0].Key)
		}

		// Key and keys
		viewParams = make(map[string]interface{}) // clear previous
		viewParams[ViewQueryParamKey] = "District"
		result, viewErr = bucket.View(ddocName, viewName, viewParams)
		require.NoError(t, viewErr)
		require.Equal(t, 1, len(result.Rows))
		assert.Equal(t, "District", result.Rows[0].Key)

		viewParams[ViewQueryParamKey] = "Central"
		result, viewErr = bucket.View(ddocName, viewName, viewParams)
		require.NoError(t, viewErr)
		require.Equal(t, 0, len(result.Rows))

		delete(viewParams, ViewQueryParamKey)
		viewParams[ViewQueryParamKeys] = []interface{}{"Central", "Circle"}
		result, viewErr = bucket.View(ddocName, viewName, viewParams)
		require.NoError(t, viewErr)
		require.Equal(t, 1, len(result.Rows))
		assert.Equal(t, "Circle", result.Rows[0].Key)

		// ViewCustom

		// ViewQuery, Next
		viewQueryParams := make(map[string]interface{})
		iterator, viewQueryErr := bucket.ViewQuery(ddocName, viewName, viewQueryParams)
		require.NoError(t, viewQueryErr)
		var value interface{}
		rowCount := 0
		for iterator.Next(&value) {
			rowCount++
		}
		assert.Equal(t, 3, rowCount)

		// ViewQuery, NextBytes
		bytesIterator, viewQueryErr := bucket.ViewQuery(ddocName, viewName, viewQueryParams)
		require.NoError(t, viewQueryErr)
		rowCount = 0
		for {
			nextBytes := bytesIterator.NextBytes()
			if nextBytes == nil {
				break
			}
			rowCount++
		}
		assert.Equal(t, 3, rowCount)

	})
}
<|endoftext|>