Skip to content

Commit b2a267f

Browse files
authored
Add files via upload
1 parent 9ee36df commit b2a267f

13 files changed

Lines changed: 501 additions & 0 deletions

File tree

tests/e2e/console_smoke.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// console_smoke.ts
2+
//
3+
// E2E smoke for Console web + Interface service.
4+
// This script is intentionally dependency-light.
5+
// Run it from repo root after starting the stack.
6+
//
7+
// Usage:
8+
// node tests/e2e/console_smoke.ts
9+
//
10+
// Environment:
11+
// SIGNIA_CONSOLE_URL (default http://127.0.0.1:3000)
12+
// SIGNIA_INTERFACE_URL (default http://127.0.0.1:7071)
13+
14+
const consoleUrl = process.env.SIGNIA_CONSOLE_URL ?? "http://127.0.0.1:3000";
15+
const interfaceUrl = process.env.SIGNIA_INTERFACE_URL ?? "http://127.0.0.1:7071";
16+
17+
async function mustFetch(url: string, init?: RequestInit) {
18+
const res = await fetch(url, init);
19+
if (!res.ok) {
20+
const txt = await res.text().catch(() => "");
21+
throw new Error(`request failed: ${res.status} ${url}\n${txt}`);
22+
}
23+
return res;
24+
}
25+
26+
async function main() {
27+
await mustFetch(`${consoleUrl}/`);
28+
await mustFetch(`${consoleUrl}/compile`);
29+
await mustFetch(`${consoleUrl}/verify`);
30+
31+
const q = {
32+
question: "What is SIGNIA?",
33+
topK: 5
34+
};
35+
36+
const res = await mustFetch(`${interfaceUrl}/ask`, {
37+
method: "POST",
38+
headers: { "content-type": "application/json" },
39+
body: JSON.stringify(q),
40+
});
41+
const data = await res.json();
42+
if (!data || typeof data.answer !== "string") {
43+
throw new Error("invalid interface response");
44+
}
45+
console.log("ok");
46+
}
47+
48+
main().catch((e) => {
49+
console.error(e);
50+
process.exit(1);
51+
});

