Files
onvif/event/stream/helpers_test.go
Sebastian Norling c6cad2c35d test(event/stream): close review-2 coverage gaps
Adds the missing test coverage flagged by the test-rigor reviewer.

Coverage / behaviour
--------------------
* TestClose_ReturnsUnsubscribeError: previously closeErr plumbing was
  effectively dead code in the suite. Inject an Unsubscribe failure
  and assert the error wraps it.
* TestNewStream_CtxAlreadyCancelled: pins the behaviour for a
  pre-cancelled parent context (construction succeeds because
  createPullPoint does not consult ctx; run goroutine exits
  immediately and Events closes).
* TestStream_DisableReconnectKeepsRetryingOriginalEndpoint: proves
  the new opt-out actually disables CreatePullPoint recreate.
* TestStream_RecreateResetsFailuresAndBackoffOnSuccess: locks the
  attemptRecreate success path resetting *failures and *backoff so a
  later failure does not accidentally enter exponential backoff
  immediately.

Race detection
--------------
* TestStream_PullPointMutationVisibleToRenewLoopUnderRace: drives the
  pullPoint write-by-pullLoop / read-by-renewLoop race so -race
  actually exercises the mutex critical sections. Previously the
  mutex was structurally correct but no test produced contention.

Decoder edge cases
------------------
* TestDecode_PropertyOperationIsCaseSensitive: per WS-Notification
  §3.3, values are PascalCase. Lowercased forms fall through to
  PropertyUnknown.
* TestDecode_StateValueTrimsWhitespace: explicit assertions for
  '  true  ', tabs, newlines and whitespace-only.
* TestDecode_SimpleItemEmptyValueIsUnknownState: empty value yields
  StateUnknown but the empty entry is still preserved in Data map.
* TestDecode_DeviceTimeAdditionalLayouts: the +0200 compact offset
  and naked-no-TZ formats added in the hardening commit.
* TestDecode_DeviceTimeStillRejectsNonsense: the broader layout list
  did not start accepting garbage.
* TestExtractState_FirstBooleanLikeWins: uses explicit slice
  construction (pair{k,v} -> SimpleItem) so the assertion does not
  depend on map iteration order, the latent flake risk in the AOA
  test pointed out by the reviewer.

Helpers
-------
* helpers_test.go waitFor(t, d, msg, cond) centralises the
  10ms-poll-until-deadline pattern that previously appeared four
  times across stream_test / renew_test / reconnect_test.
* TestFakeCaller_QueueThenDefaultFallback: self-test for the fake.
  When the fake grows to 100+ LOC, debugging a flaky stream test
  should not also require investigating whether the fake itself
  behaves correctly.
2026-05-21 15:01:35 +02:00

22 lines
522 B
Go

package stream
import (
"testing"
"time"
)
// waitFor polls cond at 10ms intervals up to d. Fails the test with msg
// if cond never returns true. Centralises the pattern that appears in
// renew/reconnect/stream tests so retries are uniform.
func waitFor(t *testing.T, d time.Duration, msg string, cond func() bool) {
t.Helper()
deadline := time.Now().Add(d)
for time.Now().Before(deadline) {
if cond() {
return
}
time.Sleep(10 * time.Millisecond)
}
t.Fatalf("waitFor timed out after %s: %s", d, msg)
}