refactor(jitsi): clean up linter suppressions and test helpers

This commit is contained in:
zarazaex69
2026-06-01 15:44:59 +03:00
parent 2cff30d55e
commit 5dd6822d80
4 changed files with 43 additions and 38 deletions
+3 -7
View File
@@ -55,11 +55,7 @@ const (
// Without this, the peer's own recovery (which produces a fresh epoch)
// drives us into an infinite reconnect loop.
reconnectGrace = 20 * time.Second
// stableUptime is how long the bridge must stay healthy before the
// reconnectCount is reset. Without this, healthy reconnects accumulated
// over hours of operation eventually cross maxReconnects and the engine
// gives up on a perfectly recoverable failure.
stableUptime = 60 * time.Second
// xmppKeepaliveInterval keeps the underlying XMPP transport alive while
// we wait for a peer. BOSH has no built-in stream management; without
// any application traffic Prosody closes the BOSH session after roughly
@@ -666,7 +662,7 @@ func (s *Session) negotiatePC(ctx context.Context, jSess *j.Session, sctpBridge
// after the default 1-minute inactivity timeout, which causes JVB to
// shut down the DTLS session and emit close_notify.
s.wg.Add(1)
go s.rtcpKeepalive(pcCtx, pc)
go s.rtcpKeepalive(pcCtx, pc) //nolint:contextcheck // pcCtx intentionally derives from s.runCtx to outlive this call
return nil
}
@@ -1297,7 +1293,7 @@ func (s *Session) inReconnectGrace() bool {
// magic. A non-olcrtc participant in the same MUC (a regular Jitsi web
// client, an unrelated bot, etc.) gets filtered out before we ever
// get here.
func (s *Session) peerLatchAccepts(from string) bool {
func (s *Session) peerLatchAccepts(from string) bool { //nolint:unparam // filter contract; always-true is policy
if cur := s.peerEndpoint.Load(); cur != nil {
if *cur == from {
return true
+2 -2
View File
@@ -180,11 +180,11 @@ func TestSanitiseNick(t *testing.T) {
raw string
want string
}{
{"alice", "alice"},
{nameAlice, nameAlice},
{"Alice Smith", "Alice-Smith"},
{"Конрад Олег", "Konrad-Oleg"},
{"olcrtc-bot42", "olcrtc-bot42"},
{" bob ", "bob"},
{" bob ", nameBob},
{"$$$ %%%", ""},
{"verylongnicknamethatexceedslimit", "verylongnicknamet"[:16]},
}
+1 -1
View File
@@ -282,7 +282,7 @@ func TestRequestReconnectIdempotent(t *testing.T) {
js.SetShouldReconnect(func() bool { return true })
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
for range 10 {
wg.Add(1)
go func() {
defer wg.Done()
+37 -28
View File
@@ -48,12 +48,12 @@ package jitsi
import (
"context"
"errors"
"fmt"
"math/rand"
"os"
"strings"
"sync"
"sync/atomic"
"testing"
"time"
@@ -67,6 +67,16 @@ const (
envPairedIdle = "OLCRTC_JITSI_PAIRED_IDLE"
envPairedChaosInterval = "OLCRTC_JITSI_PAIRED_CHAOS_INTERVAL"
envPairedVerbose = "OLCRTC_JITSI_PAIRED_VERBOSE"
nameAlice = "alice"
nameBob = "bob"
)
var (
errCastFailed = errors.New("cast to *Session failed")
errBridgeTimeout = errors.New("bridge not ready before deadline")
errRoundtripTimeout = errors.New("roundtrip timeout")
errReceiveTimeout = errors.New("receive timeout")
)
type pairedConfig struct {
@@ -84,7 +94,7 @@ func (c *pairedConfig) durationLabel() string {
return c.duration.String()
}
func readPairedConfig(t *testing.T) *pairedConfig {
func readPairedConfig(t *testing.T) *pairedConfig { //nolint:cyclop // config parsing is naturally branchy
t.Helper()
host := strings.TrimSpace(os.Getenv(envPairedHost))
if host == "" {
@@ -153,10 +163,10 @@ func (p *pairedInstance) note(b []byte) {
p.mu.Unlock()
}
func (p *pairedInstance) snapshot() (count int64, lastAt time.Time) {
func (p *pairedInstance) snapshot() int64 {
p.mu.Lock()
defer p.mu.Unlock()
return p.receivedFromOther, p.lastReceiveAt
return p.receivedFromOther
}
// startInstance spins up one Session at a time so the second one is
@@ -178,7 +188,7 @@ func startInstance(ctx context.Context, t *testing.T, cfg *pairedConfig, name st
js, ok := sess.(*Session)
if !ok {
_ = sess.Close()
return nil, fmt.Errorf("%s: cast to *Session failed", name)
return nil, fmt.Errorf("%s: cast to *Session failed: %w", name, errCastFailed)
}
js.SetShouldReconnect(func() bool { return ctx.Err() == nil })
inst.js = js
@@ -201,11 +211,11 @@ func waitForBridge(ctx context.Context, inst *pairedInstance, deadline time.Time
}
select {
case <-ctx.Done():
return ctx.Err()
return fmt.Errorf("%s: wait for bridge: %w", inst.name, ctx.Err())
case <-time.After(time.Second):
}
}
return fmt.Errorf("%s: bridge not ready before deadline", inst.name)
return fmt.Errorf("%s: bridge not ready before deadline: %w", inst.name, errBridgeTimeout)
}
// pumpLoop sends a small heartbeat payload from `from` to the other
@@ -229,8 +239,8 @@ func pumpLoop(ctx context.Context, t *testing.T, from *pairedInstance, interval
seq++
buf := append([]byte(nil), payload...)
if len(buf) >= 8 {
for i := 0; i < 8; i++ {
buf[i] = byte(seq >> (8 * i))
for i := range 8 {
buf[i] = byte(seq >> (8 * i)) //nolint:gosec // intentional truncation to byte
}
}
if err := from.js.Send(buf); err != nil {
@@ -245,7 +255,6 @@ type pairedStats struct {
cycles int64
chaosKicks int64
wedgesPair int64 // periods where neither side received any data
maxObservedRttMs atomic.Int64
startedAt time.Time
lastChaosAt time.Time
bothSidesReceived bool
@@ -268,7 +277,7 @@ type pairedStats struct {
// - Either side hits ErrSessionClosed at the engine level
// (the closed flag is the canonical "we gave up" signal).
//
//nolint:cyclop // chaos cycle structure naturally branches on phase + side
//nolint:cyclop,gocognit // chaos cycle structure naturally branches on phase + side
func TestJitsiPairedChaosStress(t *testing.T) {
cfg := readPairedConfig(t)
infinite := cfg.duration == 0
@@ -289,7 +298,7 @@ func TestJitsiPairedChaosStress(t *testing.T) {
// Spin up Alice first so she's already in the room when Bob arrives —
// this guarantees min-participants triggers session-initiate.
alice, err := startInstance(ctx, t, cfg, "alice")
alice, err := startInstance(ctx, t, cfg, nameAlice)
if err != nil {
t.Fatalf("alice: %v", err)
}
@@ -298,7 +307,7 @@ func TestJitsiPairedChaosStress(t *testing.T) {
// Brief settle so Alice is fully in the MUC before Bob joins.
time.Sleep(2 * time.Second)
bob, err := startInstance(ctx, t, cfg, "bob")
bob, err := startInstance(ctx, t, cfg, nameBob)
if err != nil {
t.Fatalf("bob: %v", err)
}
@@ -374,10 +383,10 @@ func TestJitsiPairedChaosStress(t *testing.T) {
// === Phase B: pick a victim and chaos ===
victim := alice
victimName := "alice"
victimName := nameAlice
if rng.Intn(2) == 1 {
victim = bob
victimName = "bob"
victimName = nameBob
}
if cfg.verbose {
t.Logf("[paired][%d] CHAOS victim=%s — teardownPC + requestReconnect", stats.cycles, victimName)
@@ -393,10 +402,10 @@ func TestJitsiPairedChaosStress(t *testing.T) {
// engine has wedged.
recoveryBudget := cfg.idle + 60*time.Second
survivor := alice
survivorName := "alice"
survivorName := nameAlice
if victim == alice {
survivor = bob
survivorName = "bob"
survivorName = nameBob
}
if err := waitFreshReceive(ctx, survivor, recoveryBudget); err != nil {
stats.wedgesPair++
@@ -425,21 +434,21 @@ func TestJitsiPairedChaosStress(t *testing.T) {
func waitFirstReceive(ctx context.Context, a, b *pairedInstance, budget time.Duration) error {
deadline := time.Now().Add(budget)
for time.Now().Before(deadline) {
ac, _ := a.snapshot()
bc, _ := b.snapshot()
ac := a.snapshot()
bc := b.snapshot()
if ac > 0 && bc > 0 {
return nil
}
select {
case <-ctx.Done():
return ctx.Err()
return fmt.Errorf("wait first receive: %w", ctx.Err())
case <-time.After(500 * time.Millisecond):
}
}
ac, _ := a.snapshot()
bc, _ := b.snapshot()
return fmt.Errorf("did not see bidirectional roundtrip in %s (alice=%d bob=%d)",
budget, ac, bc)
ac := a.snapshot()
bc := b.snapshot()
return fmt.Errorf("did not see bidirectional roundtrip in %s (alice=%d bob=%d): %w",
budget, ac, bc, errRoundtripTimeout)
}
// waitFreshReceive blocks until target sees a NEW receive after this call,
@@ -447,20 +456,20 @@ func waitFirstReceive(ctx context.Context, a, b *pairedInstance, budget time.Dur
// bridge fully recovered: bytes are arriving from the (forced-to-reconnect)
// peer.
func waitFreshReceive(ctx context.Context, target *pairedInstance, budget time.Duration) error {
startCount, _ := target.snapshot()
startCount := target.snapshot()
deadline := time.Now().Add(budget)
for time.Now().Before(deadline) {
c, _ := target.snapshot()
c := target.snapshot()
if c > startCount {
return nil
}
select {
case <-ctx.Done():
return ctx.Err()
return fmt.Errorf("wait fresh receive: %w", ctx.Err())
case <-time.After(500 * time.Millisecond):
}
}
return fmt.Errorf("no new receive in %s (count stuck at %d)", budget, startCount)
return fmt.Errorf("no new receive in %s (count stuck at %d): %w", budget, startCount, errReceiveTimeout)
}
func reportPairedStats(t *testing.T, s *pairedStats, cfg *pairedConfig) {