Commit VOL-4124. Testcases for device package.
Change-Id: I2fe37621e373f57d9f90da14a0bf0600b8328362
diff --git a/Makefile b/Makefile
index 218db5e..4db8dfb 100644
--- a/Makefile
+++ b/Makefile
@@ -118,6 +118,12 @@
test: ## Run unit tests
@echo "Call unit test case suite"
+ @mkdir -p ./tests/results
+ @${GO} test -mod=vendor -v -coverprofile ./tests/results/go-test-coverage.out -covermode count ./... 2>&1 | tee ./tests/results/go-test-results.out ;\
+ RETURN=$$? ;\
+ ${GO_JUNIT_REPORT} < ./tests/results/go-test-results.out > ./tests/results/go-test-results.xml ;\
+ ${GOCOVER_COBERTURA} < ./tests/results/go-test-coverage.out > ./tests/results/go-test-coverage.xml ;\
+ exit $$RETURN
sca: ## Runs static code analysis with the golangci-lint tool
@rm -rf ./sca-report
diff --git a/pkg/config/config_mock.go b/pkg/config/config_mock.go
new file mode 100644
index 0000000..f29e968
--- /dev/null
+++ b/pkg/config/config_mock.go
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * 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 Common Logger initialization
+package config
+
+import (
+ "context"
+)
+
+const (
+ FailedPattern = "error"
+)
+
+// MockConfig function will be used to set some default values for config variables
+func MockConfig(ctx context.Context) {
+ ctxGlobal = ctx
+}
diff --git a/pkg/db/connection.go b/pkg/db/connection.go
index 52cf88b..26cdba3 100644
--- a/pkg/db/connection.go
+++ b/pkg/db/connection.go
@@ -34,12 +34,7 @@
"github.com/opencord/voltha-lib-go/v4/pkg/log"
)
-var kvClient *KvStoreClient
-
-// KvStoreClient holds the KVStore info
-type KvStoreClient struct {
- client kvstore.Client
-}
+var kvClient kvstore.Client
// logger represents the log object
var logger log.CLogger
@@ -61,8 +56,7 @@
logger.Errorw(ctx, "etcd-server-unreachable", log.Fields{"address": address})
return nil, errors.New("etcd client unreachable")
}
- kvClient = new(KvStoreClient)
- kvClient.client = etcdClient
+ kvClient = etcdClient
return etcdClient, err
}
return nil, errors.New("unsupported-kv-store")
diff --git a/pkg/db/kvclient_mock.go b/pkg/db/kvclient_mock.go
new file mode 100644
index 0000000..0f292d4
--- /dev/null
+++ b/pkg/db/kvclient_mock.go
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * 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 holds utils for datastore implementation
+package db
+
+import (
+ "context"
+ "errors"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/opencord/voltha-lib-go/v4/pkg/db/kvstore"
+
+ "github.com/opencord/voltha-lib-go/v4/pkg/log"
+)
+
+type mockKVClient struct {
+}
+
+var testKvPairCache *sync.Map
+
+// MockKVClient function mimics the kvclient
+func MockKVClient() {
+ kvClient = new(mockKVClient)
+ testKvPairCache = new(sync.Map)
+}
+
+// ClearCache function clears the kvclient cache
+func ClearCache() {
+ testKvPairCache = new(sync.Map)
+}
+
+// List function implemented for KVClient.
+func (kvclient *mockKVClient) List(ctx context.Context, prefix string) (map[string]*kvstore.KVPair, error) {
+ kvPairMap := make(map[string]*kvstore.KVPair)
+ testKvPairCache.Range(func(key, value interface{}) bool {
+ if strings.Contains(key.(string), prefix) {
+ kvPair := new(kvstore.KVPair)
+ kvPair.Key = key.(string)
+ kvPair.Value = value.([]byte)
+ kvPairMap[kvPair.Key] = kvPair
+ }
+ return true
+ })
+
+ if len(kvPairMap) != 0 {
+ logger.Debugw(ctx, "List of MockKVClient called", log.Fields{"kvPairMap": kvPairMap})
+ return kvPairMap, nil
+ }
+
+ return nil, errors.New("key didn't find")
+}
+
+// Get mock function implementation for KVClient
+func (kvclient *mockKVClient) Get(ctx context.Context, key string) (*kvstore.KVPair, error) {
+ logger.Debugw(ctx, "Warning Warning Warning: Get of MockKVClient called", log.Fields{"key": key})
+
+ if val, ok := testKvPairCache.Load(key); ok {
+ kvPair := new(kvstore.KVPair)
+ kvPair.Key = key
+ kvPair.Value = val
+ return kvPair, nil
+ }
+
+ return nil, errors.New("key didn't find")
+}
+
+// Put mock function implementation for KVClient
+func (kvclient *mockKVClient) Put(ctx context.Context, key string, value interface{}) error {
+ if key != "" {
+ value = []byte(value.(string))
+ testKvPairCache.Store(key, value)
+ return nil
+ }
+ return errors.New("key didn't find")
+}
+
+// Delete mock function implementation for KVClient
+func (kvclient *mockKVClient) Delete(ctx context.Context, key string) error {
+ logger.Infow(ctx, "Error Error Error Key:", log.Fields{})
+ if key != "" {
+ testKvPairCache.Delete(key)
+ return nil
+ }
+ return errors.New("key didn't find")
+}
+
+// DeleteWithPrefix mock function implementation for KVClient
+func (kvclient *mockKVClient) DeleteWithPrefix(ctx context.Context, prefix string) error {
+ testKvPairCache.Range(func(key, value interface{}) bool {
+ if strings.Contains(key.(string), prefix) {
+ testKvPairCache.Delete(key)
+ }
+ return true
+ })
+ return nil
+}
+
+// Reserve mock function implementation for KVClient
+func (kvclient *mockKVClient) Reserve(ctx context.Context, key string, value interface{}, ttl time.Duration) (interface{}, error) {
+ return nil, errors.New("key didn't find")
+}
+
+// ReleaseReservation mock function implementation for KVClient
+func (kvclient *mockKVClient) ReleaseReservation(ctx context.Context, key string) error {
+ return nil
+}
+
+// ReleaseAllReservations mock function implementation for KVClient
+func (kvclient *mockKVClient) ReleaseAllReservations(ctx context.Context) error {
+ return nil
+}
+
+// RenewReservation mock function implementation for KVClient
+func (kvclient *mockKVClient) RenewReservation(ctx context.Context, key string) error {
+ return nil
+}
+
+// Watch mock function implementation for KVClient
+func (kvclient *mockKVClient) Watch(ctx context.Context, key string, withPrefix bool) chan *kvstore.Event {
+ return nil
+}
+
+// AcquireLock mock function implementation for KVClient
+func (kvclient *mockKVClient) AcquireLock(ctx context.Context, lockName string, timeout time.Duration) error {
+ return nil
+}
+
+// ReleaseLock mock function implementation for KVClient
+func (kvclient *mockKVClient) ReleaseLock(lockName string) error {
+ return nil
+}
+
+// IsConnectionUp mock function implementation for KVClient
+func (kvclient *mockKVClient) IsConnectionUp(ctx context.Context) bool { // timeout in second
+ return true
+}
+
+// CloseWatch mock function implementation for KVClient
+func (kvclient *mockKVClient) CloseWatch(ctx context.Context, key string, ch chan *kvstore.Event) {
+}
+
+// Close mock function implementation for KVClient
+func (kvclient *mockKVClient) Close(ctx context.Context) {
+}
diff --git a/pkg/db/operations.go b/pkg/db/operations.go
index ea63050..1d6097d 100644
--- a/pkg/db/operations.go
+++ b/pkg/db/operations.go
@@ -28,7 +28,7 @@
func Read(ctx context.Context, key string) (string, error) {
if kvClient != nil {
logger.Debugw(ctx, "Reading-key-value-pair-from-kv-store", log.Fields{"key": key})
- kvPair, err := kvClient.client.Get(ctx, key)
+ kvPair, err := kvClient.Get(ctx, key)
if err != nil {
return "", err
}
@@ -47,7 +47,7 @@
keyValues := make(map[string]string)
if kvClient != nil {
logger.Debugw(ctx, "Reading-all-key-value-pairs-from-kv-store", log.Fields{"key-prefix": keyPrefix})
- kvPairs, err := kvClient.client.List(ctx, keyPrefix)
+ kvPairs, err := kvClient.List(ctx, keyPrefix)
if err != nil {
return keyValues, err
}
@@ -68,7 +68,7 @@
func Del(ctx context.Context, key string) error {
if kvClient != nil {
logger.Debugw(ctx, "Deleting-key-value-pair-from-kv-store", log.Fields{"key": key})
- return kvClient.client.Delete(ctx, key)
+ return kvClient.Delete(ctx, key)
}
logger.Errorw(ctx, "Deleting-key-value-pair-in-kv-store-failed-because-kvstore-not-initialised", log.Fields{"key": key})
return errors.New("kvstore not initialised")
@@ -78,7 +78,7 @@
func DelAll(ctx context.Context, keyPrefix string) error {
if kvClient != nil {
logger.Debugw(ctx, "Deleting-all-key-value-pair-from-kv-store-with-prefix", log.Fields{"key-prefix": keyPrefix})
- return kvClient.client.DeleteWithPrefix(ctx, keyPrefix)
+ return kvClient.DeleteWithPrefix(ctx, keyPrefix)
}
logger.Errorw(ctx, "Deleting-all-key-value-pair-in-kv-store-with-prefix-failed-because-kvstore-not-initialised", log.Fields{"key-prefix": keyPrefix})
return errors.New("kvstore not initialised")
@@ -88,7 +88,7 @@
func Put(ctx context.Context, key string, val string) error {
if kvClient != nil {
logger.Debugw(ctx, "Storing-key-value-pair-in-kv-store", log.Fields{"key": key, "value": val})
- return kvClient.client.Put(ctx, key, val)
+ return kvClient.Put(ctx, key, val)
}
logger.Errorw(ctx, "Storing-key-value-pair-in-kv-store-failed-because-kvstore-not-initialised", log.Fields{"key": key, "value": val})
return errors.New("kvstore not initialised")
diff --git a/pkg/models/device/db_test.go b/pkg/models/device/db_test.go
new file mode 100644
index 0000000..b59d08b
--- /dev/null
+++ b/pkg/models/device/db_test.go
@@ -0,0 +1,382 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * 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 modifiablecomponent stores ModifiableComponent methods and functions
+package device
+
+import (
+ "context"
+ "fmt"
+ "strings"
+ "testing"
+
+ timestamp "github.com/golang/protobuf/ptypes/timestamp"
+ "github.com/opencord/device-management-interface/go/dmi"
+ "github.com/opencord/opendevice-manager/pkg/db"
+)
+
+// mockModifiableComp refers to mocking of modifiable component req
+func mockModifiableComp(id string) *dmi.ModifiableComponent {
+ req := new(dmi.ModifiableComponent)
+ req.Name = "olt-name-" + id
+ req.Alias = "olt-1-alias-" + id
+ req.AssetId = "olt-1-assetid-" + id
+ req.Uri = new(dmi.Uri)
+ req.Uri.Uri = "127.0.0." + id
+ req.Parent = new(dmi.Component)
+ req.AdminState = dmi.ComponentAdminState_COMP_ADMIN_STATE_UNLOCKED
+ return req
+}
+
+func mockHardware(id string) *dmi.Hardware {
+ hw := new(dmi.Hardware)
+ hw.LastChange = new(timestamp.Timestamp)
+ hw.LastBooted = new(timestamp.Timestamp)
+ hw.Root = new(dmi.Component)
+ hw.Root.ModelName = "model-name-" + id
+ return hw
+}
+
+func runTcase(tcaseName string, t *testing.T, tcaseFunc func() (bool, error)) (string, bool) {
+ fmt.Println("\n#======= TESTCASE STARTED : " + tcaseName + " ========#")
+ if ok, err := tcaseFunc(); !ok {
+ fmt.Println("#======= TESTCASE FAILED : "+tcaseName+" ========#", err)
+ return tcaseName, false
+ }
+ fmt.Println("#======= TESTCASE PASSED : " + tcaseName + " ========#")
+ return tcaseName, true
+}
+
+// _Test_PositiveTcaseNewDeviceRecord refers to the positive tcase defined for testing func NewDeviceRecord
+func Test_PositiveTcaseNewDeviceRecord(t *testing.T) {
+ req := mockModifiableComp("1")
+ var rec *DeviceRecord
+
+ db.MockKVClient()
+ ctx := context.Background()
+ defer db.ClearCache()
+
+ // Positive Testcase for NewDeviceRecord
+ tcase1 := func() (bool, error) {
+ var err error
+ if rec, err = NewDeviceRecord(ctx, req); rec == nil || err != nil {
+ return false, err
+ }
+ return true, nil
+ }
+
+ if name, ok := runTcase("Positive Testcase for NewDeviceRecord-1", t, tcase1); !ok {
+ t.Errorf("#======= FAILED : Testcase " + name + " ========#")
+ return
+ }
+}
+
+// _Test_NegativeTcaseDBGetByName refers to the negative tcase defined for testing func DBGetByName
+func Test_NegativeTcaseDBGetByName(t *testing.T) {
+ req := mockModifiableComp("1")
+
+ db.MockKVClient()
+ ctx := context.Background()
+ defer db.ClearCache()
+
+ // Negative Testcase for DBGetByName
+ tcase2 := func() (bool, error) {
+ if rec, err := DBGetByName(ctx, req.Name); rec != nil {
+ return false, err
+ }
+ return true, nil
+ }
+
+ if name, ok := runTcase("Negative Testcase for DBGetByName-1", t, tcase2); !ok {
+ t.Errorf("#======= FAILED : Testcase " + name + " ========#")
+ return
+ }
+}
+
+// _Test_Suite refers to all component testcases belongs to all packages
+func Test_Suite(t *testing.T) {
+}
+
+// _Test_NegativeTcaseDBAddByName refers to the negative tcase defined for testing func DBAddByName
+func Test_NegativeTcaseDBAddByName(t *testing.T) {
+
+ db.MockKVClient()
+ ctx := context.Background()
+ defer db.ClearCache()
+
+ // Negative Testcase for DBAddByName
+ tcase3 := func() (bool, error) {
+ emptyDevRec := new(DeviceRecord)
+ if err := emptyDevRec.DBAddByName(ctx); err == nil {
+ return false, err
+ }
+ return true, nil
+ }
+
+ if name, ok := runTcase("Negative Testcase for DBAddByName-1", t, tcase3); !ok {
+ t.Errorf("#======= FAILED : Testcase " + name + " ========#")
+ return
+ }
+
+}
+
+// _Test_PositiveTcaseDBAddByName refers to the positive tcase defined for testing func DBAddByName
+func Test_PositiveTcaseDBAddByName(t *testing.T) {
+ req := mockModifiableComp("1")
+ var rec *DeviceRecord
+ db.MockKVClient()
+ ctx := context.Background()
+ defer db.ClearCache()
+
+ // Positive Testcase for DBAddByName
+ tcase4 := func() (bool, error) {
+ var err error
+ if rec, err = NewDeviceRecord(ctx, req); rec == nil || err != nil {
+ return false, err
+ }
+ if err = rec.DBAddByName(ctx); err != nil {
+ return false, err
+ }
+ return true, nil
+ }
+
+ if name, ok := runTcase("Positive Testcase for DBAddByName-1", t, tcase4); !ok {
+ t.Errorf("#======= FAILED : Testcase " + name + " ========#")
+ return
+ }
+
+}
+
+// _Test_PositiveTcaseDBGetByName refers to the positive tcase defined for testing func DBGetByName
+func Test_PositiveTcaseDBGetByName(t *testing.T) {
+ req := mockModifiableComp("1")
+ var rec *DeviceRecord
+ db.MockKVClient()
+ ctx := context.Background()
+ defer db.ClearCache()
+
+ // Positive Testcase for DBGetByName
+ tcase5 := func() (bool, error) {
+ var err error
+ if rec, err = NewDeviceRecord(ctx, req); rec == nil || err != nil {
+ return false, err
+ }
+ if err = rec.DBAddByName(ctx); err != nil {
+ return false, err
+ }
+ if rec, err := DBGetByName(ctx, rec.Name); rec == nil || err != nil {
+ return false, err
+ }
+ return true, nil
+ }
+
+ if name, ok := runTcase("Positive Testcase for DBGetByName-1", t, tcase5); !ok {
+ t.Errorf("#======= FAILED : Testcase " + name + " ========#")
+ return
+ }
+
+}
+
+// _Test_PositiveTcaseDBGetByNameWithCacheMiss refers to the positive tcase defined for testing func DBGetByName with cache miss
+func Test_PositiveTcaseDBGetByNameWithCacheMiss(t *testing.T) {
+ req := mockModifiableComp("1")
+ var rec *DeviceRecord
+ db.MockKVClient()
+ ctx := context.Background()
+ defer db.ClearCache()
+
+ // Positive Testcase for DBGetByName with cache miss
+ tcase5 := func() (bool, error) {
+ var err error
+ if rec, err = NewDeviceRecord(ctx, req); rec == nil || err != nil {
+ return false, err
+ }
+ if err = rec.DBAddByName(ctx); err != nil {
+ return false, err
+ }
+ if rec, err := DBGetByName(ctx, rec.Name); rec == nil || err != nil {
+ return false, err
+ }
+ ClearCacheEntry(ctx, rec.Name, "")
+ if rec, err := DBGetByName(ctx, rec.Name); rec == nil || err != nil {
+ return false, err
+ }
+ return true, nil
+ }
+
+ if name, ok := runTcase("Positive Testcase for DBGetByName-2 with cache miss", t, tcase5); !ok {
+ t.Errorf("#======= FAILED : Testcase " + name + " ========#")
+ return
+ }
+
+}
+
+// _Test_PositiveTcaseDBAddUuidLookup refers to the positive tcase defined for testing func DBAddUuidLookup
+func Test_PositiveTcaseDBAddUuidLookup(t *testing.T) {
+ req := mockModifiableComp("1")
+ var rec *DeviceRecord
+ db.MockKVClient()
+ ctx := context.Background()
+ defer db.ClearCache()
+
+ // Positive Testcase for DBAddUuidLookup
+ tcase6 := func() (bool, error) {
+ var err error
+ if rec, err = NewDeviceRecord(ctx, req); rec == nil || err != nil {
+ return false, err
+ }
+ if err = rec.DBAddByName(ctx); err != nil {
+ return false, err
+ }
+ rec.Uuid = strings.Replace(rec.Name, "name", "uuid", 1)
+ if err := rec.DBAddUuidLookup(ctx); err != nil {
+ return false, err
+ }
+ if err := rec.DBAddByName(ctx); err != nil {
+ return false, err
+ }
+ if rec, err := DBGetByName(ctx, rec.Name); rec == nil || err != nil || rec.Uuid == "" {
+ return false, err
+ }
+ return true, nil
+ }
+
+ if name, ok := runTcase("Positive Testcase for DBAddUuidLookup-1", t, tcase6); !ok {
+ t.Errorf("#======= FAILED : Testcase " + name + " ========#")
+ return
+ }
+
+}
+
+// _Test_PositiveTcaseDBGetAll refers to the positive tcase defined for testing func DBGetAll
+func Test_PositiveTcaseDBGetAll(t *testing.T) {
+ req := mockModifiableComp("1")
+ var rec *DeviceRecord
+ db.MockKVClient()
+ ctx := context.Background()
+ defer db.ClearCache()
+
+ // Positive Testcase for DBGetAll
+ tcase8 := func() (bool, error) {
+ var err error
+ if rec, err = NewDeviceRecord(ctx, req); rec == nil || err != nil {
+ return false, err
+ }
+ if err = rec.DBAddByName(ctx); err != nil {
+ return false, err
+ }
+ if list, err := DBGetAll(ctx); list == nil || err != nil || len(list) != 1 {
+ return false, err
+ }
+ return true, nil
+ }
+
+ if name, ok := runTcase("Positive Testcase for DBGetAll-1", t, tcase8); !ok {
+ t.Errorf("#======= FAILED : Testcase " + name + " ========#")
+ return
+ }
+
+}
+
+// _Test_NegativeTcaseDBGetByUuid refers to the negative tcase defined for testing func DBGetByUuid
+func Test_NegativeTcaseDBGetByUuid(t *testing.T) {
+
+ db.MockKVClient()
+ ctx := context.Background()
+ defer db.ClearCache()
+
+ // Negative Testcase for DBGetByUuid
+ tcase10 := func() (bool, error) {
+ if rec, err := DBGetByUuid(ctx, "invalid-uuid-1"); rec != nil || err == nil {
+ return false, err
+ }
+ return true, nil
+ }
+
+ if name, ok := runTcase("Negative Testcase for DBGetByUuid-1", t, tcase10); !ok {
+ t.Errorf("#======= FAILED : Testcase " + name + " ========#")
+ return
+ }
+
+}
+
+// _Test_PositiveTcaseDBDelRecord refers to the positive tcase defined for testing func DBDelRecord
+func Test_PositiveTcaseDBDelRecord(t *testing.T) {
+ req := mockModifiableComp("1")
+ var rec *DeviceRecord
+ db.MockKVClient()
+ ctx := context.Background()
+ defer db.ClearCache()
+
+ // Positive Testcase for DBDelRecord
+ tcase11 := func() (bool, error) {
+ var err error
+ if rec, err = NewDeviceRecord(ctx, req); rec == nil || err != nil {
+ return false, err
+ }
+ if err = rec.DBAddByName(ctx); err != nil {
+ return false, err
+ }
+ if err := rec.DBDelRecord(ctx); err != nil {
+ return false, err
+ }
+ return true, nil
+ }
+
+ if name, ok := runTcase("Positive Testcase for DBDelRecord-1", t, tcase11); !ok {
+ t.Errorf("#======= FAILED : Testcase " + name + " ========#")
+ return
+ }
+
+}
+
+// _Test_PositiveTcaseDBSaveHwInfo refers to the positive tcase defined for testing func DBSaveHwInfo
+func Test_PositiveTcaseDBSaveHwInfo(t *testing.T) {
+ req := mockModifiableComp("1")
+ var rec *DeviceRecord
+ db.MockKVClient()
+ ctx := context.Background()
+ defer db.ClearCache()
+
+ // Positive Testcase for DBSaveHwInfo
+ tcase := func() (bool, error) {
+ var err error
+ if rec, err = NewDeviceRecord(ctx, req); rec == nil || err != nil {
+ return false, err
+ }
+ if err = rec.DBAddByName(ctx); err != nil {
+ return false, err
+ }
+ rec.Uuid = strings.Replace(rec.Name, "name", "uuid", 1)
+ if err := rec.DBAddUuidLookup(ctx); err != nil {
+ return false, err
+ }
+ hwInfo := mockHardware("1")
+ if err := rec.DBSaveHwInfo(ctx, hwInfo); rec == nil || err != nil {
+ return false, err
+ }
+ if rec, err := DBGetByName(ctx, rec.Name); rec == nil || err != nil || rec.ModelName != hwInfo.Root.ModelName {
+ return false, err
+ }
+ return true, nil
+ }
+
+ if name, ok := runTcase("Positive Testcase for DBSaveHwInfo-1", t, tcase); !ok {
+ t.Errorf("#======= FAILED : Testcase " + name + " ========#")
+ return
+ }
+
+}