Add tests

This commit is contained in:
Ticruz
2025-02-04 13:21:23 +01:00
committed by Jon Staab
parent 917727c86f
commit 8a2b62f693
57 changed files with 9231 additions and 25 deletions
@@ -0,0 +1,220 @@
import {ctx} from "@welshman/lib"
import {AuthMode} from "@welshman/net"
import {SignedEvent} from "@welshman/util"
import {beforeEach, describe, expect, it, vi} from "vitest"
import {Connection} from "../src/Connection"
import {ConnectionEvent} from "../src/ConnectionEvent"
import {ConnectionStats} from "../src/ConnectionStats"
describe("ConnectionStats", () => {
let connection: Connection
let stats: ConnectionStats
beforeEach(() => {
vi.useFakeTimers()
connection = new Connection("wss://test.relay/")
stats = connection.stats
ctx.net = {...ctx.net, authMode: AuthMode.Explicit}
})
describe("connection events tracking", () => {
it("should track socket open events", () => {
const now = Date.now()
connection.emit(ConnectionEvent.Open, connection)
expect(stats.openCount).toBe(1)
expect(stats.lastOpen).toBeGreaterThanOrEqual(now)
})
it("should track socket close events", () => {
const now = Date.now()
connection.emit(ConnectionEvent.Close, connection)
expect(stats.closeCount).toBe(1)
expect(stats.lastClose).toBeGreaterThanOrEqual(now)
})
it("should track socket error events", () => {
const now = Date.now()
connection.emit(ConnectionEvent.Error, connection)
expect(stats.errorCount).toBe(1)
expect(stats.lastError).toBeGreaterThanOrEqual(now)
})
it("should accumulate multiple events", () => {
connection.emit(ConnectionEvent.Open, connection)
connection.emit(ConnectionEvent.Close, connection)
connection.emit(ConnectionEvent.Open, connection)
connection.emit(ConnectionEvent.Error, connection)
expect(stats.openCount).toBe(2)
expect(stats.closeCount).toBe(1)
expect(stats.errorCount).toBe(1)
})
})
describe("message tracking", () => {
describe("outgoing messages", () => {
it("should track REQ messages", () => {
const now = Date.now()
connection.emit(ConnectionEvent.Send, ["REQ", "id1"])
expect(stats.requestCount).toBe(1)
expect(stats.lastRequest).toBeGreaterThanOrEqual(now)
})
it("should track EVENT messages", () => {
const now = Date.now()
connection.emit(ConnectionEvent.Send, ["EVENT", {id: "123"}])
expect(stats.publishCount).toBe(1)
expect(stats.lastPublish).toBeGreaterThanOrEqual(now)
})
})
describe("incoming messages", () => {
it("should track received EVENT messages", () => {
const now = Date.now()
connection.emit(ConnectionEvent.Receive, ["EVENT", {id: "123"}])
expect(stats.eventCount).toBe(1)
expect(stats.lastEvent).toBeGreaterThanOrEqual(now)
})
it("should track AUTH messages", () => {
const now = Date.now()
connection.emit(ConnectionEvent.Receive, ["AUTH", "challenge"])
expect(stats.lastAuth).toBeGreaterThanOrEqual(now)
})
it("should track NOTICE messages", () => {
connection.emit(ConnectionEvent.Receive, ["NOTICE", "test"])
expect(stats.noticeCount).toBe(1)
})
})
})
describe("publish tracking", () => {
beforeEach(() => {
// Setup a pending publish
connection.state.pendingPublishes.set("123", {
sent: Date.now() - 1000, // 1 second ago
event: {id: "123"} as SignedEvent,
})
})
it("should track successful publishes", () => {
connection.emit(ConnectionEvent.Receive, ["OK", "123", true])
expect(stats.publishSuccessCount).toBe(1)
expect(stats.publishFailureCount).toBe(0)
expect(stats.publishTimer).toBeGreaterThan(0)
})
it("should track failed publishes", () => {
connection.emit(ConnectionEvent.Receive, ["OK", "123", false])
expect(stats.publishSuccessCount).toBe(0)
expect(stats.publishFailureCount).toBe(1)
expect(stats.publishTimer).toBeGreaterThan(0)
})
it("should accumulate publish timing", () => {
const firstTimer = stats.publishTimer
// First publish took 1000ms
connection.emit(ConnectionEvent.Receive, ["OK", "123", true])
// Second publish took 2000ms
connection.state.pendingPublishes.set("456", {
sent: Date.now() - 2000,
event: {id: "456"} as SignedEvent,
})
connection.emit(ConnectionEvent.Receive, ["OK", "456", true])
expect(stats.publishTimer).toBe(firstTimer + 1000 + 2000)
expect(stats.publishSuccessCount).toBe(2)
})
it("should not increment publish timer for unknown publishes", () => {
connection.emit(ConnectionEvent.Receive, ["OK", "unknown", true])
expect(stats.publishSuccessCount).toBe(1)
expect(stats.publishFailureCount).toBe(0)
expect(stats.publishTimer).toBe(0)
})
})
describe("EOSE tracking", () => {
beforeEach(() => {
// Setup a pending request
connection.state.pendingRequests.set("req1", {
sent: Date.now() - 1000,
filters: [],
})
})
it("should track first EOSE for a request", () => {
connection.emit(ConnectionEvent.Receive, ["EOSE", "req1"])
expect(stats.eoseCount).toBe(1)
expect(stats.eoseTimer).toBeGreaterThan(0)
})
it("should ignore subsequent EOSE for same request", () => {
// Mark request as already EOSE'd
connection.state.pendingRequests.set("req1", {
sent: Date.now() - 1000,
filters: [],
eose: true,
})
connection.emit(ConnectionEvent.Receive, ["EOSE", "req1"])
expect(stats.eoseCount).toBe(0)
expect(stats.eoseTimer).toBe(0)
})
it("should accumulate EOSE timing", () => {
// First EOSE took 1000ms
connection.emit(ConnectionEvent.Receive, ["EOSE", "req1"])
const firstTimer = stats.eoseTimer
// Setup second request that takes 2000ms
connection.state.pendingRequests.set("req2", {
sent: Date.now() - 2000,
filters: [],
})
connection.emit(ConnectionEvent.Receive, ["EOSE", "req2"])
expect(stats.eoseTimer).toBe(firstTimer + 2000)
expect(stats.eoseCount).toBe(2)
})
})
describe("speed calculations", () => {
it("should calculate request speed", () => {
stats.eoseCount = 2
stats.eoseTimer = 3000 // 3 seconds total for 2 requests
expect(stats.getRequestSpeed()).toBe(1500) // 1.5 seconds average
})
it("should return 0 request speed when no EOSE received", () => {
expect(stats.getRequestSpeed()).toBe(0)
})
it("should calculate publish speed", () => {
stats.publishSuccessCount = 2
stats.publishTimer = 4000 // 4 seconds total for 2 publishes
expect(stats.getPublishSpeed()).toBe(2000) // 2 seconds average
})
it("should return 0 publish speed when no successful publishes", () => {
expect(stats.getPublishSpeed()).toBe(0)
})
})
})