Skip to content

Commit a22a016

Browse files
test(cost-report): validate generate->poll->download flow live (#138)
Adds live_cost_report_generate_and_download: kicks off a cost report for a fixed historical range, polls the task to completion, extracts the id from response.resource.costReportId, and downloads the report — asserting non-empty content. Non-destructive (produces a downloadable artifact; mutates nothing). Guards the #118 flow (the example's id-extraction path) with a committed regression test. fmt + clippy clean; 22 live tests pass.
1 parent 55e17d6 commit a22a016

1 file changed

Lines changed: 50 additions & 0 deletions

File tree

tests/live_integration.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,3 +670,53 @@ live_test!(live_acl_redis_rule_lifecycle, c, {
670670
);
671671
assert!(gone, "rule should be deleted");
672672
});
673+
674+
// Cost-report generate -> poll -> download flow (non-destructive: produces a
675+
// downloadable report, mutates nothing). Guards #118 — the completed task
676+
// nests the id at `response.resource.costReportId`, and the report downloads.
677+
live_test!(live_cost_report_generate_and_download, c, {
678+
use redis_cloud::cost_report::CostReportCreateRequest;
679+
use redis_cloud::types::TaskStatus;
680+
use std::time::Duration;
681+
682+
// Fixed historical range (account exists since 2025-12; <= 40-day span).
683+
let task = c
684+
.cost_reports()
685+
.generate_cost_report(CostReportCreateRequest::new("2026-05-01", "2026-05-31"))
686+
.await
687+
.expect("generate_cost_report should kick off a task");
688+
let task_id = task.task_id.expect("generate should return a task id");
689+
690+
let mut report_id = None;
691+
for _ in 0..40 {
692+
tokio::time::sleep(Duration::from_secs(3)).await;
693+
let state = c
694+
.tasks()
695+
.get_task_by_id(task_id.clone())
696+
.await
697+
.expect("get_task_by_id should deserialize");
698+
match state.status {
699+
Some(TaskStatus::ProcessingCompleted) => {
700+
report_id = state.response.and_then(|r| r.resource).and_then(|res| {
701+
res.get("costReportId")
702+
.and_then(|v| v.as_str().map(str::to_string))
703+
});
704+
break;
705+
}
706+
Some(TaskStatus::ProcessingError) => panic!("cost report generation failed"),
707+
_ => {}
708+
}
709+
}
710+
let report_id =
711+
report_id.expect("completed task should carry response.resource.costReportId (see #118)");
712+
713+
let bytes = c
714+
.cost_reports()
715+
.download_cost_report(&report_id)
716+
.await
717+
.expect("download_cost_report should succeed");
718+
assert!(
719+
!bytes.is_empty(),
720+
"downloaded cost report should have content"
721+
);
722+
});

0 commit comments

Comments
 (0)