github.com/network-quality/goresponsiveness@v0.0.0-20240129151524-343954285090/utilities/utilities_test.go (about) 1 /* 2 * This file is part of Go Responsiveness. 3 * 4 * Go Responsiveness is free software: you can redistribute it and/or modify it under 5 * the terms of the GNU General Public License as published by the Free Software Foundation, 6 * either version 2 of the License, or (at your option) any later version. 7 * Go Responsiveness is distributed in the hope that it will be useful, but WITHOUT ANY 8 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 9 * PARTICULAR PURPOSE. See the GNU General Public License for more details. 10 * 11 * You should have received a copy of the GNU General Public License along 12 * with Go Responsiveness. If not, see <https://www.gnu.org/licenses/>. 13 */ 14 package utilities 15 16 import ( 17 "context" 18 "log" 19 "sync" 20 "testing" 21 "time" 22 ) 23 24 func TestIota(t *testing.T) { 25 r := Iota(6, 15) 26 27 l := 6 28 for _, vr := range r { 29 if vr != l { 30 log.Fatalf("Iota failed: expected %d, got %d\n", l, vr) 31 } 32 l++ 33 } 34 } 35 36 func TestReadAfterCloseOnBufferedChannel(t *testing.T) { 37 communication := make(chan int, 100) 38 39 maxC := 0 40 41 wg := sync.WaitGroup{} 42 wg.Add(2) 43 44 go func() { 45 counter := 0 46 for range make([]int, 50) { 47 communication <- counter 48 counter++ 49 } 50 close(communication) 51 wg.Done() 52 }() 53 54 go func() { 55 time.Sleep(2 * time.Second) 56 for c := range communication { 57 maxC = c 58 } 59 wg.Done() 60 }() 61 62 wg.Wait() 63 if maxC != 49 { 64 t.Fatalf("Did not read all sent items from a buffered channel after channel.") 65 } 66 } 67 68 func TestOrTimeoutStopsInfiniteLoop(t *testing.T) { 69 const TimeoutTime = 2 * time.Second 70 infinity := func() { 71 for { 72 } 73 } 74 timeBefore := time.Now() 75 OrTimeout(infinity, TimeoutTime) 76 timeAfter := time.Now() 77 if timeAfter.Sub(timeBefore) < TimeoutTime { 78 t.Fatalf("OrTimeout failed to keep the infinite loop running for at least %v.", TimeoutTime) 79 } 80 } 81 82 func TestFilenameAppend(t *testing.T) { 83 const basename = "testing.csv" 84 const expected = "testing-appended.csv" 85 result := FilenameAppend(basename, "-appended") 86 if expected != result { 87 t.Fatalf("%s != %s for FilenameAppend.", expected, result) 88 } 89 } 90 91 func TestWaitWithContext(t *testing.T) { 92 ctxt, canceller := context.WithCancel(context.Background()) 93 never_true := func() bool { return false } 94 mu := sync.Mutex{} 95 cond := sync.NewCond(&mu) 96 97 wg := sync.WaitGroup{} 98 99 wg.Add(3) 100 101 go func() { 102 ContextSignaler(ctxt, 500*time.Millisecond, &never_true, cond) 103 wg.Done() 104 }() 105 106 go func() { 107 WaitWithContext(ctxt, &never_true, &mu, cond) 108 wg.Done() 109 }() 110 111 go func() { 112 time.Sleep(2 * time.Second) 113 canceller() 114 wg.Done() 115 }() 116 117 wg.Wait() 118 } 119 120 func TestPerSecondToInterval(t *testing.T) { 121 if time.Second != PerSecondToInterval(1) { 122 t.Fatalf("A number of nanoseconds is not equal to a second!") 123 } 124 125 if time.Second/2 != PerSecondToInterval(2) { 126 t.Fatalf("Something that happens twice per second should happen every 5000ns.") 127 } 128 } 129 130 func TestTrim(t *testing.T) { 131 elements := Iota(1, 101) 132 133 trimmedElements := TrimBy(elements, 75) 134 135 trimmedLength := len(trimmedElements) 136 trimmedLast := trimmedElements[trimmedLength-1] 137 138 if trimmedLength != 75 || trimmedLast != 75 { 139 t.Fatalf("When trimming, the length should be 75 but it is %d and/or the last element should be 75 but it is %d", trimmedLength, trimmedLast) 140 } 141 } 142 143 func TestTrim2(t *testing.T) { 144 elements := Iota(1, 11) 145 146 trimmedElements := TrimBy(elements, 75) 147 148 trimmedLength := len(trimmedElements) 149 trimmedLast := trimmedElements[trimmedLength-1] 150 151 if trimmedLength != 7 || trimmedLast != 7 { 152 t.Fatalf("When trimming, the length should be 7 but it is %d and/or the last element should be 7 but it is %d", trimmedLength, trimmedLast) 153 } 154 } 155 156 func TestTrim3(t *testing.T) { 157 elements := Iota(1, 6) 158 159 trimmedElements := TrimBy(elements, 101) 160 161 trimmedLength := len(trimmedElements) 162 trimmedLast := trimmedElements[trimmedLength-1] 163 164 if trimmedLength != 5 || trimmedLast != 5 { 165 t.Fatalf("When trimming, the length should be 5 but it is %d and/or the last element should be 5 but it is %d", trimmedLength, trimmedLast) 166 } 167 } 168 169 func TestTrim4(t *testing.T) { 170 elements := Iota(1, 11) 171 172 trimmedElements := TrimBy(elements, 81) 173 174 trimmedLength := len(trimmedElements) 175 trimmedLast := trimmedElements[trimmedLength-1] 176 177 if trimmedLength != 8 || trimmedLast != 8 { 178 t.Fatalf("When trimming, the length should be 8 but it is %d and/or the last element should be 8 but it is %d", trimmedLength, trimmedLast) 179 } 180 } 181 182 func TestTrimmedMean(t *testing.T) { 183 expected := 2.5 184 elements := []int{5, 4, 3, 2, 1} 185 186 result, elements := TrimmedMean(elements, 80) 187 if result != expected || len(elements) != 4 || elements[len(elements)-1] != 4 { 188 t.Fatalf("The trimmed mean result %v does not match the expected value %v", result, expected) 189 } 190 } 191 192 func TestIndentStringOneNewline(t *testing.T) { 193 output := "This is my output\n" 194 195 indendentedOutput := IndentOutput(output, 3, "--") 196 197 if indendentedOutput != "------This is my output\n" { 198 t.Fatalf("I expected the indented output to be ####%v#### but got ####%v####!", output, indendentedOutput) 199 } 200 } 201 202 func TestIndentStringMultipleNewlines(t *testing.T) { 203 output := "This is my output\n\n" 204 205 indendentedOutput := IndentOutput(output, 3, "--") 206 207 if indendentedOutput != "------This is my output\n------\n" { 208 t.Fatalf("I expected the indented output to be ####%v#### but got ####%v####!", output, indendentedOutput) 209 } 210 }