diff options
| author | Jeff Halter <868228+jhalter@users.noreply.github.com> | 2026-07-10 09:48:18 -0700 |
|---|---|---|
| committer | Jeff Halter <868228+jhalter@users.noreply.github.com> | 2026-07-10 09:48:18 -0700 |
| commit | 21f24d24fd6f501b32f15a2bef41c89cc461f623 (patch) | |
| tree | ba4952fb82f3ef9c265228633f27536866e23931 /hotline/client_test.go | |
| parent | ae44fb222ec73cae8441f5a5d9a21f8585fe587f (diff) | |
Overhaul regression testing: e2e suite, fuzzing, CI, and bug fixes
Add a protocol-level end-to-end suite (in-process fully wired server on
an ephemeral port pair, driven by hotline.Client over TCP) covering
handshake, login, public and private chat, message board, threaded
news, file list/download/upload, account admin, disconnect
notification, and shutdown broadcast. The harness retries on a fresh
port pair when another process steals a probed port before
ListenAndServe binds it, and Server gains WithConnectionRateLimit so
tests can disable the per-IP connection throttle.
Add native fuzz tests for Transaction, Field, and flattened file
object decoding, and fix the bugs the new tests surfaced:
- Transaction.Write panicked on out-of-range attacker-controlled size
fields, and transactionScanner's uint32 length addition could wrap
and yield a truncated token. The information fork size declared in
an untrusted fork header is now bounded too.
- Client keepalive read c.done unsynchronized while Disconnect
replaces it under the mutex.
- The shared Agreement's Seek+ReadAll login path raced concurrent
logins; the server now prefers an AgreementBytes() snapshot.
Fill unit-test gaps (main's config-copy helpers, file resume data,
ReloaderFunc, R2 error injection and env validation) and add a CI test
workflow (build/vet + race-enabled shuffled suite), fixed lint
workflow triggers with golangci-lint v2.6, and Makefile test/cover/
lint/fuzz targets.
Diffstat (limited to 'hotline/client_test.go')
| -rw-r--r-- | hotline/client_test.go | 24 |
1 files changed, 12 insertions, 12 deletions
diff --git a/hotline/client_test.go b/hotline/client_test.go index 23b6155..fb5a3a9 100644 --- a/hotline/client_test.go +++ b/hotline/client_test.go @@ -21,8 +21,8 @@ func newTestClient() *Client { func TestClient_Handshake(t *testing.T) { t.Run("successful handshake", func(t *testing.T) { clientConn, serverConn := net.Pipe() - defer clientConn.Close() - defer serverConn.Close() + defer func() { _ = clientConn.Close() }() + defer func() { _ = serverConn.Close() }() c := newTestClient() c.Connection = clientConn @@ -41,8 +41,8 @@ func TestClient_Handshake(t *testing.T) { t.Run("server returns error response", func(t *testing.T) { clientConn, serverConn := net.Pipe() - defer clientConn.Close() - defer serverConn.Close() + defer func() { _ = clientConn.Close() }() + defer func() { _ = serverConn.Close() }() c := newTestClient() c.Connection = clientConn @@ -61,7 +61,7 @@ func TestClient_Handshake(t *testing.T) { t.Run("connection closed during read", func(t *testing.T) { clientConn, serverConn := net.Pipe() - defer clientConn.Close() + defer func() { _ = clientConn.Close() }() c := newTestClient() c.Connection = clientConn @@ -69,7 +69,7 @@ func TestClient_Handshake(t *testing.T) { go func() { buf := make([]byte, 12) _, _ = io.ReadFull(serverConn, buf) - serverConn.Close() + _ = serverConn.Close() }() err := c.Handshake() @@ -81,8 +81,8 @@ func TestClient_Handshake(t *testing.T) { func TestClient_Send(t *testing.T) { t.Run("sends non-reply transaction and tracks it", func(t *testing.T) { clientConn, serverConn := net.Pipe() - defer clientConn.Close() - defer serverConn.Close() + defer func() { _ = clientConn.Close() }() + defer func() { _ = serverConn.Close() }() c := newTestClient() c.Connection = clientConn @@ -104,8 +104,8 @@ func TestClient_Send(t *testing.T) { t.Run("reply transactions are not tracked", func(t *testing.T) { clientConn, serverConn := net.Pipe() - defer clientConn.Close() - defer serverConn.Close() + defer func() { _ = clientConn.Close() }() + defer func() { _ = serverConn.Close() }() c := newTestClient() c.Connection = clientConn @@ -195,7 +195,7 @@ func TestClient_HandleTransaction(t *testing.T) { func TestClient_Disconnect(t *testing.T) { t.Run("closes connection and done channel", func(t *testing.T) { clientConn, serverConn := net.Pipe() - defer serverConn.Close() + defer func() { _ = serverConn.Close() }() c := newTestClient() c.Connection = clientConn @@ -220,7 +220,7 @@ func TestClient_Disconnect(t *testing.T) { t.Run("handles nil done channel", func(t *testing.T) { clientConn, serverConn := net.Pipe() - defer serverConn.Close() + defer func() { _ = serverConn.Close() }() c := newTestClient() c.Connection = clientConn |