Add Policy DSL Validator, Schema Exporter, and Simulation Smoke tools
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				Docs CI / lint-and-preview (push) Has been cancelled
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	Docs CI / lint-and-preview (push) Has been cancelled
				
			- Implemented PolicyDslValidator with command-line options for strict mode and JSON output. - Created PolicySchemaExporter to generate JSON schemas for policy-related models. - Developed PolicySimulationSmoke tool to validate policy simulations against expected outcomes. - Added project files and necessary dependencies for each tool. - Ensured proper error handling and usage instructions across tools.
This commit is contained in:
		
							
								
								
									
										256
									
								
								ops/offline-kit/test_build_offline_kit.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										256
									
								
								ops/offline-kit/test_build_offline_kit.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,256 @@ | ||||
| from __future__ import annotations | ||||
|  | ||||
| import json | ||||
| import tarfile | ||||
| import tempfile | ||||
| import unittest | ||||
| import argparse | ||||
| import sys | ||||
| from collections import OrderedDict | ||||
| from pathlib import Path | ||||
|  | ||||
| sys.path.append(str(Path(__file__).resolve().parent)) | ||||
|  | ||||
| from build_release import write_manifest  # type: ignore import-not-found | ||||
|  | ||||
| from build_offline_kit import build_offline_kit, compute_sha256  # type: ignore import-not-found | ||||
|  | ||||
|  | ||||
| class OfflineKitBuilderTests(unittest.TestCase): | ||||
|     def setUp(self) -> None: | ||||
|         self._temp = tempfile.TemporaryDirectory() | ||||
|         self.base_path = Path(self._temp.name) | ||||
|         self.out_dir = self.base_path / "out" | ||||
|         self.release_dir = self.out_dir / "release" | ||||
|         self.staging_dir = self.base_path / "staging" | ||||
|         self.output_dir = self.base_path / "dist" | ||||
|         self._create_sample_release() | ||||
|  | ||||
|     def tearDown(self) -> None: | ||||
|         self._temp.cleanup() | ||||
|  | ||||
|     def _relative_to_out(self, path: Path) -> str: | ||||
|         return path.relative_to(self.out_dir).as_posix() | ||||
|  | ||||
|     def _write_json(self, path: Path, payload: dict[str, object]) -> None: | ||||
|         path.parent.mkdir(parents=True, exist_ok=True) | ||||
|         with path.open("w", encoding="utf-8") as handle: | ||||
|             json.dump(payload, handle, indent=2) | ||||
|             handle.write("\n") | ||||
|  | ||||
|     def _create_sample_release(self) -> None: | ||||
|         self.release_dir.mkdir(parents=True, exist_ok=True) | ||||
|  | ||||
|         sbom_path = self.release_dir / "artifacts/sboms/sample.cyclonedx.json" | ||||
|         sbom_path.parent.mkdir(parents=True, exist_ok=True) | ||||
|         sbom_path.write_text('{"bomFormat":"CycloneDX","specVersion":"1.5"}\n', encoding="utf-8") | ||||
|         sbom_sha = compute_sha256(sbom_path) | ||||
|  | ||||
|         provenance_path = self.release_dir / "artifacts/provenance/sample.provenance.json" | ||||
|         self._write_json( | ||||
|             provenance_path, | ||||
|             { | ||||
|                 "buildDefinition": {"buildType": "https://example/build"}, | ||||
|                 "runDetails": {"builder": {"id": "https://example/ci"}}, | ||||
|             }, | ||||
|         ) | ||||
|         provenance_sha = compute_sha256(provenance_path) | ||||
|  | ||||
|         signature_path = self.release_dir / "artifacts/signatures/sample.signature" | ||||
|         signature_path.parent.mkdir(parents=True, exist_ok=True) | ||||
|         signature_path.write_text("signature-data\n", encoding="utf-8") | ||||
|         signature_sha = compute_sha256(signature_path) | ||||
|  | ||||
|         metadata_path = self.release_dir / "artifacts/metadata/sample.metadata.json" | ||||
|         self._write_json(metadata_path, {"digest": "sha256:1234"}) | ||||
|         metadata_sha = compute_sha256(metadata_path) | ||||
|  | ||||
|         chart_path = self.release_dir / "helm/stellaops-1.0.0.tgz" | ||||
|         chart_path.parent.mkdir(parents=True, exist_ok=True) | ||||
|         chart_path.write_bytes(b"helm-chart-data") | ||||
|         chart_sha = compute_sha256(chart_path) | ||||
|  | ||||
|         compose_path = self.release_dir.parent / "deploy/compose/docker-compose.dev.yaml" | ||||
|         compose_path.parent.mkdir(parents=True, exist_ok=True) | ||||
|         compose_path.write_text("services: {}\n", encoding="utf-8") | ||||
|         compose_sha = compute_sha256(compose_path) | ||||
|  | ||||
|         debug_file = self.release_dir / "debug/.build-id/ab/cdef.debug" | ||||
|         debug_file.parent.mkdir(parents=True, exist_ok=True) | ||||
|         debug_file.write_bytes(b"\x7fELFDEBUGDATA") | ||||
|         debug_sha = compute_sha256(debug_file) | ||||
|  | ||||
|         debug_manifest_path = self.release_dir / "debug/debug-manifest.json" | ||||
|         debug_manifest = OrderedDict( | ||||
|             ( | ||||
|                 ("generatedAt", "2025-10-26T00:00:00Z"), | ||||
|                 ("version", "1.0.0"), | ||||
|                 ("channel", "edge"), | ||||
|                 ( | ||||
|                     "artifacts", | ||||
|                     [ | ||||
|                         OrderedDict( | ||||
|                             ( | ||||
|                                 ("buildId", "abcdef1234"), | ||||
|                                 ("platform", "linux/amd64"), | ||||
|                                 ("debugPath", "debug/.build-id/ab/cdef.debug"), | ||||
|                                 ("sha256", debug_sha), | ||||
|                                 ("size", debug_file.stat().st_size), | ||||
|                                 ("components", ["sample"]), | ||||
|                                 ("images", ["registry.example/sample@sha256:feedface"]), | ||||
|                                 ("sources", ["app/sample.dll"]), | ||||
|                             ) | ||||
|                         ) | ||||
|                     ], | ||||
|                 ), | ||||
|             ) | ||||
|         ) | ||||
|         self._write_json(debug_manifest_path, debug_manifest) | ||||
|         debug_manifest_sha = compute_sha256(debug_manifest_path) | ||||
|         (debug_manifest_path.with_suffix(debug_manifest_path.suffix + ".sha256")).write_text( | ||||
|             f"{debug_manifest_sha}  {debug_manifest_path.name}\n", | ||||
|             encoding="utf-8", | ||||
|         ) | ||||
|  | ||||
|         manifest = OrderedDict( | ||||
|             ( | ||||
|                 ( | ||||
|                     "release", | ||||
|                     OrderedDict( | ||||
|                         ( | ||||
|                             ("version", "1.0.0"), | ||||
|                             ("channel", "edge"), | ||||
|                             ("date", "2025-10-26T00:00:00Z"), | ||||
|                             ("calendar", "2025.10"), | ||||
|                         ) | ||||
|                     ), | ||||
|                 ), | ||||
|                 ( | ||||
|                     "components", | ||||
|                     [ | ||||
|                         OrderedDict( | ||||
|                             ( | ||||
|                                 ("name", "sample"), | ||||
|                                 ("image", "registry.example/sample@sha256:feedface"), | ||||
|                                 ("tags", ["registry.example/sample:1.0.0"]), | ||||
|                                 ( | ||||
|                                     "sbom", | ||||
|                                     OrderedDict( | ||||
|                                         ( | ||||
|                                             ("path", self._relative_to_out(sbom_path)), | ||||
|                                             ("sha256", sbom_sha), | ||||
|                                         ) | ||||
|                                     ), | ||||
|                                 ), | ||||
|                                 ( | ||||
|                                     "provenance", | ||||
|                                     OrderedDict( | ||||
|                                         ( | ||||
|                                             ("path", self._relative_to_out(provenance_path)), | ||||
|                                             ("sha256", provenance_sha), | ||||
|                                         ) | ||||
|                                     ), | ||||
|                                 ), | ||||
|                                 ( | ||||
|                                     "signature", | ||||
|                                     OrderedDict( | ||||
|                                         ( | ||||
|                                             ("path", self._relative_to_out(signature_path)), | ||||
|                                             ("sha256", signature_sha), | ||||
|                                             ("ref", "sigstore://example"), | ||||
|                                             ("tlogUploaded", True), | ||||
|                                         ) | ||||
|                                     ), | ||||
|                                 ), | ||||
|                                 ( | ||||
|                                     "metadata", | ||||
|                                     OrderedDict( | ||||
|                                         ( | ||||
|                                             ("path", self._relative_to_out(metadata_path)), | ||||
|                                             ("sha256", metadata_sha), | ||||
|                                         ) | ||||
|                                     ), | ||||
|                                 ), | ||||
|                             ) | ||||
|                         ) | ||||
|                     ], | ||||
|                 ), | ||||
|                 ( | ||||
|                     "charts", | ||||
|                     [ | ||||
|                         OrderedDict( | ||||
|                             ( | ||||
|                                 ("name", "stellaops"), | ||||
|                                 ("version", "1.0.0"), | ||||
|                                 ("path", self._relative_to_out(chart_path)), | ||||
|                                 ("sha256", chart_sha), | ||||
|                             ) | ||||
|                         ) | ||||
|                     ], | ||||
|                 ), | ||||
|                 ( | ||||
|                     "compose", | ||||
|                     [ | ||||
|                         OrderedDict( | ||||
|                             ( | ||||
|                                 ("name", "docker-compose.dev.yaml"), | ||||
|                                 ("path", compose_path.relative_to(self.out_dir).as_posix()), | ||||
|                                 ("sha256", compose_sha), | ||||
|                             ) | ||||
|                         ) | ||||
|                     ], | ||||
|                 ), | ||||
|                 ( | ||||
|                     "debugStore", | ||||
|                     OrderedDict( | ||||
|                         ( | ||||
|                             ("manifest", "debug/debug-manifest.json"), | ||||
|                             ("sha256", debug_manifest_sha), | ||||
|                             ("entries", 1), | ||||
|                             ("platforms", ["linux/amd64"]), | ||||
|                             ("directory", "debug/.build-id"), | ||||
|                         ) | ||||
|                     ), | ||||
|                 ), | ||||
|             ) | ||||
|         ) | ||||
|         write_manifest(manifest, self.release_dir) | ||||
|  | ||||
|     def test_build_offline_kit(self) -> None: | ||||
|         args = argparse.Namespace( | ||||
|             version="2025.10.0", | ||||
|             channel="edge", | ||||
|             bundle_id="bundle-001", | ||||
|             release_dir=self.release_dir, | ||||
|             staging_dir=self.staging_dir, | ||||
|             output_dir=self.output_dir, | ||||
|             cosign_key=None, | ||||
|             cosign_password=None, | ||||
|             cosign_identity_token=None, | ||||
|             no_transparency=False, | ||||
|             skip_smoke=True, | ||||
|         ) | ||||
|         result = build_offline_kit(args) | ||||
|         bundle_path = Path(result["bundlePath"]) | ||||
|         self.assertTrue(bundle_path.exists()) | ||||
|         offline_manifest = self.output_dir.parent / "staging" / "manifest" / "offline-manifest.json" | ||||
|         self.assertTrue(offline_manifest.exists()) | ||||
|  | ||||
|         with offline_manifest.open("r", encoding="utf-8") as handle: | ||||
|             manifest_data = json.load(handle) | ||||
|         artifacts = manifest_data["artifacts"] | ||||
|         self.assertTrue(any(item["name"].startswith("sboms/") for item in artifacts)) | ||||
|  | ||||
|         metadata_path = Path(result["metadataPath"]) | ||||
|         data = json.loads(metadata_path.read_text(encoding="utf-8")) | ||||
|         self.assertTrue(data["bundleSha256"].startswith("sha256:")) | ||||
|         self.assertTrue(data["manifestSha256"].startswith("sha256:")) | ||||
|  | ||||
|         with tarfile.open(bundle_path, "r:gz") as tar: | ||||
|             members = tar.getnames() | ||||
|             self.assertIn("manifest/release.yaml", members) | ||||
|             self.assertTrue(any(name.startswith("sboms/sample-") for name in members)) | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     unittest.main() | ||||
		Reference in New Issue
	
	Block a user