aboutsummaryrefslogtreecommitdiff
path: root/hotline/client_test.go
diff options
context:
space:
mode:
authorJeff Halter <868228+jhalter@users.noreply.github.com>2026-07-10 09:48:18 -0700
committerJeff Halter <868228+jhalter@users.noreply.github.com>2026-07-10 09:48:18 -0700
commit21f24d24fd6f501b32f15a2bef41c89cc461f623 (patch)
treeba4952fb82f3ef9c265228633f27536866e23931 /hotline/client_test.go
parentae44fb222ec73cae8441f5a5d9a21f8585fe587f (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.go24
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