From 3403d6664d39129119664f6f831438cef71e4199 Mon Sep 17 00:00:00 2001 From: Eugene R Date: Tue, 21 Nov 2023 12:19:45 +0200 Subject: [PATCH] Improve test coverage (#56) --- .codecov.yml | 9 +++++ .../configuration_service_routine_test.go | 19 +++++++++ .../configuration_service_storage_test.go | 33 ++++++++++++++- pkg/service/restore_memory_test.go | 29 ++++++++++++++ pkg/util/loading_cache_test.go | 40 +++++++++++++++++++ pkg/util/log_test.go | 5 ++- pkg/util/utils.go | 6 ++- pkg/util/utils_test.go | 25 ++++++++++++ 8 files changed, 162 insertions(+), 4 deletions(-) create mode 100644 .codecov.yml create mode 100644 pkg/service/restore_memory_test.go create mode 100644 pkg/util/loading_cache_test.go create mode 100644 pkg/util/utils_test.go diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 00000000..a5cc684b --- /dev/null +++ b/.codecov.yml @@ -0,0 +1,9 @@ +ignore: + - "internal/**/*" + - "cmd/**/*" + - "docs/*" + - "**/pkg/model/*" + - "**/pkg/shared/*" + - "**/pkg/stdio/*" + - "**/pkg/service/backup_*.go" + - "**/pkg/service/configuration_manager_*.go" \ No newline at end of file diff --git a/pkg/service/configuration_service_routine_test.go b/pkg/service/configuration_service_routine_test.go index 4dfb8178..a2128d35 100644 --- a/pkg/service/configuration_service_routine_test.go +++ b/pkg/service/configuration_service_routine_test.go @@ -7,6 +7,24 @@ import ( "github.com/aws/smithy-go/ptr" ) +func TestRoutine_Add(t *testing.T) { + policy := "policy" + cluster := "cluster" + storage := "storage" + config := &model.Config{ + BackupRoutines: make(map[string]*model.BackupRoutine), + BackupPolicies: map[string]*model.BackupPolicy{policy: {Name: &policy}}, + AerospikeClusters: map[string]*model.AerospikeCluster{cluster: {Name: &cluster}}, + Storage: map[string]*model.Storage{storage: {Name: &storage}}, + } + + routine := model.BackupRoutine{Storage: storage, SourceCluster: cluster} + err := AddRoutine(config, &routine) + if err != nil { + t.Errorf("AddRoutine failed, expected nil error, got %v", err) + } +} + func TestRoutine_AddErrors(t *testing.T) { routine := "routine" policy := "policy" @@ -18,6 +36,7 @@ func TestRoutine_AddErrors(t *testing.T) { routine model.BackupRoutine }{ {name: "empty", routine: model.BackupRoutine{}}, + {name: "existing", routine: model.BackupRoutine{Storage: storage, SourceCluster: cluster, Name: routine}}, {name: "no storage", routine: model.BackupRoutine{SourceCluster: cluster}}, {name: "no cluster", routine: model.BackupRoutine{Storage: storage}}, {name: "wrong storage", routine: model.BackupRoutine{Storage: wrong, SourceCluster: cluster}}, diff --git a/pkg/service/configuration_service_storage_test.go b/pkg/service/configuration_service_storage_test.go index 3f70351f..4e40ee5c 100644 --- a/pkg/service/configuration_service_storage_test.go +++ b/pkg/service/configuration_service_storage_test.go @@ -32,6 +32,21 @@ func TestStorage_Add(t *testing.T) { } } +func TestStorage_AddFailure(t *testing.T) { + config := &model.Config{ + Storage: map[string]*model.Storage{}, + } + + newStorage := &model.Storage{ + Name: ptr.String("storage"), + } + + err := AddStorage(config, newStorage) + if err == nil { + t.Errorf("Expected validation error") + } +} + func TestStorage_Update(t *testing.T) { storage := "storage" config := &model.Config{ @@ -61,6 +76,22 @@ func TestStorage_Update(t *testing.T) { } } +func TestStorage_UpdateFailure(t *testing.T) { + storage := "storage" + config := &model.Config{ + Storage: map[string]*model.Storage{storage: {Name: &storage}}, + } + + newStorage := &model.Storage{ + Name: ptr.String(storage), + } + + err := UpdateStorage(config, newStorage) + if err == nil { + t.Errorf("Expected validation error") + } +} + func TestStorage_Delete(t *testing.T) { storage := "storage" storage2 := "storage2" @@ -83,7 +114,7 @@ func TestStorage_Delete(t *testing.T) { t.Errorf("Expected nil error, got %v", err) } if len(config.Storage) != 1 { - t.Errorf("Expected size = 1") + t.Errorf("Expected config storage size to be 1") } // Deleting a non-existent storage should result in an error diff --git a/pkg/service/restore_memory_test.go b/pkg/service/restore_memory_test.go new file mode 100644 index 00000000..68a2502c --- /dev/null +++ b/pkg/service/restore_memory_test.go @@ -0,0 +1,29 @@ +package service + +import ( + "testing" + + "github.com/aerospike/backup/pkg/model" + "github.com/aerospike/backup/pkg/util" +) + +func TestRestoreMemory(t *testing.T) { + restoreService := NewRestoreMemory() + restoreRequest := &model.RestoreRequest{ + Host: util.Ptr("localhost"), + Port: util.Ptr(int32(3000)), + Directory: util.Ptr("./testout/backup"), + SetList: []string{"set1"}, + } + jobID := restoreService.Restore(restoreRequest) + + jobStatus := restoreService.JobStatus(jobID) + if jobStatus != jobStatusRunning { + t.Errorf("Expected jobStatus to be %s", jobStatusRunning) + } + + wrongJobStatus := restoreService.JobStatus(1111) + if wrongJobStatus != jobStatusNA { + t.Errorf("Expected jobStatus to be %s", jobStatusNA) + } +} diff --git a/pkg/util/loading_cache_test.go b/pkg/util/loading_cache_test.go new file mode 100644 index 00000000..756dd3fc --- /dev/null +++ b/pkg/util/loading_cache_test.go @@ -0,0 +1,40 @@ +package util + +import ( + "context" + "errors" + "strconv" + "testing" +) + +func TestLoadingCache(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + cache := NewLoadingCache(ctx, func(s string) (any, error) { + return strconv.Atoi(s) + }) + value, _ := cache.Get("1") + if value != 1 { + t.Error("The value is expected to be 1") + } + value, _ = cache.Get("1") // existing + if value != 1 { + t.Error("The value is expected to be 1") + } + go cache.startCleanup() + cancel() + cache.clean() + value, _ = cache.Get("2") + if value != 2 { + t.Error("The value is expected to be 2") + } +} + +func TestLoadingCache_Error(t *testing.T) { + cache := NewLoadingCache(context.Background(), func(s string) (any, error) { + return nil, errors.New("error") + }) + _, err := cache.Get("1") + if err == nil { + t.Error("Error must not be nil") + } +} diff --git a/pkg/util/log_test.go b/pkg/util/log_test.go index 1f37af36..fac32750 100644 --- a/pkg/util/log_test.go +++ b/pkg/util/log_test.go @@ -1,13 +1,15 @@ package util import ( + "strings" "testing" ) func Test_libLogRegex(t *testing.T) { tests := []string{ "2023-01-01 00:00:00 UTC [INF] [74813] Starting backup for 4096 partitions from 0 to 4095", - "2023-11-08 09:44:48 GMT [ERR] [ 14] The max S3 object size is 5497558138880"} + "2023-11-08 09:44:48 GMT [ERR] [ 14] The max S3 object size is 5497558138880", + } for _, e := range tests { match := libLogRegex.FindStringSubmatch(e) @@ -15,4 +17,5 @@ func Test_libLogRegex(t *testing.T) { t.Fatal("libLogRegex error") } } + LogCaptured(strings.Join(tests, "\n")) } diff --git a/pkg/util/utils.go b/pkg/util/utils.go index c2cd44ad..675e6d8b 100644 --- a/pkg/util/utils.go +++ b/pkg/util/utils.go @@ -6,8 +6,10 @@ func Ptr[T any](obj T) *T { return &obj } -func Find[T any](collection map[string]T, f func(T) bool) (T, bool) { - for _, item := range collection { +// Find returns the first element from the given map that satisfies +// the predicate f. +func Find[T any](items map[string]T, f func(T) bool) (T, bool) { + for _, item := range items { if f(item) { return item, true } diff --git a/pkg/util/utils_test.go b/pkg/util/utils_test.go new file mode 100644 index 00000000..531f5756 --- /dev/null +++ b/pkg/util/utils_test.go @@ -0,0 +1,25 @@ +package util + +import ( + "testing" +) + +func TestPtr(t *testing.T) { + var n int32 + np := Ptr(n) + if n != *np { + t.Error("Expected to be equal") + } +} + +func TestFind(t *testing.T) { + elements := map[string]int{"a": 1} + _, found := Find(elements, func(i int) bool { return i == 1 }) + if !found { + t.Error("Expected to be found") + } + _, found = Find(elements, func(i int) bool { return i == 2 }) + if found { + t.Error("Expected not to be found") + } +}