13618fb8d5
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 14s
CI / build (pull_request) Successful in 15s
CI / quality (pull_request) Successful in 17s
CI / security (pull_request) Successful in 33s
CI / typecheck (pull_request) Successful in 47s
CI / unit_tests (pull_request) Successful in 2m35s
CI / integration_tests (pull_request) Successful in 3m13s
CI / docker (pull_request) Successful in 39s
CI / coverage (pull_request) Successful in 4m26s
CI / benchmark-regression (pull_request) Has been cancelled
- F1/F2 [P1]: Split postgresql_analyzer.py (695→310 lines) by
extracting regex patterns, URI builders, and parsing functions
into _postgresql_helpers.py (440 lines). Split
domain_analyzers.feature (605→217 lines) into separate
postgresql_analyzer.feature (201) and
docker_compose_analyzer.feature (199).
- F3 [P1]: Fix _extract_body and _split_entries to track
single-quoted SQL string literals so parentheses inside
DEFAULT/CHECK values (e.g. 'func(x)') do not corrupt depth
counting. Added regression scenarios.
- F4 [P2]: Remove prohibited `# type: ignore[arg-type]` by
adding a static protocol assertion for _DuplicatePyAnalyzer.
- F5 [P2]: Add 1 MiB size guard before yaml.safe_load in
DockerComposeAnalyzer to mitigate billion-laughs alias
expansion attacks.
- F6 [P2]: Fix quoted-keyword column names (e.g. "primary")
being silently dropped by checking raw_first.startswith('"')
before keyword filtering. Added regression scenario.
- F7 [P2]: Out-of-scope file changes resolved by rebase onto
master (changes already merged via other PRs).
All nox gates pass: lint (0 errors), typecheck (0 errors),
security_scan, behave (57 scenarios, 211 steps, 0 failures).
200 lines
6.3 KiB
Gherkin
200 lines
6.3 KiB
Gherkin
@phase2 @acms @analyzer @docker_compose_analyzer
|
|
Feature: DockerComposeAnalyzer
|
|
As a CleverAgents developer
|
|
I want a Docker Compose analyzer that produces UKO triples from YAML files
|
|
So that the ACMS can index infrastructure definitions into the UKO knowledge graph
|
|
|
|
Scenario: Analyze services
|
|
Given a DockerComposeAnalyzer analyzer
|
|
When I analyze the Docker Compose content:
|
|
"""
|
|
services:
|
|
web:
|
|
image: nginx
|
|
api:
|
|
image: node:18
|
|
"""
|
|
Then the triples should include predicate "rdf:type" with object_uri "uko-infra:DeploymentUnit"
|
|
And the triples should include predicate "rdf:type" with object_uri "uko-infra:Service"
|
|
And the triples should include predicate "uko:contains" linking subject "deployment" to object "web"
|
|
|
|
Scenario: Analyze ports
|
|
Given a DockerComposeAnalyzer analyzer
|
|
When I analyze the Docker Compose content:
|
|
"""
|
|
services:
|
|
web:
|
|
image: nginx
|
|
ports:
|
|
- "8080:80"
|
|
"""
|
|
Then the triples should include predicate "rdf:type" with object_uri "uko-infra:Port"
|
|
And the triples should include predicate "uko-infra:exposes"
|
|
|
|
Scenario: Analyze environment variables
|
|
Given a DockerComposeAnalyzer analyzer
|
|
When I analyze the Docker Compose content:
|
|
"""
|
|
services:
|
|
api:
|
|
image: node:18
|
|
environment:
|
|
DATABASE_URL: postgres://localhost/db
|
|
NODE_ENV: production
|
|
"""
|
|
Then the triples should include predicate "rdf:type" with object_uri "uko-infra:EnvironmentVariable"
|
|
And the triples should include predicate "rdfs:label" with object_value "DATABASE_URL"
|
|
And the triples should include predicate "rdfs:label" with object_value "NODE_ENV"
|
|
|
|
Scenario: Analyze depends_on
|
|
Given a DockerComposeAnalyzer analyzer
|
|
When I analyze the Docker Compose content:
|
|
"""
|
|
services:
|
|
web:
|
|
image: nginx
|
|
depends_on:
|
|
- api
|
|
- redis
|
|
api:
|
|
image: node:18
|
|
redis:
|
|
image: redis:7
|
|
"""
|
|
Then the triples should include predicate "uko-infra:connectsTo"
|
|
|
|
Scenario: Analyze depends_on as single string
|
|
Given a DockerComposeAnalyzer analyzer
|
|
When I analyze the Docker Compose content:
|
|
"""
|
|
services:
|
|
web:
|
|
image: nginx
|
|
depends_on: db
|
|
db:
|
|
image: postgres
|
|
"""
|
|
Then the triples should include predicate "uko-infra:connectsTo"
|
|
|
|
Scenario: Analyze depends_on as dict form
|
|
Given a DockerComposeAnalyzer analyzer
|
|
When I analyze the Docker Compose content:
|
|
"""
|
|
services:
|
|
web:
|
|
image: nginx
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
db:
|
|
image: postgres
|
|
"""
|
|
Then the triples should include predicate "uko-infra:connectsTo"
|
|
|
|
Scenario: Analyze volumes
|
|
Given a DockerComposeAnalyzer analyzer
|
|
When I analyze the Docker Compose content:
|
|
"""
|
|
services:
|
|
web:
|
|
image: nginx
|
|
volumes:
|
|
- ./data:/app/data
|
|
"""
|
|
Then the triples should include predicate "uko:contains" linking subject "web" to object "volume"
|
|
|
|
Scenario: Analyze environment as list form
|
|
Given a DockerComposeAnalyzer analyzer
|
|
When I analyze the Docker Compose content:
|
|
"""
|
|
services:
|
|
api:
|
|
image: node:18
|
|
environment:
|
|
- DATABASE_URL=postgres://localhost/db
|
|
- NODE_ENV=production
|
|
"""
|
|
Then the triples should include predicate "rdf:type" with object_uri "uko-infra:EnvironmentVariable"
|
|
And the triples should include predicate "rdfs:label" with object_value "DATABASE_URL"
|
|
|
|
Scenario: Analyze service with null body
|
|
Given a DockerComposeAnalyzer analyzer
|
|
When I analyze the Docker Compose content:
|
|
"""
|
|
services:
|
|
placeholder:
|
|
"""
|
|
Then the triples should include predicate "rdf:type" with object_uri "uko-infra:Service"
|
|
And the triples should include predicate "rdfs:label" with object_value "placeholder"
|
|
|
|
Scenario: Analyze dict-form port mapping
|
|
Given a DockerComposeAnalyzer analyzer
|
|
When I analyze the Docker Compose content:
|
|
"""
|
|
services:
|
|
web:
|
|
image: nginx
|
|
ports:
|
|
- target: 80
|
|
published: 8080
|
|
"""
|
|
Then the triples should include predicate "rdf:type" with object_uri "uko-infra:Port"
|
|
And the triples should include predicate "rdfs:label" with object_value "8080:80"
|
|
|
|
Scenario: Analyze dict-form volume mapping
|
|
Given a DockerComposeAnalyzer analyzer
|
|
When I analyze the Docker Compose content:
|
|
"""
|
|
services:
|
|
web:
|
|
image: nginx
|
|
volumes:
|
|
- type: bind
|
|
source: ./data
|
|
target: /data
|
|
"""
|
|
Then the triples should include predicate "rdf:type" with object_uri "uko-infra:ConfigKey"
|
|
And the triples should include predicate "rdfs:label" with object_value "./data:/data"
|
|
|
|
Scenario: Analyze empty Docker Compose content raises ValueError
|
|
Given a DockerComposeAnalyzer analyzer
|
|
Then analyzing empty content with this analyzer should raise ValueError
|
|
|
|
Scenario: Analyze whitespace-only Docker Compose content raises ValueError
|
|
Given a DockerComposeAnalyzer analyzer
|
|
Then analyzing whitespace-only content with this analyzer should raise ValueError
|
|
|
|
Scenario: Analyze Docker Compose with empty resource_uri raises ValueError
|
|
Given a DockerComposeAnalyzer analyzer
|
|
Then analyzing content with empty resource_uri should raise ValueError
|
|
|
|
Scenario: Analyze version-only YAML returns empty list
|
|
Given a DockerComposeAnalyzer analyzer
|
|
When I analyze the Docker Compose content:
|
|
"""
|
|
version: "3.8"
|
|
"""
|
|
Then no triples should be returned
|
|
|
|
Scenario: Analyze non-compose YAML returns empty list
|
|
Given a DockerComposeAnalyzer analyzer
|
|
When I analyze the Docker Compose content:
|
|
"""
|
|
name: my-application
|
|
settings:
|
|
debug: true
|
|
log_level: info
|
|
"""
|
|
Then no triples should be returned
|
|
|
|
Scenario: Analyze invalid YAML returns empty list
|
|
Given a DockerComposeAnalyzer analyzer
|
|
When I analyze the Docker Compose content:
|
|
"""
|
|
services:
|
|
web:
|
|
ports:
|
|
- this: is: broken: yaml: [
|
|
"""
|
|
Then no triples should be returned
|