Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .github/workflows/unit-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Unit test

on:
push:

jobs:
build-and-test:
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [20, 22]

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run linter
run: npm run lint

- name: Build TypeScript
run: npm run build

- name: Run tests
run: npm test
42 changes: 42 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Build and Development Commands

```bash
npm run build # Compile TypeScript to dist/
npm start -- <cmd> # Run CLI commands (e.g., npm start -- listen-udp -p 8000)
npm run dev # Build and run in one step
npm test # Run unit tests
npm run lint # Run ESLint
```

## Linting

Uses ESLint 8 with airbnb-base config for both linting and code style. Key rules:
- Space before function parens: `function name ()` not `function name()`
- Import extensions: `.js` required for local imports, not for `.ts`

```bash
npx eslint src/ # Run linter
```

## Architecture

This is a TypeScript CLI tool for sending/receiving OSC (Open Sound Control) messages over UDP and TCP. Built with Commander.js for CLI parsing and the `osc` npm package for protocol handling.

**Entry Point:** `src/cli.ts` - Defines all commands using Commander, configures logging via `@sndwrks/lumberjack`

**Four functional modules:**
- `src/osc-servers/` - UDP and TCP listeners that log incoming OSC messages
- `src/osc-senders/` - Single message senders for UDP and TCP
- `src/osc-load-test/` - Batch load testing using factory pattern (`createOscUdpLoadTest`, `createOscTcpLoadTest`)
- `src/osc-test/` - Integration testing: send to remote app, validate responses (`createOscUdpTest`, `createOscTcpTest`)

**Type definitions:** `src/types/` contains ambient declarations for the `osc` package and shared types

**Key patterns:**
- All functions receive a `Logger` instance as first parameter
- UDP uses default port 51000, TCP uses 51001
- Load testers use recursive functions with setTimeout for message rate control
82 changes: 82 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ A simple command-line application for sending and receiving OSC (Open Sound Cont
- Send OSC messages via TCP
- Load Testing with UDP
- Load Testing with TCP
- Integration Testing with UDP (send to app, validate response)
- Integration Testing with TCP (send to app, validate response)

## Installation

Expand Down Expand Up @@ -209,6 +211,86 @@ osc-cli osc-load-test-tcp \
--custom-address /my/custom/address
```

### Integration Testing

Integration testing commands send messages to a remote application and validate the responses. The remote application should echo back OSC messages to the local listener port.

#### Args

| Flag | Option | Type | Required | Description | Example | Default |
|------|--------|------|----------|-------------|---------|---------|
| `-i` | `--remote-ip-address <ip>` | string | Yes | Remote IP to send messages to | 10.10.209.5 | |
| `-p` | `--remote-port <port>` | number | Yes | Remote port to send messages to | 8000 | |
| | `--mode <mode>` | string | Yes | Test mode: "single" or "load" | single | |
| | `--local-ip-address <ip>` | string | No | Local IP to listen for responses | | 0.0.0.0 |
| | `--local-port <port>` | number | No | Local port to listen for responses | | 57120 (UDP) / 57121 (TCP) |
| `-a` | `--address <address>` | string | No | OSC address to send | /test | /test |
| | `--args <args...>` | string[] | No | Arguments to send | hello 123 | |
| | `--expected-address <address>` | string | No | Expected response address | /response | sent address |
| | `--expected-args <args...>` | string[] | No | Expected response args | ok 1 | sent args |
| | `--timeout <ms>` | number | No | Response timeout | | 5000 |
| | `--messages-per-batch <n>` | number | No | Messages per batch (load mode) | | |
| | `--total-batches <n>` | number | No | Total batches (load mode) | | |
| | `--batch-interval <seconds>` | number | No | Interval between batches (load mode) | | |
| | `--message-rate <n>` | number | No | Messages per second (load mode) | | |

**UDP Integration Test (single message):**
```bash
# Send a message and validate the response matches
osc-cli test-osc-udp \
--mode single \
-i 127.0.0.1 \
-p 8000 \
-a /test \
--args hello 123

# With custom expected response
osc-cli test-osc-udp \
--mode single \
-i 127.0.0.1 \
-p 8000 \
-a /ping \
--expected-address /pong \
--expected-args ok
```

**UDP Integration Test (load test):**
```bash
# Load test with throughput validation
osc-cli test-osc-udp \
--mode load \
-i 127.0.0.1 \
-p 8000 \
--messages-per-batch 100 \
--total-batches 10 \
--batch-interval 1
```

**TCP Integration Test (single message):**
```bash
osc-cli test-osc-tcp \
--mode single \
-i 127.0.0.1 \
-p 8001 \
-a /test \
--args hello 123
```

**TCP Integration Test (load test):**
```bash
osc-cli test-osc-tcp \
--mode load \
-i 127.0.0.1 \
-p 8001 \
--messages-per-batch 50 \
--total-batches 5 \
--batch-interval 2 \
--message-rate 100
```

**Exit codes:**
- `0` - Test passed (single: response matched; load: no dropped messages)
- `1` - Test failed (timeout, mismatch, or dropped messages)

## Development

Expand Down
Loading