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  }