mirror of
https://codeberg.org/Toasterson/ips.git
synced 2026-04-10 13:20:42 +00:00
Remove TESTING.md, fix CLI argument naming (--repo-version), enhance transaction publisher handling, and improve manifest storage logic.
This commit is contained in:
parent
4f0e2fe066
commit
307dfddc7c
5 changed files with 76 additions and 87 deletions
69
TESTING.md
69
TESTING.md
|
|
@ -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
|
|
||||||
|
|
@ -235,6 +235,8 @@ pub struct Transaction {
|
||||||
files: Vec<(PathBuf, String)>, // (source_path, sha256)
|
files: Vec<(PathBuf, String)>, // (source_path, sha256)
|
||||||
/// Repository reference
|
/// Repository reference
|
||||||
repo: PathBuf,
|
repo: PathBuf,
|
||||||
|
/// Publisher name
|
||||||
|
publisher: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Transaction {
|
impl Transaction {
|
||||||
|
|
@ -257,9 +259,15 @@ impl Transaction {
|
||||||
manifest: Manifest::new(),
|
manifest: Manifest::new(),
|
||||||
files: Vec::new(),
|
files: Vec::new(),
|
||||||
repo: repo_path,
|
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
|
/// Update the manifest in the transaction
|
||||||
///
|
///
|
||||||
/// This intelligently merges the provided manifest with the existing one,
|
/// 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
|
// Move the manifest to its final location in the repository
|
||||||
// Store in both the pkg directory and the trans directory as required
|
// 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
|
let trans_manifest_path = self
|
||||||
.repo
|
.repo
|
||||||
.join("trans")
|
.join("trans")
|
||||||
|
|
@ -588,8 +622,8 @@ impl ReadableRepository for FileBackend {
|
||||||
for entry in entries.flatten() {
|
for entry in entries.flatten() {
|
||||||
let path = entry.path();
|
let path = entry.path();
|
||||||
|
|
||||||
// Skip directories, only process files (package manifests)
|
// Skip directories, only process files with .manifest extension
|
||||||
if path.is_file() {
|
if path.is_file() && path.extension().map_or(false, |ext| ext == "manifest") {
|
||||||
// Parse the manifest file to get real package information
|
// Parse the manifest file to get real package information
|
||||||
match Manifest::parse_file(&path) {
|
match Manifest::parse_file(&path) {
|
||||||
Ok(manifest) => {
|
Ok(manifest) => {
|
||||||
|
|
@ -730,8 +764,8 @@ impl ReadableRepository for FileBackend {
|
||||||
for entry in entries.flatten() {
|
for entry in entries.flatten() {
|
||||||
let path = entry.path();
|
let path = entry.path();
|
||||||
|
|
||||||
// Skip directories, only process files (package manifests)
|
// Skip directories, only process files with .manifest extension
|
||||||
if path.is_file() {
|
if path.is_file() && path.extension().map_or(false, |ext| ext == "manifest") {
|
||||||
// Parse the manifest file to get package information
|
// Parse the manifest file to get package information
|
||||||
match Manifest::parse_file(&path) {
|
match Manifest::parse_file(&path) {
|
||||||
Ok(manifest) => {
|
Ok(manifest) => {
|
||||||
|
|
|
||||||
|
|
@ -119,10 +119,34 @@ mod tests {
|
||||||
println!("Updating manifest in transaction...");
|
println!("Updating manifest in transaction...");
|
||||||
transaction.update_manifest(manifest);
|
transaction.update_manifest(manifest);
|
||||||
|
|
||||||
|
// Set the publisher for the transaction
|
||||||
|
println!("Setting publisher: {}", publisher);
|
||||||
|
transaction.set_publisher(publisher);
|
||||||
|
|
||||||
// Commit the transaction
|
// Commit the transaction
|
||||||
println!("Committing transaction...");
|
println!("Committing transaction...");
|
||||||
transaction.commit()?;
|
transaction.commit()?;
|
||||||
println!("Transaction committed successfully");
|
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
|
// Rebuild the catalog
|
||||||
println!("Rebuilding catalog...");
|
println!("Rebuilding catalog...");
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod e2e_tests {
|
mod e2e_tests {
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::PathBuf;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
|
|
@ -102,7 +102,7 @@ mod e2e_tests {
|
||||||
let repo_path = test_dir.join("repo");
|
let repo_path = test_dir.join("repo");
|
||||||
|
|
||||||
// Create a repository using pkg6repo
|
// 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());
|
assert!(result.is_ok(), "Failed to create repository: {:?}", result.err());
|
||||||
|
|
||||||
// Check that the repository was created
|
// Check that the repository was created
|
||||||
|
|
@ -125,7 +125,7 @@ mod e2e_tests {
|
||||||
let repo_path = test_dir.join("repo");
|
let repo_path = test_dir.join("repo");
|
||||||
|
|
||||||
// Create a repository using pkg6repo
|
// 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());
|
assert!(result.is_ok(), "Failed to create repository: {:?}", result.err());
|
||||||
|
|
||||||
// Add a publisher using pkg6repo
|
// Add a publisher using pkg6repo
|
||||||
|
|
@ -154,7 +154,7 @@ mod e2e_tests {
|
||||||
let repo_path = test_dir.join("repo");
|
let repo_path = test_dir.join("repo");
|
||||||
|
|
||||||
// Create a repository using pkg6repo
|
// 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());
|
assert!(result.is_ok(), "Failed to create repository: {:?}", result.err());
|
||||||
|
|
||||||
// Add a publisher using pkg6repo
|
// Add a publisher using pkg6repo
|
||||||
|
|
@ -199,7 +199,7 @@ mod e2e_tests {
|
||||||
let repo_path = test_dir.join("repo");
|
let repo_path = test_dir.join("repo");
|
||||||
|
|
||||||
// Create a repository using pkg6repo
|
// 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());
|
assert!(result.is_ok(), "Failed to create repository: {:?}", result.err());
|
||||||
|
|
||||||
// Add a publisher using pkg6repo
|
// Add a publisher using pkg6repo
|
||||||
|
|
@ -247,7 +247,7 @@ mod e2e_tests {
|
||||||
let repo_path = test_dir.join("repo");
|
let repo_path = test_dir.join("repo");
|
||||||
|
|
||||||
// Create a repository using pkg6repo
|
// 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());
|
assert!(result.is_ok(), "Failed to create repository: {:?}", result.err());
|
||||||
|
|
||||||
// Add a publisher using pkg6repo
|
// Add a publisher using pkg6repo
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,8 @@ enum Commands {
|
||||||
/// Create a new package repository
|
/// Create a new package repository
|
||||||
Create {
|
Create {
|
||||||
/// Version of the repository to create
|
/// Version of the repository to create
|
||||||
#[clap(long, default_value = "4")]
|
#[clap(long = "repo-version", default_value = "4")]
|
||||||
version: u32,
|
repo_version: u32,
|
||||||
|
|
||||||
/// Path or URI of the repository to create
|
/// Path or URI of the repository to create
|
||||||
uri_or_path: String,
|
uri_or_path: String,
|
||||||
|
|
@ -245,14 +245,14 @@ fn main() -> Result<()> {
|
||||||
let cli = App::parse();
|
let cli = App::parse();
|
||||||
|
|
||||||
match &cli.command {
|
match &cli.command {
|
||||||
Commands::Create { version, uri_or_path } => {
|
Commands::Create { repo_version, uri_or_path } => {
|
||||||
println!("Creating repository version {} at {}", version, uri_or_path);
|
println!("Creating repository version {} at {}", repo_version, uri_or_path);
|
||||||
|
|
||||||
// Convert version to RepositoryVersion
|
// Convert repo_version to RepositoryVersion
|
||||||
let repo_version = RepositoryVersion::try_from(*version)?;
|
let repo_version_enum = RepositoryVersion::try_from(*repo_version)?;
|
||||||
|
|
||||||
// Create the repository
|
// 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());
|
println!("Repository created successfully at {}", repo.path.display());
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue