re-uploading work

This commit is contained in:
2026-02-04 17:46:30 -06:00
commit 3b14c65998
1388 changed files with 381262 additions and 0 deletions

View File

@@ -0,0 +1,494 @@
//! CLI integration tests for pack registry commands
#![allow(deprecated)]
//!
//! This module tests:
//! - `attune pack install` command with all sources
//! - `attune pack checksum` command
//! - `attune pack index-entry` command
//! - `attune pack index-update` command
//! - `attune pack index-merge` command
//! - Error handling and output formatting
use assert_cmd::Command;
use predicates::prelude::*;
use serde_json::Value;
use std::fs;
use tempfile::TempDir;
/// Helper to create a test pack directory with pack.yaml
fn create_test_pack(name: &str, version: &str, deps: &[&str]) -> TempDir {
let temp_dir = TempDir::new().unwrap();
let deps_yaml = if deps.is_empty() {
"dependencies: []".to_string()
} else {
let dep_list = deps
.iter()
.map(|d| format!(" - {}", d))
.collect::<Vec<_>>()
.join("\n");
format!("dependencies:\n{}", dep_list)
};
let pack_yaml = format!(
r#"
ref: {}
name: Test Pack {}
version: {}
description: Test pack for CLI integration tests
author: Test Author
email: test@example.com
license: Apache-2.0
homepage: https://example.com
repository: https://github.com/example/pack
keywords:
- test
- cli
{}
python: "3.8"
actions:
test_action:
entry_point: test.py
runner_type: python-script
description: Test action
sensors:
test_sensor:
entry_point: sensor.py
runner_type: python-script
triggers:
test_trigger:
description: Test trigger
"#,
name, name, version, deps_yaml
);
fs::write(temp_dir.path().join("pack.yaml"), pack_yaml).unwrap();
fs::write(temp_dir.path().join("test.py"), "print('test action')").unwrap();
fs::write(temp_dir.path().join("sensor.py"), "print('test sensor')").unwrap();
temp_dir
}
/// Helper to create a registry index file
fn create_test_index(packs: &[(&str, &str)]) -> TempDir {
let temp_dir = TempDir::new().unwrap();
let pack_entries: Vec<String> = packs
.iter()
.map(|(name, version)| {
format!(
r#"{{
"ref": "{}",
"label": "Test Pack {}",
"version": "{}",
"author": "Test",
"license": "Apache-2.0",
"keywords": ["test"],
"install_sources": [
{{
"type": "git",
"url": "https://github.com/test/{}.git",
"ref": "v{}",
"checksum": "sha256:abc123"
}}
]
}}"#,
name, name, version, name, version
)
})
.collect();
let index = format!(
r#"{{
"version": "1.0",
"packs": [
{}
]
}}"#,
pack_entries.join(",\n")
);
fs::write(temp_dir.path().join("index.json"), index).unwrap();
temp_dir
}
#[test]
fn test_pack_checksum_directory() {
let pack_dir = create_test_pack("checksum-test", "1.0.0", &[]);
let mut cmd = Command::cargo_bin("attune").unwrap();
cmd.arg("--output")
.arg("table")
.arg("pack")
.arg("checksum")
.arg(pack_dir.path().to_str().unwrap());
cmd.assert()
.success()
.stdout(predicate::str::contains("sha256:"));
}
#[test]
fn test_pack_checksum_json_output() {
let pack_dir = create_test_pack("checksum-json", "1.0.0", &[]);
let mut cmd = Command::cargo_bin("attune").unwrap();
cmd.arg("--output")
.arg("json")
.arg("pack")
.arg("checksum")
.arg(pack_dir.path().to_str().unwrap());
let output = cmd.assert().success();
let stdout = String::from_utf8(output.get_output().stdout.clone()).unwrap();
// Verify it's valid JSON
let json: Value = serde_json::from_str(&stdout).unwrap();
assert!(json["checksum"].is_string());
assert!(json["checksum"].as_str().unwrap().starts_with("sha256:"));
}
#[test]
fn test_pack_checksum_nonexistent_path() {
let mut cmd = Command::cargo_bin("attune").unwrap();
cmd.arg("pack").arg("checksum").arg("/nonexistent/path");
cmd.assert().failure().stderr(
predicate::str::contains("not found").or(predicate::str::contains("does not exist")),
);
}
#[test]
fn test_pack_index_entry_generates_valid_json() {
let pack_dir = create_test_pack("index-entry-test", "1.2.3", &[]);
let mut cmd = Command::cargo_bin("attune").unwrap();
cmd.arg("--output")
.arg("json")
.arg("pack")
.arg("index-entry")
.arg(pack_dir.path().to_str().unwrap())
.arg("--git-url")
.arg("https://github.com/test/pack.git")
.arg("--git-ref")
.arg("v1.2.3");
let output = cmd.assert().success();
let stdout = String::from_utf8(output.get_output().stdout.clone()).unwrap();
// Verify it's valid JSON
let json: Value = serde_json::from_str(&stdout).unwrap();
assert_eq!(json["ref"], "index-entry-test");
assert_eq!(json["version"], "1.2.3");
assert!(json["install_sources"].is_array());
assert!(json["install_sources"][0]["checksum"]
.as_str()
.unwrap()
.starts_with("sha256:"));
// Verify metadata
assert_eq!(json["author"], "Test Author");
assert_eq!(json["license"], "Apache-2.0");
assert!(json["keywords"].as_array().unwrap().len() > 0);
}
#[test]
fn test_pack_index_entry_with_archive_url() {
let pack_dir = create_test_pack("archive-test", "2.0.0", &[]);
let mut cmd = Command::cargo_bin("attune").unwrap();
cmd.arg("--output")
.arg("json")
.arg("pack")
.arg("index-entry")
.arg(pack_dir.path().to_str().unwrap())
.arg("--archive-url")
.arg("https://releases.example.com/pack-2.0.0.tar.gz");
let output = cmd.assert().success();
let stdout = String::from_utf8(output.get_output().stdout.clone()).unwrap();
let json: Value = serde_json::from_str(&stdout).unwrap();
assert!(json["install_sources"].as_array().unwrap().len() > 0);
let archive_source = &json["install_sources"][0];
assert_eq!(archive_source["type"], "archive");
assert_eq!(
archive_source["url"],
"https://releases.example.com/pack-2.0.0.tar.gz"
);
}
#[test]
fn test_pack_index_entry_missing_pack_yaml() {
let temp_dir = TempDir::new().unwrap();
fs::write(temp_dir.path().join("readme.txt"), "No pack.yaml here").unwrap();
let mut cmd = Command::cargo_bin("attune").unwrap();
cmd.arg("pack")
.arg("index-entry")
.arg(temp_dir.path().to_str().unwrap());
cmd.assert()
.failure()
.stderr(predicate::str::contains("pack.yaml"));
}
#[test]
fn test_pack_index_update_adds_new_entry() {
let index_dir = create_test_index(&[("existing-pack", "1.0.0")]);
let index_path = index_dir.path().join("index.json");
let pack_dir = create_test_pack("new-pack", "1.0.0", &[]);
let mut cmd = Command::cargo_bin("attune").unwrap();
cmd.arg("pack")
.arg("index-update")
.arg("--index")
.arg(index_path.to_str().unwrap())
.arg(pack_dir.path().to_str().unwrap())
.arg("--git-url")
.arg("https://github.com/test/new-pack.git")
.arg("--git-ref")
.arg("v1.0.0");
cmd.assert()
.success()
.stdout(predicate::str::contains("new-pack"))
.stdout(predicate::str::contains("1.0.0"));
// Verify index was updated
let updated_index = fs::read_to_string(&index_path).unwrap();
let json: Value = serde_json::from_str(&updated_index).unwrap();
assert_eq!(json["packs"].as_array().unwrap().len(), 2);
}
#[test]
fn test_pack_index_update_prevents_duplicate_without_flag() {
let index_dir = create_test_index(&[("existing-pack", "1.0.0")]);
let index_path = index_dir.path().join("index.json");
let pack_dir = create_test_pack("existing-pack", "1.0.0", &[]);
let mut cmd = Command::cargo_bin("attune").unwrap();
cmd.arg("pack")
.arg("index-update")
.arg("--index")
.arg(index_path.to_str().unwrap())
.arg(pack_dir.path().to_str().unwrap())
.arg("--git-url")
.arg("https://github.com/test/existing-pack.git");
cmd.assert()
.failure()
.stderr(predicate::str::contains("already exists"));
}
#[test]
fn test_pack_index_update_with_update_flag() {
let index_dir = create_test_index(&[("existing-pack", "1.0.0")]);
let index_path = index_dir.path().join("index.json");
let pack_dir = create_test_pack("existing-pack", "2.0.0", &[]);
let mut cmd = Command::cargo_bin("attune").unwrap();
cmd.arg("pack")
.arg("index-update")
.arg("--index")
.arg(index_path.to_str().unwrap())
.arg(pack_dir.path().to_str().unwrap())
.arg("--git-url")
.arg("https://github.com/test/existing-pack.git")
.arg("--git-ref")
.arg("v2.0.0")
.arg("--update");
cmd.assert()
.success()
.stdout(predicate::str::contains("existing-pack"))
.stdout(predicate::str::contains("2.0.0"));
// Verify version was updated
let updated_index = fs::read_to_string(&index_path).unwrap();
let json: Value = serde_json::from_str(&updated_index).unwrap();
let packs = json["packs"].as_array().unwrap();
assert_eq!(packs.len(), 1);
assert_eq!(packs[0]["version"], "2.0.0");
}
#[test]
fn test_pack_index_update_invalid_index_file() {
let temp_dir = TempDir::new().unwrap();
let bad_index = temp_dir.path().join("bad-index.json");
fs::write(&bad_index, "not valid json {").unwrap();
let pack_dir = create_test_pack("test-pack", "1.0.0", &[]);
let mut cmd = Command::cargo_bin("attune").unwrap();
cmd.arg("pack")
.arg("index-update")
.arg("--index")
.arg(bad_index.to_str().unwrap())
.arg(pack_dir.path().to_str().unwrap());
cmd.assert().failure();
}
#[test]
fn test_pack_index_merge_combines_indexes() {
let index1 = create_test_index(&[("pack-a", "1.0.0"), ("pack-b", "1.0.0")]);
let index2 = create_test_index(&[("pack-c", "1.0.0"), ("pack-d", "1.0.0")]);
let output_dir = TempDir::new().unwrap();
let output_path = output_dir.path().join("merged.json");
let mut cmd = Command::cargo_bin("attune").unwrap();
cmd.arg("pack")
.arg("index-merge")
.arg("--file")
.arg(output_path.to_str().unwrap())
.arg(index1.path().join("index.json").to_str().unwrap())
.arg(index2.path().join("index.json").to_str().unwrap());
cmd.assert()
.success()
.stdout(predicate::str::contains("Merged"))
.stdout(predicate::str::contains("2"));
// Verify merged file
let merged_content = fs::read_to_string(&output_path).unwrap();
let json: Value = serde_json::from_str(&merged_content).unwrap();
assert_eq!(json["packs"].as_array().unwrap().len(), 4);
}
#[test]
fn test_pack_index_merge_deduplicates() {
let index1 = create_test_index(&[("pack-a", "1.0.0"), ("pack-b", "1.0.0")]);
let index2 = create_test_index(&[("pack-a", "2.0.0"), ("pack-c", "1.0.0")]);
let output_dir = TempDir::new().unwrap();
let output_path = output_dir.path().join("merged.json");
let mut cmd = Command::cargo_bin("attune").unwrap();
cmd.arg("pack")
.arg("index-merge")
.arg("--file")
.arg(output_path.to_str().unwrap())
.arg(index1.path().join("index.json").to_str().unwrap())
.arg(index2.path().join("index.json").to_str().unwrap());
cmd.assert()
.success()
.stdout(predicate::str::contains("Duplicates resolved"));
// Verify deduplication (should have 3 unique packs: pack-a, pack-b, pack-c)
let merged_content = fs::read_to_string(&output_path).unwrap();
let json: Value = serde_json::from_str(&merged_content).unwrap();
let packs = json["packs"].as_array().unwrap();
assert_eq!(packs.len(), 3);
// Verify pack-a has the newer version
let pack_a = packs.iter().find(|p| p["ref"] == "pack-a").unwrap();
assert_eq!(pack_a["version"], "2.0.0");
}
#[test]
fn test_pack_index_merge_output_exists_without_force() {
let index1 = create_test_index(&[("pack-a", "1.0.0")]);
let output_dir = TempDir::new().unwrap();
let output_path = output_dir.path().join("merged.json");
fs::write(&output_path, "existing content").unwrap();
let mut cmd = Command::cargo_bin("attune").unwrap();
cmd.arg("pack")
.arg("index-merge")
.arg("--file")
.arg(output_path.to_str().unwrap())
.arg(index1.path().join("index.json").to_str().unwrap());
cmd.assert()
.failure()
.stderr(predicate::str::contains("already exists").or(predicate::str::contains("force")));
}
#[test]
fn test_pack_index_merge_with_force_flag() {
let index1 = create_test_index(&[("pack-a", "1.0.0")]);
let output_dir = TempDir::new().unwrap();
let output_path = output_dir.path().join("merged.json");
fs::write(&output_path, "existing content").unwrap();
let mut cmd = Command::cargo_bin("attune").unwrap();
cmd.arg("pack")
.arg("index-merge")
.arg("--file")
.arg(output_path.to_str().unwrap())
.arg(index1.path().join("index.json").to_str().unwrap())
.arg("--force");
cmd.assert().success();
// Verify file was overwritten
let merged_content = fs::read_to_string(&output_path).unwrap();
assert_ne!(merged_content, "existing content");
}
#[test]
fn test_pack_index_merge_empty_input_list() {
let output_dir = TempDir::new().unwrap();
let output_path = output_dir.path().join("merged.json");
let mut cmd = Command::cargo_bin("attune").unwrap();
cmd.arg("pack")
.arg("index-merge")
.arg("--file")
.arg(output_path.to_str().unwrap());
// Should fail due to missing required inputs
cmd.assert().failure();
}
#[test]
fn test_pack_index_merge_missing_input_file() {
let index1 = create_test_index(&[("pack-a", "1.0.0")]);
let output_dir = TempDir::new().unwrap();
let output_path = output_dir.path().join("merged.json");
let mut cmd = Command::cargo_bin("attune").unwrap();
cmd.arg("pack")
.arg("index-merge")
.arg("--file")
.arg(output_path.to_str().unwrap())
.arg(index1.path().join("index.json").to_str().unwrap())
.arg("/nonexistent/index.json");
// Should succeed but skip missing file (with warning in stderr)
cmd.assert()
.success()
.stderr(predicate::str::contains("Skipping").or(predicate::str::contains("missing")));
}
#[test]
fn test_pack_commands_help() {
let commands = vec![
vec!["pack", "checksum", "--help"],
vec!["pack", "index-entry", "--help"],
vec!["pack", "index-update", "--help"],
vec!["pack", "index-merge", "--help"],
];
for args in commands {
let mut cmd = Command::cargo_bin("attune").unwrap();
for arg in &args {
cmd.arg(arg);
}
cmd.assert()
.success()
.stdout(predicate::str::contains("Usage:"));
}
}