upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/grasp-audit/src/bin/grasp-audit.rs
blob: 6c063db5610435d87b1f6646f54be9e7ab8cf873 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//! GRASP Audit CLI Tool

use clap::{Parser, Subcommand};
use grasp_audit::*;

#[derive(Parser)]
#[command(name = "grasp-audit")]
#[command(about = "GRASP audit and compliance testing tool", long_about = None)]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    /// Run audit tests against a server
    Audit {
        /// Relay URL (e.g., ws://localhost:7000)
        #[arg(short, long)]
        relay: String,
        
        /// Mode: ci or production
        #[arg(short, long, default_value = "ci")]
        mode: String,
        
        /// Spec to test (nip01-smoke, all)
        #[arg(short, long, default_value = "nip01-smoke")]
        spec: String,
    },
}

#[tokio::main]
async fn main() -> Result<()> {
    // Initialize logging
    tracing_subscriber::fmt()
        .with_env_filter(
            tracing_subscriber::EnvFilter::from_default_env()
                .add_directive(tracing::Level::INFO.into())
        )
        .init();
    
    let cli = Cli::parse();
    
    match cli.command {
        Commands::Audit { relay, mode, spec } => {
            let config = match mode.as_str() {
                "ci" => AuditConfig::ci(),
                "production" => AuditConfig::production(),
                _ => return Err(anyhow!("Invalid mode: {}. Use 'ci' or 'production'", mode)),
            };
            
            println!("🔍 GRASP Audit Tool");
            println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
            println!("Relay:   {}", relay);
            println!("Mode:    {}", mode);
            println!("Spec:    {}", spec);
            println!("Run ID:  {}", config.run_id);
            println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
            println!();
            
            println!("Connecting to relay...");
            let client = AuditClient::new(&relay, config).await
                .map_err(|e| anyhow!("Failed to connect to relay: {}", e))?;
            
            if !client.is_connected().await {
                return Err(anyhow!("Could not establish connection to relay"));
            }
            
            println!("✓ Connected\n");
            
            let results = match spec.as_str() {
                "nip01-smoke" => {
                    println!("Running NIP-01 smoke tests...\n");
                    specs::Nip01SmokeTests::run_all(&client).await
                }
                "all" => {
                    println!("Running all tests...\n");
                    specs::Nip01SmokeTests::run_all(&client).await
                }
                _ => return Err(anyhow!("Unknown spec: {}. Use 'nip01-smoke' or 'all'", spec)),
            };
            
            results.print_report();
            
            if !results.all_passed() {
                println!("❌ Some tests failed");
                std::process::exit(1);
            } else {
                println!("✅ All tests passed!");
            }
        }
    }
    
    Ok(())
}