Skip to content

Commit e62d7ac

Browse files
Merge pull request #75 from PostHog/jose-sequeira/sdk-compliance
feat: SDK Compliance
2 parents 1298b17 + ef28b46 commit e62d7ac

File tree

11 files changed

+614
-0
lines changed

11 files changed

+614
-0
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: SDK Compliance Tests
2+
3+
permissions:
4+
contents: read
5+
packages: read
6+
pull-requests: write
7+
8+
on:
9+
pull_request:
10+
push:
11+
branches:
12+
- master
13+
14+
jobs:
15+
compliance:
16+
name: PostHog SDK compliance tests
17+
uses: PostHog/posthog-sdk-test-harness/.github/workflows/test-sdk-action.yml@main
18+
with:
19+
adapter-dockerfile: "sdk_compliance_adapter/Dockerfile"
20+
adapter-context: "."
21+
test-harness-version: "latest"

sdk_compliance_adapter/Dockerfile

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Build stage - use Debian for better compatibility
2+
FROM elixir:1.17 AS builder
3+
4+
WORKDIR /app
5+
6+
# Install hex and rebar
7+
RUN mix local.hex --force && mix local.rebar --force
8+
9+
# Set build environment
10+
ENV MIX_ENV=prod
11+
12+
# Copy the main SDK source
13+
COPY mix.exs mix.lock ./
14+
COPY lib ./lib
15+
COPY config ./config
16+
17+
# Copy the adapter
18+
COPY sdk_compliance_adapter/mix.exs ./sdk_compliance_adapter/
19+
COPY sdk_compliance_adapter/lib ./sdk_compliance_adapter/lib
20+
COPY sdk_compliance_adapter/config ./sdk_compliance_adapter/config
21+
22+
# Fetch and compile dependencies for the adapter
23+
WORKDIR /app/sdk_compliance_adapter
24+
RUN mix deps.get --only prod
25+
RUN mix compile
26+
27+
# Build release
28+
RUN mix release
29+
30+
# Runtime stage - use same base as build to avoid OpenSSL mismatch
31+
FROM debian:bookworm-slim AS runtime
32+
33+
# Install runtime dependencies
34+
RUN apt-get update && apt-get install -y --no-install-recommends \
35+
libstdc++6 \
36+
openssl \
37+
libncurses6 \
38+
locales \
39+
&& rm -rf /var/lib/apt/lists/* \
40+
&& sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen \
41+
&& locale-gen
42+
43+
ENV LANG=en_US.UTF-8
44+
ENV LANGUAGE=en_US:en
45+
ENV LC_ALL=en_US.UTF-8
46+
47+
WORKDIR /app
48+
49+
# Copy the release from builder
50+
COPY --from=builder /app/sdk_compliance_adapter/_build/prod/rel/sdk_compliance_adapter ./
51+
52+
# Set environment
53+
ENV PORT=8080
54+
55+
EXPOSE 8080
56+
57+
CMD ["bin/sdk_compliance_adapter", "start"]

sdk_compliance_adapter/README.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# PostHog Elixir SDK Compliance Adapter
2+
3+
This adapter wraps the posthog-elixir SDK for compliance testing with the [PostHog SDK Test Harness](https://github.com/PostHog/posthog-sdk-test-harness).
4+
5+
## Running Tests
6+
7+
Tests run automatically in CI via GitHub Actions. See the test harness repo for details.
8+
9+
### Locally with Docker Compose
10+
11+
```bash
12+
# From the posthog-elixir/sdk_compliance_adapter directory
13+
docker-compose up --build --abort-on-container-exit
14+
```
15+
16+
This will:
17+
18+
1. Build the Elixir SDK adapter
19+
2. Pull the test harness image
20+
3. Run all compliance tests
21+
4. Show results
22+
23+
### Manually with Docker
24+
25+
```bash
26+
# Create network
27+
docker network create test-network
28+
29+
# Build and run adapter
30+
docker build -f sdk_compliance_adapter/Dockerfile -t posthog-elixir-adapter .
31+
docker run -d --name sdk-adapter --network test-network -p 8080:8080 posthog-elixir-adapter
32+
33+
# Run test harness
34+
docker run --rm \
35+
--name test-harness \
36+
--network test-network \
37+
ghcr.io/posthog/sdk-test-harness:latest \
38+
run --adapter-url http://sdk-adapter:8080 --mock-url http://test-harness:8081
39+
40+
# Cleanup
41+
docker stop sdk-adapter && docker rm sdk-adapter
42+
docker network rm test-network
43+
```
44+
45+
## Implementation
46+
47+
See [lib/sdk_compliance_adapter/](lib/sdk_compliance_adapter/) for the adapter implementation.
48+
49+
The adapter implements the standard SDK adapter interface defined in the [test harness CONTRACT](https://github.com/PostHog/posthog-sdk-test-harness/blob/main/CONTRACT.yaml).
50+
51+
### Architecture
52+
53+
The adapter is a standalone Elixir application that:
54+
55+
1. Starts an HTTP server (using Plug/Cowboy) on port 8080
56+
2. Dynamically starts/stops the PostHog SDK based on `/init` and `/reset` requests
57+
3. Uses a custom `TrackedClient` to intercept HTTP requests and track them for assertions
58+
4. Maintains state (events captured, sent, retries, etc.) for the test harness to query
59+
60+
### Endpoints
61+
62+
- `GET /health` - Health check, returns SDK name/version
63+
- `POST /init` - Initialize SDK with configuration
64+
- `POST /capture` - Capture a single event
65+
- `POST /flush` - Flush pending events
66+
- `GET /state` - Get internal state for test assertions
67+
- `POST /reset` - Reset SDK state
68+
69+
## Documentation
70+
71+
For complete documentation, see:
72+
73+
- [PostHog SDK Test Harness](https://github.com/PostHog/posthog-sdk-test-harness)
74+
- [Adapter Implementation Guide](https://github.com/PostHog/posthog-sdk-test-harness/blob/main/ADAPTER_GUIDE.md)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import Config
2+
3+
# Disable default PostHog startup - we manage it dynamically
4+
config :posthog, enable: false
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
version: "3.8"
2+
3+
services:
4+
# PostHog Elixir SDK adapter
5+
sdk-adapter:
6+
build:
7+
context: ..
8+
dockerfile: sdk_compliance_adapter/Dockerfile
9+
ports:
10+
- "8080:8080"
11+
networks:
12+
- test-network
13+
14+
# Test harness
15+
test-harness:
16+
image: ghcr.io/posthog/sdk-test-harness:latest
17+
command: ["run", "--adapter-url", "http://sdk-adapter:8080", "--mock-url", "http://test-harness:8081"]
18+
networks:
19+
- test-network
20+
depends_on:
21+
- sdk-adapter
22+
23+
networks:
24+
test-network:
25+
driver: bridge
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
defmodule SdkComplianceAdapter do
2+
@moduledoc """
3+
SDK Compliance Adapter for PostHog Elixir SDK.
4+
5+
This adapter wraps the posthog-elixir SDK for compliance testing with the
6+
PostHog SDK Test Harness.
7+
"""
8+
9+
@version "1.0.0"
10+
11+
def version, do: @version
12+
end
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
defmodule SdkComplianceAdapter.Application do
2+
@moduledoc false
3+
use Application
4+
5+
@impl true
6+
def start(_type, _args) do
7+
port = System.get_env("PORT", "8080") |> String.to_integer()
8+
9+
children = [
10+
SdkComplianceAdapter.State,
11+
{DynamicSupervisor, strategy: :one_for_one, name: SdkComplianceAdapter.DynamicSupervisor},
12+
{Plug.Cowboy, scheme: :http, plug: SdkComplianceAdapter.Router, options: [port: port]}
13+
]
14+
15+
opts = [strategy: :one_for_one, name: SdkComplianceAdapter.Supervisor]
16+
17+
IO.puts("Starting PostHog Elixir SDK adapter on port #{port}")
18+
19+
Supervisor.start_link(children, opts)
20+
end
21+
end

0 commit comments

Comments
 (0)