Remove TESTING.md, fix CLI argument naming (--repo-version), enhance transaction publisher handling, and improve manifest storage logic.

This commit is contained in:
Till Wegmueller 2025-07-26 11:52:42 +02:00
parent 4f0e2fe066
commit 307dfddc7c
No known key found for this signature in database
5 changed files with 76 additions and 87 deletions

View file

@ -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

View file

@ -235,6 +235,8 @@ pub struct Transaction {
files: Vec<(PathBuf, String)>, // (source_path, sha256)
/// Repository reference
repo: PathBuf,
/// Publisher name
publisher: Option<String>,
}
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) => {

View file

@ -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...");

View file

@ -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

View file

@ -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(())