Add sys import to test files and remove obsolete integration tests
Some checks failed
API Endpoint Tests / test-api-endpoints (push) Successful in 9s
Blockchain Synchronization Verification / sync-verification (push) Failing after 1s
CLI Tests / test-cli (push) Failing after 3s
Documentation Validation / validate-docs (push) Successful in 6s
Documentation Validation / validate-policies-strict (push) Successful in 2s
Integration Tests / test-service-integration (push) Successful in 40s
Multi-Node Blockchain Health Monitoring / health-check (push) Successful in 1s
P2P Network Verification / p2p-verification (push) Successful in 2s
Production Tests / Production Integration Tests (push) Successful in 21s
Python Tests / test-python (push) Successful in 13s
Security Scanning / security-scan (push) Failing after 46s
Smart Contract Tests / test-solidity (map[name:aitbc-token path:packages/solidity/aitbc-token]) (push) Successful in 17s
Smart Contract Tests / lint-solidity (push) Successful in 10s

- Add sys import to 29 test files across agent-coordinator, blockchain-event-bridge, blockchain-node, and coordinator-api
- Remove apps/blockchain-event-bridge/tests/test_integration.py (obsolete bridge integration tests)
- Remove apps/coordinator-api/tests/test_integration.py (obsolete API integration tests)
- Implement GPU registration in marketplace_gpu.py with GPURegistry model persistence
This commit is contained in:
aitbc
2026-04-23 16:43:17 +02:00
parent b8b1454573
commit e60cc3226c
134 changed files with 14321 additions and 1873 deletions

View File

@@ -0,0 +1 @@
"""ZK circuits service tests"""

View File

@@ -0,0 +1,205 @@
"""Edge case and error handling tests for ZK circuit cache system"""
import pytest
import sys
import sys
from pathlib import Path
from unittest.mock import Mock, patch, MagicMock
import json
from zk_cache import ZKCircuitCache
@pytest.mark.unit
def test_is_cache_valid_no_cache_entry():
"""Test cache validation with no cache entry"""
cache = ZKCircuitCache()
test_file = Path("/tmp/test_circuit.circom")
test_file.write_text('pragma circom 2.0.0;')
output_dir = Path("/tmp/build/test")
try:
is_valid = cache.is_cache_valid(test_file, output_dir)
assert is_valid is False
finally:
test_file.unlink()
@pytest.mark.unit
def test_is_cache_valid_missing_output_files():
"""Test cache validation when output files are missing"""
cache = ZKCircuitCache()
test_file = Path("/tmp/test_circuit.circom")
test_file.write_text('pragma circom 2.0.0;')
output_dir = Path("/tmp/build/test_missing")
# Create a cache entry with non-existent output files
cache_key = cache._get_cache_key(test_file, output_dir)
test_entry = {
'circuit_file': str(test_file),
'circuit_hash': cache._calculate_file_hash(test_file),
'dependencies': {},
'output_files': ['/nonexistent/file.r1cs']
}
cache._save_cache_entry(cache_key, test_entry)
try:
is_valid = cache.is_cache_valid(test_file, output_dir)
assert is_valid is False
finally:
test_file.unlink()
@pytest.mark.unit
def test_is_cache_valid_changed_source():
"""Test cache validation when source file has changed"""
cache = ZKCircuitCache()
test_file = Path("/tmp/test_circuit_change.circom")
test_file.write_text('pragma circom 2.0.0;')
output_dir = Path("/tmp/build/test_change")
# Create a cache entry
cache_key = cache._get_cache_key(test_file, output_dir)
original_hash = cache._calculate_file_hash(test_file)
test_entry = {
'circuit_file': str(test_file),
'circuit_hash': original_hash,
'dependencies': {},
'output_files': []
}
cache._save_cache_entry(cache_key, test_entry)
# Modify the source file
test_file.write_text('pragma circom 2.0.0;\ninclude "new_dep.circom"')
try:
is_valid = cache.is_cache_valid(test_file, output_dir)
assert is_valid is False
finally:
test_file.unlink()
@pytest.mark.unit
def test_cache_artifacts_with_missing_files():
"""Test caching artifacts when output directory is empty"""
cache = ZKCircuitCache()
test_file = Path("/tmp/test_cache_empty.circom")
test_file.write_text('pragma circom 2.0.0;')
output_dir = Path("/tmp/build/test_empty")
output_dir.mkdir(parents=True, exist_ok=True)
try:
cache.cache_artifacts(test_file, output_dir, 1.5)
cache_key = cache._get_cache_key(test_file, output_dir)
entry = cache._load_cache_entry(cache_key)
assert entry is not None
assert entry['output_files'] == []
finally:
test_file.unlink()
import shutil
shutil.rmtree(output_dir.parent)
@pytest.mark.unit
def test_get_cached_artifacts_invalid():
"""Test getting cached artifacts when cache is invalid"""
cache = ZKCircuitCache()
test_file = Path("/tmp/test_cache_invalid.circom")
test_file.write_text('pragma circom 2.0.0;')
output_dir = Path("/tmp/build/test_invalid")
try:
result = cache.get_cached_artifacts(test_file, output_dir)
assert result is None
finally:
test_file.unlink()
@pytest.mark.unit
def test_save_cache_entry_json_error():
"""Test saving cache entry with JSON error"""
cache = ZKCircuitCache()
# Mock json.dump to raise an exception
with patch('json.dump', side_effect=Exception("JSON error")):
test_entry = {'circuit_file': '/test.circom'}
cache._save_cache_entry("test_key", test_entry)
# Should not raise exception, just print warning
@pytest.mark.unit
def test_load_cache_entry_json_error():
"""Test loading cache entry with JSON error"""
cache = ZKCircuitCache()
# Create a malformed manifest
cache.cache_manifest.write_text("invalid json")
entry = cache._load_cache_entry("test_key")
assert entry is None
cache.cache_manifest.unlink()
@pytest.mark.unit
def test_find_dependencies_file_read_error():
"""Test dependency finding with file read error"""
cache = ZKCircuitCache()
test_file = Path("/tmp/test_deps_error.circom")
test_file.write_text('include "dep.circom"')
# Make file unreadable
test_file.chmod(0o000)
try:
deps = cache._find_dependencies(test_file)
# Should return empty list on error
assert isinstance(deps, list)
finally:
test_file.chmod(0o644)
test_file.unlink()
@pytest.mark.unit
def test_get_cache_stats_file_stat_error():
"""Test cache stats with file stat errors"""
cache = ZKCircuitCache()
# Add a cache entry with non-existent files
test_entry = {
'output_files': ['/nonexistent/file.r1cs']
}
cache._save_cache_entry("test_key", test_entry)
stats = cache.get_cache_stats()
# Should handle missing files gracefully
assert stats['entries'] == 1
assert stats['total_size_mb'] >= 0
@pytest.mark.unit
def test_clear_cache_nonexistent_dir():
"""Test clearing cache when directory doesn't exist"""
cache = ZKCircuitCache()
# Remove cache directory
if cache.cache_dir.exists():
import shutil
shutil.rmtree(cache.cache_dir)
# Clear should recreate directory
cache.clear_cache()
assert cache.cache_dir.exists()

