|
| 1 | +"""Resource contract tests for the monitoring Flask backend.""" |
| 2 | + |
| 3 | +import os |
| 4 | +import subprocess |
| 5 | + |
| 6 | +import pytest |
| 7 | +import yaml |
| 8 | + |
| 9 | + |
| 10 | +PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')) |
| 11 | +EXPECTED_MEMORY_BYTES = 1073741824 |
| 12 | + |
| 13 | + |
| 14 | +def _load_yaml(*parts): |
| 15 | + with open(os.path.join(PROJECT_ROOT, *parts)) as f: |
| 16 | + return yaml.safe_load(f) |
| 17 | + |
| 18 | + |
| 19 | +def test_docker_compose_flask_resources_match_expected_limits(): |
| 20 | + compose = _load_yaml('docker-compose.yml') |
| 21 | + flask = compose['services']['monitoring_flask_backend'] |
| 22 | + |
| 23 | + assert flask['cpus'] == 0.5 |
| 24 | + assert flask['mem_limit'] == EXPECTED_MEMORY_BYTES |
| 25 | + |
| 26 | + |
| 27 | +def test_helm_flask_resources_match_expected_requests_and_limits(): |
| 28 | + values = _load_yaml('postgres_ai_helm', 'values.yaml') |
| 29 | + resources = values['flask']['resources'] |
| 30 | + |
| 31 | + assert resources['requests'] == { |
| 32 | + 'cpu': '500m', |
| 33 | + 'memory': '256Mi', |
| 34 | + } |
| 35 | + assert resources['limits'] == { |
| 36 | + 'cpu': '500m', |
| 37 | + 'memory': '1Gi', |
| 38 | + } |
| 39 | + |
| 40 | + |
| 41 | +@pytest.fixture |
| 42 | +def rendered_helm_docs(): |
| 43 | + try: |
| 44 | + subprocess.run(['helm', 'version', '--short'], capture_output=True, check=True) |
| 45 | + except (FileNotFoundError, subprocess.CalledProcessError): |
| 46 | + pytest.skip('helm not available') |
| 47 | + |
| 48 | + chart_path = os.path.join(PROJECT_ROOT, 'postgres_ai_helm') |
| 49 | + subprocess.run(['helm', 'dependency', 'build', chart_path], capture_output=True, check=False) |
| 50 | + result = subprocess.run( |
| 51 | + ['helm', 'template', 'test', chart_path, '--set', 'secrets.createFromValues=true'], |
| 52 | + capture_output=True, |
| 53 | + text=True, |
| 54 | + ) |
| 55 | + if result.returncode != 0: |
| 56 | + pytest.fail(f'helm template failed: {result.stderr}') |
| 57 | + |
| 58 | + return [doc for doc in yaml.safe_load_all(result.stdout) if isinstance(doc, dict)] |
| 59 | + |
| 60 | + |
| 61 | +def test_helm_template_renders_flask_resources(rendered_helm_docs): |
| 62 | + flask_deployments = [ |
| 63 | + doc for doc in rendered_helm_docs |
| 64 | + if doc.get('kind') == 'Deployment' |
| 65 | + and doc.get('metadata', {}).get('name', '').endswith('-flask') |
| 66 | + ] |
| 67 | + assert len(flask_deployments) == 1 |
| 68 | + |
| 69 | + container = flask_deployments[0]['spec']['template']['spec']['containers'][0] |
| 70 | + assert container['resources'] == { |
| 71 | + 'requests': {'cpu': '500m', 'memory': '256Mi'}, |
| 72 | + 'limits': {'cpu': '500m', 'memory': '1Gi'}, |
| 73 | + } |
0 commit comments