tests/e2e/docker_compose_up.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//! docker_compose_up.rs
2+
//!
3+
//! End-to-end smoke that checks Docker Compose can bring up the stack.
4+
//! This test is skipped unless SIGNIA_RUN_E2E=1.
5+
//!
6+
//! Expected file at repo root: docker-compose.yml
7+
//!
8+
//! It will run:
9+
//! - docker compose up -d
10+
//! - docker compose ps
11+
//! - docker compose down
12+
//!
13+
//! No external Rust dependencies.
14+
15+
use std::env;
16+
use std::path::PathBuf;
17+
use std::process::Command;
18+
19+
fn repo_root() -> PathBuf {
20+
PathBuf::from(env!("CARGO_MANIFEST_DIR")).parent().unwrap().to_path_buf()
21+
}
22+
23+
#[test]
24+
fn docker_compose_stack_up_down() {
25+
if env::var("SIGNIA_RUN_E2E").ok().as_deref() != Some("1") {
26+
eprintln!("skip: set SIGNIA_RUN_E2E=1 to enable docker compose test");
27+
return;
28+
}
29+
30+
let root = repo_root();
31+
let compose = root.join("docker-compose.yml");
32+
if !compose.exists() {
33+
eprintln!("skip: docker-compose.yml not found at {}", compose.display());
34+
return;
35+
}
36+
37+
let up = Command::new("sh")
38+
.arg("-lc")
39+
.arg("docker compose up -d")
40+
.current_dir(&root)
41+
.status();
42+
43+
match up {
44+
Ok(s) if s.success() => {}
45+
_ => {
46+
eprintln!("skip: docker compose not available or failed to start");
47+
return;
48+
}
49+
}
50+
51+
let _ = Command::new("sh").arg("-lc").arg("docker compose ps").current_dir(&root).status();
52+
let down = Command::new("sh").arg("-lc").arg("docker compose down -v").current_dir(&root).status();
53+
54+
assert!(down.map(|s| s.success()).unwrap_or(false), "docker compose down failed");
55+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
id,name,score
2+
1,alpha,10
3+
2,beta,20
4+
3,gamma,30
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
openapi: 3.0.0
2+
info:
3+
title: Petstore
4+
version: "1.0.0"
5+
paths:
6+
/pets:
7+
get:
8+
summary: List pets
9+
responses:
10+
"200":
11+
description: OK
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "repo_small"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[lib]
7+
path = "src/lib.rs"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# repo_small
2+
3+
A tiny local fixture repository for SIGNIA tests.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
pub fn add(a: i32, b: i32) -> i32 { a + b }
2+
3+
#[cfg(test)]
4+
mod tests {
5+
use super::*;
6+
#[test]
7+
fn it_adds() {
8+
assert_eq!(add(2, 3), 5);
9+
}
10+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
version: 1
2+
name: workflow-small
3+
steps:
4+
- id: fetch
5+
kind: http_get
6+
with:
7+
url: https://example.com/data.json
8+
- id: publish
9+
kind: signia_publish
10+
with:
11+
target: registry
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
//! api_compile_flow.rs
2+
//!
3+
//! Starts `signia-api` as a subprocess and calls /v1/compile.
4+
//!
5+
//! This is an optional integration test and will be skipped unless:
6+
//! - the `signia-api` binary exists (or SIGNIA_API_BIN is set)
7+
//! - the selected port is free
8+
//!
9+
//! Environment:
10+
//! - SIGNIA_API_BIN: path to the signia-api binary
11+
//! - SIGNIA_API_PORT: port to bind (default 8787)
12+
13+
use std::env;
14+
use std::net::TcpListener;
15+
use std::path::PathBuf;
16+
use std::process::{Command, Stdio};
17+
use std::thread;
18+
use std::time::Duration;
19+
20+
fn repo_root() -> PathBuf {
21+
PathBuf::from(env!("CARGO_MANIFEST_DIR")).parent().unwrap().to_path_buf()
22+
}
23+
24+
fn api_bin() -> Option<PathBuf> {
25+
if let Ok(p) = env::var("SIGNIA_API_BIN") {
26+
let pb = PathBuf::from(p);
27+
if pb.exists() { return Some(pb); }
28+
}
29+
let p = repo_root().join("target").join("debug").join(if cfg!(windows) { "signia-api.exe" } else { "signia-api" });
30+
if p.exists() { Some(p) } else { None }
31+
}
32+
33+
fn can_bind(port: u16) -> bool {
34+
TcpListener::bind(("127.0.0.1", port)).is_ok()
35+
}
36+
37+
#[test]
38+
fn api_compile_smoke() {
39+
let Some(bin) = api_bin() else {
40+
eprintln!("skip: signia-api binary not found (set SIGNIA_API_BIN or build signia-api)");
41+
return;
42+
};
43+
44+
let port: u16 = env::var("SIGNIA_API_PORT").ok().and_then(|s| s.parse().ok()).unwrap_or(8787);
45+
if !can_bind(port) {
46+
eprintln!("skip: port {} is not available", port);
47+
return;
48+
}
49+
50+
let mut child = Command::new(&bin)
51+
.env("SIGNIA_BIND_ADDR", format!("127.0.0.1:{port}"))
52+
.stdout(Stdio::null())
53+
.stderr(Stdio::null())
54+
.spawn()
55+
.expect("failed to start signia-api");
56+
57+
// give it time to boot
58+
thread::sleep(Duration::from_millis(700));
59+
60+
// Use curl if available (no external Rust deps).
61+
let payload = r#"{"type":"dataset","content":"id,name\n1,a\n"}"#;
62+
63+
let status = Command::new("sh")
64+
.arg("-lc")
65+
.arg(format!(
66+
"curl -fsS -H 'content-type: application/json' -d '{}' http://127.0.0.1:{}/v1/compile > /dev/null",
67+
payload.replace("'", "'\"'\"'"),
68+
port
69+
))
70+
.status();
71+
72+
// best effort cleanup
73+
let _ = child.kill();
74+
75+
match status {
76+
Ok(s) => assert!(s.success(), "curl request to /v1/compile failed"),
77+
Err(_) => {
78+
eprintln!("skip: curl is not available in this environment");
79+
}
80+
}
81+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//! determinism_roundtrip.rs
2+
//!
3+
//! Black-box determinism test:
4+
//! same input => same output byte-for-byte.
5+
//!
6+
//! This test executes the `signia` CLI twice and compares produced bundles.
7+
//!
8+
//! How to run:
9+
//! - build CLI: `cargo build -p signia-cli`
10+
//! - then: `cargo test -q` (from workspace root)
11+
//!
12+
//! Notes:
13+
//! - The CLI path can be overridden via SIGNIA_BIN.
14+
//! - If the CLI binary is not found, the test is skipped.
15+
16+
use std::env;
17+
use std::fs;
18+
use std::path::{Path, PathBuf};
19+
use std::process::Command;
20+
21+
fn repo_root() -> PathBuf {
22+
PathBuf::from(env!("CARGO_MANIFEST_DIR")).parent().unwrap().to_path_buf()
23+
}
24+
25+
fn signia_bin() -> Option<PathBuf> {
26+
if let Ok(p) = env::var("SIGNIA_BIN") {
27+
let pb = PathBuf::from(p);
28+
if pb.exists() { return Some(pb); }
29+
}
30+
let p = repo_root().join("target").join("debug").join(if cfg!(windows) { "signia.exe" } else { "signia" });
31+
if p.exists() { Some(p) } else { None }
32+
}
33+
34+
fn run_compile(bin: &Path, input: &Path, typ: &str, out: &Path) {
35+
let status = Command::new(bin)
36+
.arg("compile")
37+
.arg(input)
38+
.arg("--type").arg(typ)
39+
.arg("--out").arg(out)
40+
.status()
41+
.expect("failed to spawn signia");
42+
assert!(status.success(), "signia compile failed");
43+
}
44+
45+
fn read_bytes(p: &Path) -> Vec<u8> {
46+
fs::read(p).unwrap_or_else(|e| panic!("failed to read {}: {e}", p.display()))
47+
}
48+
49+
#[test]
50+
fn determinism_dataset() {
51+
let Some(bin) = signia_bin() else {
52+
eprintln!("skip: signia CLI not found (set SIGNIA_BIN or build signia-cli)");
53+
return;
54+
};
55+
56+
let root = repo_root();
57+
let input = root.join("tests").join("fixtures").join("dataset_small").join("sample.csv");
58+
59+
let out1 = root.join("target").join("tmp").join("signia_test_determinism_1");
60+
let out2 = root.join("target").join("tmp").join("signia_test_determinism_2");
61+
let _ = fs::remove_dir_all(&out1);
62+
let _ = fs::remove_dir_all(&out2);
63+
fs::create_dir_all(&out1).unwrap();
64+
fs::create_dir_all(&out2).unwrap();
65+
66+
run_compile(&bin, &input, "dataset", &out1);
67+
run_compile(&bin, &input, "dataset", &out2);
68+
69+
for name in ["schema.json", "manifest.json", "proof.json"] {
70+
let b1 = read_bytes(&out1.join(name));
71+
let b2 = read_bytes(&out2.join(name));
72+
assert_eq!(b1, b2, "bundle file differs: {name}");
73+
}
74+
}

0 commit comments

Comments
 (0)