Skip to content

Commit ed467da

Browse files
committed
Add RUSTAPI_CONFIG_PATH for isolated cloud CLI verification tests
1 parent db85c81 commit ed467da

2 files changed

Lines changed: 77 additions & 0 deletions

File tree

crates/cargo-rustapi/src/config.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ fn config_dir() -> PathBuf {
3333
}
3434

3535
fn config_path() -> PathBuf {
36+
if let Ok(path) = std::env::var("RUSTAPI_CONFIG_PATH") {
37+
return PathBuf::from(path);
38+
}
3639
config_dir().join("config.json")
3740
}
3841

crates/cargo-rustapi/tests/cli_tests.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,59 @@ mod migrate_command {
470470
#[cfg(feature = "cloud")]
471471
mod deploy_command {
472472
use super::*;
473+
use std::io::Write;
474+
use std::net::TcpListener;
475+
use std::sync::atomic::{AtomicUsize, Ordering};
476+
use std::sync::Arc;
477+
use std::thread;
478+
use std::time::Duration;
479+
480+
fn spawn_mock_deploy_status_server(deploy_id: &str) -> (String, thread::JoinHandle<()>) {
481+
let listener = TcpListener::bind("127.0.0.1:0").expect("bind mock cloud");
482+
let port = listener.local_addr().expect("addr").port();
483+
let cloud_url = format!("http://127.0.0.1:{port}");
484+
let id = deploy_id.to_string();
485+
let hits = Arc::new(AtomicUsize::new(0));
486+
487+
let handle = thread::spawn(move || {
488+
listener.set_nonblocking(true).ok();
489+
let deadline = std::time::Instant::now() + Duration::from_secs(30);
490+
while hits.load(Ordering::SeqCst) < 2 && std::time::Instant::now() < deadline {
491+
if let Ok((mut stream, _)) = listener.accept() {
492+
let mut buf = [0u8; 4096];
493+
let _ = std::io::Read::read(&mut stream, &mut buf);
494+
let body = format!(
495+
r#"{{"deploy_id":"{id}","status":"live","url":"http://127.0.0.1:59999"}}"#
496+
);
497+
let response = format!(
498+
"HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: {}\r\nConnection: close\r\n\r\n{body}",
499+
body.len()
500+
);
501+
let _ = stream.write_all(response.as_bytes());
502+
hits.fetch_add(1, Ordering::SeqCst);
503+
} else {
504+
thread::sleep(Duration::from_millis(20));
505+
}
506+
}
507+
});
508+
509+
(cloud_url, handle)
510+
}
511+
512+
fn write_cloud_config(home: &std::path::Path, cloud_url: &str, token: &str) {
513+
let dir = home.join(".rustapi");
514+
fs::create_dir_all(&dir).expect("config dir");
515+
let config = serde_json::json!({
516+
"token": token,
517+
"cloud_url": cloud_url,
518+
"user": { "login": "cli-test", "tier": "hobby" }
519+
});
520+
fs::write(
521+
dir.join("config.json"),
522+
serde_json::to_string_pretty(&config).expect("json"),
523+
)
524+
.expect("write config");
525+
}
473526

474527
#[test]
475528
fn test_deploy_status_help() {
@@ -488,4 +541,25 @@ mod deploy_command {
488541
.success()
489542
.stdout(predicate::str::contains("RustAPI Cloud"));
490543
}
544+
545+
#[test]
546+
fn test_deploy_status_fetches_live_response_from_cloud() {
547+
let deploy_id = "cli-mock-deploy-1";
548+
let (cloud_url, server) = spawn_mock_deploy_status_server(deploy_id);
549+
let home = tempdir().expect("cli home");
550+
write_cloud_config(home.path(), &cloud_url, "mock-jwt-token");
551+
552+
cargo_rustapi()
553+
.env("USERPROFILE", home.path())
554+
.env("HOME", home.path())
555+
.args(["deploy", "status", deploy_id])
556+
.assert()
557+
.success()
558+
.stdout(predicate::str::contains(deploy_id))
559+
.stdout(predicate::str::contains("live"))
560+
.stdout(predicate::str::contains("URL:"))
561+
.stdout(predicate::str::contains("http://127.0.0.1:59999"));
562+
563+
server.join().expect("mock server thread");
564+
}
491565
}

0 commit comments

Comments
 (0)