View File

@@ -0,0 +1,190 @@
"""Integration tests for ZK circuit cache system"""
import pytest
import sys
import sys
from pathlib import Path
from unittest.mock import Mock, patch, MagicMock
import json
from zk_cache import ZKCircuitCache
from compile_cached import compile_circuit_cached
@pytest.mark.integration
def test_full_cache_workflow():
"""Test complete cache workflow: cache, validate, retrieve"""
cache = ZKCircuitCache()
# Create a test circuit file
test_file = Path("/tmp/test_workflow.circom")
test_file.write_text('pragma circom 2.0.0;')
output_dir = Path("/tmp/build/test_workflow")
output_dir.mkdir(parents=True, exist_ok=True)
# Create a dummy output file
output_file = output_dir / "test_workflow.r1cs"
output_file.write_text("dummy r1cs content")
try:
# Cache artifacts
cache.cache_artifacts(test_file, output_dir, 2.5)
# Validate cache
is_valid = cache.is_cache_valid(test_file, output_dir)
assert is_valid is True
# Retrieve cached artifacts
cached = cache.get_cached_artifacts(test_file, output_dir)
assert cached is not None
assert cached['compilation_time'] == 2.5
assert len(cached['output_files']) > 0
finally:
test_file.unlink()
import shutil
shutil.rmtree(output_dir.parent)
cache.clear_cache()
@pytest.mark.integration
def test_cache_invalidation():
"""Test cache invalidation when source changes"""
cache = ZKCircuitCache()
test_file = Path("/tmp/test_invalidation.circom")
test_file.write_text('pragma circom 2.0.0;')
output_dir = Path("/tmp/build/test_invalidation")
output_dir.mkdir(parents=True, exist_ok=True)
output_file = output_dir / "test_invalidation.r1cs"
output_file.write_text("dummy content")
try:
# Cache initial version
cache.cache_artifacts(test_file, output_dir, 1.0)
is_valid = cache.is_cache_valid(test_file, output_dir)
assert is_valid is True
# Modify source file
test_file.write_text('pragma circom 2.0.0;\ninclude "new.circom"')
# Cache should be invalid
is_valid = cache.is_cache_valid(test_file, output_dir)
assert is_valid is False
finally:
test_file.unlink()
import shutil
shutil.rmtree(output_dir.parent)
cache.clear_cache()
@pytest.mark.integration
def test_cache_stats_with_entries():
"""Test cache statistics with multiple entries"""
cache = ZKCircuitCache()
# Create multiple cache entries
for i in range(3):
test_file = Path(f"/tmp/test_stats_{i}.circom")
test_file.write_text(f'pragma circom 2.0.0; /* test {i} */')
output_dir = Path(f"/tmp/build/test_stats_{i}")
output_dir.mkdir(parents=True, exist_ok=True)
output_file = output_dir / f"test_stats_{i}.r1cs"
output_file.write_text(f"dummy content {i}")
cache.cache_artifacts(test_file, output_dir, 1.0 + i)
try:
stats = cache.get_cache_stats()
assert stats['entries'] == 3
assert stats['total_size_mb'] > 0
finally:
for i in range(3):
test_file = Path(f"/tmp/test_stats_{i}.circom")
if test_file.exists():
test_file.unlink()
import shutil
if Path("/tmp/build").exists():
shutil.rmtree("/tmp/build")
cache.clear_cache()
@pytest.mark.integration
def test_compile_circuit_cached_file_not_found():
"""Test compile_circuit_cached with nonexistent file"""
with pytest.raises(FileNotFoundError):
compile_circuit_cached("/nonexistent/file.circom", use_cache=False)
@pytest.mark.integration
def test_compile_circuit_cached_auto_output_dir():
"""Test compile_circuit_cached with auto-generated output directory"""
# Create a test circuit file
test_file = Path("/tmp/test_auto_dir.circom")
test_file.write_text('pragma circom 2.0.0;')
try:
result = compile_circuit_cached(str(test_file), use_cache=False)
# Should fail compilation but have output_dir set
assert 'output_dir' in result
assert 'test_auto_dir' in result['output_dir']
finally:
test_file.unlink()
@pytest.mark.integration
def test_compile_circuit_cached_with_cache_disabled():
"""Test compile_circuit_cached with cache disabled"""
cache = ZKCircuitCache()
test_file = Path("/tmp/test_no_cache.circom")
test_file.write_text('pragma circom 2.0.0;')
output_dir = Path("/tmp/build/test_no_cache")
output_dir.mkdir(parents=True, exist_ok=True)
try:
result = compile_circuit_cached(str(test_file), str(output_dir), use_cache=False)
assert result['cache_hit'] is False
finally:
test_file.unlink()
import shutil
shutil.rmtree(output_dir.parent)
@pytest.mark.integration
def test_compile_circuit_cached_cache_hit():
"""Test compile_circuit_cached with cache hit"""
cache = ZKCircuitCache()
test_file = Path("/tmp/test_cache_hit.circom")
test_file.write_text('pragma circom 2.0.0;')
output_dir = Path("/tmp/build/test_cache_hit")
output_dir.mkdir(parents=True, exist_ok=True)
# Create output file to make cache valid
output_file = output_dir / "test_cache_hit.r1cs"
output_file.write_text("dummy content")
try:
# First call - cache miss
result1 = compile_circuit_cached(str(test_file), str(output_dir), use_cache=False)
assert result1['cache_hit'] is False
# Cache the result manually
cache.cache_artifacts(test_file, output_dir, 2.0)
# Second call - should hit cache
result2 = compile_circuit_cached(str(test_file), str(output_dir), use_cache=True)
assert result2['cache_hit'] is True
finally:
test_file.unlink()
import shutil
shutil.rmtree(output_dir.parent)
cache.clear_cache()

