summaryrefslogtreecommitdiffstats
path: root/src/orchestrator/internal
diff options
context:
space:
mode:
authorRitu Sood <ritu.sood@intel.com>2020-01-31 23:29:51 -0800
committerSrivahni Chivukula <srivahni.chivukula@intel.com>2020-02-14 03:54:11 -0800
commita75d489bbf87712371d67dce0753577bdacce0c3 (patch)
treedee646769aa432c814abd86645af612e714640be /src/orchestrator/internal
parentc06be6458e9985bd7ac0b25fab03d9c8605f6c4a (diff)
Restructure code and create module library
Restructures and moves code to make it aligned with the current design. https://wiki.onap.org/display/DW/Multi+Cluster+Application+Scheduler examples/example_module.go shows how to import and use modules from this package. Patch#2 Updated example Issue-ID: MULTICLOUD-871 Signed-off-by: Ritu Sood <ritu.sood@intel.com> Change-Id: Ia1e9802a946a07dcca8f79f0e2250933ab3efa66
Diffstat (limited to 'src/orchestrator/internal')
-rw-r--r--src/orchestrator/internal/auth/auth.go107
-rw-r--r--src/orchestrator/internal/auth/auth_test.go47
-rw-r--r--src/orchestrator/internal/config/config.go130
-rw-r--r--src/orchestrator/internal/config/config_test.go40
-rw-r--r--src/orchestrator/internal/db/README.md123
-rw-r--r--src/orchestrator/internal/db/mock.go94
-rw-r--r--src/orchestrator/internal/db/mongo.go396
-rw-r--r--src/orchestrator/internal/db/mongo_test.go597
-rw-r--r--src/orchestrator/internal/db/store.go106
-rw-r--r--src/orchestrator/internal/db/store_test.go121
-rw-r--r--src/orchestrator/internal/logutils/logger.go28
-rw-r--r--src/orchestrator/internal/project/project.go133
-rw-r--r--src/orchestrator/internal/project/project_test.go177
13 files changed, 0 insertions, 2099 deletions
diff --git a/src/orchestrator/internal/auth/auth.go b/src/orchestrator/internal/auth/auth.go
deleted file mode 100644
index 3da8f2af..00000000
--- a/src/orchestrator/internal/auth/auth.go
+++ /dev/null
@@ -1,107 +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 auth
-
-import (
- "crypto/tls"
- "crypto/x509"
- "encoding/base64"
- "encoding/pem"
- "io/ioutil"
- "log"
-
- pkgerrors "github.com/pkg/errors"
-)
-
-// GetTLSConfig initializes a tlsConfig using the CA's certificate
-// This config is then used to enable the server for mutual TLS
-func GetTLSConfig(caCertFile string, certFile string, keyFile string) (*tls.Config, error) {
-
- // Initialize tlsConfig once
- caCert, err := ioutil.ReadFile(caCertFile)
-
- if err != nil {
- return nil, pkgerrors.Wrap(err, "Read CA Cert file")
- }
-
- caCertPool := x509.NewCertPool()
- caCertPool.AppendCertsFromPEM(caCert)
-
- tlsConfig := &tls.Config{
- // Change to RequireAndVerify once we have mandatory certs
- ClientAuth: tls.VerifyClientCertIfGiven,
- ClientCAs: caCertPool,
- MinVersion: tls.VersionTLS12,
- }
-
- certPEMBlk, err := readPEMBlock(certFile)
- if err != nil {
- return nil, pkgerrors.Wrap(err, "Read Cert File")
- }
-
- keyPEMBlk, err := readPEMBlock(keyFile)
- if err != nil {
- return nil, pkgerrors.Wrap(err, "Read Key File")
- }
-
- tlsConfig.Certificates = make([]tls.Certificate, 1)
- tlsConfig.Certificates[0], err = tls.X509KeyPair(certPEMBlk, keyPEMBlk)
- if err != nil {
- return nil, pkgerrors.Wrap(err, "Load x509 cert and key")
- }
-
- tlsConfig.BuildNameToCertificate()
- return tlsConfig, nil
-}
-
-func readPEMBlock(filename string) ([]byte, error) {
-
- pemData, err := ioutil.ReadFile(filename)
- if err != nil {
- return nil, pkgerrors.Wrap(err, "Read PEM File")
- }
-
- pemBlock, rest := pem.Decode(pemData)
- if len(rest) > 0 {
- log.Println("Pemfile has extra data")
- }
-
- if x509.IsEncryptedPEMBlock(pemBlock) {
- password, err := ioutil.ReadFile(filename + ".pass")
- if err != nil {
- return nil, pkgerrors.Wrap(err, "Read Password File")
- }
-
- pByte, err := base64.StdEncoding.DecodeString(string(password))
- if err != nil {
- return nil, pkgerrors.Wrap(err, "Decode PEM Password")
- }
-
- pemData, err = x509.DecryptPEMBlock(pemBlock, pByte)
- if err != nil {
- return nil, pkgerrors.Wrap(err, "Decrypt PEM Data")
- }
- var newPEMBlock pem.Block
- newPEMBlock.Type = pemBlock.Type
- newPEMBlock.Bytes = pemData
- // Converting back to PEM from DER data you get from
- // DecryptPEMBlock
- pemData = pem.EncodeToMemory(&newPEMBlock)
- }
-
- return pemData, nil
-}
diff --git a/src/orchestrator/internal/auth/auth_test.go b/src/orchestrator/internal/auth/auth_test.go
deleted file mode 100644
index e41cb1ac..00000000
--- a/src/orchestrator/internal/auth/auth_test.go
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-* Copyright 2018 TechMahindra
-*
-* 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 auth
-
-import (
- "crypto/tls"
- "testing"
-)
-
-//Unit test to varify GetTLSconfig func and varify the tls config min version to be 771
-//Assuming cert file name as auth_test.cert
-func TestGetTLSConfig(t *testing.T) {
- _, err := GetTLSConfig("filedoesnotexist.cert", "filedoesnotexist.cert", "filedoesnotexist.cert")
- if err == nil {
- t.Errorf("Test failed, expected error but got none")
- }
- tlsConfig, err := GetTLSConfig("../../tests/certs/auth_test_certificate.pem",
- "../../tests/certs/auth_test_certificate.pem",
- "../../tests/certs/auth_test_key.pem")
- if err != nil {
- t.Fatal("Test Failed as GetTLSConfig returned error: " + err.Error())
- }
- expected := tls.VersionTLS12
- actual := tlsConfig.MinVersion
- if tlsConfig != nil {
- if int(actual) != expected {
- t.Errorf("Test Failed due to version mismatch")
- }
- if tlsConfig == nil {
- t.Errorf("Test Failed due to GetTLSConfig returned nil")
- }
- }
-}
diff --git a/src/orchestrator/internal/config/config.go b/src/orchestrator/internal/config/config.go
deleted file mode 100644
index cb4656f0..00000000
--- a/src/orchestrator/internal/config/config.go
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright 2019 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 config
-
-import (
- "encoding/json"
- "log"
- "os"
- "reflect"
-)
-
-// Configuration loads up all the values that are used to configure
-// backend implementations
-type Configuration struct {
- CAFile string `json:"ca-file"`
- ServerCert string `json:"server-cert"`
- ServerKey string `json:"server-key"`
- Password string `json:"password"`
- DatabaseIP string `json:"database-ip"`
- DatabaseType string `json:"database-type"`
- PluginDir string `json:"plugin-dir"`
- EtcdIP string `json:"etcd-ip"`
- EtcdCert string `json:"etcd-cert"`
- EtcdKey string `json:"etcd-key"`
- EtcdCAFile string `json:"etcd-ca-file"`
- ServicePort string `json:"service-port"`
- KubernetesLabelName string `json:"kubernetes-label-name"`
-}
-
-// Config is the structure that stores the configuration
-var gConfig *Configuration
-
-// readConfigFile reads the specified smsConfig file to setup some env variables
-func readConfigFile(file string) (*Configuration, error) {
- f, err := os.Open(file)
- if err != nil {
- return defaultConfiguration(), err
- }
- defer f.Close()
-
- // Setup some defaults here
- // If the json file has values in it, the defaults will be overwritten
- conf := defaultConfiguration()
-
- // Read the configuration from json file
- decoder := json.NewDecoder(f)
- decoder.DisallowUnknownFields()
- err = decoder.Decode(conf)
- if err != nil {
- return conf, err
- }
-
- return conf, nil
-}
-
-func defaultConfiguration() *Configuration {
- cwd, err := os.Getwd()
- if err != nil {
- log.Println("Error getting cwd. Using .")
- cwd = "."
- }
-
- return &Configuration{
- CAFile: "ca.cert",
- ServerCert: "server.cert",
- ServerKey: "server.key",
- Password: "",
- DatabaseIP: "127.0.0.1",
- DatabaseType: "mongo",
- PluginDir: cwd,
- EtcdIP: "127.0.0.1",
- EtcdCert: "etcd.cert",
- EtcdKey: "etcd.key",
- EtcdCAFile: "etcd-ca.cert",
- ServicePort: "9015",
- KubernetesLabelName: "orchestrator.io/rb-instance-id",
- }
-}
-
-// GetConfiguration returns the configuration for the app.
-// It will try to load it if it is not already loaded.
-func GetConfiguration() *Configuration {
- if gConfig == nil {
- conf, err := readConfigFile("config.json")
- if err != nil {
- log.Println("Error loading config file: ", err)
- log.Println("Using defaults...")
- }
- gConfig = conf
- }
-
- return gConfig
-}
-
-// SetConfigValue sets a value in the configuration
-// This is mostly used to customize the application and
-// should be used carefully.
-func SetConfigValue(key string, value string) *Configuration {
- c := GetConfiguration()
- if value == "" || key == "" {
- return c
- }
-
- v := reflect.ValueOf(c).Elem()
- if v.Kind() == reflect.Struct {
- f := v.FieldByName(key)
- if f.IsValid() {
- if f.CanSet() {
- if f.Kind() == reflect.String {
- f.SetString(value)
- }
- }
- }
- }
- return c
-}
diff --git a/src/orchestrator/internal/config/config_test.go b/src/orchestrator/internal/config/config_test.go
deleted file mode 100644
index ce7641ae..00000000
--- a/src/orchestrator/internal/config/config_test.go
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2019 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 config
-
-import (
- "testing"
-)
-
-func TestReadConfigurationFile(t *testing.T) {
- t.Run("Non Existent Configuration File", func(t *testing.T) {
- _, err := readConfigFile("filedoesnotexist.json")
- if err == nil {
- t.Fatal("ReadConfiguationFile: Expected Error, got nil")
- }
- })
-
- t.Run("Read Configuration File", func(t *testing.T) {
- conf, err := readConfigFile("../../tests/configs/mock_config.json")
- if err != nil {
- t.Fatal("ReadConfigurationFile: Error reading file: ", err)
- }
- if conf.DatabaseType != "mock_db_test" {
- t.Fatal("ReadConfigurationFile: Incorrect entry read from file")
- }
- })
-}
diff --git a/src/orchestrator/internal/db/README.md b/src/orchestrator/internal/db/README.md
deleted file mode 100644
index cba1b7ea..00000000
--- a/src/orchestrator/internal/db/README.md
+++ /dev/null
@@ -1,123 +0,0 @@
-# Database Abstraction Layer
-
-This package contains implementations of the Database interface defined in `store.go`
-Any database can be used as the backend as long as the following interface is implemented;
-
-```go
-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 string, key Key, tag string, data interface{}) error
-
- // Reads data for a particular key with specific tag.
- Read(table string, key Key, tag string) ([]byte, error)
-
- // Update data for particular key with specific tag
- Update(table string, key Key, tag string, data interface{}) error
-
- // Deletes a specific tag data for key.
- // TODO: If tag is empty, it will delete all tags under key.
- Delete(table string, key Key, tag string) error
-
- // Reads all master tables and data from the specified tag in table
- ReadAll(table string, tag string) (map[string][]byte, error)
-}
-```
-
-Therefore, `mongo.go`, `consul.go` implement the above interface and can be used as the backend as needed based on initial configuration.
-
-## Details on Mongo Implementation
-
-`mongo.go` implements the above interface using the `go.mongodb.org/mongo-driver` package.
-The code converts incoming binary data and creates a new document in the database.
-
-### Create
-
-Arguments:
-```go
-collection string
-key interface
-tag string
-data []byte
-```
-
-Create inserts the provided `data` into the `collection` which returns an auto-generated (by `mongodb`) ID which we then associate with the `key` that is provided as one of the arguments.
-
-We use the `FindOneAndUpdate` mongo API to achieve this with the `upsert` option set to `true`.
-We create the following documents in mongodb for each new definition added to the database:
-
-There is a Master Key document that contains references to other documents which are related to this `key`.
-
-#### Master Key Entry
-```json
-{
- "_id" : ObjectId("5e0a8554b78a15f71d2dce7e"),
- "key" : { "rbname" : "edgex", "rbversion" : "v1"},
- "defmetadata" : ObjectId("5e0a8554be261ecb57f067eb"),
- "defcontent" : ObjectId("5e0a8377bcfcdd0f01dc7b0d")
-}
-```
-#### Metadata Key Entry
-```json
-{
- "_id" : ObjectId("5e0a8554be261ecb57f067eb"),
- "defmetadata" : { "rbname" : "edgex", "rbversion" : "v1", "chartname" : "", "description" : "", "labels" : null }
-}
-```
-#### Definition Content
-```json
-{
- "_id" : ObjectId("5e0a8377bcfcdd0f01dc7b0d"),
- "defcontent" : "H4sICCVd3FwAA3Byb2ZpbGUxLnRhcgDt1NEKgjAUxvFd7ylG98aWOsGXiYELxLRwJvj2rbyoIPDGiuD/uzmwM9iB7Vvruvrgw7CdXHsUn6Ejm2W3aopcP9eZLYRJM1voPN+ZndAm16kVSn9onheXMLheKeGqfdM0rq07/3bfUv9PJUkiR9+H+tSVajRymM6+lEqN7njxoVSbU+z2deX388r9nWzkr8fGSt5d79pnLOZfm0f+dRrzb7P4DZD/LyDJAAAAAAAAAAAAAAAA/+0Ksq1N5QAoAAA="
-}
-```
-
-### Unmarshal
-
-Data in mongo is stored as `bson` which is a compressed form of `json`. We need mongo to convert the stored `bson` data to regular `json`
-that we can use in our code when returned.
-
-We just use the `bson.Unmarshal` API to achieve this.
-
-### Read
-
-Arguments:
-```go
-collection string
-key interface
-tag string
-```
-
-Read is straight forward and it uses the `FindOne` API to find our Mongo document based on the provided `key` and then gets the corresponding data for the given `tag`. It will return []byte which can then be passed to the `Unmarshal` function to get the desired GO object.
-
-### Delete
-
-Delete is similar to Read and deletes all the objectIDs being stored for a given `key` in the collection.
-
-## Testing Interfaces
-
-The following interface exists to allow for the development of unit tests which don't require mongo to be running.
-It is mentioned so in the code as well.
-
-```go
-// 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)
-}
-``` \ No newline at end of file
diff --git a/src/orchestrator/internal/db/mock.go b/src/orchestrator/internal/db/mock.go
deleted file mode 100644
index 1dbca4b4..00000000
--- a/src/orchestrator/internal/db/mock.go
+++ /dev/null
@@ -1,94 +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"
-
- pkgerrors "github.com/pkg/errors"
-)
-
-type MockKey struct {
- Key string
-}
-
-func (m MockKey) String() string {
- return m.Key
-}
-
-//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) HealthCheck() error {
- return m.Err
-}
-
-func (m *MockDB) Create(table string, key Key, tag string, data interface{}) error {
- return m.Err
-}
-
-func (m *MockDB) Update(table string, key 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 string, key Key, tag string) ([]byte, error) {
- if m.Err != nil {
- return nil, m.Err
- }
-
- for k, v := range m.Items {
- if k == key.String() {
- return v[tag], nil
- }
- }
-
- return nil, m.Err
-}
-
-func (m *MockDB) Delete(table string, key Key, tag string) error {
- return m.Err
-}
-
-func (m *MockDB) ReadAll(table string, 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
-}
diff --git a/src/orchestrator/internal/db/mongo.go b/src/orchestrator/internal/db/mongo.go
deleted file mode 100644
index 3720a4f2..00000000
--- a/src/orchestrator/internal/db/mongo.go
+++ /dev/null
@@ -1,396 +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 (
- "log"
-
- "golang.org/x/net/context"
-
- "github.com/onap/multicloud-k8s/src/orchestrator/internal/config"
-
- pkgerrors "github.com/pkg/errors"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/primitive"
- "go.mongodb.org/mongo-driver/mongo"
- "go.mongodb.org/mongo-driver/mongo/options"
-)
-
-// 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()
-}
-
-// These exists only for allowing us to mock the cursor.Next function
-// Mainly because we cannot construct a mongo.Cursor struct from our
-// tests. All fields in that struct are private and there is no public
-// constructor method.
-var cursorNext = func(ctx context.Context, cursor *mongo.Cursor) bool {
- return cursor.Next(ctx)
-}
-var cursorClose = func(ctx context.Context, cursor *mongo.Cursor) error {
- return cursor.Close(ctx)
-}
-
-// 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://" + config.GetConfiguration().DatabaseIP + ":27017"
- clientOptions := options.Client()
- clientOptions.ApplyURI(ip)
- mongoClient, err := mongo.NewClient(clientOptions)
- 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 ...interface{}) bool {
- for _, v := range args {
- val, ok := v.(string)
- if ok {
- if val == "" {
- return false
- }
- } else {
- if v == nil {
- return false
- }
- }
- }
-
- return true
-}
-
-// Create is used to create a DB entry
-func (m *MongoStore) Create(coll string, key 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
-}
-
-// Update is used to update a DB entry
-func (m *MongoStore) Update(coll string, key Key, tag string, data interface{}) error {
- if data == nil || !m.validateParams(coll, key, tag) {
- return pkgerrors.New("No Data to update")
- }
-
- 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 pkgerrors.Errorf("Error finding master table: %s", err.Error())
- }
-
- //Read the tag objectID from document
- tagoid, ok := keydata.Lookup(tag).ObjectIDOK()
- if !ok {
- return pkgerrors.Errorf("Error finding objectID for tag %s", tag)
- }
-
- //Update the document with new data
- filter = bson.D{{"_id", tagoid}}
-
- _, err = decodeBytes(
- c.FindOneAndUpdate(
- ctx,
- filter,
- bson.D{
- {"$set", bson.D{
- {tag, data},
- }},
- },
- options.FindOneAndUpdate().SetReturnDocument(options.After)))
-
- if err != nil {
- return pkgerrors.Errorf("Error updating record: %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 string, key 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 string, key 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 cursorClose(ctx, cursor)
-
- //Iterate over all the master tables
- result := make(map[string][]byte)
- for cursorNext(ctx, cursor) {
- d := cursor.Current
-
- //Read key of each master table
- key, ok := d.Lookup("key").DocumentOK()
- if !ok {
- //Throw error if key is not found
- pkgerrors.New("Unable to read key from mastertable")
- }
-
- //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.String()] = 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/orchestrator/internal/db/mongo_test.go b/src/orchestrator/internal/db/mongo_test.go
deleted file mode 100644
index 171c908f..00000000
--- a/src/orchestrator/internal/db/mongo_test.go
+++ /dev/null
@@ -1,597 +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 (
- "bytes"
- "context"
- "reflect"
- "strings"
- "testing"
-
- pkgerrors "github.com/pkg/errors"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/mongo"
- "go.mongodb.org/mongo-driver/mongo/options"
-)
-
-//Implements the functions used currently in mongo.go
-type mockCollection struct {
- Err error
- mCursor *mongo.Cursor
- mCursorCount int
-}
-
-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": MockKey{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": MockKey{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": MockKey{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"].(Key),
- 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 TestUpdate(t *testing.T) {
- testCases := []struct {
- label string
- input map[string]interface{}
- mockColl *mockCollection
- bson bson.Raw
- expectedError string
- }{
- {
- label: "Successfull update of entry",
- input: map[string]interface{}{
- "coll": "collname",
- "key": MockKey{Key: "keyvalue"},
- "tag": "metadata",
- "data": "Data In String Format",
- },
- // Binary form of
- // {
- // "_id" : ObjectId("5c115156777ff85654248ae1"),
- // "key" : bson.D{{"name","testdef"},{"version","v1"}},
- // "metadata" : ObjectId("5c115156c9755047e318bbfd")
- // }
- bson: bson.Raw{
- '\x58', '\x00', '\x00', '\x00', '\x03', '\x6b', '\x65', '\x79',
- '\x00', '\x27', '\x00', '\x00', '\x00', '\x02', '\x6e', '\x61',
- '\x6d', '\x65', '\x00', '\x08', '\x00', '\x00', '\x00', '\x74',
- '\x65', '\x73', '\x74', '\x64', '\x65', '\x66', '\x00', '\x02',
- '\x76', '\x65', '\x72', '\x73', '\x69', '\x6f', '\x6e', '\x00',
- '\x03', '\x00', '\x00', '\x00', '\x76', '\x31', '\x00', '\x00',
- '\x07', '\x6d', '\x65', '\x74', '\x61', '\x64', '\x61', '\x74',
- '\x61', '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77', '\x7f',
- '\xf8', '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x07', '\x5f',
- '\x69', '\x64', '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77',
- '\x7f', '\xf8', '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x00',
- },
- mockColl: &mockCollection{},
- },
- {
- label: "Entry does not exist",
- input: map[string]interface{}{
- "coll": "collname",
- "key": MockKey{Key: "keyvalue"},
- "tag": "tagName",
- "data": "Data In String Format",
- },
- mockColl: &mockCollection{
- Err: pkgerrors.New("DB Error"),
- },
- expectedError: "DB Error",
- },
- }
-
- 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.Update(testCase.input["coll"].(string), testCase.input["key"].(Key),
- 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": MockKey{Key: "keyvalue"},
- "tag": "metadata",
- },
- // Binary form of
- // {
- // "_id" : ObjectId("5c115156777ff85654248ae1"),
- // "key" : bson.D{{"name","testdef"},{"version","v1"}},
- // "metadata" : ObjectId("5c115156c9755047e318bbfd")
- // }
- bson: bson.Raw{
- '\x58', '\x00', '\x00', '\x00', '\x03', '\x6b', '\x65', '\x79',
- '\x00', '\x27', '\x00', '\x00', '\x00', '\x02', '\x6e', '\x61',
- '\x6d', '\x65', '\x00', '\x08', '\x00', '\x00', '\x00', '\x74',
- '\x65', '\x73', '\x74', '\x64', '\x65', '\x66', '\x00', '\x02',
- '\x76', '\x65', '\x72', '\x73', '\x69', '\x6f', '\x6e', '\x00',
- '\x03', '\x00', '\x00', '\x00', '\x76', '\x31', '\x00', '\x00',
- '\x07', '\x6d', '\x65', '\x74', '\x61', '\x64', '\x61', '\x74',
- '\x61', '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77', '\x7f',
- '\xf8', '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x07', '\x5f',
- '\x69', '\x64', '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77',
- '\x7f', '\xf8', '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x00',
- },
- mockColl: &mockCollection{},
- // This is not the document because we are mocking decodeBytes
- expected: []byte{92, 17, 81, 86, 119, 127, 248, 86, 84, 36, 138, 225},
- },
- {
- label: "UnSuccessfull Read of entry: object not found",
- input: map[string]interface{}{
- "coll": "collname",
- "key": MockKey{Key: "keyvalue"},
- "tag": "badtag",
- },
- // Binary form of
- // {
- // "_id" : ObjectId("5c115156777ff85654248ae1"),
- // "key" : bson.D{{"name","testdef"},{"version","v1"}},
- // "metadata" : ObjectId("5c115156c9755047e318bbfd")
- // }
- bson: bson.Raw{
- '\x58', '\x00', '\x00', '\x00', '\x03', '\x6b', '\x65', '\x79',
- '\x00', '\x27', '\x00', '\x00', '\x00', '\x02', '\x6e', '\x61',
- '\x6d', '\x65', '\x00', '\x08', '\x00', '\x00', '\x00', '\x74',
- '\x65', '\x73', '\x74', '\x64', '\x65', '\x66', '\x00', '\x02',
- '\x76', '\x65', '\x72', '\x73', '\x69', '\x6f', '\x6e', '\x00',
- '\x03', '\x00', '\x00', '\x00', '\x76', '\x31', '\x00', '\x00',
- '\x07', '\x6d', '\x65', '\x74', '\x61', '\x64', '\x61', '\x74',
- '\x61', '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77', '\x7f',
- '\xf8', '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x07', '\x5f',
- '\x69', '\x64', '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77',
- '\x7f', '\xf8', '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x00',
- },
- mockColl: &mockCollection{},
- expectedError: "Error finding objectID",
- },
- {
- label: "UnSuccessfull Read of entry",
- input: map[string]interface{}{
- "coll": "collname",
- "key": MockKey{Key: "keyvalue"},
- "tag": "tagName",
- },
- mockColl: &mockCollection{
- Err: pkgerrors.New("DB Error"),
- },
- expectedError: "DB Error",
- },
- {
- label: "Missing input fields",
- input: map[string]interface{}{
- "coll": "",
- "key": MockKey{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"].(Key),
- 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: %v, expected: %v",
- 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": MockKey{Key: "keyvalue"},
- "tag": "metadata",
- },
- // Binary form of
- // {
- // "_id" : ObjectId("5c115156777ff85654248ae1"),
- // "key" : bson.D{{"name","testdef"},{"version","v1"}},
- // "metadata" : ObjectId("5c115156c9755047e318bbfd")
- // }
- bson: bson.Raw{
- '\x58', '\x00', '\x00', '\x00', '\x03', '\x6b', '\x65', '\x79',
- '\x00', '\x27', '\x00', '\x00', '\x00', '\x02', '\x6e', '\x61',
- '\x6d', '\x65', '\x00', '\x08', '\x00', '\x00', '\x00', '\x74',
- '\x65', '\x73', '\x74', '\x64', '\x65', '\x66', '\x00', '\x02',
- '\x76', '\x65', '\x72', '\x73', '\x69', '\x6f', '\x6e', '\x00',
- '\x03', '\x00', '\x00', '\x00', '\x76', '\x31', '\x00', '\x00',
- '\x07', '\x6d', '\x65', '\x74', '\x61', '\x64', '\x61', '\x74',
- '\x61', '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77', '\x7f',
- '\xf8', '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x07', '\x5f',
- '\x69', '\x64', '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77',
- '\x7f', '\xf8', '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x00',
- },
- mockColl: &mockCollection{},
- },
- {
- label: "UnSuccessfull Delete of entry",
- input: map[string]interface{}{
- "coll": "collname",
- "key": MockKey{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": MockKey{Key: "keyvalue"},
- "tag": "tagName",
- },
- // Binary form of
- // {
- // "_id" : ObjectId("5c115156777ff85654248ae1"),
- // "key" : bson.D{{"name","testdef"},{"version","v1"}},
- // "metadata" : ObjectId("5c115156c9755047e318bbfd")
- // }
- bson: bson.Raw{
- '\x58', '\x00', '\x00', '\x00', '\x03', '\x6b', '\x65', '\x79',
- '\x00', '\x27', '\x00', '\x00', '\x00', '\x02', '\x6e', '\x61',
- '\x6d', '\x65', '\x00', '\x08', '\x00', '\x00', '\x00', '\x74',
- '\x65', '\x73', '\x74', '\x64', '\x65', '\x66', '\x00', '\x02',
- '\x76', '\x65', '\x72', '\x73', '\x69', '\x6f', '\x6e', '\x00',
- '\x03', '\x00', '\x00', '\x00', '\x76', '\x31', '\x00', '\x00',
- '\x07', '\x6d', '\x65', '\x74', '\x61', '\x64', '\x61', '\x74',
- '\x61', '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77', '\x7f',
- '\xf8', '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x07', '\x5f',
- '\x69', '\x64', '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77',
- '\x7f', '\xf8', '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x00',
- },
- mockColl: &mockCollection{},
- expectedError: "Error finding objectID",
- },
- {
- label: "Missing input fields",
- input: map[string]interface{}{
- "coll": "",
- "key": MockKey{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"].(Key),
- 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: &mongo.Cursor{
- // Binary form of
- // {
- // "_id" : ObjectId("5c115156777ff85654248ae1"),
- // "key" : bson.D{{"name","testdef"},{"version","v1"}},
- // "metadata" : ObjectId("5c115156c9755047e318bbfd")
- // }
-
- Current: bson.Raw{
- '\x58', '\x00', '\x00', '\x00', '\x03', '\x6b', '\x65', '\x79',
- '\x00', '\x27', '\x00', '\x00', '\x00', '\x02', '\x6e', '\x61',
- '\x6d', '\x65', '\x00', '\x08', '\x00', '\x00', '\x00', '\x74',
- '\x65', '\x73', '\x74', '\x64', '\x65', '\x66', '\x00', '\x02',
- '\x76', '\x65', '\x72', '\x73', '\x69', '\x6f', '\x6e', '\x00',
- '\x03', '\x00', '\x00', '\x00', '\x76', '\x31', '\x00', '\x00',
- '\x07', '\x6d', '\x65', '\x74', '\x61', '\x64', '\x61', '\x74',
- '\x61', '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77', '\x7f',
- '\xf8', '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x07', '\x5f',
- '\x69', '\x64', '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77',
- '\x7f', '\xf8', '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x00',
- },
- },
- mCursorCount: 1,
- },
- expected: map[string][]byte{
- `{"name": "testdef","version": "v1"}`: []byte{
- 92, 17, 81, 86, 119, 127, 248, 86, 84, 36, 138, 225},
- },
- },
- {
- 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: &mongo.Cursor{
- // Binary form of
- // {
- // "_id" : ObjectId("5c115156777ff85654248ae1"),
- // "key" : bson.D{{"name","testdef"},{"version","v1"}},
- // "metadata" : ObjectId("5c115156c9755047e318bbfd")
- // }
- Current: bson.Raw{
- '\x58', '\x00', '\x00', '\x00', '\x03', '\x6b', '\x65', '\x79',
- '\x00', '\x27', '\x00', '\x00', '\x00', '\x02', '\x6e', '\x61',
- '\x6d', '\x65', '\x00', '\x08', '\x00', '\x00', '\x00', '\x74',
- '\x65', '\x73', '\x74', '\x64', '\x65', '\x66', '\x00', '\x02',
- '\x76', '\x65', '\x72', '\x73', '\x69', '\x6f', '\x6e', '\x00',
- '\x03', '\x00', '\x00', '\x00', '\x76', '\x31', '\x00', '\x00',
- '\x07', '\x6d', '\x65', '\x74', '\x61', '\x64', '\x61', '\x74',
- '\x61', '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77', '\x7f',
- '\xf8', '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x07', '\x5f',
- '\x69', '\x64', '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77',
- '\x7f', '\xf8', '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x00',
- },
- },
- mCursorCount: 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.Current, testCase.mockColl.Err
- }
-
- cursorNext = func(ctx context.Context, cursor *mongo.Cursor) bool {
- if testCase.mockColl.mCursorCount > 0 {
- testCase.mockColl.mCursorCount -= 1
- return true
- }
- return false
- }
-
- cursorClose = func(ctx context.Context, cursor *mongo.Cursor) error {
- return nil
- }
-
- 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/orchestrator/internal/db/store.go b/src/orchestrator/internal/db/store.go
deleted file mode 100644
index ed394205..00000000
--- a/src/orchestrator/internal/db/store.go
+++ /dev/null
@@ -1,106 +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"
-
- "github.com/onap/multicloud-k8s/src/orchestrator/internal/config"
-
- pkgerrors "github.com/pkg/errors"
-)
-
-// DBconn interface used to talk a concrete Database connection
-var DBconn Store
-
-// Key is an interface that will be implemented by anypackage
-// that wants to use the Store interface. This allows various
-// db backends and key types.
-type Key interface {
- String() string
-}
-
-// Store is an interface for accessing the 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 document with key and links data with tag and
- // creates a pointer(row) to the newly added data in the master table
- Create(table string, key Key, tag string, data interface{}) error
-
- // Reads data for a particular key with specific tag.
- Read(table string, key Key, tag string) ([]byte, error)
-
- // Update data for particular key with specific tag
- Update(table string, key Key, tag string, data interface{}) error
-
- // Deletes a specific tag data for key.
- // TODO: If tag is empty, it will delete all tags under key.
- Delete(table string, key Key, tag string) error
-
- // Reads all master tables and data from the specified tag in table
- ReadAll(table string, 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 orchestrator as the name
- DBconn, err = NewMongoStore("orchestrator", 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
-}
-
-// InitializeDatabaseConnection sets up the connection to the
-// configured database to allow the application to talk to it.
-func InitializeDatabaseConnection() error {
- err := createDBClient(config.GetConfiguration().DatabaseType)
- if err != nil {
- return pkgerrors.Cause(err)
- }
-
- err = DBconn.HealthCheck()
- if err != nil {
- return pkgerrors.Cause(err)
- }
-
- return nil
-}
diff --git a/src/orchestrator/internal/db/store_test.go b/src/orchestrator/internal/db/store_test.go
deleted file mode 100644
index 42a41787..00000000
--- a/src/orchestrator/internal/db/store_test.go
+++ /dev/null
@@ -1,121 +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 (
- "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/orchestrator/internal/logutils/logger.go b/src/orchestrator/internal/logutils/logger.go
deleted file mode 100644
index 2e8f9969..00000000
--- a/src/orchestrator/internal/logutils/logger.go
+++ /dev/null
@@ -1,28 +0,0 @@
-package logutils
-
-import (
- log "github.com/sirupsen/logrus"
-)
-
-//Fields is type that will be used by the calling function
-type Fields map[string]interface{}
-
-func init() {
- // Log as JSON instead of the default ASCII formatter.
- log.SetFormatter(&log.JSONFormatter{})
-}
-
-// Error uses the fields provided and logs
-func Error(msg string, fields Fields) {
- log.WithFields(log.Fields(fields)).Error(msg)
-}
-
-// Warn uses the fields provided and logs
-func Warn(msg string, fields Fields) {
- log.WithFields(log.Fields(fields)).Warn(msg)
-}
-
-// Info uses the fields provided and logs
-func Info(msg string, fields Fields) {
- log.WithFields(log.Fields(fields)).Info(msg)
-}
diff --git a/src/orchestrator/internal/project/project.go b/src/orchestrator/internal/project/project.go
deleted file mode 100644
index f0c50065..00000000
--- a/src/orchestrator/internal/project/project.go
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright 2019 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 project
-
-import (
- "encoding/json"
-
- "github.com/onap/multicloud-k8s/src/orchestrator/internal/db"
-
- pkgerrors "github.com/pkg/errors"
-)
-
-// Project contains the parameters needed for Projects
-// It implements the interface for managing the Projects
-type Project struct {
- ProjectName string `json:"project-name"`
- Description string `json:"description"`
-}
-
-// ProjectKey is the key structure that is used in the database
-type ProjectKey struct {
- ProjectName string `json:"rb-name"`
-}
-
-// We will use json marshalling to convert to string to
-// preserve the underlying structure.
-func (pk ProjectKey) String() string {
- out, err := json.Marshal(pk)
- if err != nil {
- return ""
- }
-
- return string(out)
-}
-
-// ProjectManager is an interface exposes the Project functionality
-type ProjectManager interface {
- Create(pr Project) (Project, error)
- Get(name string) (Project, error)
- Delete(name string) error
-}
-
-// ProjectClient implements the ProjectManager
-// It will also be used to maintain some localized state
-type ProjectClient struct {
- storeName string
- tagMeta, tagContent string
-}
-
-// NewProjectClient returns an instance of the ProjectClient
-// which implements the ProjectManager
-func NewProjectClient() *ProjectClient {
- return &ProjectClient{
- tagMeta: "projectmetadata",
- }
-}
-
-// Create a new collection based on the project
-func (v *ProjectClient) Create(p Project) (Project, error) {
-
- //Construct the composite key to select the entry
- key := ProjectKey{
- ProjectName: p.ProjectName,
- }
-
- //Check if this Project already exists
- _, err := v.Get(p.ProjectName)
- if err == nil {
- return Project{}, pkgerrors.New("Project already exists")
- }
-
- err = db.DBconn.Create(p.ProjectName, key, v.tagMeta, p)
- if err != nil {
- return Project{}, pkgerrors.Wrap(err, "Creating DB Entry")
- }
-
- return p, nil
-}
-
-// Get returns the Project for corresponding name
-func (v *ProjectClient) Get(name string) (Project, error) {
-
- //Construct the composite key to select the entry
- key := ProjectKey{
- ProjectName: name,
- }
- value, err := db.DBconn.Read(name, key, v.tagMeta)
- if err != nil {
- return Project{}, pkgerrors.Wrap(err, "Get Project")
- }
-
- //value is a byte array
- if value != nil {
- proj := Project{}
- err = db.DBconn.Unmarshal(value, &proj)
- if err != nil {
- return Project{}, pkgerrors.Wrap(err, "Unmarshaling Value")
- }
- return proj, nil
- }
-
- return Project{}, pkgerrors.New("Error getting Project")
-}
-
-// Delete the Project from database
-func (v *ProjectClient) Delete(name string) error {
-
- //Construct the composite key to select the entry
- key := ProjectKey{
- ProjectName: name,
- }
- err := db.DBconn.Delete(name, key, v.tagMeta)
- if err != nil {
- return pkgerrors.Wrap(err, "Delete Project Entry;")
- }
-
- //TODO: Delete the collection when the project is deleted
- return nil
-}
diff --git a/src/orchestrator/internal/project/project_test.go b/src/orchestrator/internal/project/project_test.go
deleted file mode 100644
index cc691e33..00000000
--- a/src/orchestrator/internal/project/project_test.go
+++ /dev/null
@@ -1,177 +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 project
-
-import (
- "reflect"
- "strings"
- "testing"
-
- "github.com/onap/multicloud-k8s/src/orchestrator/internal/db"
-
- pkgerrors "github.com/pkg/errors"
-)
-
-func TestCreateProject(t *testing.T) {
- testCases := []struct {
- label string
- inp Project
- expectedError string
- mockdb *db.MockDB
- expected Project
- }{
- {
- label: "Create Project",
- inp: Project{
- ProjectName: "testProject",
- Description: "A sample Project used for unit testing",
- },
- expected: Project{
- ProjectName: "testProject",
- Description: "A sample Project used for unit testing",
- },
- expectedError: "",
- mockdb: &db.MockDB{},
- },
- {
- label: "Failed Create Project",
- expectedError: "Error Creating Project",
- mockdb: &db.MockDB{
- Err: pkgerrors.New("Error Creating Project"),
- },
- },
- }
-
- for _, testCase := range testCases {
- t.Run(testCase.label, func(t *testing.T) {
- db.DBconn = testCase.mockdb
- impl := NewProjectClient()
- got, err := impl.Create(testCase.inp)
- if err != nil {
- if testCase.expectedError == "" {
- t.Fatalf("Create returned an unexpected error %s", err)
- }
- if strings.Contains(err.Error(), testCase.expectedError) == false {
- t.Fatalf("Create returned an unexpected error %s", err)
- }
- } else {
- if reflect.DeepEqual(testCase.expected, got) == false {
- t.Errorf("Create returned unexpected body: got %v;"+
- " expected %v", got, testCase.expected)
- }
- }
- })
- }
-}
-
-func TestGetProject(t *testing.T) {
-
- testCases := []struct {
- label string
- name string
- expectedError string
- mockdb *db.MockDB
- inp string
- expected Project
- }{
- {
- label: "Get Project",
- name: "testProject",
- expected: Project{
- ProjectName: "testProject",
- Description: "Test project for unit testing",
- },
- expectedError: "",
- mockdb: &db.MockDB{
- Items: map[string]map[string][]byte{
- ProjectKey{ProjectName: "testProject"}.String(): {
- "projectmetadata": []byte(
- "{\"project-name\":\"testProject\"," +
- "\"description\":\"Test project for unit testing\"}"),
- },
- },
- },
- },
- {
- label: "Get Error",
- expectedError: "DB Error",
- mockdb: &db.MockDB{
- Err: pkgerrors.New("DB Error"),
- },
- },
- }
-
- for _, testCase := range testCases {
- t.Run(testCase.label, func(t *testing.T) {
- db.DBconn = testCase.mockdb
- impl := NewProjectClient()
- got, err := impl.Get(testCase.name)
- if err != nil {
- if testCase.expectedError == "" {
- t.Fatalf("Get returned an unexpected error: %s", err)
- }
- if strings.Contains(err.Error(), testCase.expectedError) == false {
- t.Fatalf("Get returned an unexpected error: %s", err)
- }
- } else {
- if reflect.DeepEqual(testCase.expected, got) == false {
- t.Errorf("Get returned unexpected body: got %v;"+
- " expected %v", got, testCase.expected)
- }
- }
- })
- }
-}
-
-func TestDeleteProject(t *testing.T) {
-
- testCases := []struct {
- label string
- name string
- expectedError string
- mockdb *db.MockDB
- }{
- {
- label: "Delete Project",
- name: "testProject",
- mockdb: &db.MockDB{},
- },
- {
- label: "Delete Error",
- expectedError: "DB Error",
- mockdb: &db.MockDB{
- Err: pkgerrors.New("DB Error"),
- },
- },
- }
-
- for _, testCase := range testCases {
- t.Run(testCase.label, func(t *testing.T) {
- db.DBconn = testCase.mockdb
- impl := NewProjectClient()
- err := impl.Delete(testCase.name)
- if err != nil {
- if testCase.expectedError == "" {
- t.Fatalf("Delete returned an unexpected error %s", err)
- }
- if strings.Contains(err.Error(), testCase.expectedError) == false {
- t.Fatalf("Delete returned an unexpected error %s", err)
- }
- }
- })
- }
-}