blob: 04576061f3f15fd404bc8211116958e63feff8a3 [file] [log] [blame]
khenaidoo68c930b2019-05-13 11:46:51 -04001/*
2 * Copyright 2019-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package utils
17
18import (
npujar1d86a522019-11-14 17:11:16 +053019 "math/rand"
20 "testing"
21 "time"
22
serkant.uluderya2ae470f2020-01-21 11:13:09 -080023 "github.com/opencord/voltha-lib-go/v3/pkg/log"
khenaidoo68c930b2019-05-13 11:46:51 -040024 "github.com/stretchr/testify/assert"
25 "google.golang.org/grpc/codes"
26 "google.golang.org/grpc/status"
khenaidoo68c930b2019-05-13 11:46:51 -040027)
28
29var (
30 timeoutError error
31 taskFailureError error
32)
33
34func init() {
npujar1d86a522019-11-14 17:11:16 +053035 _, err := log.AddPackage(log.JSON, log.WarnLevel, nil)
36 if err != nil {
37 log.Errorw("unable-to-register-package-to-the-log-map", log.Fields{"error": err})
38 }
khenaidoo68c930b2019-05-13 11:46:51 -040039 timeoutError = status.Errorf(codes.Aborted, "timeout")
40 taskFailureError = status.Error(codes.Internal, "test failure task")
41}
42
Kent Hagerman8da2f1e2019-11-25 17:28:09 -050043func runSuccessfulTask(response Response, durationRange int) {
khenaidoo68c930b2019-05-13 11:46:51 -040044 time.Sleep(time.Duration(rand.Intn(durationRange)) * time.Millisecond)
Kent Hagerman8da2f1e2019-11-25 17:28:09 -050045 response.Done()
khenaidoo68c930b2019-05-13 11:46:51 -040046}
47
Kent Hagerman8da2f1e2019-11-25 17:28:09 -050048func runFailureTask(response Response, durationRange int) {
khenaidoo68c930b2019-05-13 11:46:51 -040049 time.Sleep(time.Duration(rand.Intn(durationRange)) * time.Millisecond)
Kent Hagerman8da2f1e2019-11-25 17:28:09 -050050 response.Error(taskFailureError)
khenaidoo68c930b2019-05-13 11:46:51 -040051}
52
khenaidoo442e7c72020-03-10 16:13:48 -040053func runMultipleTasks(timeout time.Duration, numTasks, taskDurationRange, numSuccessfulTask, numFailuretask int) []error {
khenaidoo68c930b2019-05-13 11:46:51 -040054 if numTasks != numSuccessfulTask+numFailuretask {
55 return []error{status.Error(codes.FailedPrecondition, "invalid-num-tasks")}
56 }
57 numSuccessfulTaskCreated := 0
Kent Hagerman8da2f1e2019-11-25 17:28:09 -050058 responses := make([]Response, numTasks)
khenaidoo68c930b2019-05-13 11:46:51 -040059 for i := 0; i < numTasks; i++ {
Kent Hagerman8da2f1e2019-11-25 17:28:09 -050060 responses[i] = NewResponse()
khenaidoo68c930b2019-05-13 11:46:51 -040061 if numSuccessfulTaskCreated < numSuccessfulTask {
Kent Hagerman8da2f1e2019-11-25 17:28:09 -050062 go runSuccessfulTask(responses[i], taskDurationRange)
npujar1d86a522019-11-14 17:11:16 +053063 numSuccessfulTaskCreated++
khenaidoo68c930b2019-05-13 11:46:51 -040064 continue
65 }
Kent Hagerman8da2f1e2019-11-25 17:28:09 -050066 go runFailureTask(responses[i], taskDurationRange)
khenaidoo68c930b2019-05-13 11:46:51 -040067 }
khenaidoo442e7c72020-03-10 16:13:48 -040068 return WaitForNilOrErrorResponses(timeout, responses...)
khenaidoo68c930b2019-05-13 11:46:51 -040069}
70
71func getNumSuccessFailure(inputs []error) (numSuccess, numFailure, numTimeout int) {
72 numFailure = 0
73 numSuccess = 0
74 numTimeout = 0
75 for _, input := range inputs {
76 if input != nil {
77 if input.Error() == timeoutError.Error() {
npujar1d86a522019-11-14 17:11:16 +053078 numTimeout++
khenaidoo68c930b2019-05-13 11:46:51 -040079 }
npujar1d86a522019-11-14 17:11:16 +053080 numFailure++
khenaidoo68c930b2019-05-13 11:46:51 -040081 } else {
npujar1d86a522019-11-14 17:11:16 +053082 numSuccess++
khenaidoo68c930b2019-05-13 11:46:51 -040083 }
84 }
85 return
86}
87
88func TestNoTimeouts(t *testing.T) {
89 var (
90 totalSuccess int
91 totalFailure int
92 results []error
93 nSuccess int
94 nFailure int
95 nTimeouts int
96 )
97 numIterations := 5
98 numTasks := 5
99 for i := 0; i < numIterations; i++ {
100 totalSuccess = rand.Intn(numTasks)
101 totalFailure = numTasks - totalSuccess
khenaidoo442e7c72020-03-10 16:13:48 -0400102 results = runMultipleTasks(110*time.Millisecond, numTasks, 50, totalSuccess, totalFailure)
khenaidoo68c930b2019-05-13 11:46:51 -0400103 nSuccess, nFailure, nTimeouts = getNumSuccessFailure(results)
104 assert.Equal(t, totalFailure, nFailure)
105 assert.Equal(t, totalSuccess, nSuccess)
106 assert.Equal(t, 0, nTimeouts)
khenaidoo68c930b2019-05-13 11:46:51 -0400107 }
108}
109
110func TestSomeTasksTimeouts(t *testing.T) {
111 var (
112 totalSuccess int
113 totalFailure int
114 results []error
115 nSuccess int
116 nFailure int
117 nTimeouts int
118 )
119 numIterations := 5
120 numTasks := 5
121 for i := 0; i < numIterations; i++ {
122 totalSuccess = rand.Intn(numTasks)
123 totalFailure = numTasks - totalSuccess
khenaidoo442e7c72020-03-10 16:13:48 -0400124 results = runMultipleTasks(50*time.Millisecond, numTasks, 100, totalSuccess, totalFailure)
khenaidoo68c930b2019-05-13 11:46:51 -0400125 nSuccess, nFailure, nTimeouts = getNumSuccessFailure(results)
126 assert.True(t, nFailure >= totalFailure)
127 assert.True(t, nSuccess <= totalSuccess)
128 assert.True(t, nTimeouts > 0)
129 }
130}