diff options
| -rw-r--r-- | storage/memory.go | 47 | ||||
| -rw-r--r-- | storage/memory_test.go | 56 | ||||
| -rw-r--r-- | storage/redis.go | 2 | ||||
| -rw-r--r-- | storage/type.go | 2 |
4 files changed, 106 insertions, 1 deletions
diff --git a/storage/memory.go b/storage/memory.go new file mode 100644 index 0000000..80f6579 --- /dev/null +++ b/storage/memory.go @@ -0,0 +1,47 @@ +package storage + +var _ CHR = &Memory{} + +// Memory is an in-memory non-persistent storage type +// using it in production is not recommended +type Memory struct { + store map[string]string +} + +// Create will store a value in a key in memory +func (r *Memory) Create(key, value string, checkcollision bool) error { + if !r.Healthy() { + return Unhealthy + } + if checkcollision { + if _, ok := r.store[key]; ok { + return Collision + } + } + r.store[key] = value + return nil +} + +// Read will read a key from memory, if it's there +func (r *Memory) Read(key string) (string, error) { + if !r.Healthy() { + return "", Unhealthy + } + if val, ok := r.store[key]; ok { + return val, nil + } + return "", Error("value not found") +} + +// Healthy checks if the memory storage is initialized +func (r *Memory) Healthy() bool { + return r.store != nil +} + +// NewMemory initializes a memory backend for use +func NewMemory() CHR { + m := Memory{ + store: make(map[string]string), + } + return &m +} diff --git a/storage/memory_test.go b/storage/memory_test.go new file mode 100644 index 0000000..fa0666e --- /dev/null +++ b/storage/memory_test.go @@ -0,0 +1,56 @@ +package storage + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestMemory(t *testing.T) { + assert := assert.New(t) + const ( + k = "key" + v1 = "val1" + v2 = "val2" + ) + + m := NewMemory() + + err := m.Create(k, v1, false) + assert.Nil(err) + + err = m.Create(k, v2, false) + assert.Nil(err) + + err = m.Create(k, v1, true) + assert.Equal(Collision, err) + + v, err := m.Read(k) + assert.Nil(err) + assert.Equal(v2, v) + + _, err = m.Read(v1) + assert.NotNil(err) + assert.Equal(NotFound, err) +} + +func TestUnhealthyMemory(t *testing.T) { + assert := assert.New(t) + m := &Memory{} + + var ( + e1 = m.Create("", "", false) + e2 = m.Create("", "", true) + _, e3 = m.Read("") + ) + + assert.NotNil(e1) + assert.NotNil(e2) + assert.NotNil(e3) + + assert.Equal(Unhealthy, e1) + assert.Equal(Unhealthy, e2) + assert.Equal(Unhealthy, e3) + + assert.False(m.Healthy()) +} diff --git a/storage/redis.go b/storage/redis.go index de207a5..317ee3e 100644 --- a/storage/redis.go +++ b/storage/redis.go @@ -29,7 +29,7 @@ func (r *Redis) Read(key string) (string, error) { if !r.Healthy() { return "", Unhealthy } - return r.Get(key).Result() + return r.Get(key).Result() // TODO: return NotFound conditionally } // Healthy determines whether redis is responding to pings diff --git a/storage/type.go b/storage/type.go index 4f78a46..b2d3136 100644 --- a/storage/type.go +++ b/storage/type.go @@ -3,6 +3,8 @@ package storage const ( // Collision is a fatal collision error, only triggered when it fails Collision = Error("collision detected") + // NotFound is a fatal error when the backend cannot find a key to read + NotFound = Error("value not found") // Unhealthy is a fatal error when the backend ceases to be healthy Unhealthy = Error("backend unhealthy") ) |
