github.com/verrazzano/verrazzano@v1.7.1/tools/psr/backend/workers/opensearch/postlogs/postlogs_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 postlogs
     5  
     6  import (
     7  	"errors"
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/verrazzano/verrazzano/pkg/log/vzlog"
    10  	"github.com/verrazzano/verrazzano/tools/psr/backend/config"
    11  	"io"
    12  	"net/http"
    13  	"strings"
    14  	"testing"
    15  )
    16  
    17  type fakeHTTP struct {
    18  	resp        *http.Response
    19  	httpDoError error
    20  }
    21  
    22  type fakeBody struct {
    23  	bodyData      string
    24  	httpReadError error
    25  }
    26  
    27  var _ httpClientI = &fakeHTTP{}
    28  
    29  // TestGetters tests the worker getters
    30  // GIVEN a worker
    31  //
    32  //	WHEN the getter methods are calls
    33  //	THEN ensure that the correct results are returned
    34  func TestGetters(t *testing.T) {
    35  	w, err := NewPostLogsWorker()
    36  	assert.NoError(t, err)
    37  
    38  	wd := w.GetWorkerDesc()
    39  	assert.Equal(t, config.WorkerTypeOpsPostLogs, wd.WorkerType)
    40  	assert.Equal(t, "The postlogs worker performs POST requests on the OpenSearch endpoint", wd.Description)
    41  	assert.Equal(t, metricsPrefix, wd.MetricsPrefix)
    42  
    43  	logged := w.WantLoopInfoLogged()
    44  	assert.False(t, logged)
    45  }
    46  
    47  // TestGetEnvDescList tests the GetEnvDescList method
    48  // GIVEN a worker
    49  //
    50  //	WHEN the GetEnvDescList methods is called
    51  //	THEN ensure that the correct results are returned
    52  func TestGetEnvDescList(t *testing.T) {
    53  	tests := []struct {
    54  		name     string
    55  		key      string
    56  		defval   string
    57  		required bool
    58  	}{
    59  		{name: "1",
    60  			key:      LogEntries,
    61  			defval:   "1",
    62  			required: false,
    63  		},
    64  		{name: "2",
    65  			key:      LogLength,
    66  			defval:   "1",
    67  			required: false,
    68  		},
    69  	}
    70  
    71  	for _, test := range tests {
    72  		t.Run(test.name, func(t *testing.T) {
    73  			w, err := NewPostLogsWorker()
    74  			assert.NoError(t, err)
    75  			el := w.GetEnvDescList()
    76  			for _, e := range el {
    77  				if e.Key == test.key {
    78  					assert.Equal(t, test.defval, e.DefaultVal)
    79  					assert.Equal(t, test.required, e.Required)
    80  				}
    81  			}
    82  		})
    83  	}
    84  }
    85  
    86  func TestGetMetricDescList(t *testing.T) {
    87  	tests := []struct {
    88  		name   string
    89  		fqName string
    90  		help   string
    91  	}{
    92  		{name: "1", fqName: "opensearch_postlogs_success_count_total", help: "The total number of successful OpenSearch POST requests"},
    93  		{name: "2", fqName: "opensearch_postlogs_failure_count_total", help: "The total number of successful OpenSearch POST requests"},
    94  		{name: "3", fqName: "opensearch_postlogs_success_latency_nanoseconds", help: "The latency of successful OpenSearch POST requests in nanoseconds"},
    95  		{name: "4", fqName: "opensearch_postlogs_failure_latency_nanoseconds", help: "The latency of failed OpenSearch POST requests in nanoseconds"},
    96  		{name: "5", fqName: "opensearch_postlogs_data_chars_total", help: "The total number of characters posted to OpenSearch"},
    97  	}
    98  	for _, test := range tests {
    99  		t.Run(test.name, func(t *testing.T) {
   100  			wi, err := NewPostLogsWorker()
   101  			assert.NoError(t, err)
   102  			w := wi.(worker)
   103  			assert.NoError(t, err)
   104  			dl := w.GetMetricDescList()
   105  			var found int
   106  			for _, d := range dl {
   107  				s := d.String()
   108  				if strings.Contains(s, test.fqName) && strings.Contains(s, test.help) {
   109  					found++
   110  				}
   111  			}
   112  			assert.Equal(t, 1, found)
   113  		})
   114  	}
   115  }
   116  
   117  func TestGetMetricList(t *testing.T) {
   118  	tests := []struct {
   119  		name   string
   120  		fqName string
   121  		help   string
   122  	}{
   123  		{name: "1", fqName: metricsPrefix + "_success_count_total", help: "The total number of successful OpenSearch POST requests"},
   124  		{name: "2", fqName: metricsPrefix + "_failure_count_total", help: "The total number of successful OpenSearch POST requests"},
   125  		{name: "3", fqName: metricsPrefix + "_success_latency_nanoseconds", help: "The latency of successful OpenSearch POST requests in nanoseconds"},
   126  		{name: "4", fqName: metricsPrefix + "_failure_latency_nanoseconds", help: "The latency of failed OpenSearch POST requests in nanoseconds"},
   127  		{name: "5", fqName: metricsPrefix + "_data_chars_total", help: "The total number of characters posted to OpenSearch"},
   128  	}
   129  	for _, test := range tests {
   130  		t.Run(test.name, func(t *testing.T) {
   131  			wi, err := NewPostLogsWorker()
   132  			w := wi.(worker)
   133  			assert.NoError(t, err)
   134  			ml := w.GetMetricList()
   135  			var found int
   136  			for _, m := range ml {
   137  				s := m.Desc().String()
   138  				if strings.Contains(s, test.fqName) && strings.Contains(s, test.help) {
   139  					found++
   140  				}
   141  			}
   142  			assert.Equal(t, 1, found)
   143  		})
   144  	}
   145  }
   146  
   147  // TestDoWork tests the DoWork method
   148  // GIVEN a worker
   149  //
   150  //	WHEN the DoWork methods is called
   151  //	THEN ensure that the correct results are returned
   152  func TestDoWork(t *testing.T) {
   153  	tests := []struct {
   154  		name         string
   155  		doworkError  error
   156  		httpDoError  error
   157  		nilResp      bool
   158  		statusCode   int
   159  		reqCount     int
   160  		successCount int
   161  		failureCount int
   162  		fakeBody
   163  	}{
   164  		{
   165  			name:         "1",
   166  			statusCode:   201,
   167  			reqCount:     1,
   168  			successCount: 1,
   169  			failureCount: 0,
   170  			fakeBody: fakeBody{
   171  				bodyData: "bodydata",
   172  			},
   173  		},
   174  		{
   175  			name:         "2",
   176  			reqCount:     1,
   177  			successCount: 0,
   178  			failureCount: 1,
   179  			doworkError:  errors.New("error"),
   180  			httpDoError:  errors.New("error"),
   181  			fakeBody: fakeBody{
   182  				bodyData: "bodydata",
   183  			},
   184  		},
   185  		{
   186  			name:         "3",
   187  			statusCode:   500,
   188  			doworkError:  errors.New("error"),
   189  			reqCount:     1,
   190  			successCount: 0,
   191  			failureCount: 1,
   192  			fakeBody: fakeBody{
   193  				bodyData:      "bodydata",
   194  				httpReadError: errors.New("error"),
   195  			},
   196  		},
   197  		{
   198  			name:         "4",
   199  			doworkError:  errors.New("GET request to endpoint received a nil response"),
   200  			nilResp:      true,
   201  			reqCount:     1,
   202  			successCount: 0,
   203  			failureCount: 1,
   204  			fakeBody: fakeBody{
   205  				bodyData:      "bodydata",
   206  				httpReadError: errors.New("error"),
   207  			},
   208  		},
   209  	}
   210  	for _, test := range tests {
   211  		t.Run(test.name, func(t *testing.T) {
   212  			var resp *http.Response
   213  			if !test.nilResp {
   214  				resp = &http.Response{
   215  					StatusCode:    test.statusCode,
   216  					Body:          &test.fakeBody,
   217  					ContentLength: int64(len(test.bodyData)),
   218  				}
   219  			}
   220  
   221  			c := httpClient
   222  			defer func() {
   223  				httpClient = c
   224  			}()
   225  			httpClient = &fakeHTTP{
   226  				httpDoError: test.doworkError,
   227  				resp:        resp,
   228  			}
   229  
   230  			wi, err := NewPostLogsWorker()
   231  			assert.NoError(t, err)
   232  
   233  			w := wi.(worker)
   234  
   235  			err = config.PsrEnv.LoadFromEnv(w.GetEnvDescList())
   236  			assert.NoError(t, err)
   237  
   238  			err = w.DoWork(config.CommonConfig{
   239  				WorkerType: "Fake",
   240  			}, vzlog.DefaultLogger())
   241  			if test.doworkError == nil && test.httpDoError == nil && test.httpReadError == nil {
   242  				assert.NoError(t, err)
   243  			} else {
   244  				assert.Error(t, err)
   245  			}
   246  
   247  			assert.Equal(t, int64(test.successCount), w.openSearchPostSuccessCountTotal.Val)
   248  			assert.Equal(t, int64(test.failureCount), w.openSearchPostFailureCountTotal.Val)
   249  		})
   250  	}
   251  }
   252  
   253  func (f *fakeHTTP) Do(_ *http.Request) (resp *http.Response, err error) {
   254  	return f.resp, f.httpDoError
   255  }
   256  
   257  func (f fakeBody) ReadAll(d []byte) (n int, err error) {
   258  	if f.httpReadError != nil {
   259  		return 0, f.httpReadError
   260  	}
   261  	copy(d, f.bodyData)
   262  	return len(f.bodyData), nil
   263  }
   264  
   265  func (f fakeBody) Read(d []byte) (n int, err error) {
   266  	if f.httpReadError != nil {
   267  		return 0, f.httpReadError
   268  	}
   269  	copy(d, f.bodyData)
   270  	return len(f.bodyData), io.EOF
   271  }
   272  
   273  func (f fakeBody) Close() error {
   274  	return nil
   275  }