github.com/choria-io/go-choria@v0.28.1-0.20240416190746-b3bf9c7d5a45/providers/agent/mcorpc/client/stats_test.go (about) 1 // Copyright (c) 2020-2021, R.I. Pienaar and the Choria Project contributors 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 5 package client 6 7 import ( 8 "sort" 9 "strings" 10 "time" 11 12 . "github.com/onsi/ginkgo/v2" 13 . "github.com/onsi/gomega" 14 ) 15 16 var _ = Describe("McoRPC/Client/Stats", func() { 17 Describe("All", func() { 18 var ( 19 s *Stats 20 ) 21 22 BeforeEach(func() { 23 s = NewStats() 24 }) 25 26 Describe("Merge", func() { 27 It("Should correctly merge", func() { 28 other := NewStats() 29 30 s.SetDiscoveredNodes([]string{"host1", "host2", "host3"}) 31 other.SetDiscoveredNodes([]string{"host2", "host3"}) 32 33 other.StartPublish() 34 other.publishStart = other.publishStart.Add(-10 * time.Second) 35 36 other.RecordReceived("host2") 37 other.RecordReceived("host3") 38 other.RecordReceived("host4") 39 other.PassedRequestInc() 40 other.FailedRequestInc() 41 42 other.EndPublish() 43 44 s.Merge(other) 45 46 Expect(s.UnexpectedResponseFrom()).To(Equal([]string{"host4"})) 47 Expect(s.outstandingNodes.Hosts()).To(Equal([]string{"host1"})) 48 Expect(s.FailCount()).To(Equal(1)) 49 Expect(s.OKCount()).To(Equal(1)) 50 Expect(s.PublishDuration()).To(BeNumerically("~", 10*time.Second, 10*time.Millisecond)) 51 }) 52 }) 53 54 Describe("SetAgent / Agent", func() { 55 It("Should set and get the right agent", func() { 56 Expect(s.Agent()).To(Equal("")) 57 s.SetAgent("foo") 58 Expect(s.Agent()).To(Equal("foo")) 59 }) 60 }) 61 62 Describe("SetAction / Action", func() { 63 It("Should set and get the right action", func() { 64 Expect(s.Action()).To(Equal("")) 65 s.SetAction("foo") 66 Expect(s.Action()).To(Equal("foo")) 67 }) 68 }) 69 70 Describe("All", func() { 71 It("Should correctly determine if all nodes have completed", func() { 72 s.SetDiscoveredNodes([]string{"host1", "host2"}) 73 Expect(s.All()).To(BeFalse()) 74 s.RecordReceived("host1") 75 Expect(s.All()).To(BeFalse()) 76 s.RecordReceived("host2") 77 Expect(s.All()).To(BeTrue()) 78 }) 79 }) 80 81 Describe("NoResponseFrom", func() { 82 It("Should return the correct list", func() { 83 s.SetDiscoveredNodes([]string{"host1", "host2"}) 84 85 nr := s.NoResponseFrom() 86 sort.Strings(nr) 87 Expect(nr).To(Equal(strings.Fields("host1 host2"))) 88 89 s.RecordReceived("host1") 90 Expect(s.NoResponseFrom()).To(Equal([]string{"host2"})) 91 92 s.RecordReceived("host2") 93 Expect(s.NoResponseFrom()).To(Equal([]string{})) 94 }) 95 }) 96 97 Describe("UnexpectedResponseFrom", func() { 98 It("Should report correctly", func() { 99 s.SetDiscoveredNodes([]string{"host1", "host2"}) 100 Expect(s.UnexpectedResponseFrom()).To(Equal([]string{})) 101 s.RecordReceived("host3") 102 Expect(s.UnexpectedResponseFrom()).To(Equal([]string{"host3"})) 103 }) 104 }) 105 106 Describe("WaitingFor", func() { 107 It("Should report nodes correctly", func() { 108 s.SetDiscoveredNodes([]string{"host1", "host2"}) 109 Expect(s.outstandingNodes.Count()).To(Equal(2)) 110 Expect(s.outstandingNodes.HaveAny("host1", "host2")).To(BeTrue()) 111 Expect(s.WaitingFor([]string{"host1", "host2"})).To(BeTrue()) 112 Expect(s.WaitingFor([]string{"host3", "host4"})).To(BeFalse()) 113 }) 114 }) 115 116 Describe("SetDiscoveredNodes", func() { 117 It("Should set the node and outstanding nodes", func() { 118 s.outstandingNodes.AddHosts("host100") 119 s.SetDiscoveredNodes([]string{"host1", "host2"}) 120 Expect(s.discoveredNodes).To(Equal([]string{"host1", "host2"})) 121 122 o := s.outstandingNodes.Hosts() 123 sort.Strings(o) 124 Expect(o).To(Equal([]string{"host1", "host2"})) 125 }) 126 }) 127 128 Describe("FailedRequestInc", func() { 129 It("Should increase the count", func() { 130 Expect(s.failed).To(Equal(int32(0))) 131 s.FailedRequestInc() 132 Expect(s.failed).To(Equal(int32(1))) 133 }) 134 }) 135 136 Describe("PassedRequestInc", func() { 137 It("Should increase the count", func() { 138 Expect(s.passed).To(Equal(int32(0))) 139 s.PassedRequestInc() 140 Expect(s.passed).To(Equal(int32(1))) 141 }) 142 }) 143 144 Describe("RecordReceived", func() { 145 It("Should handle outstanding nodes", func() { 146 s.SetDiscoveredNodes([]string{"host1", "host2"}) 147 Expect(s.responses).To(Equal(int32(0))) 148 s.RecordReceived("host2") 149 Expect(s.responses).To(Equal(int32(1))) 150 Expect(s.NoResponseFrom()).To(Equal([]string{"host1"})) 151 }) 152 153 It("Should handle unexpected nodes", func() { 154 s.SetDiscoveredNodes([]string{"host1", "host2"}) 155 Expect(s.responses).To(Equal(int32(0))) 156 s.RecordReceived("host3") 157 Expect(s.responses).To(Equal(int32(1))) 158 Expect(s.UnexpectedResponseFrom()).To(Equal([]string{"host3"})) 159 }) 160 }) 161 162 Describe("DiscoveredCount", func() { 163 It("Should return the right length", func() { 164 Expect(s.DiscoveredCount()).To(Equal(0)) 165 s.SetDiscoveredNodes([]string{"host1", "host2"}) 166 Expect(s.DiscoveredCount()).To(Equal(2)) 167 }) 168 }) 169 170 Describe("FailCount", func() { 171 It("Should return the right length", func() { 172 Expect(s.FailCount()).To(Equal(0)) 173 s.FailedRequestInc() 174 Expect(s.FailCount()).To(Equal(1)) 175 }) 176 }) 177 178 Describe("OKCount", func() { 179 It("Should return the right length", func() { 180 Expect(s.OKCount()).To(Equal(0)) 181 s.PassedRequestInc() 182 Expect(s.OKCount()).To(Equal(1)) 183 }) 184 }) 185 186 Describe("ResponsesCount", func() { 187 It("Should return the right length", func() { 188 Expect(s.ResponsesCount()).To(Equal(0)) 189 s.RecordReceived("host1") 190 Expect(s.ResponsesCount()).To(Equal(1)) 191 }) 192 }) 193 194 Describe("StartPublish", func() { 195 It("Should start the clock if it has not yet started", func() { 196 Expect(s.publishStart).To(BeZero()) 197 s.StartPublish() 198 199 t := s.publishStart 200 Expect(t).ToNot(BeZero()) 201 202 s.StartPublish() 203 Expect(s.publishStart).To(Equal(t)) 204 }) 205 }) 206 207 Describe("EndPublish", func() { 208 It("Should end the publishing if its not already ended", func() { 209 Expect(s.publishEnd).To(BeZero()) 210 s.StartPublish() 211 s.EndPublish() 212 213 t := s.publishEnd 214 Expect(t).ToNot(BeZero()) 215 216 s.EndPublish() 217 Expect(s.publishEnd).To(Equal(t)) 218 }) 219 }) 220 221 Describe("PublishDuration", func() { 222 It("Should handle in-progress or not yet started requests", func() { 223 _, err := s.PublishDuration() 224 Expect(err).To(MatchError("publishing is not completed")) 225 226 s.StartPublish() 227 _, err = s.PublishDuration() 228 Expect(err).To(MatchError("publishing is not completed")) 229 230 s.publishStart = time.Now().Add(-10 * time.Second) 231 232 Expect(s.publishStart).ToNot(BeZero()) 233 Expect(s.publishing).To(BeTrue()) 234 Expect(s.publishEnd).To(BeZero()) 235 236 s.EndPublish() 237 238 Expect(s.publishEnd).ToNot(BeZero()) 239 Expect(s.publishing).To(BeFalse()) 240 241 _, err = s.PublishDuration() 242 Expect(err).ToNot(HaveOccurred()) 243 }) 244 245 It("Should determine the correct duration", func() { 246 t := time.Now() 247 248 s.StartPublish() 249 s.publishStart = t.Add(-10 * time.Second) 250 s.EndPublish() 251 252 Expect(s.PublishDuration()).To(BeNumerically("~", 10*time.Second, 100*time.Millisecond)) 253 }) 254 255 It("Should support multiple publishes", func() { 256 t := time.Now() 257 258 s.StartPublish() 259 s.publishStart = t.Add(-10 * time.Second) 260 s.EndPublish() 261 262 t = time.Now() 263 s.StartPublish() 264 s.publishStart = t.Add(-10 * time.Second) 265 s.EndPublish() 266 267 Expect(s.PublishDuration()).To(BeNumerically("~", 20*time.Second, 100*time.Millisecond)) 268 }) 269 }) 270 271 Describe("Start", func() { 272 It("Should start the clock if its not already started", func() { 273 Expect(s.start).To(BeZero()) 274 s.Start() 275 t := s.start 276 s.Start() 277 Expect(s.start).To(Equal(t)) 278 }) 279 }) 280 281 Describe("End", func() { 282 It("Should end the clock if its not already end", func() { 283 Expect(s.end).To(BeZero()) 284 s.End() 285 t := s.end 286 s.End() 287 Expect(s.end).To(Equal(t)) 288 }) 289 }) 290 291 Describe("RequestDuration", func() { 292 It("Should detect unfinished requests", func() { 293 s.Start() 294 _, err := s.RequestDuration() 295 Expect(err).To(MatchError("request is not completed")) 296 }) 297 298 It("Should handle completed requests", func() { 299 s.Start() 300 s.start = time.Now().Add(-1 * time.Second) 301 s.End() 302 d, err := s.RequestDuration() 303 Expect(err).ToNot(HaveOccurred()) 304 Expect(d).To(BeNumerically("~", time.Second, 50*time.Millisecond)) 305 }) 306 }) 307 }) 308 })