Explains inception testing pattern, pipeline stages, and how 42+ SDKs are tested with only a C compiler on the build server.
204 lines
8.6 KiB
Markdown
204 lines
8.6 KiB
Markdown
# UN-Inception CI/CD Pipeline
|
|
|
|
## Overview
|
|
|
|
The UN-Inception pipeline tests 42+ SDK implementations across 8 languages without requiring any language runtimes on the build server. It achieves this through **inception testing** - using the compiled C CLI to execute other SDKs through the unsandbox API.
|
|
|
|
```
|
|
Build Server (C only) → unsandbox API → SDK (Python/JS/etc) → unsandbox API → Test Code
|
|
```
|
|
|
|
## Pipeline Stages
|
|
|
|
```
|
|
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────────┐ ┌──────────┐ ┌──────────┐ ┌────────┐
|
|
│ PRE │ → │ BUILD │ → │ TEST │ → │ SCIENCE │ → │ VALIDATE │ → │ DOCUMENT │ → │ REPORT │
|
|
└─────────┘ └─────────┘ └─────────┘ └─────────────┘ └──────────┘ └──────────┘ └────────┘
|
|
```
|
|
|
|
### Stage 1: PRE
|
|
|
|
**detect-changes**
|
|
- Analyzes git diff to identify which SDKs changed
|
|
- Outputs `changes.json` with list of affected languages
|
|
- Enables selective testing (only test what changed)
|
|
|
|
**generate-matrix**
|
|
- Reads `changes.json`
|
|
- Generates `test-matrix.yml` with parallel test jobs
|
|
- Each changed SDK gets its own test job
|
|
|
|
### Stage 2: BUILD
|
|
|
|
**build**
|
|
- Compiles the C CLI binary (`build/un`)
|
|
- Dependencies: `gcc`, `libcurl`, `libwebsockets`, `libssl`
|
|
- The C binary is the **only** compiled artifact needed
|
|
- All other SDKs are interpreted and tested remotely
|
|
|
|
```bash
|
|
make -C clients/c cli
|
|
cp clients/c/un build/un
|
|
```
|
|
|
|
### Stage 3: TEST (Dynamic Matrix)
|
|
|
|
Generated dynamically based on changed SDKs. Each job runs inception tests:
|
|
|
|
```bash
|
|
# Example: Testing Python SDK
|
|
build/un -n semitrusted \
|
|
-e UNSANDBOX_PUBLIC_KEY=$KEY \
|
|
-e UNSANDBOX_SECRET_KEY=$SECRET \
|
|
clients/python/sync/src/un.py --help
|
|
|
|
build/un -n semitrusted \
|
|
-e UNSANDBOX_PUBLIC_KEY=$KEY \
|
|
-e UNSANDBOX_SECRET_KEY=$SECRET \
|
|
clients/python/sync/src/un.py -s python 'print("test")'
|
|
```
|
|
|
|
**What's happening:**
|
|
1. `build/un` (C CLI on build server) calls unsandbox API
|
|
2. unsandbox runs `un.py` in a container with network access
|
|
3. `un.py` calls the unsandbox API to execute test code
|
|
4. Results bubble back through both layers
|
|
|
|
### Stage 4: SCIENCE
|
|
|
|
Parallel jobs for extended validation:
|
|
|
|
**science-validate-examples**
|
|
- Runs example code from all SDKs
|
|
- Burns API pool credits for real-world testing
|
|
|
|
**science-lint-sdks**
|
|
- Static analysis across SDK implementations
|
|
- Checks for consistency and code quality
|
|
|
|
**science-benchmark-clients**
|
|
- Performance testing of SDK implementations
|
|
- Measures execution time and resource usage
|
|
|
|
### Stage 5: VALIDATE
|
|
|
|
**validate-examples**
|
|
- Aggregates results from science jobs
|
|
- Generates summary statistics
|
|
- Identifies failures across SDK matrix
|
|
|
|
### Stage 6: DOCUMENT
|
|
|
|
**generate-documentation**
|
|
- Auto-generates docs from test results
|
|
- Creates verification timestamps
|
|
- Updates SDK status information
|
|
|
|
### Stage 7: REPORT
|
|
|
|
**report**
|
|
- Final aggregation of all results
|
|
- Generates JUnit XML for GitLab integration
|
|
- Produces human-readable summary
|
|
|
|
## The Inception Pattern
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────┐
|
|
│ Build Server │
|
|
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
|
│ │ build/un (C binary) │ │
|
|
│ │ └─→ POST api.unsandbox.com/execute │ │
|
|
│ └─────────────────────────────────────────────────────────────────┘ │
|
|
└───────────────────────────────┬─────────────────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────────────┐
|
|
│ Unsandbox Container (semitrusted network) │
|
|
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
|
│ │ un.py / un.js / un.rb / etc │ │
|
|
│ │ └─→ POST api.unsandbox.com/execute │ │
|
|
│ └─────────────────────────────────────────────────────────────────┘ │
|
|
└───────────────────────────────┬─────────────────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────────────┐
|
|
│ Unsandbox Container (isolated) │
|
|
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
|
│ │ Test code execution │ │
|
|
│ │ print("inception-test-ok") │ │
|
|
│ └─────────────────────────────────────────────────────────────────┘ │
|
|
└─────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
## Build Server Requirements
|
|
|
|
Minimal dependencies - only what's needed to compile C:
|
|
|
|
```bash
|
|
apt install build-essential libcurl4-openssl-dev libwebsockets-dev libssl-dev
|
|
```
|
|
|
|
**Not required:** Python, Ruby, PHP, Go, Java, Rust, Node.js, etc.
|
|
|
|
All language runtimes exist in unsandbox containers, not on the build server.
|
|
|
|
## Environment Variables
|
|
|
|
Required in GitLab CI/CD Settings → Variables:
|
|
|
|
| Variable | Description | Protected | Masked |
|
|
|----------|-------------|-----------|--------|
|
|
| `UNSANDBOX_PUBLIC_KEY` | API public key | Yes | Yes |
|
|
| `UNSANDBOX_SECRET_KEY` | API secret key | Yes | Yes |
|
|
|
|
## Artifacts
|
|
|
|
Each stage produces artifacts passed to subsequent stages:
|
|
|
|
| Job | Artifact | Purpose |
|
|
|-----|----------|---------|
|
|
| detect-changes | `changes.json` | List of changed SDKs |
|
|
| generate-matrix | `test-matrix.yml` | Dynamic test job definitions |
|
|
| build | `build/un` | Compiled C CLI |
|
|
| test-* | `test-results-*/` | Per-SDK test results |
|
|
| science-* | `*-results/` | Extended validation data |
|
|
| report | `final-report.xml` | JUnit results for GitLab |
|
|
|
|
## Triggering
|
|
|
|
Pipeline runs on:
|
|
- Push to `main` branch
|
|
- Tags matching `v*.*.*`
|
|
|
|
## Local Testing
|
|
|
|
Test the inception pattern locally:
|
|
|
|
```bash
|
|
# Build C CLI
|
|
make -C clients/c cli
|
|
|
|
# Test Python SDK through inception
|
|
./clients/c/un -n semitrusted \
|
|
-e UNSANDBOX_PUBLIC_KEY=$UNSANDBOX_PUBLIC_KEY \
|
|
-e UNSANDBOX_SECRET_KEY=$UNSANDBOX_SECRET_KEY \
|
|
clients/python/sync/src/un.py -s python 'print("hello")'
|
|
```
|
|
|
|
## Files
|
|
|
|
```
|
|
.gitlab-ci.yml # Pipeline definition
|
|
test-matrix.yml # Placeholder (overwritten by generate-matrix)
|
|
scripts/
|
|
├── detect-changes.sh # Identifies changed SDKs
|
|
├── generate-matrix.sh # Creates dynamic test jobs
|
|
├── build-clients.sh # Compiles C CLI
|
|
├── test-sdk.sh # Runs inception tests
|
|
├── validate-examples.sh
|
|
├── filter-results.sh
|
|
└── science/
|
|
├── lint-all-sdks.sh
|
|
└── benchmark-clients.sh
|
|
```
|