summaryrefslogtreecommitdiffstats
path: root/src/k8splugin/db
diff options
context:
space:
mode:
authorVictor Morales <victor.morales@intel.com>2018-10-23 11:54:58 -0700
committerVictor Morales <victor.morales@intel.com>2018-11-13 16:20:57 -0800
commitcc05d4af8f082d8174bde5c43fc45b1acc61339f (patch)
treee5614b80fd1f4762c195eb26f639f7963eb2bb5f /src/k8splugin/db
parent7d2d48d3d0b35de0acd03c6e8a1261efd736edc3 (diff)
Create UTs to cover DB calls
This change pretends to increase the code coverage creating Unit Tests for the interactions with the Databases. Change-Id: I3b78ebe8ddb131e3c06bcee0065ad5eabeed5677 Signed-off-by: Victor Morales <victor.morales@intel.com> Issue-ID: MULTICLOUD-301
Diffstat (limited to 'src/k8splugin/db')
-rw-r--r--src/k8splugin/db/consul.go118
-rw-r--r--src/k8splugin/db/consul_test.go298
-rw-r--r--src/k8splugin/db/db_test.go99
-rw-r--r--src/k8splugin/db/store.go (renamed from src/k8splugin/db/DB.go)27
-rw-r--r--src/k8splugin/db/store_test.go123
-rw-r--r--src/k8splugin/db/testing.go65
6 files changed, 557 insertions, 173 deletions
diff --git a/src/k8splugin/db/consul.go b/src/k8splugin/db/consul.go
index 950eea34..d7507242 100644
--- a/src/k8splugin/db/consul.go
+++ b/src/k8splugin/db/consul.go
@@ -16,95 +16,89 @@ package db
import (
"os"
- consulapi "github.com/hashicorp/consul/api"
+ "github.com/hashicorp/consul/api"
pkgerrors "github.com/pkg/errors"
)
-// ConsulDB is an implementation of the DatabaseConnection interface
-type ConsulDB struct {
- consulClient *consulapi.Client
+// ConsulKVStore defines the a subset of Consul DB operations
+// Note: This interface is defined mainly for allowing mock testing
+type ConsulKVStore interface {
+ List(prefix string, q *api.QueryOptions) (api.KVPairs, *api.QueryMeta, error)
+ Get(key string, q *api.QueryOptions) (*api.KVPair, *api.QueryMeta, error)
+ Put(p *api.KVPair, q *api.WriteOptions) (*api.WriteMeta, error)
+ Delete(key string, w *api.WriteOptions) (*api.WriteMeta, error)
}
-// InitializeDatabase initialized the initial steps
-func (c *ConsulDB) InitializeDatabase() error {
- config := consulapi.DefaultConfig()
- config.Address = os.Getenv("DATABASE_IP") + ":8500"
+// ConsulStore is an implementation of the ConsulKVStore interface
+type ConsulStore struct {
+ client ConsulKVStore
+}
- client, err := consulapi.NewClient(config)
- if err != nil {
- return err
+// NewConsulStore initializes a Consul Store instance using the default values
+func NewConsulStore(store ConsulKVStore) (Store, error) {
+ if store == nil {
+ config := api.DefaultConfig()
+ config.Address = os.Getenv("DATABASE_IP") + ":8500"
+
+ consulClient, err := api.NewClient(config)
+ if err != nil {
+ return nil, err
+ }
+ store = consulClient.KV()
}
- c.consulClient = client
- return nil
+
+ return &ConsulStore{
+ client: store,
+ }, nil
}
-// CheckDatabase checks if the database is running
-func (c *ConsulDB) CheckDatabase() error {
- kv := c.consulClient.KV()
- _, _, err := kv.Get("test", nil)
+// HealthCheck verifies if the database is up and running
+func (c *ConsulStore) HealthCheck() error {
+ _, err := c.Read("test")
if err != nil {
return pkgerrors.New("[ERROR] Cannot talk to Datastore. Check if it is running/reachable.")
}
return nil
}
-// CreateEntry is used to create a DB entry
-func (c *ConsulDB) CreateEntry(key string, value string) error {
- kv := c.consulClient.KV()
-
- p := &consulapi.KVPair{Key: key, Value: []byte(value)}
-
- _, err := kv.Put(p, nil)
-
- if err != nil {
- return err
+// Create is used to create a DB entry
+func (c *ConsulStore) Create(key, value string) error {
+ p := &api.KVPair{
+ Key: key,
+ Value: []byte(value),
}
-
- return nil
+ _, err := c.client.Put(p, nil)
+ return err
}
-// ReadEntry returns the internalID for a particular externalID is present in a namespace
-func (c *ConsulDB) ReadEntry(key string) (string, bool, error) {
-
- kv := c.consulClient.KV()
-
- pair, _, err := kv.Get(key, nil)
-
+// Read method returns the internalID for a particular externalID
+func (c *ConsulStore) Read(key string) (string, error) {
+ pair, _, err := c.client.Get(key, nil)
+ if err != nil {
+ return "", err
+ }
if pair == nil {
- return string("No value found for ID: " + key), false, err
+ return "", nil
}
- return string(pair.Value), true, err
+ return string(pair.Value), nil
}
-// DeleteEntry is used to delete an ID
-func (c *ConsulDB) DeleteEntry(key string) error {
-
- kv := c.consulClient.KV()
-
- _, err := kv.Delete(key, nil)
-
- if err != nil {
- return err
- }
-
- return nil
+// Delete method removes an internalID from the Database
+func (c *ConsulStore) Delete(key string) error {
+ _, err := c.client.Delete(key, nil)
+ return err
}
// ReadAll is used to get all ExternalIDs in a namespace
-func (c *ConsulDB) ReadAll(prefix string) ([]string, error) {
- kv := c.consulClient.KV()
-
- pairs, _, err := kv.List(prefix, nil)
-
- if len(pairs) == 0 {
- return []string{""}, err
+func (c *ConsulStore) ReadAll(prefix string) ([]string, error) {
+ pairs, _, err := c.client.List(prefix, nil)
+ if err != nil {
+ return nil, err
}
-
- var res []string
-
+ var result []string
for _, keypair := range pairs {
- res = append(res, keypair.Key)
+ result = append(result, keypair.Key)
}
- return res, err
+ return result, nil
}
diff --git a/src/k8splugin/db/consul_test.go b/src/k8splugin/db/consul_test.go
new file mode 100644
index 00000000..ede1a5e9
--- /dev/null
+++ b/src/k8splugin/db/consul_test.go
@@ -0,0 +1,298 @@
+// +build unit
+
+/*
+Copyright 2018 Intel Corporation.
+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 db
+
+import (
+ "reflect"
+ "strings"
+ "testing"
+
+ "github.com/hashicorp/consul/api"
+ pkgerrors "github.com/pkg/errors"
+)
+
+type mockConsulKVStore struct {
+ Items api.KVPairs
+ Err error
+}
+
+func (c *mockConsulKVStore) Put(p *api.KVPair, q *api.WriteOptions) (*api.WriteMeta, error) {
+ return nil, c.Err
+}
+
+func (c *mockConsulKVStore) Get(key string, q *api.QueryOptions) (*api.KVPair, *api.QueryMeta, error) {
+ if c.Err != nil {
+ return nil, nil, c.Err
+ }
+ for _, kvpair := range c.Items {
+ if kvpair.Key == key {
+ return kvpair, nil, nil
+ }
+ }
+ return nil, nil, nil
+}
+
+func (c *mockConsulKVStore) Delete(key string, w *api.WriteOptions) (*api.WriteMeta, error) {
+ return nil, c.Err
+}
+
+func (c *mockConsulKVStore) List(prefix string, q *api.QueryOptions) (api.KVPairs, *api.QueryMeta, error) {
+ if c.Err != nil {
+ return nil, nil, c.Err
+ }
+ return c.Items, nil, nil
+}
+
+func TestConsulHealthCheck(t *testing.T) {
+ testCases := []struct {
+ label string
+ mock *mockConsulKVStore
+ expectedError string
+ }{
+ {
+ label: "Sucessful health check Consul Database",
+ mock: &mockConsulKVStore{
+ Items: api.KVPairs{
+ &api.KVPair{
+ Key: "test-key",
+ Value: nil,
+ },
+ },
+ },
+ },
+ {
+ label: "Fail connectivity to Consul Database",
+ mock: &mockConsulKVStore{
+ Err: pkgerrors.New("Timeout"),
+ },
+ expectedError: "Cannot talk to Datastore. Check if it is running/reachable.",
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ client, _ := NewConsulStore(testCase.mock)
+ err := client.HealthCheck()
+ if err != nil {
+ if testCase.expectedError == "" {
+ t.Fatalf("HealthCheck method return an un-expected (%s)", err)
+ }
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("HealthCheck method returned an error (%s)", err)
+ }
+ }
+ })
+ }
+}
+
+func TestConsulCreate(t *testing.T) {
+ testCases := []struct {
+ label string
+ input map[string]string
+ mock *mockConsulKVStore
+ expectedError string
+ }{
+ {
+ label: "Sucessful register a record to Consul Database",
+ input: map[string]string{"key": "test-key", "value": "test-value"},
+ mock: &mockConsulKVStore{},
+ },
+ {
+ label: "Fail to create a new record in Consul Database",
+ input: map[string]string{"key": "test-key", "value": "test-value"},
+ mock: &mockConsulKVStore{
+ Err: pkgerrors.New("DB error"),
+ },
+ expectedError: "DB error",
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ client, _ := NewConsulStore(testCase.mock)
+ err := client.Create(testCase.input["key"], testCase.input["value"])
+ if err != nil {
+ if testCase.expectedError == "" {
+ t.Fatalf("Create method return an un-expected (%s)", err)
+ }
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Create method returned an error (%s)", err)
+ }
+ }
+ })
+ }
+}
+
+func TestConsulRead(t *testing.T) {
+ testCases := []struct {
+ label string
+ input string
+ mock *mockConsulKVStore
+ expectedError string
+ expectedResult string
+ }{
+ {
+ label: "Sucessful retrieve a record from Consul Database",
+ input: "test",
+ mock: &mockConsulKVStore{
+ Items: api.KVPairs{
+ &api.KVPair{
+ Key: "test",
+ Value: []byte("test-value"),
+ },
+ },
+ },
+ expectedResult: "test-value",
+ },
+ {
+ label: "Fail retrieve a non-existing record from Consul Database",
+ input: "test",
+ mock: &mockConsulKVStore{},
+ },
+ {
+ label: "Fail retrieve a record from Consul Database",
+ input: "test",
+ mock: &mockConsulKVStore{
+ Err: pkgerrors.New("DB error"),
+ },
+ expectedError: "DB error",
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ client, _ := NewConsulStore(testCase.mock)
+ result, err := client.Read(testCase.input)
+ if err != nil {
+ if testCase.expectedError == "" {
+ t.Fatalf("Read method return an un-expected (%s)", err)
+ }
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Read method returned an error (%s)", err)
+ }
+ } else {
+ if testCase.expectedError != "" && testCase.expectedResult == "" {
+ t.Fatalf("Read method was expecting \"%s\" error message", testCase.expectedError)
+ }
+ if !reflect.DeepEqual(testCase.expectedResult, result) {
+
+ t.Fatalf("Read method returned: \n%v\n and it was expected: \n%v", result, testCase.expectedResult)
+ }
+ }
+ })
+ }
+}
+
+func TestConsulDelete(t *testing.T) {
+ testCases := []struct {
+ label string
+ input string
+ mock *mockConsulKVStore
+ expectedError string
+ }{
+ {
+ label: "Sucessful delete a record to Consul Database",
+ input: "test",
+ mock: &mockConsulKVStore{},
+ },
+ {
+ label: "Fail to delete a record in Consul Database",
+ mock: &mockConsulKVStore{
+ Err: pkgerrors.New("DB error"),
+ },
+ expectedError: "DB error",
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ client, _ := NewConsulStore(testCase.mock)
+ err := client.Delete(testCase.input)
+ if err != nil {
+ if testCase.expectedError == "" {
+ t.Fatalf("Delete method return an un-expected (%s)", err)
+ }
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("Delete method returned an error (%s)", err)
+ }
+ }
+ })
+ }
+}
+
+func TestConsulReadAll(t *testing.T) {
+ testCases := []struct {
+ label string
+ input string
+ mock *mockConsulKVStore
+ expectedError string
+ expectedResult []string
+ }{
+ {
+ label: "Sucessful retrieve a list from Consul Database",
+ input: "test",
+ mock: &mockConsulKVStore{
+ Items: api.KVPairs{
+ &api.KVPair{
+ Key: "test",
+ Value: []byte("test-value"),
+ },
+ &api.KVPair{
+ Key: "test2",
+ Value: []byte("test-value2"),
+ },
+ },
+ },
+ expectedResult: []string{"test", "test2"},
+ },
+ {
+ label: "Sucessful retrieve an empty list from Consul Database",
+ input: "test",
+ mock: &mockConsulKVStore{},
+ },
+ {
+ label: "Fail retrieve a record from Consul Database",
+ input: "test",
+ mock: &mockConsulKVStore{
+ Err: pkgerrors.New("DB error"),
+ },
+ expectedError: "DB error",
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ client, _ := NewConsulStore(testCase.mock)
+ result, err := client.ReadAll(testCase.input)
+ if err != nil {
+ if testCase.expectedError == "" {
+ t.Fatalf("ReadAll method return an un-expected (%s)", err)
+ }
+ if !strings.Contains(string(err.Error()), testCase.expectedError) {
+ t.Fatalf("ReadAll method returned an error (%s)", err)
+ }
+ } else {
+ if testCase.expectedError != "" && testCase.expectedResult == nil {
+ t.Fatalf("ReadAll method was expecting \"%s\" error message", testCase.expectedError)
+ }
+ if !reflect.DeepEqual(testCase.expectedResult, result) {
+
+ t.Fatalf("ReadAll method returned: \n%v\n and it was expected: \n%v", result, testCase.expectedResult)
+ }
+ }
+ })
+ }
+}
diff --git a/src/k8splugin/db/db_test.go b/src/k8splugin/db/db_test.go
deleted file mode 100644
index d37cd7ae..00000000
--- a/src/k8splugin/db/db_test.go
+++ /dev/null
@@ -1,99 +0,0 @@
-// +build unit
-
-/*
-Copyright 2018 Intel Corporation.
-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 db
-
-import (
- "reflect"
- "testing"
-)
-
-func TestCreateDBClient(t *testing.T) {
- oldDBconn := DBconn
-
- defer func() {
- DBconn = oldDBconn
- }()
-
- t.Run("Successfully create DB client", func(t *testing.T) {
- expectedDB := ConsulDB{}
-
- err := CreateDBClient("consul")
- if err != nil {
- t.Fatalf("TestCreateDBClient returned an error (%s)", err)
- }
-
- if !reflect.DeepEqual(DBconn, &expectedDB) {
- t.Fatalf("TestCreateDBClient set DBconn as:\n result=%v\n expected=%v", DBconn, expectedDB)
- }
- })
-}
-
-func TestSerialize(t *testing.T) {
-
- inp := map[string]interface{}{
- "UUID": "123e4567-e89b-12d3-a456-426655440000",
- "Data": "sdaijsdiodalkfjsdlagf",
- "Number": 23,
- "Float": 34.4,
- "Map": map[string]interface{}{
- "m1": "m1",
- "m2": 2,
- "m3": 3.0,
- },
- }
-
- got, err := Serialize(inp)
- if err != nil {
- t.Fatal(err)
- }
-
- expected := "{\"Data\":\"sdaijsdiodalkfjsdlagf\"," +
- "\"Float\":34.4,\"Map\":{\"m1\":\"m1\",\"m2\":2,\"m3\":3}," +
- "\"Number\":23,\"UUID\":\"123e4567-e89b-12d3-a456-426655440000\"}"
-
- if expected != got {
- t.Errorf("Serialize returned unexpected string: %s;"+
- " expected %sv", got, expected)
- }
-}
-
-func TestDeSerialize(t *testing.T) {
-
- inp := "{\"Data\":\"sdaijsdiodalkfjsdlagf\"," +
- "\"Float\":34.4,\"Map\":{\"m1\":\"m1\",\"m3\":3}," +
- "\"UUID\":\"123e4567-e89b-12d3-a456-426655440000\"}"
-
- got := make(map[string]interface{})
- err := DeSerialize(inp, &got)
- if err != nil {
- t.Fatal(err)
- }
-
- expected := map[string]interface{}{
- "UUID": "123e4567-e89b-12d3-a456-426655440000",
- "Data": "sdaijsdiodalkfjsdlagf",
- "Float": 34.4,
- "Map": map[string]interface{}{
- "m1": "m1",
- "m3": 3.0,
- },
- }
-
- if reflect.DeepEqual(expected, got) == false {
- t.Errorf("Serialize returned unexpected : %s;"+
- " expected %s", got, expected)
- }
-}
diff --git a/src/k8splugin/db/DB.go b/src/k8splugin/db/store.go
index d92b5953..c1a8b31f 100644
--- a/src/k8splugin/db/DB.go
+++ b/src/k8splugin/db/store.go
@@ -21,27 +21,30 @@ import (
)
// DBconn interface used to talk a concrete Database connection
-var DBconn DatabaseConnection
-
-// DatabaseConnection is an interface for accessing a database
-type DatabaseConnection interface {
- InitializeDatabase() error
- CheckDatabase() error
- CreateEntry(string, string) error
- ReadEntry(string) (string, bool, error)
- DeleteEntry(string) error
+var DBconn Store
+
+// Store is an interface for accessing a database
+type Store interface {
+ HealthCheck() error
+
+ Create(string, string) error
+ Read(string) (string, error)
+ // Update(string) (string, error)
+ Delete(string) error
+
ReadAll(string) ([]string, error)
}
// CreateDBClient creates the DB client
-var CreateDBClient = func(dbType string) error {
+func CreateDBClient(dbType string) error {
+ var err error
switch dbType {
case "consul":
- DBconn = &ConsulDB{}
- return nil
+ DBconn, err = NewConsulStore(nil)
default:
return pkgerrors.New(dbType + "DB not supported")
}
+ return err
}
// Serialize converts given data into a JSON string
diff --git a/src/k8splugin/db/store_test.go b/src/k8splugin/db/store_test.go
new file mode 100644
index 00000000..9bbe4a92
--- /dev/null
+++ b/src/k8splugin/db/store_test.go
@@ -0,0 +1,123 @@
+// +build unit
+
+/*
+Copyright 2018 Intel Corporation.
+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 db
+
+import (
+ "reflect"
+ "strings"
+ "testing"
+)
+
+func TestCreateDBClient(t *testing.T) {
+ t.Run("Successfully create DB client", func(t *testing.T) {
+ expected := &ConsulStore{}
+
+ err := CreateDBClient("consul")
+ if err != nil {
+ t.Fatalf("CreateDBClient returned an error (%s)", err)
+ }
+ if reflect.TypeOf(DBconn) != reflect.TypeOf(expected) {
+ t.Fatalf("CreateDBClient set DBconn as:\n result=%T\n expected=%T", DBconn, expected)
+ }
+ })
+ t.Run("Fail to create client for unsupported DB", func(t *testing.T) {
+ err := CreateDBClient("fakeDB")
+ if err == nil {
+ t.Fatal("CreateDBClient didn't return an error")
+ }
+ if !strings.Contains(string(err.Error()), "DB not supported") {
+ t.Fatalf("CreateDBClient method returned an error (%s)", err)
+ }
+ })
+}
+
+func TestSerialize(t *testing.T) {
+
+ inp := map[string]interface{}{
+ "UUID": "123e4567-e89b-12d3-a456-426655440000",
+ "Data": "sdaijsdiodalkfjsdlagf",
+ "Number": 23,
+ "Float": 34.4,
+ "Map": map[string]interface{}{
+ "m1": "m1",
+ "m2": 2,
+ "m3": 3.0,
+ },
+ }
+
+ got, err := Serialize(inp)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ expected := "{\"Data\":\"sdaijsdiodalkfjsdlagf\"," +
+ "\"Float\":34.4,\"Map\":{\"m1\":\"m1\",\"m2\":2,\"m3\":3}," +
+ "\"Number\":23,\"UUID\":\"123e4567-e89b-12d3-a456-426655440000\"}"
+
+ if expected != got {
+ t.Errorf("Serialize returned unexpected string: %s;"+
+ " expected %sv", got, expected)
+ }
+}
+
+func TestDeSerialize(t *testing.T) {
+ testCases := []struct {
+ label string
+ input string
+ expected map[string]interface{}
+ errMsg string
+ }{
+ {
+ label: "Sucessful deserialize entry",
+ input: "{\"Data\":\"sdaijsdiodalkfjsdlagf\"," +
+ "\"Float\":34.4,\"Map\":{\"m1\":\"m1\",\"m3\":3}," +
+ "\"UUID\":\"123e4567-e89b-12d3-a456-426655440000\"}",
+ expected: map[string]interface{}{
+ "UUID": "123e4567-e89b-12d3-a456-426655440000",
+ "Data": "sdaijsdiodalkfjsdlagf",
+ "Float": 34.4,
+ "Map": map[string]interface{}{
+ "m1": "m1",
+ "m3": 3.0,
+ },
+ },
+ },
+ {
+ label: "Fail to deserialize invalid entry",
+ input: "{invalid}",
+ errMsg: "Error deSerializing {invalid}: invalid character 'i' looking for beginning of object key string",
+ },
+ }
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ got := make(map[string]interface{})
+ err := DeSerialize(testCase.input, &got)
+ if err != nil {
+ if testCase.errMsg == "" {
+ t.Fatalf("DeSerialize method return an un-expected (%s)", err)
+ }
+ if !strings.Contains(string(err.Error()), testCase.errMsg) {
+ t.Fatalf("DeSerialize method returned an error (%s)", err)
+ }
+ } else {
+ if !reflect.DeepEqual(testCase.expected, got) {
+ t.Errorf("Serialize returned unexpected : %v;"+
+ " expected %v", got, testCase.expected)
+ }
+ }
+ })
+ }
+}
diff --git a/src/k8splugin/db/testing.go b/src/k8splugin/db/testing.go
new file mode 100644
index 00000000..672fcbfb
--- /dev/null
+++ b/src/k8splugin/db/testing.go
@@ -0,0 +1,65 @@
+// +build unit
+
+/*
+Copyright 2018 Intel Corporation.
+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 db
+
+import (
+ "github.com/hashicorp/consul/api"
+)
+
+//Creating an embedded interface via anonymous variable
+//This allows us to make mockDB satisfy the DatabaseConnection
+//interface even if we are not implementing all the methods in it
+type MockDB struct {
+ Store
+ Items api.KVPairs
+ Err error
+}
+
+func (m *MockDB) Create(key string, value string) error {
+ return m.Err
+}
+
+func (m *MockDB) Read(key string) (string, error) {
+ if m.Err != nil {
+ return "", m.Err
+ }
+
+ for _, kvpair := range m.Items {
+ if kvpair.Key == key {
+ return string(kvpair.Value), nil
+ }
+ }
+
+ return "", nil
+}
+
+func (m *MockDB) Delete(key string) error {
+ return m.Err
+}
+
+func (m *MockDB) ReadAll(prefix string) ([]string, error) {
+ if m.Err != nil {
+ return []string{}, m.Err
+ }
+
+ var res []string
+
+ for _, keypair := range m.Items {
+ res = append(res, keypair.Key)
+ }
+
+ return res, nil
+}