Stop the slow test packages waiting (closes #263)
check / check (push) Failing after 1m9s

The slowest test packages spent their time waiting rather than testing.

db.Params gains an optional PasswordCost (zero means bcrypt.DefaultCost), and the db, ircserver and handlers tests hash at bcrypt.MinCost. A test IRC server's relay checks its queue on broker notification instead of polling. The service and handlers tests build config.Config directly and run in parallel; config exports DefaultTrustedProxies and ParseTrustedProxies for them. Fixed sleeps give way to waits for the event. Production defaults are unchanged.

What still takes time is CPU work under -race or a timeout a test is about.

Model: opus-5-5
This commit was merged in pull request #267.
This commit is contained in:
clawbot committed 2026-11-11 01:15:43 +01:00
1 parent 847f5c6fec
commit ed5125606a
15 files changed
+558 -261

No files matched your search

+63 -1
View File
@@ -9,6 +9,7 @@ import (
"time"
"golang.org/x/crypto/bcrypt"
"sneak.berlin/go/neoirc/internal/config"
"sneak.berlin/go/neoirc/internal/dbtest"
"sneak.berlin/go/neoirc/internal/ircserver"
"sneak.berlin/go/neoirc/internal/service"
@@ -58,7 +59,11 @@ func (env *testEnv) queueMessage(
func TestRelayKeepsOneWaitChannel(t *testing.T) {
t.Parallel()
env := newTestEnv(t)
env := newTestEnvWithResolver(
t, &config.Config{ServerName: testServerName},
ircserver.PingInterval, ircserver.PongDeadline,
ircserver.PollInterval, ircserver.ResolveHost,
)
client := env.dial(t)
client.register("idle")
@@ -119,6 +124,63 @@ func (env *testEnv) checkOneWaitChannel(
}
}
// TestRelayDeliversAfterFailedRead checks that when the relay
// cannot read the client output queue, it waits for the next
// notification, and delivers once the queue can be read again.
func TestRelayDeliversAfterFailedRead(t *testing.T) {
t.Parallel()
env := newTestEnv(t)
client := env.dial(t)
client.register("reader")
sessionID, err := env.database.GetSessionByNick(t.Context(), "reader")
if err != nil {
t.Fatalf("get session of reader: %v", err)
}
dbtest.Exec(t, env.dbURL,
"ALTER TABLE client_queues RENAME TO hidden_queues")
// Each pass of the relay takes a wait channel and then reads
// the queue. Once it holds a channel after the second
// notification, the read after the first one has failed.
for range 2 {
env.waitForWaitChannel(t, sessionID)
env.brk.Notify(sessionID)
}
env.waitForWaitChannel(t, sessionID)
dbtest.Exec(t, env.dbURL,
"ALTER TABLE hidden_queues RENAME TO client_queues")
env.queueMessage(
t, "reader", "PRIVMSG", "carol", "reader", []string{"readable"},
)
client.readUntil(func(l string) bool {
return strings.Contains(l, "readable")
})
}
// waitForWaitChannel waits until the session sessionID holds a
// broker wait channel, and fails the test if it does not
// within testTimeout.
func (env *testEnv) waitForWaitChannel(t *testing.T, sessionID int64) {
t.Helper()
deadline := time.Now().Add(testTimeout)
for env.brk.ListenerCount(sessionID) == 0 {
if time.Now().After(deadline) {
t.Fatal("the relay is not waiting for a notification")
}
time.Sleep(relayCheckStep)
}
}
// TestRelayMultiLineBody checks that each line of a PRIVMSG
// or NOTICE body sent over the HTTP API reaches an IRC
// listener user as its own line.