diff --git a/TESTING.md b/TESTING.md deleted file mode 100644 index 4d12f5d..0000000 --- a/TESTING.md +++ /dev/null @@ -1,69 +0,0 @@ -# Repository Testing - -This document describes the testing infrastructure for the repository implementation in the IPS project. - -## Overview - -The repository implementation is tested at two levels: - -1. **Unit Tests**: Tests for the individual components of the repository implementation, such as the FileBackend, CatalogManager, etc. -2. **End-to-End Tests**: Tests for the complete workflow of creating a repository, adding packages, and querying the repository. - -## Test Setup - -Before running the tests, you need to set up the test environment by running the `setup_test_env.sh` script: - -```bash -./setup_test_env.sh -``` - -This script: -1. Compiles the application -2. Creates a prototype directory with example files -3. Creates package manifests for testing - -## Unit Tests - -The unit tests are implemented in `libips/src/repository/tests.rs`. These tests cover: - -- Creating a repository -- Adding a publisher -- Testing the CatalogManager functionality -- Publishing files to a repository -- Listing packages in a repository -- Showing package contents -- Searching for packages - -To run the unit tests: - -```bash -cargo test repository::tests -``` - -**Note**: Some of the unit tests are currently failing due to issues with how packages are created and queried. These issues need to be addressed in future work. - -## End-to-End Tests - -The end-to-end tests are implemented in `pkg6repo/src/e2e_tests.rs`. These tests use the actual command-line tools to test the complete workflow: - -- Creating a repository using pkg6repo -- Adding a publisher to a repository -- Publishing a package to a repository using pkg6dev -- Showing package contents -- Publishing multiple packages - -To run the end-to-end tests: - -```bash -cargo test -p pkg6repo -``` - -**Note**: The end-to-end tests are currently failing due to a conflict with the argument name 'version' in the pkg6repo command-line interface. This issue needs to be addressed in future work. - -## Future Work - -1. Fix the unit tests to properly create and query packages -2. Fix the conflict with the argument name 'version' in the pkg6repo command-line interface -3. Add more comprehensive tests for edge cases and error conditions -4. Add tests for the RestBackend implementation -5. Add tests for the repository search functionality \ No newline at end of file diff --git a/libips/src/repository/file_backend.rs b/libips/src/repository/file_backend.rs index e3693bb..8624390 100644 --- a/libips/src/repository/file_backend.rs +++ b/libips/src/repository/file_backend.rs @@ -235,6 +235,8 @@ pub struct Transaction { files: Vec<(PathBuf, String)>, // (source_path, sha256) /// Repository reference repo: PathBuf, + /// Publisher name + publisher: Option, } impl Transaction { @@ -257,9 +259,15 @@ impl Transaction { manifest: Manifest::new(), files: Vec::new(), repo: repo_path, + publisher: None, }) } + /// Set the publisher for this transaction + pub fn set_publisher(&mut self, publisher: &str) { + self.publisher = Some(publisher.to_string()); + } + /// Update the manifest in the transaction /// /// This intelligently merges the provided manifest with the existing one, @@ -423,7 +431,33 @@ impl Transaction { // Move the manifest to its final location in the repository // Store in both the pkg directory and the trans directory as required - let pkg_manifest_path = self.repo.join("pkg").join("manifest"); + + // Extract package name from manifest + let mut package_name = String::from("unknown"); + for attr in &self.manifest.attributes { + if attr.key == "pkg.fmri" && !attr.values.is_empty() { + if let Ok(fmri) = Fmri::parse(&attr.values[0]) { + package_name = fmri.name.to_string(); + break; + } + } + } + + // Determine the pkg directory path based on publisher + let pkg_manifest_path = if let Some(publisher) = &self.publisher { + // Create publisher directory if it doesn't exist + let publisher_dir = self.repo.join("pkg").join(publisher); + if !publisher_dir.exists() { + fs::create_dir_all(&publisher_dir)?; + } + + // Store in publisher-specific directory with package name + publisher_dir.join(format!("{}.manifest", package_name)) + } else { + // Store in root pkg directory (legacy behavior) + self.repo.join("pkg").join("manifest") + }; + let trans_manifest_path = self .repo .join("trans") @@ -588,8 +622,8 @@ impl ReadableRepository for FileBackend { for entry in entries.flatten() { let path = entry.path(); - // Skip directories, only process files (package manifests) - if path.is_file() { + // Skip directories, only process files with .manifest extension + if path.is_file() && path.extension().map_or(false, |ext| ext == "manifest") { // Parse the manifest file to get real package information match Manifest::parse_file(&path) { Ok(manifest) => { @@ -730,8 +764,8 @@ impl ReadableRepository for FileBackend { for entry in entries.flatten() { let path = entry.path(); - // Skip directories, only process files (package manifests) - if path.is_file() { + // Skip directories, only process files with .manifest extension + if path.is_file() && path.extension().map_or(false, |ext| ext == "manifest") { // Parse the manifest file to get package information match Manifest::parse_file(&path) { Ok(manifest) => { diff --git a/libips/src/repository/tests.rs b/libips/src/repository/tests.rs index 38e18d5..65dd4bc 100644 --- a/libips/src/repository/tests.rs +++ b/libips/src/repository/tests.rs @@ -119,10 +119,34 @@ mod tests { println!("Updating manifest in transaction..."); transaction.update_manifest(manifest); + // Set the publisher for the transaction + println!("Setting publisher: {}", publisher); + transaction.set_publisher(publisher); + // Commit the transaction println!("Committing transaction..."); transaction.commit()?; println!("Transaction committed successfully"); + + // Debug: Check if the package manifest was stored in the correct location + let publisher_pkg_dir = repo.path.join("pkg").join(publisher); + println!("Publisher package directory: {}", publisher_pkg_dir.display()); + + if publisher_pkg_dir.exists() { + println!("Publisher directory exists"); + + // List files in the publisher directory + if let Ok(entries) = std::fs::read_dir(&publisher_pkg_dir) { + println!("Files in publisher directory:"); + for entry in entries.flatten() { + println!(" {}", entry.path().display()); + } + } else { + println!("Failed to read publisher directory"); + } + } else { + println!("Publisher directory does not exist"); + } // Rebuild the catalog println!("Rebuilding catalog..."); diff --git a/pkg6repo/src/e2e_tests.rs b/pkg6repo/src/e2e_tests.rs index 3686e1e..8252c70 100644 --- a/pkg6repo/src/e2e_tests.rs +++ b/pkg6repo/src/e2e_tests.rs @@ -6,7 +6,7 @@ #[cfg(test)] mod e2e_tests { use std::fs; - use std::path::{Path, PathBuf}; + use std::path::PathBuf; use std::process::Command; use std::str; @@ -102,7 +102,7 @@ mod e2e_tests { let repo_path = test_dir.join("repo"); // Create a repository using pkg6repo - let result = run_pkg6repo(&["create", "-v", "4", repo_path.to_str().unwrap()]); + let result = run_pkg6repo(&["create", "--repo-version", "4", repo_path.to_str().unwrap()]); assert!(result.is_ok(), "Failed to create repository: {:?}", result.err()); // Check that the repository was created @@ -125,7 +125,7 @@ mod e2e_tests { let repo_path = test_dir.join("repo"); // Create a repository using pkg6repo - let result = run_pkg6repo(&["create", "-v", "4", repo_path.to_str().unwrap()]); + let result = run_pkg6repo(&["create", "--repo-version", "4", repo_path.to_str().unwrap()]); assert!(result.is_ok(), "Failed to create repository: {:?}", result.err()); // Add a publisher using pkg6repo @@ -154,7 +154,7 @@ mod e2e_tests { let repo_path = test_dir.join("repo"); // Create a repository using pkg6repo - let result = run_pkg6repo(&["create", "-v", "4", repo_path.to_str().unwrap()]); + let result = run_pkg6repo(&["create", "--repo-version", "4", repo_path.to_str().unwrap()]); assert!(result.is_ok(), "Failed to create repository: {:?}", result.err()); // Add a publisher using pkg6repo @@ -199,7 +199,7 @@ mod e2e_tests { let repo_path = test_dir.join("repo"); // Create a repository using pkg6repo - let result = run_pkg6repo(&["create", "-v", "4", repo_path.to_str().unwrap()]); + let result = run_pkg6repo(&["create", "--repo-version", "4", repo_path.to_str().unwrap()]); assert!(result.is_ok(), "Failed to create repository: {:?}", result.err()); // Add a publisher using pkg6repo @@ -247,7 +247,7 @@ mod e2e_tests { let repo_path = test_dir.join("repo"); // Create a repository using pkg6repo - let result = run_pkg6repo(&["create", "-v", "4", repo_path.to_str().unwrap()]); + let result = run_pkg6repo(&["create", "--repo-version", "4", repo_path.to_str().unwrap()]); assert!(result.is_ok(), "Failed to create repository: {:?}", result.err()); // Add a publisher using pkg6repo diff --git a/pkg6repo/src/main.rs b/pkg6repo/src/main.rs index 5f11e11..5af627c 100644 --- a/pkg6repo/src/main.rs +++ b/pkg6repo/src/main.rs @@ -24,8 +24,8 @@ enum Commands { /// Create a new package repository Create { /// Version of the repository to create - #[clap(long, default_value = "4")] - version: u32, + #[clap(long = "repo-version", default_value = "4")] + repo_version: u32, /// Path or URI of the repository to create uri_or_path: String, @@ -245,14 +245,14 @@ fn main() -> Result<()> { let cli = App::parse(); match &cli.command { - Commands::Create { version, uri_or_path } => { - println!("Creating repository version {} at {}", version, uri_or_path); + Commands::Create { repo_version, uri_or_path } => { + println!("Creating repository version {} at {}", repo_version, uri_or_path); - // Convert version to RepositoryVersion - let repo_version = RepositoryVersion::try_from(*version)?; + // Convert repo_version to RepositoryVersion + let repo_version_enum = RepositoryVersion::try_from(*repo_version)?; // Create the repository - let repo = FileBackend::create(uri_or_path, repo_version)?; + let repo = FileBackend::create(uri_or_path, repo_version_enum)?; println!("Repository created successfully at {}", repo.path.display()); Ok(())