diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2025-11-21 05:45:31 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2025-11-21 05:45:31 +0000 |
| commit | 12756fa66e3ec7f9dd24c66598085772829a8063 (patch) | |
| tree | d8eefd3548b6f0487a3c49852f583ea309e083d7 /grasp-audit/src | |
| parent | 7a81643367515a9d01eb2d4deb623e9a7c071a12 (diff) | |
removed test that checked repository test cleanup
Diffstat (limited to 'grasp-audit/src')
| -rw-r--r-- | grasp-audit/src/specs/grasp01/repository_creation.rs | 207 |
1 files changed, 89 insertions, 118 deletions
diff --git a/grasp-audit/src/specs/grasp01/repository_creation.rs b/grasp-audit/src/specs/grasp01/repository_creation.rs index bd6c16a..31ef400 100644 --- a/grasp-audit/src/specs/grasp01/repository_creation.rs +++ b/grasp-audit/src/specs/grasp01/repository_creation.rs | |||
| @@ -16,7 +16,7 @@ | |||
| 16 | //! cd grasp-audit && nix develop -c bash test-ngit-relay.sh --mode test | 16 | //! cd grasp-audit && nix develop -c bash test-ngit-relay.sh --mode test |
| 17 | //! ``` | 17 | //! ``` |
| 18 | 18 | ||
| 19 | use crate::{AuditClient, TestContext, FixtureKind, TestResult}; | 19 | use crate::{AuditClient, FixtureKind, TestContext, TestResult}; |
| 20 | use nostr_sdk::prelude::*; | 20 | use nostr_sdk::prelude::*; |
| 21 | use std::path::Path; | 21 | use std::path::Path; |
| 22 | 22 | ||
| @@ -36,58 +36,74 @@ impl RepositoryCreationTests { | |||
| 36 | ) -> TestResult { | 36 | ) -> TestResult { |
| 37 | let test_name = "test_bare_repo_created_on_announcement"; | 37 | let test_name = "test_bare_repo_created_on_announcement"; |
| 38 | let ctx = TestContext::new(client); | 38 | let ctx = TestContext::new(client); |
| 39 | 39 | ||
| 40 | // Use TestContext to create and send repository announcement | 40 | // Use TestContext to create and send repository announcement |
| 41 | let repo = match ctx.get_fixture(FixtureKind::ValidRepo).await { | 41 | let repo = match ctx.get_fixture(FixtureKind::ValidRepo).await { |
| 42 | Ok(r) => r, | 42 | Ok(r) => r, |
| 43 | Err(e) => return TestResult::new( | 43 | Err(e) => { |
| 44 | test_name, | 44 | return TestResult::new( |
| 45 | "GRASP-01", | 45 | test_name, |
| 46 | "Bare repository must be created when announcement is accepted", | 46 | "GRASP-01", |
| 47 | ).fail(&format!("Failed to create repo fixture: {}", e)), | 47 | "Bare repository must be created when announcement is accepted", |
| 48 | ) | ||
| 49 | .fail(&format!("Failed to create repo fixture: {}", e)) | ||
| 50 | } | ||
| 48 | }; | 51 | }; |
| 49 | 52 | ||
| 50 | // Wait a bit for repository creation | 53 | // Wait a bit for repository creation |
| 51 | tokio::time::sleep(std::time::Duration::from_millis(200)).await; | 54 | tokio::time::sleep(std::time::Duration::from_millis(200)).await; |
| 52 | 55 | ||
| 53 | // Extract repo identifier and npub from announcement | 56 | // Extract repo identifier and npub from announcement |
| 54 | let repo_id = match repo.tags.iter() | 57 | let repo_id = match repo |
| 58 | .tags | ||
| 59 | .iter() | ||
| 55 | .find(|t| t.kind() == TagKind::d()) | 60 | .find(|t| t.kind() == TagKind::d()) |
| 56 | .and_then(|t| t.content()) | 61 | .and_then(|t| t.content()) |
| 57 | { | 62 | { |
| 58 | Some(id) => id.to_string(), | 63 | Some(id) => id.to_string(), |
| 59 | None => return TestResult::new( | 64 | None => { |
| 60 | test_name, | 65 | return TestResult::new( |
| 61 | "GRASP-01", | 66 | test_name, |
| 62 | "Bare repository must be created when announcement is accepted", | 67 | "GRASP-01", |
| 63 | ).fail("Repository announcement missing d tag"), | 68 | "Bare repository must be created when announcement is accepted", |
| 69 | ) | ||
| 70 | .fail("Repository announcement missing d tag") | ||
| 71 | } | ||
| 64 | }; | 72 | }; |
| 65 | 73 | ||
| 66 | let npub = match repo.pubkey.to_bech32() { | 74 | let npub = match repo.pubkey.to_bech32() { |
| 67 | Ok(n) => n, | 75 | Ok(n) => n, |
| 68 | Err(e) => return TestResult::new( | 76 | Err(e) => { |
| 69 | test_name, | 77 | return TestResult::new( |
| 70 | "GRASP-01", | 78 | test_name, |
| 71 | "Bare repository must be created when announcement is accepted", | 79 | "GRASP-01", |
| 72 | ).fail(&format!("Failed to convert pubkey to npub: {}", e)), | 80 | "Bare repository must be created when announcement is accepted", |
| 81 | ) | ||
| 82 | .fail(&format!("Failed to convert pubkey to npub: {}", e)) | ||
| 83 | } | ||
| 73 | }; | 84 | }; |
| 74 | 85 | ||
| 75 | // Check if repository was created | 86 | // Check if repository was created |
| 76 | let repo_path = git_data_dir.join(&npub).join(format!("{}.git", repo_id)); | 87 | let repo_path = git_data_dir.join(&npub).join(format!("{}.git", repo_id)); |
| 77 | 88 | ||
| 78 | if !is_bare_repository(&repo_path) { | 89 | if !is_bare_repository(&repo_path) { |
| 79 | return TestResult::new( | 90 | return TestResult::new( |
| 80 | test_name, | 91 | test_name, |
| 81 | "GRASP-01", | 92 | "GRASP-01", |
| 82 | "Bare repository must be created when announcement is accepted", | 93 | "Bare repository must be created when announcement is accepted", |
| 83 | ).fail(&format!("Bare repository not found at: {}", repo_path.display())); | 94 | ) |
| 95 | .fail(&format!( | ||
| 96 | "Bare repository not found at: {}", | ||
| 97 | repo_path.display() | ||
| 98 | )); | ||
| 84 | } | 99 | } |
| 85 | 100 | ||
| 86 | TestResult::new( | 101 | TestResult::new( |
| 87 | test_name, | 102 | test_name, |
| 88 | "GRASP-01", | 103 | "GRASP-01", |
| 89 | "Bare repository must be created when announcement is accepted", | 104 | "Bare repository must be created when announcement is accepted", |
| 90 | ).pass() | 105 | ) |
| 106 | .pass() | ||
| 91 | } | 107 | } |
| 92 | 108 | ||
| 93 | /// Test that repository creation is idempotent | 109 | /// Test that repository creation is idempotent |
| @@ -102,15 +118,18 @@ impl RepositoryCreationTests { | |||
| 102 | ) -> TestResult { | 118 | ) -> TestResult { |
| 103 | let test_name = "test_repo_creation_idempotent"; | 119 | let test_name = "test_repo_creation_idempotent"; |
| 104 | let ctx = TestContext::new(client); | 120 | let ctx = TestContext::new(client); |
| 105 | 121 | ||
| 106 | // Create and send repository announcement first time via TestContext | 122 | // Create and send repository announcement first time via TestContext |
| 107 | let repo = match ctx.get_fixture(FixtureKind::ValidRepo).await { | 123 | let repo = match ctx.get_fixture(FixtureKind::ValidRepo).await { |
| 108 | Ok(r) => r, | 124 | Ok(r) => r, |
| 109 | Err(e) => return TestResult::new( | 125 | Err(e) => { |
| 110 | test_name, | 126 | return TestResult::new( |
| 111 | "GRASP-01", | 127 | test_name, |
| 112 | "Repository creation must be idempotent", | 128 | "GRASP-01", |
| 113 | ).fail(&format!("Failed to create repo fixture: {}", e)), | 129 | "Repository creation must be idempotent", |
| 130 | ) | ||
| 131 | .fail(&format!("Failed to create repo fixture: {}", e)) | ||
| 132 | } | ||
| 114 | }; | 133 | }; |
| 115 | 134 | ||
| 116 | // Wait for repository creation | 135 | // Wait for repository creation |
| @@ -122,14 +141,17 @@ impl RepositoryCreationTests { | |||
| 122 | test_name, | 141 | test_name, |
| 123 | "GRASP-01", | 142 | "GRASP-01", |
| 124 | "Repository creation must be idempotent", | 143 | "Repository creation must be idempotent", |
| 125 | ).fail(&format!("Second send failed (not idempotent): {}", e)); | 144 | ) |
| 145 | .fail(&format!("Second send failed (not idempotent): {}", e)); | ||
| 126 | } | 146 | } |
| 127 | 147 | ||
| 128 | // Wait again | 148 | // Wait again |
| 129 | tokio::time::sleep(std::time::Duration::from_millis(200)).await; | 149 | tokio::time::sleep(std::time::Duration::from_millis(200)).await; |
| 130 | 150 | ||
| 131 | // Verify repository still exists and is valid | 151 | // Verify repository still exists and is valid |
| 132 | let repo_id = repo.tags.iter() | 152 | let repo_id = repo |
| 153 | .tags | ||
| 154 | .iter() | ||
| 133 | .find(|t| t.kind() == TagKind::d()) | 155 | .find(|t| t.kind() == TagKind::d()) |
| 134 | .and_then(|t| t.content()) | 156 | .and_then(|t| t.content()) |
| 135 | .ok_or("Missing d tag") | 157 | .ok_or("Missing d tag") |
| @@ -138,20 +160,22 @@ impl RepositoryCreationTests { | |||
| 138 | 160 | ||
| 139 | let npub = repo.pubkey.to_bech32().unwrap(); | 161 | let npub = repo.pubkey.to_bech32().unwrap(); |
| 140 | let repo_path = git_data_dir.join(&npub).join(format!("{}.git", repo_id)); | 162 | let repo_path = git_data_dir.join(&npub).join(format!("{}.git", repo_id)); |
| 141 | 163 | ||
| 142 | if !is_bare_repository(&repo_path) { | 164 | if !is_bare_repository(&repo_path) { |
| 143 | return TestResult::new( | 165 | return TestResult::new( |
| 144 | test_name, | 166 | test_name, |
| 145 | "GRASP-01", | 167 | "GRASP-01", |
| 146 | "Repository creation must be idempotent", | 168 | "Repository creation must be idempotent", |
| 147 | ).fail("Repository not found after second send"); | 169 | ) |
| 170 | .fail("Repository not found after second send"); | ||
| 148 | } | 171 | } |
| 149 | 172 | ||
| 150 | TestResult::new( | 173 | TestResult::new( |
| 151 | test_name, | 174 | test_name, |
| 152 | "GRASP-01", | 175 | "GRASP-01", |
| 153 | "Repository creation must be idempotent", | 176 | "Repository creation must be idempotent", |
| 154 | ).pass() | 177 | ) |
| 178 | .pass() | ||
| 155 | } | 179 | } |
| 156 | 180 | ||
| 157 | /// Test that the repository has the correct structure | 181 | /// Test that the repository has the correct structure |
| @@ -160,28 +184,30 @@ impl RepositoryCreationTests { | |||
| 160 | /// 1. Repository is at <git_data_path>/<npub>/<identifier>.git | 184 | /// 1. Repository is at <git_data_path>/<npub>/<identifier>.git |
| 161 | /// 2. Repository is bare (no working directory) | 185 | /// 2. Repository is bare (no working directory) |
| 162 | /// 3. Repository has required git structure (HEAD, config, objects/, refs/) | 186 | /// 3. Repository has required git structure (HEAD, config, objects/, refs/) |
| 163 | pub async fn test_bare_repo_structure( | 187 | pub async fn test_bare_repo_structure(client: &AuditClient, git_data_dir: &Path) -> TestResult { |
| 164 | client: &AuditClient, | ||
| 165 | git_data_dir: &Path, | ||
| 166 | ) -> TestResult { | ||
| 167 | let test_name = "test_bare_repo_structure"; | 188 | let test_name = "test_bare_repo_structure"; |
| 168 | let ctx = TestContext::new(client); | 189 | let ctx = TestContext::new(client); |
| 169 | 190 | ||
| 170 | // Create and send repository announcement via TestContext | 191 | // Create and send repository announcement via TestContext |
| 171 | let repo = match ctx.get_fixture(FixtureKind::ValidRepo).await { | 192 | let repo = match ctx.get_fixture(FixtureKind::ValidRepo).await { |
| 172 | Ok(r) => r, | 193 | Ok(r) => r, |
| 173 | Err(e) => return TestResult::new( | 194 | Err(e) => { |
| 174 | test_name, | 195 | return TestResult::new( |
| 175 | "GRASP-01", | 196 | test_name, |
| 176 | "Bare repository must have correct structure", | 197 | "GRASP-01", |
| 177 | ).fail(&format!("Failed to create repo fixture: {}", e)), | 198 | "Bare repository must have correct structure", |
| 199 | ) | ||
| 200 | .fail(&format!("Failed to create repo fixture: {}", e)) | ||
| 201 | } | ||
| 178 | }; | 202 | }; |
| 179 | 203 | ||
| 180 | // Wait for repository creation | 204 | // Wait for repository creation |
| 181 | tokio::time::sleep(std::time::Duration::from_millis(200)).await; | 205 | tokio::time::sleep(std::time::Duration::from_millis(200)).await; |
| 182 | 206 | ||
| 183 | // Extract repo identifier and npub | 207 | // Extract repo identifier and npub |
| 184 | let repo_id = repo.tags.iter() | 208 | let repo_id = repo |
| 209 | .tags | ||
| 210 | .iter() | ||
| 185 | .find(|t| t.kind() == TagKind::d()) | 211 | .find(|t| t.kind() == TagKind::d()) |
| 186 | .and_then(|t| t.content()) | 212 | .and_then(|t| t.content()) |
| 187 | .ok_or("Missing d tag") | 213 | .ok_or("Missing d tag") |
| @@ -192,13 +218,17 @@ impl RepositoryCreationTests { | |||
| 192 | 218 | ||
| 193 | // Verify correct path structure: <git_data_path>/<npub>/<identifier>.git | 219 | // Verify correct path structure: <git_data_path>/<npub>/<identifier>.git |
| 194 | let expected_path = git_data_dir.join(&npub).join(format!("{}.git", repo_id)); | 220 | let expected_path = git_data_dir.join(&npub).join(format!("{}.git", repo_id)); |
| 195 | 221 | ||
| 196 | if !expected_path.exists() { | 222 | if !expected_path.exists() { |
| 197 | return TestResult::new( | 223 | return TestResult::new( |
| 198 | test_name, | 224 | test_name, |
| 199 | "GRASP-01", | 225 | "GRASP-01", |
| 200 | "Bare repository must have correct structure", | 226 | "Bare repository must have correct structure", |
| 201 | ).fail(&format!("Repository not at expected path: {}", expected_path.display())); | 227 | ) |
| 228 | .fail(&format!( | ||
| 229 | "Repository not at expected path: {}", | ||
| 230 | expected_path.display() | ||
| 231 | )); | ||
| 202 | } | 232 | } |
| 203 | 233 | ||
| 204 | // Verify it's a bare repository with correct structure | 234 | // Verify it's a bare repository with correct structure |
| @@ -207,7 +237,8 @@ impl RepositoryCreationTests { | |||
| 207 | test_name, | 237 | test_name, |
| 208 | "GRASP-01", | 238 | "GRASP-01", |
| 209 | "Bare repository must have correct structure", | 239 | "Bare repository must have correct structure", |
| 210 | ).fail("Missing HEAD file"); | 240 | ) |
| 241 | .fail("Missing HEAD file"); | ||
| 211 | } | 242 | } |
| 212 | 243 | ||
| 213 | if !expected_path.join("config").is_file() { | 244 | if !expected_path.join("config").is_file() { |
| @@ -215,7 +246,8 @@ impl RepositoryCreationTests { | |||
| 215 | test_name, | 246 | test_name, |
| 216 | "GRASP-01", | 247 | "GRASP-01", |
| 217 | "Bare repository must have correct structure", | 248 | "Bare repository must have correct structure", |
| 218 | ).fail("Missing config file"); | 249 | ) |
| 250 | .fail("Missing config file"); | ||
| 219 | } | 251 | } |
| 220 | 252 | ||
| 221 | if !expected_path.join("objects").is_dir() { | 253 | if !expected_path.join("objects").is_dir() { |
| @@ -223,7 +255,8 @@ impl RepositoryCreationTests { | |||
| 223 | test_name, | 255 | test_name, |
| 224 | "GRASP-01", | 256 | "GRASP-01", |
| 225 | "Bare repository must have correct structure", | 257 | "Bare repository must have correct structure", |
| 226 | ).fail("Missing objects/ directory"); | 258 | ) |
| 259 | .fail("Missing objects/ directory"); | ||
| 227 | } | 260 | } |
| 228 | 261 | ||
| 229 | if !expected_path.join("refs").is_dir() { | 262 | if !expected_path.join("refs").is_dir() { |
| @@ -231,7 +264,8 @@ impl RepositoryCreationTests { | |||
| 231 | test_name, | 264 | test_name, |
| 232 | "GRASP-01", | 265 | "GRASP-01", |
| 233 | "Bare repository must have correct structure", | 266 | "Bare repository must have correct structure", |
| 234 | ).fail("Missing refs/ directory"); | 267 | ) |
| 268 | .fail("Missing refs/ directory"); | ||
| 235 | } | 269 | } |
| 236 | 270 | ||
| 237 | // Verify the helper function agrees | 271 | // Verify the helper function agrees |
| @@ -240,76 +274,16 @@ impl RepositoryCreationTests { | |||
| 240 | test_name, | 274 | test_name, |
| 241 | "GRASP-01", | 275 | "GRASP-01", |
| 242 | "Bare repository must have correct structure", | 276 | "Bare repository must have correct structure", |
| 243 | ).fail("Helper function does not recognize repository as bare"); | 277 | ) |
| 278 | .fail("Helper function does not recognize repository as bare"); | ||
| 244 | } | 279 | } |
| 245 | 280 | ||
| 246 | TestResult::new( | 281 | TestResult::new( |
| 247 | test_name, | 282 | test_name, |
| 248 | "GRASP-01", | 283 | "GRASP-01", |
| 249 | "Bare repository must have correct structure", | 284 | "Bare repository must have correct structure", |
| 250 | ).pass() | 285 | ) |
| 251 | } | 286 | .pass() |
| 252 | |||
| 253 | /// Test that repository creation cleanup works | ||
| 254 | /// | ||
| 255 | /// This test: | ||
| 256 | /// 1. Creates multiple repositories via TestContext | ||
| 257 | /// 2. Verifies they exist | ||
| 258 | /// 3. Ensures test cleanup removes them (via TempDir drop) | ||
| 259 | pub async fn test_repo_cleanup( | ||
| 260 | client: &AuditClient, | ||
| 261 | git_data_dir: &Path, | ||
| 262 | ) -> TestResult { | ||
| 263 | let test_name = "test_repo_cleanup"; | ||
| 264 | let ctx = TestContext::new(client); | ||
| 265 | |||
| 266 | // Create multiple repositories via TestContext | ||
| 267 | let mut repo_paths = Vec::new(); | ||
| 268 | |||
| 269 | for _i in 0..3 { | ||
| 270 | let repo = match ctx.get_fixture(FixtureKind::ValidRepo).await { | ||
| 271 | Ok(r) => r, | ||
| 272 | Err(e) => return TestResult::new( | ||
| 273 | test_name, | ||
| 274 | "GRASP-01", | ||
| 275 | "Test cleanup must remove created repositories", | ||
| 276 | ).fail(&format!("Failed to create repo fixture: {}", e)), | ||
| 277 | }; | ||
| 278 | |||
| 279 | // Extract path | ||
| 280 | let repo_id = repo.tags.iter() | ||
| 281 | .find(|t| t.kind() == TagKind::d()) | ||
| 282 | .and_then(|t| t.content()) | ||
| 283 | .unwrap() | ||
| 284 | .to_string(); | ||
| 285 | let npub = repo.pubkey.to_bech32().unwrap(); | ||
| 286 | let path = git_data_dir.join(&npub).join(format!("{}.git", repo_id)); | ||
| 287 | repo_paths.push(path); | ||
| 288 | } | ||
| 289 | |||
| 290 | // Wait for all repositories to be created | ||
| 291 | tokio::time::sleep(std::time::Duration::from_millis(300)).await; | ||
| 292 | |||
| 293 | // Verify all repositories exist | ||
| 294 | for path in &repo_paths { | ||
| 295 | if !is_bare_repository(path) { | ||
| 296 | return TestResult::new( | ||
| 297 | test_name, | ||
| 298 | "GRASP-01", | ||
| 299 | "Test cleanup must remove created repositories", | ||
| 300 | ).fail(&format!("Repository not created at: {}", path.display())); | ||
| 301 | } | ||
| 302 | } | ||
| 303 | |||
| 304 | // Note: Actual cleanup happens when the TestRelay's TempDir is dropped | ||
| 305 | // This test just verifies that repositories were created successfully | ||
| 306 | // The integration test framework will verify cleanup | ||
| 307 | |||
| 308 | TestResult::new( | ||
| 309 | test_name, | ||
| 310 | "GRASP-01", | ||
| 311 | "Test cleanup must remove created repositories", | ||
| 312 | ).pass() | ||
| 313 | } | 287 | } |
| 314 | } | 288 | } |
| 315 | 289 | ||
| @@ -370,9 +344,6 @@ mod tests { | |||
| 370 | #[test] | 344 | #[test] |
| 371 | fn test_is_bare_repository_rejects_nonexistent() { | 345 | fn test_is_bare_repository_rejects_nonexistent() { |
| 372 | let path = Path::new("/nonexistent/path/to/repo.git"); | 346 | let path = Path::new("/nonexistent/path/to/repo.git"); |
| 373 | assert!( | 347 | assert!(!is_bare_repository(path), "Should reject nonexistent path"); |
| 374 | !is_bare_repository(path), | ||
| 375 | "Should reject nonexistent path" | ||
| 376 | ); | ||
| 377 | } | 348 | } |
| 378 | } \ No newline at end of file | 349 | } |