use clap::{Parser, ValueEnum};
use std::path::PathBuf;
#[derive(Parser)]
#[command(name = "h2_enable_push_conformance")]
#[command(about = "HTTP/2 SETTINGS_ENABLE_PUSH=0 enforcement conformance tester")]
struct Args {
#[arg(long, default_value = "markdown")]
format: OutputFormat,
#[arg(long, short)]
output: Option<PathBuf>,
#[arg(long)]
test_case: Option<String>,
#[arg(long, short)]
verbose: bool,
#[arg(long, default_value = "30")]
timeout: u64,
}
#[derive(Debug, Clone, ValueEnum)]
enum OutputFormat {
Json,
Markdown,
Summary,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let args = Args::parse();
if args.verbose {
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("debug")).init();
}
println!("๐ง HTTP/2 SETTINGS_ENABLE_PUSH=0 Enforcement Conformance Tester");
println!(" Testing live asupersync SETTINGS/Frame/Connection seams");
println!(" Focus: Server must not send PUSH_PROMISE when ENABLE_PUSH=0");
println!();
let mut tester = asupersync_conformance::EnablePushConformanceTester::new();
if let Some(test_id) = &args.test_case {
tester.test_cases.retain(|case| case.id == *test_id);
if tester.test_cases.is_empty() {
eprintln!("โ Test case '{}' not found", test_id);
std::process::exit(1);
}
println!("๐ Running single test case: {}", test_id);
} else {
println!(
"๐ Running {} conformance test cases",
tester.test_cases.len()
);
}
let timeout_duration = std::time::Duration::from_secs(args.timeout);
let report = match tokio::time::timeout(timeout_duration, tester.run_all_tests()).await {
Ok(report) => report,
Err(_) => {
eprintln!("โ Tests timed out after {} seconds", args.timeout);
std::process::exit(1);
}
};
let output = match args.format {
OutputFormat::Json => serde_json::to_string_pretty(&report)?,
OutputFormat::Markdown => tester.generate_markdown_report(&report),
OutputFormat::Summary => generate_summary_output(&report),
};
match args.output {
Some(path) => {
std::fs::write(&path, &output)?;
println!("๐ Report written to: {}", path.display());
}
None => {
println!("{}", output);
}
}
println!();
print_test_summary(&report);
std::process::exit(exit_code(&report));
}
fn generate_summary_output(report: &asupersync_conformance::EnablePushComplianceReport) -> String {
let mut output = String::new();
output.push_str("HTTP/2 SETTINGS_ENABLE_PUSH=0 CONFORMANCE SUMMARY\n");
output.push_str("============================================\n\n");
output.push_str(&format!("Test Run: {}\n", report.test_run_id));
output.push_str(&format!("Timestamp: {}\n", report.timestamp));
output.push_str(&format!("Total Cases: {}\n\n", report.total_cases));
output.push_str("RESULTS:\n");
output.push_str(&format!(" โ
Passed: {}\n", report.summary.passed));
output.push_str(&format!(" โ Failed: {}\n", report.summary.failed));
output.push_str(&format!(
" โ ๏ธ Expected Failures: {}\n",
report.summary.expected_failures
));
output.push_str(&format!(" โญ๏ธ Skipped: {}\n\n", report.summary.skipped));
output.push_str(&format!(
"Compliance Score: {:.1}%\n",
report.summary.compliance_score * 100.0
));
if report.summary.failed > 0 {
output.push_str("\nFAILURES:\n");
for result in &report.results {
if result.verdict == asupersync_conformance::EnablePushTestVerdict::Fail {
output.push_str(&format!(
" โ {}: {}\n",
result.case_id,
result.error.as_deref().unwrap_or("Unknown error")
));
output.push_str(&format!(
" PUSH_PROMISE accepted by asupersync: {}\n",
result.asupersync_push_promise_count
));
}
}
}
output.push_str("\nPUSH_PROMISE ENFORCEMENT ANALYSIS:\n");
for result in &report.results {
output.push_str(&format!(
" ๐ {}: support={}, asupersync={} PUSH_PROMISE, reference={}\n",
result.case_id,
result.support_class,
result.asupersync_push_promise_count,
result.reference_status
));
}
output
}
fn print_test_summary(report: &asupersync_conformance::EnablePushComplianceReport) {
eprintln!("โญโ HTTP/2 SETTINGS_ENABLE_PUSH=0 CONFORMANCE RESULTS โโฎ");
eprintln!("โ โ");
if report.summary.failed == 0 {
eprintln!(
"โ {} โ",
final_status_line(report.summary.skipped, report.summary.expected_failures)
);
eprintln!(
"โ ๐ฏ Compliance: {:.1}% โ",
report.summary.compliance_score * 100.0
);
} else {
eprintln!(
"โ โ {} TESTS FAILED โ",
report.summary.failed
);
eprintln!(
"โ ๐ Compliance: {:.1}% โ",
report.summary.compliance_score * 100.0
);
}
eprintln!("โ โ");
eprintln!(
"โ ๐ Total: {} โ",
report.total_cases
);
eprintln!(
"โ โ
Passed: {} โ",
report.summary.passed
);
eprintln!(
"โ โ Failed: {} โ",
report.summary.failed
);
eprintln!(
"โ โ ๏ธ Expected: {} โ",
report.summary.expected_failures
);
eprintln!(
"โ โญ๏ธ Skipped: {} โ",
report.summary.skipped
);
eprintln!("โ โ");
eprintln!("โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ");
}
fn final_status_line(skipped_count: usize, expected_failure_count: usize) -> String {
if skipped_count == 0 && expected_failure_count == 0 {
"โ
ALL TESTS PASSED".to_string()
} else {
format!(
"โ ๏ธ NO FAILURES; PARTIAL COVERAGE ({skipped_count} skipped, {expected_failure_count} expected failures)"
)
}
}
fn has_incomplete_coverage(report: &asupersync_conformance::EnablePushComplianceReport) -> bool {
report.total_cases == 0 || report.summary.skipped > 0 || report.summary.expected_failures > 0
}
fn exit_code(report: &asupersync_conformance::EnablePushComplianceReport) -> i32 {
if report.summary.failed > 0 || has_incomplete_coverage(report) {
1
} else {
0
}
}
#[cfg(test)]
mod tests {
use super::*;
use asupersync_conformance::EnablePushComplianceSummary;
fn synthetic_report(
total_cases: usize,
failed: usize,
expected_failures: usize,
skipped: usize,
) -> asupersync_conformance::EnablePushComplianceReport {
asupersync_conformance::EnablePushComplianceReport {
test_run_id: "synthetic".to_string(),
timestamp: chrono::Utc::now().to_rfc3339(),
total_cases,
results: Vec::new(),
summary: EnablePushComplianceSummary {
passed: total_cases
.saturating_sub(failed)
.saturating_sub(expected_failures)
.saturating_sub(skipped),
failed,
expected_failures,
skipped,
total: total_cases,
compliance_score: 0.0,
},
}
}
#[test]
fn final_status_does_not_claim_all_passed_for_partial_coverage() {
let status = final_status_line(1, 0);
assert!(status.contains("NO FAILURES; PARTIAL COVERAGE"));
assert!(!status.contains("ALL TESTS PASSED"));
}
#[test]
fn final_status_claims_all_passed_only_for_full_green_results() {
assert_eq!(final_status_line(0, 0), "โ
ALL TESTS PASSED");
}
#[test]
fn exit_code_is_nonzero_for_expected_failures() {
let report = synthetic_report(8, 0, 1, 0);
assert_eq!(exit_code(&report), 1);
}
#[test]
fn exit_code_is_nonzero_for_skipped_coverage() {
let report = synthetic_report(8, 0, 0, 1);
assert_eq!(exit_code(&report), 1);
}
#[test]
fn exit_code_is_nonzero_for_zero_case_reports() {
let report = synthetic_report(0, 0, 0, 0);
assert_eq!(exit_code(&report), 1);
}
#[test]
fn exit_code_is_zero_for_full_pass_coverage() {
let report = synthetic_report(8, 0, 0, 0);
assert_eq!(exit_code(&report), 0);
}
}