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
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
${{ runner.os }}-npm-

- name: Install dependencies
run: npm install
run: npm ci

- name: Start Docker Compose services
run: docker compose -f docker-compose.test.yml up -d --wait
Expand Down
22 changes: 16 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,22 +96,27 @@ An instrumentation needs custom ESM support if it:
**Why**: In ESM, default exports are in the `.default` property of the namespace object, not directly accessible.

**Example** (postgres):

- **CommonJS**: `const postgres = require('postgres')` → `postgres` IS the function
- **ESM**: `import postgres from 'postgres'` → `postgres.default` IS the function

**Detection**:

```typescript
const isESM = (moduleExports as any)[Symbol.toStringTag] === 'Module';
const isESM = (moduleExports as any)[Symbol.toStringTag] === "Module";
```

**Solution**:

```typescript
if (isESM) {
// Wrap the .default property
this._wrap(moduleExports, 'default', wrapper);
this._wrap(moduleExports, "default", wrapper);
} else {
// Create wrapped function and return it
const wrappedFn = function(...args) { /* ... */ };
const wrappedFn = function (...args) {
/* ... */
};
// Copy all properties...
return wrappedFn;
}
Expand Down Expand Up @@ -145,19 +150,22 @@ Each instrumentation typically:
We have unit tests and integration tests with [ava](https://github.com/avajs/ava).
Some integration tests (pg, mongo, etc.) require external dependencies.
A docker compose is provided for you to get these dependencies up easily:
```

```yaml
docker compose -f docker-compose.test.yml up -d --wait
```

After it's done setting up you can run `npm test` as usual.
You can leave it up, and tests should clean up after themselves so that we can
leave these services up during development without restarting all the time.
To bring them down, run
```

```yaml
docker compose -f docker-compose.test.yml down
```

Some important notes during testing, especially integration tests:

- The tusk sdk needs to be initialized before importing anything that is going
to be patched.
- Since the TuskDrift object is a singleton, each integration test (or at least
Expand All @@ -173,14 +181,14 @@ Some important notes during testing, especially integration tests:
The SDK includes comprehensive end-to-end (E2E) tests that verify instrumentations work correctly in real Docker environments. These tests record actual network traffic and replay it to ensure consistent behavior.

**Quick Overview:**

- E2E tests are located in `src/instrumentation/libraries/{library}/e2e-tests/`
- Each test runs in a Docker container with the full SDK
- Tests record network interactions, then replay them to verify correctness
- Use these tests when debugging instrumentation issues or adding new features

**For detailed instructions on running and debugging E2E tests, see the [E2E Testing Guide](./E2E_TESTING_GUIDE.md).**


#### Code Quality

- Follow existing code patterns and conventions
Expand All @@ -203,12 +211,14 @@ The SDK communicates with the Tusk CLI using socket connections, supporting both
### Connection Types

#### Unix Socket (Default)

- **Use case**: Local development and non-containerized environments
- **How it works**: SDK connects to the CLI via a Unix domain socket file
- **Environment variable**: `TUSK_MOCK_SOCKET` (optional, defaults to `/tmp/tusk-connect.sock`)
- **Benefits**: Lower overhead, faster communication for same-machine connections

#### TCP Socket (Docker/Remote)

- **Use case**: Dockerized applications where Unix sockets can't be shared
- **How it works**: SDK connects to the CLI via TCP (host:port)
- **Environment variables**:
Expand Down
13 changes: 12 additions & 1 deletion E2E_TESTING_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The SDK instruments various Node.js libraries (http, https, fetch, pg, postgres,
## Purpose of This Guide

This guide provides step-by-step instructions for iterating on SDK instrumentations when debugging E2E tests. Use this when:

- An E2E test endpoint is failing
- You need to debug or fix instrumentation code
- You want to verify that SDK changes work correctly
Expand All @@ -18,6 +19,7 @@ This guide provides step-by-step instructions for iterating on SDK instrumentati
E2E tests are located in `src/instrumentation/libraries/{library}/e2e-tests/{module-type}-{library}/`:

Each test directory contains:

- `src/` - Test application source code
- `Dockerfile` - Container configuration
- `docker-compose.yml` - Container orchestration
Expand All @@ -33,6 +35,7 @@ cd src/instrumentation/libraries/{library}/e2e-tests/{test-name}
```

Example:

```bash
cd src/instrumentation/libraries/http/e2e-tests/cjs-http
```
Expand Down Expand Up @@ -65,6 +68,7 @@ docker-compose exec -e TUSK_DRIFT_MODE=RECORD app sh -c "npm run build && npm ru
```

Wait a few seconds for the server to fully start (5-10 seconds recommended):

```bash
sleep 5
```
Expand Down Expand Up @@ -111,18 +115,21 @@ docker-compose exec -T app tusk run --print --output-format "json" --enable-serv
```

**Flags explained:**

- `--print` - Print test results to stdout
- `--output-format "json"` - Output results in JSON format
- `--enable-service-logs` - Write detailed service logs to `.tusk/logs/` for debugging

To see all available flags, run:

```bash
tusk run --help
```

**Interpreting Results:**

The output will be JSON with test results:

```json
[
{
Expand Down Expand Up @@ -156,9 +163,11 @@ When you need to fix instrumentation code:

1. **Make changes to the SDK source code**
2. **Rebuild the SDK** from the repository root:

```bash
npm run build
```

3. **NO need to rebuild Docker containers** - the SDK is mounted as a volume, so changes propagate automatically
4. **Clean up traces and logs** (Step 2)
5. **Restart the server in RECORD mode** (Step 4)
Expand All @@ -182,10 +191,11 @@ The Docker Compose configuration mounts the SDK source code as a read-only volum

```yaml
volumes:
- ../../../../../..:/sdk:ro # SDK source mounted at /sdk
- ../../../../../..:/sdk:ro # SDK source mounted at /sdk
```

This means:

- ✅ **SDK changes propagate automatically** - no need to rebuild containers
- ✅ **Fast iteration** - just run `npm run build` in the SDK root
- ❌ **Must rebuild SDK** - changes won't take effect until you run `npm run build`
Expand All @@ -212,6 +222,7 @@ Each E2E test directory has a `run.sh` script that automates the entire workflow
```

This script:

1. Cleans traces and logs
2. Starts containers
3. Starts server in RECORD mode
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ For comprehensive guides and API reference, visit our [full documentation](https
Tusk Drift currently supports the following packages and versions:

- **HTTP/HTTPS**: All versions (Node.js built-in)
- **GRPC**: `@grpc/grpc-js@1.x` (Outbound requests only)
- **PG**: `pg@8.x`, `pg-pool@2.x-3.x`
- **Postgres**: `postgres@3.x`
- **MySQL**: `mysql2@3.x`
Expand Down
15 changes: 15 additions & 0 deletions docker-compose.test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,18 @@ services:
interval: 5s
timeout: 5s
retries: 5

grpc-server:
image: node:20
working_dir: /workspace
volumes:
- .:/workspace
command: sh -c "apt-get update && apt-get install -y netcat-openbsd && node /workspace/src/instrumentation/libraries/grpc/integration-tests/server.cjs"
ports:
- "50051:50051"
healthcheck:
test: ["CMD", "nc", "-z", "localhost", "50051"]
interval: 5s
timeout: 5s
retries: 10
start_period: 10s
Loading