blob: 9d5ed8e658258e424049e2f0b330cf46fecbc330 [file] [log] [blame]
khenaidoo68c930b2019-05-13 11:46:51 -04001/*
Joey Armstrong5f51f2e2023-01-17 17:06:26 -05002 * Copyright 2019-2023 Open Networking Foundation (ONF) and the ONF Contributors
khenaidoo68c930b2019-05-13 11:46:51 -04003 *
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
khenaidoo68c930b2019-05-13 11:46:51 -040023 "github.com/stretchr/testify/assert"
24 "google.golang.org/grpc/codes"
25 "google.golang.org/grpc/status"
khenaidoo68c930b2019-05-13 11:46:51 -040026)
27
28var (
29 timeoutError error
30 taskFailureError error
31)
32
33func init() {
khenaidoo68c930b2019-05-13 11:46:51 -040034 timeoutError = status.Errorf(codes.Aborted, "timeout")
35 taskFailureError = status.Error(codes.Internal, "test failure task")
36}
37
Kent Hagerman8da2f1e2019-11-25 17:28:09 -050038func runSuccessfulTask(response Response, durationRange int) {
khenaidoo68c930b2019-05-13 11:46:51 -040039 time.Sleep(time.Duration(rand.Intn(durationRange)) * time.Millisecond)
Kent Hagerman8da2f1e2019-11-25 17:28:09 -050040 response.Done()
khenaidoo68c930b2019-05-13 11:46:51 -040041}
42
Kent Hagerman8da2f1e2019-11-25 17:28:09 -050043func runFailureTask(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.Error(taskFailureError)
khenaidoo68c930b2019-05-13 11:46:51 -040046}
47
khenaidoo442e7c72020-03-10 16:13:48 -040048func runMultipleTasks(timeout time.Duration, numTasks, taskDurationRange, numSuccessfulTask, numFailuretask int) []error {
khenaidoo68c930b2019-05-13 11:46:51 -040049 if numTasks != numSuccessfulTask+numFailuretask {
50 return []error{status.Error(codes.FailedPrecondition, "invalid-num-tasks")}
51 }
52 numSuccessfulTaskCreated := 0
Kent Hagerman8da2f1e2019-11-25 17:28:09 -050053 responses := make([]Response, numTasks)
khenaidoo68c930b2019-05-13 11:46:51 -040054 for i := 0; i < numTasks; i++ {
Kent Hagerman8da2f1e2019-11-25 17:28:09 -050055 responses[i] = NewResponse()
khenaidoo68c930b2019-05-13 11:46:51 -040056 if numSuccessfulTaskCreated < numSuccessfulTask {
Kent Hagerman8da2f1e2019-11-25 17:28:09 -050057 go runSuccessfulTask(responses[i], taskDurationRange)
npujar1d86a522019-11-14 17:11:16 +053058 numSuccessfulTaskCreated++
khenaidoo68c930b2019-05-13 11:46:51 -040059 continue
60 }
Kent Hagerman8da2f1e2019-11-25 17:28:09 -050061 go runFailureTask(responses[i], taskDurationRange)
khenaidoo68c930b2019-05-13 11:46:51 -040062 }
khenaidoo442e7c72020-03-10 16:13:48 -040063 return WaitForNilOrErrorResponses(timeout, responses...)
khenaidoo68c930b2019-05-13 11:46:51 -040064}
65
66func getNumSuccessFailure(inputs []error) (numSuccess, numFailure, numTimeout int) {
67 numFailure = 0
68 numSuccess = 0
69 numTimeout = 0
70 for _, input := range inputs {
71 if input != nil {
72 if input.Error() == timeoutError.Error() {
npujar1d86a522019-11-14 17:11:16 +053073 numTimeout++
khenaidoo68c930b2019-05-13 11:46:51 -040074 }
npujar1d86a522019-11-14 17:11:16 +053075 numFailure++
khenaidoo68c930b2019-05-13 11:46:51 -040076 } else {
npujar1d86a522019-11-14 17:11:16 +053077 numSuccess++
khenaidoo68c930b2019-05-13 11:46:51 -040078 }
79 }
80 return
81}
82
83func TestNoTimeouts(t *testing.T) {
84 var (
85 totalSuccess int
86 totalFailure int
87 results []error
88 nSuccess int
89 nFailure int
90 nTimeouts int
91 )
92 numIterations := 5
93 numTasks := 5
94 for i := 0; i < numIterations; i++ {
95 totalSuccess = rand.Intn(numTasks)
96 totalFailure = numTasks - totalSuccess
khenaidoo442e7c72020-03-10 16:13:48 -040097 results = runMultipleTasks(110*time.Millisecond, numTasks, 50, totalSuccess, totalFailure)
khenaidoo68c930b2019-05-13 11:46:51 -040098 nSuccess, nFailure, nTimeouts = getNumSuccessFailure(results)
99 assert.Equal(t, totalFailure, nFailure)
100 assert.Equal(t, totalSuccess, nSuccess)
101 assert.Equal(t, 0, nTimeouts)
khenaidoo68c930b2019-05-13 11:46:51 -0400102 }
103}
104
105func TestSomeTasksTimeouts(t *testing.T) {
106 var (
107 totalSuccess int
108 totalFailure int
109 results []error
110 nSuccess int
111 nFailure int
112 nTimeouts int
113 )
114 numIterations := 5
115 numTasks := 5
116 for i := 0; i < numIterations; i++ {
117 totalSuccess = rand.Intn(numTasks)
118 totalFailure = numTasks - totalSuccess
khenaidoo442e7c72020-03-10 16:13:48 -0400119 results = runMultipleTasks(50*time.Millisecond, numTasks, 100, totalSuccess, totalFailure)
khenaidoo68c930b2019-05-13 11:46:51 -0400120 nSuccess, nFailure, nTimeouts = getNumSuccessFailure(results)
121 assert.True(t, nFailure >= totalFailure)
122 assert.True(t, nSuccess <= totalSuccess)
123 assert.True(t, nTimeouts > 0)
124 }
125}