diff --git a/.gitignore b/.gitignore index 6229c73..eb799b5 100644 --- a/.gitignore +++ b/.gitignore @@ -90,4 +90,5 @@ Cargo.lock # Prototype directory sample_data/**/build/prototype/i386 -.vagrant \ No newline at end of file +.vagrant +/.output.txt diff --git a/TESTING.md b/TESTING.md new file mode 100644 index 0000000..4d12f5d --- /dev/null +++ b/TESTING.md @@ -0,0 +1,69 @@ +# 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/mod.rs b/libips/src/repository/mod.rs index daffdd9..7e88f74 100644 --- a/libips/src/repository/mod.rs +++ b/libips/src/repository/mod.rs @@ -10,6 +10,8 @@ use std::collections::HashMap; mod file_backend; mod rest_backend; mod catalog; +#[cfg(test)] +mod tests; pub use file_backend::FileBackend; pub use rest_backend::RestBackend; diff --git a/libips/src/repository/tests.rs b/libips/src/repository/tests.rs new file mode 100644 index 0000000..38e18d5 --- /dev/null +++ b/libips/src/repository/tests.rs @@ -0,0 +1,354 @@ +// This Source Code Form is subject to the terms of +// the Mozilla Public License, v. 2.0. If a copy of the +// MPL was not distributed with this file, You can +// obtain one at https://mozilla.org/MPL/2.0/. + +#[cfg(test)] +mod tests { + use crate::actions::Manifest; + use crate::fmri::Fmri; + use crate::repository::{ + CatalogManager, FileBackend, ReadableRepository, + RepositoryVersion, WritableRepository, REPOSITORY_CONFIG_FILENAME, + }; + use std::fs; + use std::path::PathBuf; + use std::process::Command; + + // The base directory for all test repositories + const TEST_REPO_BASE_DIR: &str = "/tmp/libips_repo_test"; + + // Helper function to create a unique test directory + fn create_test_dir(test_name: &str) -> PathBuf { + let test_dir = PathBuf::from(format!("{}/{}", TEST_REPO_BASE_DIR, test_name)); + + // Clean up any existing directory + if test_dir.exists() { + fs::remove_dir_all(&test_dir).unwrap(); + } + + // Create the directory + fs::create_dir_all(&test_dir).unwrap(); + + test_dir + } + + // Helper function to clean up test directory + fn cleanup_test_dir(test_dir: &PathBuf) { + if test_dir.exists() { + fs::remove_dir_all(test_dir).unwrap(); + } + } + + // Helper function to run the setup script + fn run_setup_script() -> (PathBuf, PathBuf) { + // Get the project root directory + let output = Command::new("git") + .args(["rev-parse", "--show-toplevel"]) + .output() + .expect("Failed to execute git command"); + + let project_root = String::from_utf8(output.stdout) + .expect("Invalid UTF-8 output") + .trim() + .to_string(); + + // Run the setup script + Command::new("bash") + .arg(format!("{}/setup_test_env.sh", project_root)) + .status() + .expect("Failed to run setup script"); + + // Return the paths to the prototype and manifest directories + ( + PathBuf::from("/tmp/pkg6_test/prototype"), + PathBuf::from("/tmp/pkg6_test/manifests"), + ) + } + + // Helper function to publish a package to a repository + fn publish_package( + repo: &mut FileBackend, + manifest_path: &PathBuf, + prototype_dir: &PathBuf, + publisher: &str, + ) -> Result<(), anyhow::Error> { + println!("Publishing package from manifest: {}", manifest_path.display()); + println!("Prototype directory: {}", prototype_dir.display()); + println!("Publisher: {}", publisher); + + // Check if the manifest file exists + if !manifest_path.exists() { + println!("Error: Manifest file does not exist"); + return Err(anyhow::anyhow!("Manifest file does not exist: {}", manifest_path.display())); + } + + // Check if the prototype directory exists + if !prototype_dir.exists() { + println!("Error: Prototype directory does not exist"); + return Err(anyhow::anyhow!("Prototype directory does not exist: {}", prototype_dir.display())); + } + + // Parse the manifest file + println!("Parsing manifest file..."); + let manifest = Manifest::parse_file(manifest_path)?; + println!("Manifest parsed successfully. Files: {}", manifest.files.len()); + + // Begin a transaction + println!("Beginning transaction..."); + let mut transaction = repo.begin_transaction()?; + + // Add files from the prototype directory to the transaction + println!("Adding files to transaction..."); + for file_action in manifest.files.iter() { + // Construct the full path to the file in the prototype directory + let file_path = prototype_dir.join(&file_action.path); + + // Check if the file exists + if !file_path.exists() { + println!("Warning: File does not exist in prototype directory: {}", file_path.display()); + continue; + } + + // Add the file to the transaction + println!("Adding file: {}", file_action.path); + transaction.add_file(file_action.clone(), &file_path)?; + } + + // Update the manifest in the transaction + println!("Updating manifest in transaction..."); + transaction.update_manifest(manifest); + + // Commit the transaction + println!("Committing transaction..."); + transaction.commit()?; + println!("Transaction committed successfully"); + + // Rebuild the catalog + println!("Rebuilding catalog..."); + repo.rebuild(Some(publisher), false, false)?; + println!("Catalog rebuilt successfully"); + + Ok(()) + } + + #[test] + fn test_create_repository() { + // Create a test directory + let test_dir = create_test_dir("create_repository"); + let repo_path = test_dir.join("repo"); + + // Create a repository + let _repo = FileBackend::create(&repo_path, RepositoryVersion::V4).unwrap(); + + // Check that the repository was created + assert!(repo_path.exists()); + assert!(repo_path.join("catalog").exists()); + assert!(repo_path.join("file").exists()); + assert!(repo_path.join("index").exists()); + assert!(repo_path.join("pkg").exists()); + assert!(repo_path.join("trans").exists()); + assert!(repo_path.join(REPOSITORY_CONFIG_FILENAME).exists()); + + // Clean up + cleanup_test_dir(&test_dir); + } + + #[test] + fn test_add_publisher() { + // Create a test directory + let test_dir = create_test_dir("add_publisher"); + let repo_path = test_dir.join("repo"); + + // Create a repository + let mut repo = FileBackend::create(&repo_path, RepositoryVersion::V4).unwrap(); + + // Add a publisher + repo.add_publisher("example.com").unwrap(); + + // Check that the publisher was added + assert!(repo.config.publishers.contains(&"example.com".to_string())); + assert!(repo_path.join("catalog").join("example.com").exists()); + assert!(repo_path.join("pkg").join("example.com").exists()); + + // Clean up + cleanup_test_dir(&test_dir); + } + + #[test] + fn test_catalog_manager() { + // Create a test directory + let test_dir = create_test_dir("catalog_manager"); + let catalog_dir = test_dir.join("catalog"); + + // Create the catalog directory + fs::create_dir_all(&catalog_dir).unwrap(); + + // Create a catalog manager + let mut catalog_manager = CatalogManager::new(&catalog_dir).unwrap(); + + // Create a catalog part + let part = catalog_manager.create_part("test_part"); + + // Add a package to the part + let fmri = Fmri::parse("pkg://test/example@1.0.0").unwrap(); + part.add_package("test", &fmri, None, None); + + // Save the part + catalog_manager.save_part("test_part").unwrap(); + + // Check that the part was saved + assert!(catalog_dir.join("test_part").exists()); + + // Create a new catalog manager and load the part + let mut new_catalog_manager = CatalogManager::new(&catalog_dir).unwrap(); + new_catalog_manager.load_part("test_part").unwrap(); + + // Check that the part was loaded + let loaded_part = new_catalog_manager.get_part("test_part").unwrap(); + assert_eq!(loaded_part.packages.len(), 1); + + // Clean up + cleanup_test_dir(&test_dir); + } + + #[test] + fn test_publish_files() { + // Run the setup script to prepare the test environment + let (prototype_dir, manifest_dir) = run_setup_script(); + + // Create a test directory + let test_dir = create_test_dir("publish_files"); + let repo_path = test_dir.join("repo"); + + // Create a repository + let mut repo = FileBackend::create(&repo_path, RepositoryVersion::V4).unwrap(); + + // Add a publisher + repo.add_publisher("test").unwrap(); + + // Publish a package using the manifest + let manifest_path = manifest_dir.join("example.p5m"); + publish_package(&mut repo, &manifest_path, &prototype_dir, "test").unwrap(); + + // Check that the files were published + assert!(repo_path.join("file").exists()); + + // Get repository information + let repo_info = repo.get_info().unwrap(); + + // Check that the publisher information is correct + assert_eq!(repo_info.publishers.len(), 1); + let publisher_info = &repo_info.publishers[0]; + assert_eq!(publisher_info.name, "test"); + + // Clean up + cleanup_test_dir(&test_dir); + } + + #[test] + fn test_list_packages() { + // Run the setup script to prepare the test environment + let (prototype_dir, manifest_dir) = run_setup_script(); + + // Create a test directory + let test_dir = create_test_dir("list_packages"); + let repo_path = test_dir.join("repo"); + + // Create a repository + let mut repo = FileBackend::create(&repo_path, RepositoryVersion::V4).unwrap(); + + // Add a publisher + repo.add_publisher("test").unwrap(); + + // Publish a package using the manifest + let manifest_path = manifest_dir.join("example.p5m"); + publish_package(&mut repo, &manifest_path, &prototype_dir, "test").unwrap(); + + // List packages + let packages = repo.list_packages(Some("test"), None).unwrap(); + + // Check that packages were listed + assert!(!packages.is_empty()); + + // Check that the package name is correct + assert_eq!(packages[0].fmri.name, "example"); + + // Clean up + cleanup_test_dir(&test_dir); + } + + #[test] + fn test_show_contents() { + // Run the setup script to prepare the test environment + let (prototype_dir, manifest_dir) = run_setup_script(); + + // Create a test directory + let test_dir = create_test_dir("show_contents"); + let repo_path = test_dir.join("repo"); + + // Create a repository + let mut repo = FileBackend::create(&repo_path, RepositoryVersion::V4).unwrap(); + + // Add a publisher + repo.add_publisher("test").unwrap(); + + // Publish a package using the manifest + let manifest_path = manifest_dir.join("example.p5m"); + publish_package(&mut repo, &manifest_path, &prototype_dir, "test").unwrap(); + + // Show contents + let contents = repo.show_contents(Some("test"), None, None).unwrap(); + + // Check that contents were shown + assert!(!contents.is_empty()); + + // Check that the contents include the expected files + let package_contents = &contents[0]; + assert!(package_contents.files.is_some()); + let files = package_contents.files.as_ref().unwrap(); + + // Check for specific files + assert!(files.iter().any(|f| f.contains("usr/bin/hello"))); + assert!(files.iter().any(|f| f.contains("usr/share/doc/example/README.txt"))); + assert!(files.iter().any(|f| f.contains("etc/config/example.conf"))); + + // Clean up + cleanup_test_dir(&test_dir); + } + + #[test] + fn test_search() { + // Run the setup script to prepare the test environment + let (prototype_dir, manifest_dir) = run_setup_script(); + + // Create a test directory + let test_dir = create_test_dir("search"); + let repo_path = test_dir.join("repo"); + + // Create a repository + let mut repo = FileBackend::create(&repo_path, RepositoryVersion::V4).unwrap(); + + // Add a publisher + repo.add_publisher("test").unwrap(); + + // Publish a package using the manifest + let manifest_path = manifest_dir.join("example.p5m"); + publish_package(&mut repo, &manifest_path, &prototype_dir, "test").unwrap(); + + // Build the search index + repo.rebuild(Some("test"), false, false).unwrap(); + + // Search for packages + let results = repo.search("example", Some("test"), None).unwrap(); + + // Check that search results were returned + assert!(!results.is_empty()); + + // Check that the package name is correct + assert_eq!(results[0].fmri.name, "example"); + + // Clean up + cleanup_test_dir(&test_dir); + } +} \ No newline at end of file diff --git a/pkg6repo/src/e2e_tests.rs b/pkg6repo/src/e2e_tests.rs new file mode 100644 index 0000000..3686e1e --- /dev/null +++ b/pkg6repo/src/e2e_tests.rs @@ -0,0 +1,295 @@ +// This Source Code Form is subject to the terms of +// the Mozilla Public License, v. 2.0. If a copy of the +// MPL was not distributed with this file, You can +// obtain one at https://mozilla.org/MPL/2.0/. + +#[cfg(test)] +mod e2e_tests { + use std::fs; + use std::path::{Path, PathBuf}; + use std::process::Command; + use std::str; + + // The base directory for all test repositories + const TEST_REPO_BASE_DIR: &str = "/tmp/pkg6repo_e2e_test"; + + // Helper function to create a unique test directory + fn create_test_dir(test_name: &str) -> PathBuf { + let test_dir = PathBuf::from(format!("{}/{}", TEST_REPO_BASE_DIR, test_name)); + + // Clean up any existing directory + if test_dir.exists() { + fs::remove_dir_all(&test_dir).unwrap(); + } + + // Create the directory + fs::create_dir_all(&test_dir).unwrap(); + + test_dir + } + + // Helper function to clean up test directory + fn cleanup_test_dir(test_dir: &PathBuf) { + if test_dir.exists() { + fs::remove_dir_all(test_dir).unwrap(); + } + } + + // Helper function to run the setup script + fn run_setup_script() -> (PathBuf, PathBuf) { + // Get the project root directory + let output = Command::new("git") + .args(["rev-parse", "--show-toplevel"]) + .output() + .expect("Failed to execute git command"); + + let project_root = String::from_utf8(output.stdout) + .expect("Invalid UTF-8 output") + .trim() + .to_string(); + + // Run the setup script + Command::new("bash") + .arg(format!("{}/setup_test_env.sh", project_root)) + .status() + .expect("Failed to run setup script"); + + // Return the paths to the prototype and manifest directories + ( + PathBuf::from("/tmp/pkg6_test/prototype"), + PathBuf::from("/tmp/pkg6_test/manifests"), + ) + } + + // Helper function to run pkg6repo command + fn run_pkg6repo(args: &[&str]) -> Result { + let output = Command::new("cargo") + .arg("run") + .arg("--bin") + .arg("pkg6repo") + .args(args) + .output() + .expect("Failed to execute pkg6repo command"); + + if output.status.success() { + Ok(String::from_utf8_lossy(&output.stdout).to_string()) + } else { + Err(String::from_utf8_lossy(&output.stderr).to_string()) + } + } + + // Helper function to run pkg6dev command + fn run_pkg6dev(args: &[&str]) -> Result { + let output = Command::new("cargo") + .arg("run") + .arg("--bin") + .arg("pkg6dev") + .args(args) + .output() + .expect("Failed to execute pkg6dev command"); + + if output.status.success() { + Ok(String::from_utf8_lossy(&output.stdout).to_string()) + } else { + Err(String::from_utf8_lossy(&output.stderr).to_string()) + } + } + + #[test] + fn test_e2e_create_repository() { + // Create a test directory + let test_dir = create_test_dir("e2e_create_repository"); + let repo_path = test_dir.join("repo"); + + // Create a repository using pkg6repo + let result = run_pkg6repo(&["create", "-v", "4", repo_path.to_str().unwrap()]); + assert!(result.is_ok(), "Failed to create repository: {:?}", result.err()); + + // Check that the repository was created + assert!(repo_path.exists()); + assert!(repo_path.join("catalog").exists()); + assert!(repo_path.join("file").exists()); + assert!(repo_path.join("index").exists()); + assert!(repo_path.join("pkg").exists()); + assert!(repo_path.join("trans").exists()); + assert!(repo_path.join("pkg6.repository").exists()); + + // Clean up + cleanup_test_dir(&test_dir); + } + + #[test] + fn test_e2e_add_publisher() { + // Create a test directory + let test_dir = create_test_dir("e2e_add_publisher"); + let repo_path = test_dir.join("repo"); + + // Create a repository using pkg6repo + let result = run_pkg6repo(&["create", "-v", "4", repo_path.to_str().unwrap()]); + assert!(result.is_ok(), "Failed to create repository: {:?}", result.err()); + + // Add a publisher using pkg6repo + let result = run_pkg6repo(&[ + "add-publisher", + repo_path.to_str().unwrap(), + "example.com", + ]); + assert!(result.is_ok(), "Failed to add publisher: {:?}", result.err()); + + // Check that the publisher was added + assert!(repo_path.join("catalog").join("example.com").exists()); + assert!(repo_path.join("pkg").join("example.com").exists()); + + // Clean up + cleanup_test_dir(&test_dir); + } + + #[test] + fn test_e2e_publish_package() { + // Run the setup script to prepare the test environment + let (prototype_dir, manifest_dir) = run_setup_script(); + + // Create a test directory + let test_dir = create_test_dir("e2e_publish_package"); + let repo_path = test_dir.join("repo"); + + // Create a repository using pkg6repo + let result = run_pkg6repo(&["create", "-v", "4", repo_path.to_str().unwrap()]); + assert!(result.is_ok(), "Failed to create repository: {:?}", result.err()); + + // Add a publisher using pkg6repo + let result = run_pkg6repo(&[ + "add-publisher", + repo_path.to_str().unwrap(), + "test", + ]); + assert!(result.is_ok(), "Failed to add publisher: {:?}", result.err()); + + // Publish a package using pkg6dev + let manifest_path = manifest_dir.join("example.p5m"); + let result = run_pkg6dev(&[ + "publish", + manifest_path.to_str().unwrap(), + prototype_dir.to_str().unwrap(), + repo_path.to_str().unwrap(), + ]); + assert!(result.is_ok(), "Failed to publish package: {:?}", result.err()); + + // Check that the package was published + let result = run_pkg6repo(&[ + "list", + repo_path.to_str().unwrap(), + ]); + assert!(result.is_ok(), "Failed to list packages: {:?}", result.err()); + + let output = result.unwrap(); + assert!(output.contains("example"), "Package not found in repository"); + + // Clean up + cleanup_test_dir(&test_dir); + } + + #[test] + fn test_e2e_show_contents() { + // Run the setup script to prepare the test environment + let (prototype_dir, manifest_dir) = run_setup_script(); + + // Create a test directory + let test_dir = create_test_dir("e2e_show_contents"); + let repo_path = test_dir.join("repo"); + + // Create a repository using pkg6repo + let result = run_pkg6repo(&["create", "-v", "4", repo_path.to_str().unwrap()]); + assert!(result.is_ok(), "Failed to create repository: {:?}", result.err()); + + // Add a publisher using pkg6repo + let result = run_pkg6repo(&[ + "add-publisher", + repo_path.to_str().unwrap(), + "test", + ]); + assert!(result.is_ok(), "Failed to add publisher: {:?}", result.err()); + + // Publish a package using pkg6dev + let manifest_path = manifest_dir.join("example.p5m"); + let result = run_pkg6dev(&[ + "publish", + manifest_path.to_str().unwrap(), + prototype_dir.to_str().unwrap(), + repo_path.to_str().unwrap(), + ]); + assert!(result.is_ok(), "Failed to publish package: {:?}", result.err()); + + // Show package contents using pkg6repo + let result = run_pkg6repo(&[ + "contents", + repo_path.to_str().unwrap(), + "example", + ]); + assert!(result.is_ok(), "Failed to show package contents: {:?}", result.err()); + + let output = result.unwrap(); + assert!(output.contains("usr/bin/hello"), "File not found in package contents"); + assert!(output.contains("usr/share/doc/example/README.txt"), "File not found in package contents"); + assert!(output.contains("etc/config/example.conf"), "File not found in package contents"); + + // Clean up + cleanup_test_dir(&test_dir); + } + + #[test] + fn test_e2e_multiple_packages() { + // Run the setup script to prepare the test environment + let (prototype_dir, manifest_dir) = run_setup_script(); + + // Create a test directory + let test_dir = create_test_dir("e2e_multiple_packages"); + let repo_path = test_dir.join("repo"); + + // Create a repository using pkg6repo + let result = run_pkg6repo(&["create", "-v", "4", repo_path.to_str().unwrap()]); + assert!(result.is_ok(), "Failed to create repository: {:?}", result.err()); + + // Add a publisher using pkg6repo + let result = run_pkg6repo(&[ + "add-publisher", + repo_path.to_str().unwrap(), + "test", + ]); + assert!(result.is_ok(), "Failed to add publisher: {:?}", result.err()); + + // Publish the first package using pkg6dev + let manifest_path1 = manifest_dir.join("example.p5m"); + let result = run_pkg6dev(&[ + "publish", + manifest_path1.to_str().unwrap(), + prototype_dir.to_str().unwrap(), + repo_path.to_str().unwrap(), + ]); + assert!(result.is_ok(), "Failed to publish first package: {:?}", result.err()); + + // Publish the second package using pkg6dev + let manifest_path2 = manifest_dir.join("example2.p5m"); + let result = run_pkg6dev(&[ + "publish", + manifest_path2.to_str().unwrap(), + prototype_dir.to_str().unwrap(), + repo_path.to_str().unwrap(), + ]); + assert!(result.is_ok(), "Failed to publish second package: {:?}", result.err()); + + // List packages using pkg6repo + let result = run_pkg6repo(&[ + "list", + repo_path.to_str().unwrap(), + ]); + assert!(result.is_ok(), "Failed to list packages: {:?}", result.err()); + + let output = result.unwrap(); + assert!(output.contains("example"), "First package not found in repository"); + assert!(output.contains("example2"), "Second package not found in repository"); + + // Clean up + cleanup_test_dir(&test_dir); + } +} \ No newline at end of file diff --git a/pkg6repo/src/main.rs b/pkg6repo/src/main.rs index 54ba1c2..5f11e11 100644 --- a/pkg6repo/src/main.rs +++ b/pkg6repo/src/main.rs @@ -7,6 +7,8 @@ use libips::repository::{FileBackend, ReadableRepository, RepositoryVersion, Wri #[cfg(test)] mod tests; +#[cfg(test)] +mod e2e_tests; /// pkg6repo - Image Packaging System repository management utility #[derive(Parser, Debug)] diff --git a/setup_test_env.sh b/setup_test_env.sh new file mode 100755 index 0000000..b7b18fb --- /dev/null +++ b/setup_test_env.sh @@ -0,0 +1,74 @@ +#!/bin/bash +# Script to set up the test environment for repository tests + +set -e # Exit on error + +# Directory where test files will be created +TEST_BASE_DIR="/tmp/pkg6_test" +PROTOTYPE_DIR="$TEST_BASE_DIR/prototype" +MANIFEST_DIR="$TEST_BASE_DIR/manifests" + +# Clean up any existing test directories +if [ -d "$TEST_BASE_DIR" ]; then + echo "Cleaning up existing test directory..." + rm -rf "$TEST_BASE_DIR" +fi + +# Create test directories +echo "Creating test directories..." +mkdir -p "$PROTOTYPE_DIR" +mkdir -p "$MANIFEST_DIR" + +# Compile the applications +echo "Compiling applications..." +cd "$(dirname "$0")" +cargo build + +# Create a simple prototype directory structure with some files +echo "Creating prototype directory structure..." + +# Create some directories +mkdir -p "$PROTOTYPE_DIR/usr/bin" +mkdir -p "$PROTOTYPE_DIR/usr/share/doc/example" +mkdir -p "$PROTOTYPE_DIR/etc/config" + +# Create some files +echo "#!/bin/sh\necho 'Hello, World!'" > "$PROTOTYPE_DIR/usr/bin/hello" +chmod +x "$PROTOTYPE_DIR/usr/bin/hello" + +echo "This is an example document." > "$PROTOTYPE_DIR/usr/share/doc/example/README.txt" + +echo "# Example configuration file\nvalue=42" > "$PROTOTYPE_DIR/etc/config/example.conf" + +# Create a simple manifest +echo "Creating package manifest..." +cat > "$MANIFEST_DIR/example.p5m" << EOF +set name=pkg.fmri value=pkg://test/example@1.0.0 +set name=pkg.summary value="Example package for testing" +set name=pkg.description value="This is an example package used for testing the repository implementation." +set name=info.classification value="org.opensolaris.category.2008:System/Core" +set name=variant.arch value=i386 value=sparc +file path=usr/bin/hello mode=0755 owner=root group=bin +file path=usr/share/doc/example/README.txt mode=0644 owner=root group=bin +file path=etc/config/example.conf mode=0644 owner=root group=bin preserve=true +dir path=usr/bin mode=0755 owner=root group=bin +dir path=usr/share/doc/example mode=0755 owner=root group=bin +dir path=etc/config mode=0755 owner=root group=sys +EOF + +# Create a second manifest for testing multiple packages +cat > "$MANIFEST_DIR/example2.p5m" << EOF +set name=pkg.fmri value=pkg://test/example2@1.0.0 +set name=pkg.summary value="Second example package for testing" +set name=pkg.description value="This is a second example package used for testing the repository implementation." +set name=info.classification value="org.opensolaris.category.2008:System/Core" +set name=variant.arch value=i386 value=sparc +file path=usr/bin/hello mode=0755 owner=root group=bin +file path=usr/share/doc/example/README.txt mode=0644 owner=root group=bin +dir path=usr/bin mode=0755 owner=root group=bin +dir path=usr/share/doc/example mode=0755 owner=root group=bin +EOF + +echo "Test environment setup complete!" +echo "Prototype directory: $PROTOTYPE_DIR" +echo "Manifest directory: $MANIFEST_DIR" \ No newline at end of file