View File

@@ -0,0 +1,192 @@
"""Unit tests for ZK circuit cache system"""
import pytest
import sys
import sys
from pathlib import Path
from unittest.mock import Mock, patch, MagicMock
import json
from zk_cache import ZKCircuitCache
@pytest.mark.unit
def test_cache_initialization():
"""Test that ZKCircuitCache initializes correctly"""
cache = ZKCircuitCache()
assert cache.cache_dir.exists()
assert cache.cache_manifest.name == "manifest.json"
@pytest.mark.unit
def test_cache_initialization_custom_dir():
"""Test ZKCircuitCache with custom cache directory"""
custom_dir = Path("/tmp/test_zk_cache")
cache = ZKCircuitCache(cache_dir=custom_dir)
assert cache.cache_dir == custom_dir
@pytest.mark.unit
def test_calculate_file_hash():
"""Test file hash calculation"""
cache = ZKCircuitCache()
# Create a temporary file
test_file = Path("/tmp/test_hash.txt")
test_file.write_text("test content")
try:
hash1 = cache._calculate_file_hash(test_file)
hash2 = cache._calculate_file_hash(test_file)
assert hash1 == hash2
assert len(hash1) == 64 # SHA256 produces 64 hex chars
finally:
test_file.unlink()
@pytest.mark.unit
def test_calculate_file_hash_nonexistent():
"""Test file hash calculation for nonexistent file"""
cache = ZKCircuitCache()
hash_value = cache._calculate_file_hash(Path("/nonexistent/file.txt"))
assert hash_value == ""
@pytest.mark.unit
def test_find_dependencies():
"""Test dependency finding"""
cache = ZKCircuitCache()
# Create a test circuit file with includes
test_file = Path("/tmp/test_circuit.circom")
test_file.write_text('include "dependency.circom"')
dep_file = Path("/tmp/dependency.circom")
dep_file.write_text('pragma circom 2.0.0;')
try:
deps = cache._find_dependencies(test_file)
assert len(deps) == 1
assert dep_file in deps
finally:
test_file.unlink()
dep_file.unlink()
@pytest.mark.unit
def test_find_dependencies_none():
"""Test dependency finding with no includes"""
cache = ZKCircuitCache()
test_file = Path("/tmp/test_circuit_no_deps.circom")
test_file.write_text('pragma circom 2.0.0;')
try:
deps = cache._find_dependencies(test_file)
assert len(deps) == 0
finally:
test_file.unlink()
@pytest.mark.unit
def test_find_dependencies_recursive():
"""Test recursive dependency finding"""
cache = ZKCircuitCache()
# Create a chain of dependencies
test_file = Path("/tmp/test_main.circom")
test_file.write_text('include "dep1.circom"')
dep1 = Path("/tmp/dep1.circom")
dep1.write_text('include "dep2.circom"')
dep2 = Path("/tmp/dep2.circom")
dep2.write_text('pragma circom 2.0.0;')
try:
deps = cache._find_dependencies(test_file)
assert len(deps) == 2
assert dep1 in deps
assert dep2 in deps
finally:
test_file.unlink()
dep1.unlink()
dep2.unlink()
@pytest.mark.unit
def test_get_cache_key():
"""Test cache key generation"""
cache = ZKCircuitCache()
test_file = Path("/tmp/test_circuit.circom")
test_file.write_text('pragma circom 2.0.0;')
output_dir = Path("/tmp/build/test")
try:
key1 = cache._get_cache_key(test_file, output_dir)
key2 = cache._get_cache_key(test_file, output_dir)
assert key1 == key2
assert len(key1) == 16 # Truncated to 16 chars
finally:
test_file.unlink()
@pytest.mark.unit
def test_load_cache_entry_nonexistent():
"""Test loading cache entry when manifest doesn't exist"""
cache = ZKCircuitCache()
entry = cache._load_cache_entry("test_key")
assert entry is None
@pytest.mark.unit
def test_save_and_load_cache_entry():
"""Test saving and loading cache entry"""
cache = ZKCircuitCache()
test_entry = {
'circuit_file': '/test.circom',
'output_dir': '/build',
'circuit_hash': 'abc123',
'dependencies': {},
'output_files': [],
'compilation_time': 1.5,
'cached_at': 1234567890
}
cache._save_cache_entry("test_key", test_entry)
loaded = cache._load_cache_entry("test_key")
assert loaded is not None
assert loaded['circuit_file'] == '/test.circom'
assert loaded['compilation_time'] == 1.5
@pytest.mark.unit
def test_get_cache_stats_empty():
"""Test cache stats with empty cache"""
cache = ZKCircuitCache()
cache.clear_cache() # Clear any existing entries
stats = cache.get_cache_stats()
assert stats['entries'] == 0
assert stats['total_size_mb'] == 0
@pytest.mark.unit
def test_clear_cache():
"""Test clearing cache"""
cache = ZKCircuitCache()
# Add a test entry
test_entry = {'circuit_file': '/test.circom'}
cache._save_cache_entry("test_key", test_entry)
# Clear cache
cache.clear_cache()
# Verify cache is empty
stats = cache.get_cache_stats()
assert stats['entries'] == 0