github.com/verrazzano/verrazzano@v1.7.1/tools/psr/backend/workmanager/runner_test.go (about) 1 // Copyright (c) 2022, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 4 package workmanager 5 6 import ( 7 "testing" 8 "time" 9 10 "github.com/prometheus/client_golang/prometheus" 11 "github.com/stretchr/testify/assert" 12 "github.com/verrazzano/verrazzano/pkg/log/vzlog" 13 "github.com/verrazzano/verrazzano/tools/psr/backend/config" 14 "github.com/verrazzano/verrazzano/tools/psr/backend/osenv" 15 "github.com/verrazzano/verrazzano/tools/psr/backend/spi" 16 ) 17 18 type fakeWorker struct { 19 doWorkCount int64 20 } 21 22 var _ spi.Worker = &fakeWorker{} 23 24 // TestMetricDesc tests the Runner Metric Descriptors 25 // GIVEN a Runner 26 // 27 // WHEN GetMetricDescList is called 28 // THEN ensure that all the descriptors are correct 29 func TestMetricDesc(t *testing.T) { 30 log := vzlog.DefaultLogger() 31 r, err := NewRunner(&fakeWorker{}, config.CommonConfig{}, log) 32 assert.NoError(t, err) 33 34 // Make sure each Desc is expected 35 mdList := r.GetMetricDescList() 36 assertMetricDescList(t, mdList) 37 38 // Make sure each Metric Desc is expected 39 mList := r.GetMetricList() 40 mdList2 := []prometheus.Desc{} 41 for i := range mList { 42 mdList2 = append(mdList2, *mList[i].Desc()) 43 } 44 assertMetricDescList(t, mdList2) 45 } 46 47 func assertMetricDescList(t *testing.T, mdList []prometheus.Desc) { 48 const ( 49 desc1 = `Desc{fqName: "psr_example_loop_count_total", help: "The total number of loops executed", constLabels: {}, variableLabels: []}` 50 desc2 = `Desc{fqName: "psr_example_worker_thread_count_total", help: "The total number of worker threads (goroutines) running", constLabels: {}, variableLabels: []}` 51 desc3 = `Desc{fqName: "psr_example_worker_last_loop_nanoseconds", help: "The number of nanoseconds that the worker took to run the last loop of doing work", constLabels: {}, variableLabels: []}` 52 desc4 = `Desc{fqName: "psr_example_worker_running_seconds_total", help: "The total number of seconds that the worker has been running", constLabels: {}, variableLabels: []}` 53 ) 54 55 // Build set to validate descriptors 56 mdSet := map[string]bool{ 57 desc1: true, 58 desc2: true, 59 desc3: true, 60 desc4: true, 61 } 62 63 // Make sure each Desc is expected 64 assert.Len(t, mdList, 4) 65 66 for _, md := range mdList { 67 _, ok := mdSet[md.String()] 68 assert.NotNil(t, ok) 69 delete(mdSet, md.String()) 70 } 71 // Make sure each string was seen 72 assert.Len(t, mdSet, 0) 73 } 74 75 // TestRunWorker tests the Runner.RunWorker method 76 // GIVEN a Runner 77 // 78 // WHEN RunWorker is called for the correct number of loops 79 // THEN ensure that the worker is called 80 func TestRunWorker(t *testing.T) { 81 var tests = []struct { 82 name string 83 duration time.Duration 84 loops int64 85 expectErr bool 86 }{ 87 {name: "oneIter", loops: 1, expectErr: false}, 88 {name: "tenIter", loops: 10, expectErr: false}, 89 } 90 for _, test := range tests { 91 t.Run(test.name, func(t *testing.T) { 92 log := vzlog.DefaultLogger() 93 f := fakeWorker{} 94 r, err := NewRunner(&f, config.CommonConfig{}, log) 95 actualRunner := r.(workerRunner) 96 assert.NoError(t, err) 97 98 err = r.RunWorker(config.CommonConfig{ 99 WorkerType: "Fake", 100 NumLoops: test.loops, 101 PsrDuration: config.UnlimitedWorkerDuration, 102 }, log) 103 104 assert.NoError(t, err) 105 assert.Equal(t, test.loops, f.doWorkCount) 106 assert.Equal(t, test.loops, actualRunner.loopCount.Val) 107 }) 108 } 109 } 110 111 // TestRunDuration tests the Runner.RunWorker method 112 // GIVEN a Runner 113 // 114 // WHEN RunWorker is called with different duration values 115 // THEN ensure that the worker is called without error 116 func TestRunDuration(t *testing.T) { 117 var tests = []struct { 118 name string 119 expectErr bool 120 duration time.Duration 121 }{ 122 {name: "oneS", duration: 1 * time.Second, expectErr: false}, 123 {name: "fiveMs", duration: 5 * time.Millisecond, expectErr: false}, 124 } 125 for _, test := range tests { 126 t.Run(test.name, func(t *testing.T) { 127 log := vzlog.DefaultLogger() 128 f := fakeWorker{} 129 r, err := NewRunner(&f, config.CommonConfig{}, log) 130 assert.NoError(t, err) 131 132 err = r.RunWorker(config.CommonConfig{ 133 WorkerType: "Fake", 134 PsrDuration: test.duration, 135 }, log) 136 137 assert.NoError(t, err) 138 }) 139 } 140 } 141 142 // GetWorkerDesc returns the WorkerDesc for the worker 143 func (w fakeWorker) GetWorkerDesc() spi.WorkerDesc { 144 return spi.WorkerDesc{ 145 WorkerType: config.WorkerTypeExample, 146 Description: "Example worker that demonstrates executing a fake use case", 147 MetricsPrefix: "example", 148 } 149 } 150 151 func (w *fakeWorker) GetEnvDescList() []osenv.EnvVarDesc { 152 return []osenv.EnvVarDesc{} 153 } 154 155 func (w *fakeWorker) GetMetricDescList() []prometheus.Desc { 156 return nil 157 } 158 159 func (w *fakeWorker) GetMetricList() []prometheus.Metric { 160 return nil 161 } 162 163 func (w *fakeWorker) WantLoopInfoLogged() bool { 164 return true 165 } 166 167 func (w fakeWorker) PreconditionsMet() (bool, error) { 168 return true, nil 169 } 170 171 func (w *fakeWorker) DoWork(config.CommonConfig, vzlog.VerrazzanoLogger) error { 172 w.doWorkCount = w.doWorkCount + 1 173 return nil 174 }