Beispiel #1
0
// incrementOffset is a common incrementor method used between Increment and
// Decrement. If the key isn't set before, we will set the initial value. If
// there is a value present, we will add the given offset to that value and
// update the value with the new TTL.
func (c *Cache) incrementOffset(key string, initial, offset, ttl int64) error {
	c.client.Do("WATCH", key)

	if err := c.exists(key); err != nil {
		c.client.Do("MULTI")
		defer c.client.Do("EXEC")
		return c.Set(key, encoding.Int64Bytes(initial), ttl)
	}

	getValue, _, err := c.Get(key)
	if err != nil {
		return err
	}

	val, ok := encoding.BytesInt64(getValue)

	if !ok {
		return errors.NewEncoding(key)
	}

	// We are watching our key. With using a transaction, we can check that this
	// increment doesn't inflect with another concurrent request that might
	// happen.
	c.client.Do("MULTI")
	defer c.client.Do("EXEC")

	val += offset
	if val < 0 {
		return errors.NewValueBelowZero(key)
	}

	return c.Set(key, encoding.Int64Bytes(val), ttl)
}
Beispiel #2
0
func TestSet(t *testing.T) {
	values := map[string][]byte{
		"key1": []byte("value"),
		"key2": encoding.Int64Bytes(2),
	}

	for _, cache := range testDrivers() {
		for key, value := range values {
			if err := cache.Set(key, value, 0); err != nil {
				tests.FailMsg(t, cache, "Expecting `key1` to be `value`")
			}

			val, _, _ := cache.Get(key)
			if !reflect.DeepEqual(val, value) {
				tests.FailMsg(t, cache, "Value for key `"+key+"` does not match.")
			}
		}

		cache.Set("key1", []byte("value"), -1)
		_, _, err := cache.Get("key1")

		if err == nil {
			tests.FailMsg(t, cache, "key1 should be deleted with negative value")
		}

	}
}
Beispiel #3
0
func TestDeleteMulti(t *testing.T) {
	for _, cache := range testDrivers() {
		items := map[string][]byte{
			"item1": encoding.Int64Bytes(1),
			"item2": []byte("string"),
		}

		cache.SetMulti(items, 0)
		cache.Set("key1", []byte("value1"), 0)

		var keys []string
		for k := range items {
			keys = append(keys, k)
		}

		cache.DeleteMulti(keys)

		if _, _, err := cache.Get("item1"); err == nil {
			tests.FailMsg(t, cache, "`item1` should be deleted from the cache.")
		}

		if _, _, err := cache.Get("item2"); err == nil {
			tests.FailMsg(t, cache, "`item2` should be deleted from the cache.")
		}

		tests.Compare(t, cache, "key1", "value1")
	}
}
Beispiel #4
0
func TestGetMulti(t *testing.T) {
	for _, cache := range testDrivers() {
		items := map[string][]byte{
			"item1": encoding.Int64Bytes(1),
			"item2": []byte("string"),
		}

		cache.SetMulti(items, 0)

		var keys []string
		for k := range items {
			keys = append(keys, k)
		}

		values, tokens, errs := cache.GetMulti(keys)

		_, val := binary.Varint(values["item1"])
		if val != 1 {
			tests.FailMsg(t, cache, "Expected `item1` to equal `1`")
		}

		if err, ok := errs["item1"]; !ok || err != nil {
			tests.FailMsg(t, cache, "Expected `item1` to be ok.")
		}

		if tokens["item1"] == "" {
			tests.FailMsg(t, cache, "Expected `item1` to have a valid token.")
		}

		if string(values["item2"]) != "string" {
			tests.FailMsg(t, cache, "Expected `item2` to equal `string`")
		}
	}
}
Beispiel #5
0
// incrementOffset is a common incrementor method used between Increment and
// Decrement. If the key isn't set before, we will set the initial value. If
// there is a value present, we will add the given offset to that value and
// update the value with the new TTL.
func (c *Cache) incrementOffset(key string, initial, offset, ttl int64) error {
	if err := c.exists(key); err != nil {
		return c.Set(key, encoding.Int64Bytes(initial), ttl)
	}

	val, ok := encoding.BytesInt64(c.items[key].value)

	if !ok {
		return errors.NewEncoding(key)
	}

	val += offset
	if val < 0 {
		return errors.NewValueBelowZero(key)
	}

	return c.Set(key, encoding.Int64Bytes(val), ttl)
}
Beispiel #6
0
func TestSetMulti(t *testing.T) {
	for _, cache := range testDrivers() {
		items := map[string][]byte{
			"item1": encoding.Int64Bytes(1),
			"item2": []byte("string"),
		}

		cache.SetMulti(items, 0)

		tests.Compare(t, cache, "item1", 1)
		tests.Compare(t, cache, "item2", "string")
	}
}