diff options
author | Victor Morales <victor.morales@intel.com> | 2019-01-24 17:46:43 -0800 |
---|---|---|
committer | Victor Morales <victor.morales@intel.com> | 2019-01-25 16:52:38 -0800 |
commit | 083465d10c8fdeaffa89aa7daa93def3eca77df1 (patch) | |
tree | 23135a724a1628e986f9c6748b82f275763cdf10 /src/k8splugin/db | |
parent | 5c4e91705457dc4bdb5526e6f5210fa879ab659d (diff) |
Use a standard Go project layout
This project wasn't following some Standard Go Project Layout
guidelines(https://github.com/golang-standards/project-layout). This
change pretends to organize the source code and following those
guidelines.
Change-Id: I61085ac20f28069cede013f83034bed06892d87c
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.go | 118 | ||||
-rw-r--r-- | src/k8splugin/db/consul_test.go | 313 | ||||
-rw-r--r-- | src/k8splugin/db/mongo.go | 334 | ||||
-rw-r--r-- | src/k8splugin/db/mongo_test.go | 530 | ||||
-rw-r--r-- | src/k8splugin/db/store.go | 83 | ||||
-rw-r--r-- | src/k8splugin/db/store_test.go | 123 | ||||
-rw-r--r-- | src/k8splugin/db/testing.go | 79 |
7 files changed, 0 insertions, 1580 deletions
diff --git a/src/k8splugin/db/consul.go b/src/k8splugin/db/consul.go deleted file mode 100644 index a61a4c10..00000000 --- a/src/k8splugin/db/consul.go +++ /dev/null @@ -1,118 +0,0 @@ -/* -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 ( - "os" - - "github.com/hashicorp/consul/api" - pkgerrors "github.com/pkg/errors" -) - -// 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) -} - -// ConsulStore is an implementation of the ConsulKVStore interface -type ConsulStore struct { - client ConsulKVStore -} - -// 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() - } - - return &ConsulStore{ - client: store, - }, nil -} - -// HealthCheck verifies if the database is up and running -func (c *ConsulStore) HealthCheck() error { - _, err := c.Read("test", "test", "test") - if err != nil { - return pkgerrors.New("[ERROR] Cannot talk to Datastore. Check if it is running/reachable.") - } - return nil -} - -// Unmarshal implements any unmarshaling that is needed when using consul -func (c *ConsulStore) Unmarshal(inp []byte, out interface{}) error { - return nil -} - -// Create is used to create a DB entry -func (c *ConsulStore) Create(root, key, tag string, data interface{}) error { - - value, err := Serialize(data) - if err != nil { - return pkgerrors.Wrap(err, "Serializing input data") - } - - p := &api.KVPair{ - Key: key, - Value: []byte(value), - } - _, err = c.client.Put(p, nil) - return err -} - -// Read method returns the internalID for a particular externalID -func (c *ConsulStore) Read(root, key, tag string) ([]byte, error) { - key = root + "/" + key + "/" + tag - pair, _, err := c.client.Get(key, nil) - if err != nil { - return nil, err - } - if pair == nil { - return nil, nil - } - return pair.Value, nil -} - -// Delete method removes an internalID from the Database -func (c *ConsulStore) Delete(root, key, tag string) error { - _, err := c.client.Delete(key, nil) - return err -} - -// ReadAll is used to get all ExternalIDs in a namespace -func (c *ConsulStore) ReadAll(root, tag string) (map[string][]byte, error) { - pairs, _, err := c.client.List(root, nil) - if err != nil { - return nil, err - } - - //TODO: Filter results by tag and return it - result := make(map[string][]byte) - for _, keypair := range pairs { - result[keypair.Key] = keypair.Value - } - - return result, nil -} diff --git a/src/k8splugin/db/consul_test.go b/src/k8splugin/db/consul_test.go deleted file mode 100644 index 754112ad..00000000 --- a/src/k8splugin/db/consul_test.go +++ /dev/null @@ -1,313 +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" - "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{"root": "rbinst", "key": "test-key", - "tag": "data", "value": "test-value"}, - mock: &mockConsulKVStore{}, - }, - { - label: "Fail to create a new record in Consul Database", - input: map[string]string{"root": "rbinst", "key": "test-key", - "tag": "data", "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["root"], testCase.input["key"], - testCase.input["tag"], 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 map[string]string - mock *mockConsulKVStore - expectedError string - expectedResult string - }{ - { - label: "Sucessful retrieve a record from Consul Database", - input: map[string]string{"root": "rbinst", "key": "test", - "tag": "data"}, - mock: &mockConsulKVStore{ - Items: api.KVPairs{ - &api.KVPair{ - Key: "rbinst/test/data", - Value: []byte("test-value"), - }, - }, - }, - expectedResult: "test-value", - }, - { - label: "Fail retrieve a non-existing record from Consul Database", - input: map[string]string{"root": "rbinst", "key": "test-key", - "tag": "data"}, - mock: &mockConsulKVStore{}, - }, - { - label: "Fail retrieve a record from Consul Database", - input: map[string]string{"root": "rbinst", "key": "test-key", - "tag": "data"}, - 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["root"], testCase.input["key"], - testCase.input["tag"]) - 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, string(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 map[string]string - mock *mockConsulKVStore - expectedError string - }{ - { - label: "Sucessful delete a record to Consul Database", - input: map[string]string{"root": "rbinst", "key": "test-key", - "tag": "data"}, - 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["root"], testCase.input["key"], - testCase.input["tag"]) - 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 map[string]string - mock *mockConsulKVStore - expectedError string - expectedResult map[string][]byte - }{ - { - label: "Sucessful retrieve a list from Consul Database", - input: map[string]string{"root": "rbinst", "key": "test-key", - "tag": "data"}, - mock: &mockConsulKVStore{ - Items: api.KVPairs{ - &api.KVPair{ - Key: "test", - Value: []byte("test-value"), - }, - &api.KVPair{ - Key: "test2", - Value: []byte("test-value2"), - }, - }, - }, - expectedResult: map[string][]byte{"test": []byte("test-value"), - "test2": []byte("test-value2")}, - }, - { - label: "Sucessful retrieve an empty list from Consul Database", - input: map[string]string{"root": "rbinst", "key": "test-key", - "tag": "data"}, - mock: &mockConsulKVStore{}, - expectedResult: map[string][]byte{}, - }, - { - label: "Fail retrieve a record from Consul Database", - input: map[string]string{"root": "rbinst", "key": "test-key", - "tag": "data"}, - 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["root"], - testCase.input["tag"]) - 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/mongo.go b/src/k8splugin/db/mongo.go deleted file mode 100644 index 05976b12..00000000 --- a/src/k8splugin/db/mongo.go +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Copyright 2018 Intel Corporation, Inc - * - * 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/mongodb/mongo-go-driver/bson" - "github.com/mongodb/mongo-go-driver/bson/primitive" - "github.com/mongodb/mongo-go-driver/mongo" - "github.com/mongodb/mongo-go-driver/mongo/options" - pkgerrors "github.com/pkg/errors" - "golang.org/x/net/context" - "log" - "os" -) - -// MongoCollection defines the a subset of MongoDB operations -// Note: This interface is defined mainly for mock testing -type MongoCollection interface { - InsertOne(ctx context.Context, document interface{}, - opts ...*options.InsertOneOptions) (*mongo.InsertOneResult, error) - FindOne(ctx context.Context, filter interface{}, - opts ...*options.FindOneOptions) *mongo.SingleResult - FindOneAndUpdate(ctx context.Context, filter interface{}, - update interface{}, opts ...*options.FindOneAndUpdateOptions) *mongo.SingleResult - DeleteOne(ctx context.Context, filter interface{}, - opts ...*options.DeleteOptions) (*mongo.DeleteResult, error) - Find(ctx context.Context, filter interface{}, - opts ...*options.FindOptions) (mongo.Cursor, error) -} - -// MongoStore is an implementation of the db.Store interface -type MongoStore struct { - db *mongo.Database -} - -// This exists only for allowing us to mock the collection object -// for testing purposes -var getCollection = func(coll string, m *MongoStore) MongoCollection { - return m.db.Collection(coll) -} - -// This exists only for allowing us to mock the DecodeBytes function -// Mainly because we cannot construct a SingleResult struct from our -// tests. All fields in that struct are private. -var decodeBytes = func(sr *mongo.SingleResult) (bson.Raw, error) { - return sr.DecodeBytes() -} - -// NewMongoStore initializes a Mongo Database with the name provided -// If a database with that name exists, it will be returned -func NewMongoStore(name string, store *mongo.Database) (Store, error) { - if store == nil { - ip := "mongodb://" + os.Getenv("DATABASE_IP") + ":27017" - mongoClient, err := mongo.NewClient(ip) - if err != nil { - return nil, err - } - - err = mongoClient.Connect(context.Background()) - if err != nil { - return nil, err - } - store = mongoClient.Database(name) - } - - return &MongoStore{ - db: store, - }, nil -} - -// HealthCheck verifies if the database is up and running -func (m *MongoStore) HealthCheck() error { - - _, err := decodeBytes(m.db.RunCommand(context.Background(), bson.D{{"serverStatus", 1}})) - if err != nil { - return pkgerrors.Wrap(err, "Error getting server status") - } - - return nil -} - -// validateParams checks to see if any parameters are empty -func (m *MongoStore) validateParams(args ...string) bool { - for _, v := range args { - if v == "" { - return false - } - } - - return true -} - -// Create is used to create a DB entry -func (m *MongoStore) Create(coll, key, tag string, data interface{}) error { - if data == nil || !m.validateParams(coll, key, tag) { - return pkgerrors.New("No Data to store") - } - - c := getCollection(coll, m) - ctx := context.Background() - - //Insert the data and then add the objectID to the masterTable - res, err := c.InsertOne(ctx, bson.D{ - {tag, data}, - }) - if err != nil { - return pkgerrors.Errorf("Error inserting into database: %s", err.Error()) - } - - //Add objectID of created data to masterKey document - //Create masterkey document if it does not exist - filter := bson.D{{"key", key}} - - _, err = decodeBytes( - c.FindOneAndUpdate( - ctx, - filter, - bson.D{ - {"$set", bson.D{ - {tag, res.InsertedID}, - }}, - }, - options.FindOneAndUpdate().SetUpsert(true).SetReturnDocument(options.After))) - - if err != nil { - return pkgerrors.Errorf("Error updating master table: %s", err.Error()) - } - - return nil -} - -// Unmarshal implements an unmarshaler for bson data that -// is produced from the mongo database -func (m *MongoStore) Unmarshal(inp []byte, out interface{}) error { - err := bson.Unmarshal(inp, out) - if err != nil { - return pkgerrors.Wrap(err, "Unmarshaling bson") - } - return nil -} - -// Read method returns the data stored for this key and for this particular tag -func (m *MongoStore) Read(coll, key, tag string) ([]byte, error) { - if !m.validateParams(coll, key, tag) { - return nil, pkgerrors.New("Mandatory fields are missing") - } - - c := getCollection(coll, m) - ctx := context.Background() - - //Get the masterkey document based on given key - filter := bson.D{{"key", key}} - keydata, err := decodeBytes(c.FindOne(context.Background(), filter)) - if err != nil { - return nil, pkgerrors.Errorf("Error finding master table: %s", err.Error()) - } - - //Read the tag objectID from document - tagoid, ok := keydata.Lookup(tag).ObjectIDOK() - if !ok { - return nil, pkgerrors.Errorf("Error finding objectID for tag %s", tag) - } - - //Use tag objectID to read the data from store - filter = bson.D{{"_id", tagoid}} - tagdata, err := decodeBytes(c.FindOne(ctx, filter)) - if err != nil { - return nil, pkgerrors.Errorf("Error reading found object: %s", err.Error()) - } - - //Return the data as a byte array - //Convert string data to byte array using the built-in functions - switch tagdata.Lookup(tag).Type { - case bson.TypeString: - return []byte(tagdata.Lookup(tag).StringValue()), nil - default: - return tagdata.Lookup(tag).Value, nil - } -} - -// Helper function that deletes an object by its ID -func (m *MongoStore) deleteObjectByID(coll string, objID primitive.ObjectID) error { - - c := getCollection(coll, m) - ctx := context.Background() - - _, err := c.DeleteOne(ctx, bson.D{{"_id", objID}}) - if err != nil { - return pkgerrors.Errorf("Error Deleting from database: %s", err.Error()) - } - - log.Printf("Deleted Obj with ID %s", objID.String()) - return nil -} - -// Delete method removes a document from the Database that matches key -// TODO: delete all referenced docs if tag is empty string -func (m *MongoStore) Delete(coll, key, tag string) error { - if !m.validateParams(coll, key, tag) { - return pkgerrors.New("Mandatory fields are missing") - } - - c := getCollection(coll, m) - ctx := context.Background() - - //Get the masterkey document based on given key - filter := bson.D{{"key", key}} - //Remove the tag ID entry from masterkey table - update := bson.D{ - { - "$unset", bson.D{ - {tag, ""}, - }, - }, - } - keydata, err := decodeBytes(c.FindOneAndUpdate(ctx, filter, update, - options.FindOneAndUpdate().SetReturnDocument(options.Before))) - if err != nil { - //No document was found. Return nil. - if err == mongo.ErrNoDocuments { - return nil - } - //Return any other error that was found. - return pkgerrors.Errorf("Error decoding master table after update: %s", - err.Error()) - } - - //Read the tag objectID from document - elems, err := keydata.Elements() - if err != nil { - return pkgerrors.Errorf("Error reading elements from database: %s", err.Error()) - } - - tagoid, ok := keydata.Lookup(tag).ObjectIDOK() - if !ok { - return pkgerrors.Errorf("Error finding objectID for tag %s", tag) - } - - //Use tag objectID to read the data from store - err = m.deleteObjectByID(coll, tagoid) - if err != nil { - return pkgerrors.Errorf("Error deleting from database: %s", err.Error()) - } - - //Delete master table if no more tags left - //_id, key and tag should be elements in before doc - //if master table needs to be removed too - if len(elems) == 3 { - keyid, ok := keydata.Lookup("_id").ObjectIDOK() - if !ok { - return pkgerrors.Errorf("Error finding objectID for key %s", key) - } - err = m.deleteObjectByID(coll, keyid) - if err != nil { - return pkgerrors.Errorf("Error deleting master table from database: %s", err.Error()) - } - } - - return nil -} - -// ReadAll is used to get all documents in db of a particular tag -func (m *MongoStore) ReadAll(coll, tag string) (map[string][]byte, error) { - if !m.validateParams(coll, tag) { - return nil, pkgerrors.New("Missing collection or tag name") - } - - c := getCollection(coll, m) - ctx := context.Background() - - //Get all master tables in this collection - filter := bson.D{ - {"key", bson.D{ - {"$exists", true}, - }}, - } - cursor, err := c.Find(ctx, filter) - if err != nil { - return nil, pkgerrors.Errorf("Error reading from database: %s", err.Error()) - } - defer cursor.Close(ctx) - - //Iterate over all the master tables - result := make(map[string][]byte) - for cursor.Next(ctx) { - d, err := cursor.DecodeBytes() - if err != nil { - log.Printf("Unable to decode data in Readall: %s", err.Error()) - continue - } - - //Read key of each master table - key, ok := d.Lookup("key").StringValueOK() - if !ok { - log.Printf("Unable to read key string from mastertable %s", err.Error()) - continue - } - - //Get objectID of tag document - tid, ok := d.Lookup(tag).ObjectIDOK() - if !ok { - log.Printf("Did not find tag: %s", tag) - continue - } - - //Find tag document and unmarshal it into []byte - tagData, err := decodeBytes(c.FindOne(ctx, bson.D{{"_id", tid}})) - if err != nil { - log.Printf("Unable to decode tag data %s", err.Error()) - continue - } - result[key] = tagData.Lookup(tag).Value - } - - if len(result) == 0 { - return result, pkgerrors.Errorf("Did not find any objects with tag: %s", tag) - } - - return result, nil -} diff --git a/src/k8splugin/db/mongo_test.go b/src/k8splugin/db/mongo_test.go deleted file mode 100644 index 1663e774..00000000 --- a/src/k8splugin/db/mongo_test.go +++ /dev/null @@ -1,530 +0,0 @@ -// +build unit - -/* - * Copyright 2018 Intel Corporation, Inc - * - * 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 ( - "bytes" - "context" - "github.com/mongodb/mongo-go-driver/bson" - "github.com/mongodb/mongo-go-driver/mongo" - "github.com/mongodb/mongo-go-driver/mongo/options" - pkgerrors "github.com/pkg/errors" - "reflect" - "strings" - "testing" -) - -// Implements the mongo.Cursor interface -type mockCursor struct { - mongo.Cursor - err error - bson bson.Raw - count int -} - -func (mc *mockCursor) Next(ctx context.Context) bool { - if mc.count > 0 { - mc.count = mc.count - 1 - return true - } - return false -} - -func (mc *mockCursor) DecodeBytes() (bson.Raw, error) { - return mc.bson, mc.err -} - -func (mc *mockCursor) Close(ctx context.Context) error { - return nil -} - -//Implements the functions used currently in mongo.go -type mockCollection struct { - Err error - mCursor mongo.Cursor -} - -func (c *mockCollection) InsertOne(ctx context.Context, document interface{}, - opts ...*options.InsertOneOptions) (*mongo.InsertOneResult, error) { - - if c.Err != nil { - return nil, c.Err - } - - return &mongo.InsertOneResult{InsertedID: "_id1234"}, nil -} - -func (c *mockCollection) FindOne(ctx context.Context, filter interface{}, - opts ...*options.FindOneOptions) *mongo.SingleResult { - - return &mongo.SingleResult{} -} - -func (c *mockCollection) FindOneAndUpdate(ctx context.Context, filter interface{}, - update interface{}, opts ...*options.FindOneAndUpdateOptions) *mongo.SingleResult { - - return &mongo.SingleResult{} -} - -func (c *mockCollection) DeleteOne(ctx context.Context, filter interface{}, - opts ...*options.DeleteOptions) (*mongo.DeleteResult, error) { - - return nil, c.Err -} - -func (c *mockCollection) Find(ctx context.Context, filter interface{}, - opts ...*options.FindOptions) (mongo.Cursor, error) { - - return c.mCursor, c.Err -} - -func TestCreate(t *testing.T) { - testCases := []struct { - label string - input map[string]interface{} - mockColl *mockCollection - bson bson.Raw - expectedError string - }{ - { - label: "Successfull creation of entry", - input: map[string]interface{}{ - "coll": "collname", - "key": "keyvalue", - "tag": "tagName", - "data": "Data In String Format", - }, - bson: bson.Raw{'\x08', '\x00', '\x00', '\x00', '\x0A', 'x', '\x00', '\x00'}, - mockColl: &mockCollection{}, - }, - { - label: "UnSuccessfull creation of entry", - input: map[string]interface{}{ - "coll": "collname", - "key": "keyvalue", - "tag": "tagName", - "data": "Data In String Format", - }, - mockColl: &mockCollection{ - Err: pkgerrors.New("DB Error"), - }, - expectedError: "DB Error", - }, - { - label: "Missing input fields", - input: map[string]interface{}{ - "coll": "", - "key": "", - "tag": "", - "data": "", - }, - expectedError: "No Data to store", - mockColl: &mockCollection{}, - }, - } - - for _, testCase := range testCases { - t.Run(testCase.label, func(t *testing.T) { - m, _ := NewMongoStore("name", &mongo.Database{}) - // Override the getCollection function with our mocked version - getCollection = func(coll string, m *MongoStore) MongoCollection { - return testCase.mockColl - } - - decodeBytes = func(sr *mongo.SingleResult) (bson.Raw, error) { - return testCase.bson, testCase.mockColl.Err - } - - err := m.Create(testCase.input["coll"].(string), testCase.input["key"].(string), - testCase.input["tag"].(string), testCase.input["data"]) - if err != nil { - if testCase.expectedError == "" { - t.Fatalf("Create method returned an un-expected (%s)", err) - } - if !strings.Contains(string(err.Error()), testCase.expectedError) { - t.Fatalf("Create method returned an error (%s)", err) - } - } - }) - } -} - -func TestRead(t *testing.T) { - testCases := []struct { - label string - input map[string]interface{} - mockColl *mockCollection - bson bson.Raw - expectedError string - expected []byte - }{ - { - label: "Successfull Read of entry", - input: map[string]interface{}{ - "coll": "collname", - "key": "keyvalue", - "tag": "metadata", - }, - // Binary form of - // { - // "_id" : ObjectId("5c115156777ff85654248ae1"), - // "key" : "b82c4bb1-09ff-6093-4d58-8327b94e1e20", - // "metadata" : ObjectId("5c115156c9755047e318bbfd") - // } - bson: bson.Raw{ - '\x5a', '\x00', '\x00', '\x00', '\x07', '\x5f', '\x69', '\x64', - '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77', '\x7f', '\xf8', - '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x02', '\x6b', '\x65', - '\x79', '\x00', '\x25', '\x00', '\x00', '\x00', '\x62', '\x38', - '\x32', '\x63', '\x34', '\x62', '\x62', '\x31', '\x2d', '\x30', - '\x39', '\x66', '\x66', '\x2d', '\x36', '\x30', '\x39', '\x33', - '\x2d', '\x34', '\x64', '\x35', '\x38', '\x2d', '\x38', '\x33', - '\x32', '\x37', '\x62', '\x39', '\x34', '\x65', '\x31', '\x65', - '\x32', '\x30', '\x00', '\x07', '\x6d', '\x65', '\x74', '\x61', - '\x64', '\x61', '\x74', '\x61', '\x00', '\x5c', '\x11', '\x51', - '\x56', '\xc9', '\x75', '\x50', '\x47', '\xe3', '\x18', '\xbb', - '\xfd', '\x00', - }, - mockColl: &mockCollection{}, - // This is not the document because we are mocking decodeBytes - expected: []byte{92, 17, 81, 86, 201, 117, 80, 71, 227, 24, 187, 253}, - }, - { - label: "UnSuccessfull Read of entry: object not found", - input: map[string]interface{}{ - "coll": "collname", - "key": "keyvalue", - "tag": "badtag", - }, - // Binary form of - // { - // "_id" : ObjectId("5c115156777ff85654248ae1"), - // "key" : "b82c4bb1-09ff-6093-4d58-8327b94e1e20", - // "metadata" : ObjectId("5c115156c9755047e318bbfd") - // } - bson: bson.Raw{ - '\x5a', '\x00', '\x00', '\x00', '\x07', '\x5f', '\x69', '\x64', - '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77', '\x7f', '\xf8', - '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x02', '\x6b', '\x65', - '\x79', '\x00', '\x25', '\x00', '\x00', '\x00', '\x62', '\x38', - '\x32', '\x63', '\x34', '\x62', '\x62', '\x31', '\x2d', '\x30', - '\x39', '\x66', '\x66', '\x2d', '\x36', '\x30', '\x39', '\x33', - '\x2d', '\x34', '\x64', '\x35', '\x38', '\x2d', '\x38', '\x33', - '\x32', '\x37', '\x62', '\x39', '\x34', '\x65', '\x31', '\x65', - '\x32', '\x30', '\x00', '\x07', '\x6d', '\x65', '\x74', '\x61', - '\x64', '\x61', '\x74', '\x61', '\x00', '\x5c', '\x11', '\x51', - '\x56', '\xc9', '\x75', '\x50', '\x47', '\xe3', '\x18', '\xbb', - '\xfd', '\x00', - }, - mockColl: &mockCollection{}, - expectedError: "Error finding objectID", - }, - { - label: "UnSuccessfull Read of entry", - input: map[string]interface{}{ - "coll": "collname", - "key": "keyvalue", - "tag": "tagName", - }, - mockColl: &mockCollection{ - Err: pkgerrors.New("DB Error"), - }, - expectedError: "DB Error", - }, - { - label: "Missing input fields", - input: map[string]interface{}{ - "coll": "", - "key": "", - "tag": "", - }, - expectedError: "Mandatory fields are missing", - mockColl: &mockCollection{}, - }, - } - - for _, testCase := range testCases { - t.Run(testCase.label, func(t *testing.T) { - m, _ := NewMongoStore("name", &mongo.Database{}) - // Override the getCollection function with our mocked version - getCollection = func(coll string, m *MongoStore) MongoCollection { - return testCase.mockColl - } - - decodeBytes = func(sr *mongo.SingleResult) (bson.Raw, error) { - return testCase.bson, testCase.mockColl.Err - } - got, err := m.Read(testCase.input["coll"].(string), testCase.input["key"].(string), - testCase.input["tag"].(string)) - if err != nil { - if testCase.expectedError == "" { - t.Fatalf("Read method returned an un-expected (%s)", err) - } - if !strings.Contains(string(err.Error()), testCase.expectedError) { - t.Fatalf("Read method returned an error (%s)", err) - } - } else { - if bytes.Compare(got, testCase.expected) != 0 { - t.Fatalf("Read returned unexpected data: %s, expected: %s", - string(got), testCase.expected) - } - } - }) - } -} - -func TestDelete(t *testing.T) { - testCases := []struct { - label string - input map[string]interface{} - mockColl *mockCollection - bson bson.Raw - expectedError string - }{ - { - label: "Successfull Delete of entry", - input: map[string]interface{}{ - "coll": "collname", - "key": "keyvalue", - "tag": "metadata", - }, - // Binary form of - // { - // "_id" : ObjectId("5c115156777ff85654248ae1"), - // "key" : "b82c4bb1-09ff-6093-4d58-8327b94e1e20", - // "metadata" : ObjectId("5c115156c9755047e318bbfd") - // } - bson: bson.Raw{ - '\x5a', '\x00', '\x00', '\x00', '\x07', '\x5f', '\x69', '\x64', - '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77', '\x7f', '\xf8', - '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x02', '\x6b', '\x65', - '\x79', '\x00', '\x25', '\x00', '\x00', '\x00', '\x62', '\x38', - '\x32', '\x63', '\x34', '\x62', '\x62', '\x31', '\x2d', '\x30', - '\x39', '\x66', '\x66', '\x2d', '\x36', '\x30', '\x39', '\x33', - '\x2d', '\x34', '\x64', '\x35', '\x38', '\x2d', '\x38', '\x33', - '\x32', '\x37', '\x62', '\x39', '\x34', '\x65', '\x31', '\x65', - '\x32', '\x30', '\x00', '\x07', '\x6d', '\x65', '\x74', '\x61', - '\x64', '\x61', '\x74', '\x61', '\x00', '\x5c', '\x11', '\x51', - '\x56', '\xc9', '\x75', '\x50', '\x47', '\xe3', '\x18', '\xbb', - '\xfd', '\x00', - }, - mockColl: &mockCollection{}, - }, - { - label: "UnSuccessfull Delete of entry", - input: map[string]interface{}{ - "coll": "collname", - "key": "keyvalue", - "tag": "tagName", - }, - mockColl: &mockCollection{ - Err: pkgerrors.New("DB Error"), - }, - expectedError: "DB Error", - }, - { - label: "UnSuccessfull Delete, key not found", - input: map[string]interface{}{ - "coll": "collname", - "key": "keyvalue", - "tag": "tagName", - }, - bson: bson.Raw{ - '\x5a', '\x00', '\x00', '\x00', '\x07', '\x5f', '\x69', '\x64', - '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77', '\x7f', '\xf8', - '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x02', '\x6b', '\x65', - '\x79', '\x00', '\x25', '\x00', '\x00', '\x00', '\x62', '\x38', - '\x32', '\x63', '\x34', '\x62', '\x62', '\x31', '\x2d', '\x30', - '\x39', '\x66', '\x66', '\x2d', '\x36', '\x30', '\x39', '\x33', - '\x2d', '\x34', '\x64', '\x35', '\x38', '\x2d', '\x38', '\x33', - '\x32', '\x37', '\x62', '\x39', '\x34', '\x65', '\x31', '\x65', - '\x32', '\x30', '\x00', '\x07', '\x6d', '\x65', '\x74', '\x61', - '\x64', '\x61', '\x74', '\x61', '\x00', '\x5c', '\x11', '\x51', - '\x56', '\xc9', '\x75', '\x50', '\x47', '\xe3', '\x18', '\xbb', - '\xfd', '\x00', - }, - mockColl: &mockCollection{}, - expectedError: "Error finding objectID", - }, - { - label: "Missing input fields", - input: map[string]interface{}{ - "coll": "", - "key": "", - "tag": "", - }, - expectedError: "Mandatory fields are missing", - mockColl: &mockCollection{}, - }, - } - - for _, testCase := range testCases { - t.Run(testCase.label, func(t *testing.T) { - m, _ := NewMongoStore("name", &mongo.Database{}) - // Override the getCollection function with our mocked version - getCollection = func(coll string, m *MongoStore) MongoCollection { - return testCase.mockColl - } - - decodeBytes = func(sr *mongo.SingleResult) (bson.Raw, error) { - return testCase.bson, testCase.mockColl.Err - } - err := m.Delete(testCase.input["coll"].(string), testCase.input["key"].(string), - testCase.input["tag"].(string)) - if err != nil { - if testCase.expectedError == "" { - t.Fatalf("Delete method returned an un-expected (%s)", err) - } - if !strings.Contains(string(err.Error()), testCase.expectedError) { - t.Fatalf("Delete method returned an error (%s)", err) - } - } - }) - } -} - -func TestReadAll(t *testing.T) { - testCases := []struct { - label string - input map[string]interface{} - mockColl *mockCollection - bson bson.Raw - expectedError string - expected map[string][]byte - }{ - { - label: "Successfully Read all entries", - input: map[string]interface{}{ - "coll": "collname", - "tag": "metadata", - }, - mockColl: &mockCollection{ - mCursor: &mockCursor{ - // Binary form of - // { - // "_id" : ObjectId("5c115156777ff85654248ae1"), - // "key" : "b82c4bb1-09ff-6093-4d58-8327b94e1e20", - // "metadata" : ObjectId("5c115156c9755047e318bbfd") - // } - bson: bson.Raw{ - '\x5a', '\x00', '\x00', '\x00', '\x07', '\x5f', '\x69', '\x64', - '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77', '\x7f', '\xf8', - '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x02', '\x6b', '\x65', - '\x79', '\x00', '\x25', '\x00', '\x00', '\x00', '\x62', '\x38', - '\x32', '\x63', '\x34', '\x62', '\x62', '\x31', '\x2d', '\x30', - '\x39', '\x66', '\x66', '\x2d', '\x36', '\x30', '\x39', '\x33', - '\x2d', '\x34', '\x64', '\x35', '\x38', '\x2d', '\x38', '\x33', - '\x32', '\x37', '\x62', '\x39', '\x34', '\x65', '\x31', '\x65', - '\x32', '\x30', '\x00', '\x07', '\x6d', '\x65', '\x74', '\x61', - '\x64', '\x61', '\x74', '\x61', '\x00', '\x5c', '\x11', '\x51', - '\x56', '\xc9', '\x75', '\x50', '\x47', '\xe3', '\x18', '\xbb', - '\xfd', '\x00', - }, - count: 1, - }, - }, - expected: map[string][]byte{ - "b82c4bb1-09ff-6093-4d58-8327b94e1e20": []byte{ - 92, 17, 81, 86, 201, 117, 80, 71, 227, 24, 187, 253}, - }, - }, - { - label: "UnSuccessfully Read of all entries", - input: map[string]interface{}{ - "coll": "collname", - "tag": "tagName", - }, - mockColl: &mockCollection{ - Err: pkgerrors.New("DB Error"), - }, - expectedError: "DB Error", - }, - { - label: "UnSuccessfull Readall, tag not found", - input: map[string]interface{}{ - "coll": "collname", - "tag": "tagName", - }, - mockColl: &mockCollection{ - mCursor: &mockCursor{ - // Binary form of - // { - // "_id" : ObjectId("5c115156777ff85654248ae1"), - // "key" : "b82c4bb1-09ff-6093-4d58-8327b94e1e20", - // "metadata" : ObjectId("5c115156c9755047e318bbfd") - // } - bson: bson.Raw{ - '\x5a', '\x00', '\x00', '\x00', '\x07', '\x5f', '\x69', '\x64', - '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77', '\x7f', '\xf8', - '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x02', '\x6b', '\x65', - '\x79', '\x00', '\x25', '\x00', '\x00', '\x00', '\x62', '\x38', - '\x32', '\x63', '\x34', '\x62', '\x62', '\x31', '\x2d', '\x30', - '\x39', '\x66', '\x66', '\x2d', '\x36', '\x30', '\x39', '\x33', - '\x2d', '\x34', '\x64', '\x35', '\x38', '\x2d', '\x38', '\x33', - '\x32', '\x37', '\x62', '\x39', '\x34', '\x65', '\x31', '\x65', - '\x32', '\x30', '\x00', '\x07', '\x6d', '\x65', '\x74', '\x61', - '\x64', '\x61', '\x74', '\x61', '\x00', '\x5c', '\x11', '\x51', - '\x56', '\xc9', '\x75', '\x50', '\x47', '\xe3', '\x18', '\xbb', - '\xfd', '\x00', - }, - count: 1, - }, - }, - expectedError: "Did not find any objects with tag", - }, - { - label: "Missing input fields", - input: map[string]interface{}{ - "coll": "", - "tag": "", - }, - expectedError: "Missing collection or tag name", - mockColl: &mockCollection{}, - }, - } - - for _, testCase := range testCases { - t.Run(testCase.label, func(t *testing.T) { - m, _ := NewMongoStore("name", &mongo.Database{}) - // Override the getCollection function with our mocked version - getCollection = func(coll string, m *MongoStore) MongoCollection { - return testCase.mockColl - } - - decodeBytes = func(sr *mongo.SingleResult) (bson.Raw, error) { - return testCase.mockColl.mCursor.DecodeBytes() - } - - got, err := m.ReadAll(testCase.input["coll"].(string), testCase.input["tag"].(string)) - if err != nil { - if testCase.expectedError == "" { - t.Fatalf("Readall method returned an un-expected (%s)", err) - } - if !strings.Contains(string(err.Error()), testCase.expectedError) { - t.Fatalf("Readall method returned an error (%s)", err) - } - } else { - if reflect.DeepEqual(got, testCase.expected) == false { - t.Fatalf("Readall returned unexpected data: %v, expected: %v", - got, testCase.expected) - } - } - }) - } -} diff --git a/src/k8splugin/db/store.go b/src/k8splugin/db/store.go deleted file mode 100644 index a235597a..00000000 --- a/src/k8splugin/db/store.go +++ /dev/null @@ -1,83 +0,0 @@ -/* -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 ( - "encoding/json" - "reflect" - - pkgerrors "github.com/pkg/errors" -) - -// DBconn interface used to talk a concrete Database connection -var DBconn Store - -// Store is an interface for accessing a database -type Store interface { - // Returns nil if db health is good - HealthCheck() error - - // Unmarshal implements any unmarshaling needed for the database - Unmarshal(inp []byte, out interface{}) error - - // Creates a new master table with key and links data with tag and - // creates a pointer to the newly added data in the master table - Create(table, key, tag string, data interface{}) error - - // Reads data for a particular key with specific tag. - Read(table, key, tag string) ([]byte, error) - - //TODO: Update(context.Context, string, interface{}) error - - // Deletes a specific tag data for key. - // TODO: If tag is empty, it will delete all tags under key. - Delete(table, key, tag string) error - - // Reads all master tables and data from the specified tag in table - ReadAll(table, tag string) (map[string][]byte, error) -} - -// CreateDBClient creates the DB client -func CreateDBClient(dbType string) error { - var err error - switch dbType { - case "mongo": - // create a mongodb database with k8splugin as the name - DBconn, err = NewMongoStore("k8splugin", nil) - case "consul": - // create a consul kv store - DBconn, err = NewConsulStore(nil) - default: - return pkgerrors.New(dbType + "DB not supported") - } - return err -} - -// Serialize converts given data into a JSON string -func Serialize(v interface{}) (string, error) { - out, err := json.Marshal(v) - if err != nil { - return "", pkgerrors.Wrap(err, "Error serializing "+reflect.TypeOf(v).String()) - } - return string(out), nil -} - -// DeSerialize converts string to a json object specified by type -func DeSerialize(str string, v interface{}) error { - err := json.Unmarshal([]byte(str), &v) - if err != nil { - return pkgerrors.Wrap(err, "Error deSerializing "+str) - } - return nil -} diff --git a/src/k8splugin/db/store_test.go b/src/k8splugin/db/store_test.go deleted file mode 100644 index eed7065f..00000000 --- a/src/k8splugin/db/store_test.go +++ /dev/null @@ -1,123 +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" - "strings" - "testing" -) - -func TestCreateDBClient(t *testing.T) { - t.Run("Successfully create DB client", func(t *testing.T) { - expected := &MongoStore{} - - err := CreateDBClient("mongo") - 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 deleted file mode 100644 index 003399af..00000000 --- a/src/k8splugin/db/testing.go +++ /dev/null @@ -1,79 +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 ( - "encoding/json" - pkgerrors "github.com/pkg/errors" -) - -//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 map[string]map[string][]byte - Err error -} - -func (m *MockDB) Create(table, key, tag string, data interface{}) error { - return m.Err -} - -// MockDB uses simple JSON and not BSON -func (m *MockDB) Unmarshal(inp []byte, out interface{}) error { - err := json.Unmarshal(inp, out) - if err != nil { - return pkgerrors.Wrap(err, "Unmarshaling json") - } - return nil -} - -func (m *MockDB) Read(table, key, tag string) ([]byte, error) { - if m.Err != nil { - return nil, m.Err - } - - for k, v := range m.Items { - if k == key { - return v[tag], nil - } - } - - return nil, m.Err -} - -func (m *MockDB) Delete(table, key, tag string) error { - return m.Err -} - -func (m *MockDB) ReadAll(table, tag string) (map[string][]byte, error) { - if m.Err != nil { - return nil, m.Err - } - - ret := make(map[string][]byte) - - for k, v := range m.Items { - for k1, v1 := range v { - if k1 == tag { - ret[k] = v1 - } - } - } - - return ret, nil -} |