ontobdc-dev
Standalone Python package for OntoBDC development workflows.
Installation
pip install -e .
This exposes the executable:
ontobdc-dev --help
Commands
Show repository status:
ontobdc-dev branch
Create a branch across discovered repositories:
ontobdc-dev branch --create feature/my-branch
Checkout a branch across discovered repositories:
ontobdc-dev branch --checkout feature/my-branch
Fetch and pull a branch across discovered repositories:
ontobdc-dev branch --pull feature/my-branch
If omitted, --pull uses the current branch of each repository:
ontobdc-dev branch --pull
Run the changelog scaffold:
ontobdc-dev branch --changelog
Commit and push selected registered Git submodules:
ontobdc-dev commit "feat: your message" --submodule ontobdc-wip,infobim-wip
Submodule names may be separated by commas, semicolons, or spaces:
ontobdc-dev commit "feat: your message" --submodule "ontobdc-wip;infobim-wip"
ontobdc-dev commit "feat: your message" --submodule ontobdc-wip infobim-wip
When --submodule is omitted, the command selects only the current submodule if the current working directory is exactly its registered root. Otherwise, it selects every submodule registered in .gitmodules.
Run the Rich renderer test suite. This instantiates every scenario declared in
src/ontobdc_dev/render/plugin/command/scenarios.yaml,
resolves the real ontobdc.view.adapter.response adapter for each response
class, and prints the resulting Rich message box so you can visually inspect
how CommandResponse, HelpCommandResponse, ExceptionCommandResponse,
ListCommandResponse, and WelcomeCommandResponse render in the terminal:
ontobdc-dev render
--test defaults to rich when omitted, so bare render is equivalent to
--test rich; any other explicit --test value is still rejected.
Through the OntoBDC development proxy:
ontobdc dev render
Limit the run to scenarios targeting one exact response class, identified by
its module.path:ClassName URI:
ontobdc dev render --test rich --response ontobdc.cli.domain.response.command:CommandResponse
Semantic test orchestrator
The full architecture and implementation plan for the declarative, state-oriented semantic test orchestrator is documented in:
That document covers the complete design across nine phases: YAML manifests, state observers, checks, hotfixes, capabilities, fixtures, semantic planning, execution evidence, coverage gates, and migrating every OntoBDC check/hotfix into executable test cases.
The package under src/ontobdc_dev/testing/ implements the slice needed to execute an existing check and hotfix through a manifest, corresponding to the document's sections 4 (terminology), 6 (check/hotfix semantics), 7 (manifest model), 8 (state expressions), and 10 (execution cycle) — roughly phases 1 through 3 of section 24. The rest of this section is a usage manual for that slice.
What this does and does not cover
Implemented:
- loading and validating
StateDefinition/TestActionYAML manifests; - observing a state by calling an existing
check.py:main(or a plain filesystem existence check) with no source change to the check itself; - executing an existing
hotfix.py:mainthe same way; - composite states (
all/any/notover other states); - the
check -> hotfix -> recheckcycle with a verdict derived only from the recheck.
Not implemented (see docs/testing/semantic-test-orchestrator.md for the full design of each):
- fixture/sandbox materialization (section 13) — there is no isolated working copy;
--parampoints directly at real paths you prepare yourself; - a semantic planner or
ExecutionPlan(section 9) — you must already know which state and which action to run, and satisfyrequiresyourself; TestCase/TestFlow/TestSuitegrouping, matrices, and invariants (section 7.2, 7.7–7.9);- evidence persistence and JUnit reporting (section 12);
- inventory, scaffold, and the coverage gate (sections 15–16);
- JSON-Schema-driven structural validation (section 20.1) — validation is hand-written Python, and unrecognized manifest fields (
behavior,effects,planning,evidence, ...) are accepted but silently ignored instead of rejected, unlike section 7.1's rule for a complete implementation.
Concepts
| Term | Meaning here |
|---|---|
StateDefinition |
A named, checkable condition of the system. Backed by either an observer (a probe) or an expression (a composite of other states). |
| Observer | The thing that actually checks a state. Two types are supported: python-call (calls an existing check.py:main) and filesystem (checks a path exists). |
TestAction |
A named, executable operation — in practice, a wrapper around an existing hotfix.py:main. |
requires / ensures |
Metadata on a TestAction describing which states it needs beforehand and which it is meant to produce. Recorded and reference-checked against the catalog, but not automatically satisfied — there is no planner in this slice. |
verification.states |
The states the runner actually reobserves right after executing an action. Defaults to ensures when omitted. This is what the verdict is computed from. |
ExecutionContext |
The --param key=value values you pass on the command line, substituted into ${context.key} placeholders inside the manifest. |
| Verdict | passed, failed, or error in this slice (the full vocabulary also has blocked/skipped/inconclusive, which nothing here produces yet). |
Directory layout
dev/
├── src/ontobdc_dev/testing/ # the runner: domain models, adapters, catalog loader, CLI commands
└── tests/semantic/
├── states/ # StateDefinition manifests
└── actions/ # TestAction manifests
--manifest <path> accepts either a single YAML file or a directory, searched
recursively for *.yaml. There is no auto-discovery of a default path — you
always pass --manifest explicitly.
Manifest reference
Every document starts with the same header:
apiVersion: ontobdc.org/testing/v1alpha1
kind: StateDefinition # or TestAction
metadata:
name: my.dotted.state.name # required, unique across the whole catalog
title: Human-readable title # optional
description: > # optional
Longer explanation.
tags: [optional, list, of, strings]
spec:
...
StateDefinition.spec — exactly one of:
spec:
observer:
type: python-call
target: package.module.path:callable # must return an int
arguments:
some_argument: "${context.some_param}"
result:
satisfiedWhen: { exitCode: [0] }
unsatisfiedWhen: { exitCode: [1] }
errorWhen: { exitCode: [2] }
otherwise: error # satisfied | unsatisfied | error, used for any code not listed above
spec:
observer:
type: filesystem
exists: "${context.some_path}"
kind: directory # or file; omit to accept either
spec:
expression:
all: [state.name.one, state.name.two] # every referenced name must already exist in the catalog
# or: any: [...]
# or: not: state.name.one
TestAction.spec:
spec:
role: repair # free text; "repair" is the convention for hotfix-backed actions
executor:
type: python-call
target: package.module.path:callable # must return an int
arguments:
some_argument: "${context.some_param}"
result:
succeededWhen: { exitCode: [0] }
failedWhen: { exitCode: [1] }
otherwise: error # succeeded | failed | error
requires:
- state: some.precondition.state # informational + reference-checked only
ensures:
- state: some.state.this.fixes
verification:
states:
- some.state.this.fixes # what actually gets reobserved; defaults to `ensures` if omitted
A TestAction must end up with at least one verification state (explicit or via ensures); the loader rejects an action that declares nothing to check afterwards.
Walkthrough: the shipped example
tests/semantic/states/storage.container.metadata.ready.yaml,
tests/semantic/states/storage.container.directory.ready.yaml, and
tests/semantic/actions/storage.container.metadata.repair.yaml
wrap the real ontobdc.storage.plugin.check.is_container_metadata_ready check
and hotfix — no wrapper code was written on the ontobdc side, the manifest
calls check.py:main/hotfix.py:main directly.
-
Validate the manifests:
ontobdc-dev test validate --manifest tests/semantic
-
See what got loaded:
ontobdc-dev test list states --manifest tests/semantic ontobdc-dev test list actions --manifest tests/semantic
-
Pick (or create) a container directory to test against, then run the bare check. Against an empty/nonexistent container this reports
failed:ontobdc-dev test run --manifest tests/semantic \ --state storage.container.metadata.ready \ --param root_path=/path/to/workspace \ --param container_path=/path/to/workspace/my-container
-
Run the full
check -> hotfix -> recheckcycle. The hotfix creates/repairs the container metadata, and the verdict comes from reobservingstorage.container.metadata.readyafterwards — never from the hotfix's own exit code (semantic-test-orchestrator.md, section 6.1: "o retorno do hotfix não comprova estado"):ontobdc-dev test run --manifest tests/semantic \ --action storage.container.metadata.repair \ --param root_path=/path/to/workspace \ --param container_path=/path/to/workspace/my-container
-
Running the bare check again now reports
passed.
Writing a test for another check/hotfix
- Pick the check, e.g.
ontobdc.storage.plugin.check.is_container_manifest_synced.check:main. Read its signature to know which arguments it takes and confirm it returnsint. - Add a
StateDefinitionundertests/semantic/states/, named after the check (dotted, lower-case), with apython-callobserver pointing atmodule:mainand anargumentsmap using${context.<name>}for every parameter the check needs. - If there is a matching
hotfix.py, add aTestActionundertests/semantic/actions/with rolerepair, an executor pointing athotfix.py:main,ensurespointing back at theStateDefinitionfrom step 2, andrequiresfor any precondition state (add aStateDefinitionfor it too if one does not exist yet — afilesystemobserver is usually enough for "does this directory exist"). - Run
ontobdc-dev test validate --manifest tests/semantic— it will catch a typo'd state reference or a missingmetadata.nameimmediately. - Run
ontobdc-dev test run --state ... --param ...against a real (or intentionally broken) path first, to see the check fail the way you expect, thenontobdc-dev test run --action ... --param ...to see the repair cycle.
Reading the output
test run returns a CommandResponse whose content always has this shape:
{
"mode": "state" | "action",
"target": "the state or action name you passed",
"verdict": "passed" | "failed" | "error",
"before": { "<state name>": { "status": "...", "observed_at": "...", "detail": "...", "evidence": {...} } },
"action_result": null | { "action": "...", "status": "succeeded|failed|error", "executed_at": "...", "detail": "..." },
"after": { "<state name>": { ... } }, // empty for `--state` runs; only populated after a non-erroring action
"detail": "short human-readable summary"
}
before is always populated (for --action, it is the pre-execution
observation, informational only). after is only populated once the action
itself did not error or fail. Pass --json on the outer ontobdc-dev
invocation to get this as plain JSON instead of a Rich box.
Troubleshooting
| Symptom | Cause |
|---|---|
Missing context value for '${context.foo}'. Provide it with --param foo=<value>. |
The manifest references a ${context.foo} placeholder you did not supply with --param foo=.... |
Unknown state 'x'. / Unknown action 'x'. |
The name passed to --state/--action, or referenced by requires/ensures/verification.states/an expression, does not match any metadata.name in the loaded manifests. Check for typos or a missing --manifest path. |
TestAction 'x' references unknown state 'y'. |
Add the missing StateDefinition, or fix the reference. |
StateDefinition 'x' must declare exactly one of 'observer' or 'expression'. |
A state manifest has both, or neither, under spec. |
'<target>' returned <value>; a python-call target must return an int exit code. |
The wrapped check.py/hotfix.py function did not return a plain int — every OntoBDC check/hotfix main() is expected to. |
Verdict is error instead of failed |
Something in the observer/executor itself broke (bad target, exception, wrong argument), as opposed to the state simply being unsatisfied. The detail/evidence fields carry the underlying message. |
TestAction 'x' declares no 'ensures' or 'verification.states' to reobserve after execution. |
Add at least one ensures entry or an explicit verification.states list — the runner has nothing to reobserve otherwise. |
Root Resolution
RootDirStrategy owns workspace-root resolution inside ontobdc-dev.
An explicit root may be passed in any position:
ontobdc-dev --root-dir /path/to/workspace branch
ontobdc-dev branch --root-dir /path/to/workspace
The explicit directory must exist and contain .gitmodules.
When --root-dir is omitted, the strategy starts at the current working directory and walks through its parents until it finds .gitmodules. The resolved value is stored in the CLI context as pathlib.Path and is consumed by workspace commands and dependent strategies.
The ontobdc dev proxy only locates and executes the ontobdc-dev package. It forwards arguments and preserves the current working directory; it does not resolve or inject the workspace root.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ontobdc_dev-0.1.0.tar.gz.
File metadata
- Download URL: ontobdc_dev-0.1.0.tar.gz
- Upload date:
- Size: 47.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
65ebc05eedbbe6c4101a88bdc365ef8081c2613ca0430947156f6d73433692dc
|
|
| MD5 |
d795722fdc1f1596ef82b45960ab80ef
|
|
| BLAKE2b-256 |
088b1394c047db24d719a5f8925473b6dda866c8ef627d90bee2ac8b7533ed7b
|
File details
Details for the file ontobdc_dev-0.1.0-py3-none-any.whl.
File metadata
- Download URL: ontobdc_dev-0.1.0-py3-none-any.whl
- Upload date:
- Size: 63.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9347e772f0627c8236f936ce4a1aca77b592ee905ef102153f6d1f51ac47a027
|
|
| MD5 |
8df69de0775758e77d556e6cba31fa4c
|
|
| BLAKE2b-256 |
90a2daa99bc919fe290383b84635296e3ed58903457b5fdf198e80d72c6723a7
|