Repository navigation
Refactor suite, device, plan and CLI around typed inputs - #47
Merged
Merged
Conversation
Signed-off-by: jaenrig-ifx <enriquezgarcia.external@infineon.com>
… model. Signed-off-by: jaenrig-ifx <enriquezgarcia.external@infineon.com>
Signed-off-by: jaenrig-ifx <enriquezgarcia.external@infineon.com>
Print a sectioned report per suite: a "> suite : <name>" heading, the acquired devices, the test results, and a summary line such as "1 passed, 1 failed". Sections are divided by separator lines whose width matches the longest line of the report. List each device once, stacked under a cyan "> device [n]" heading with aligned name, uid and address fields in magenta. Prefix every test row with its device index instead of repeating the device name, and drop the parallel job id from the displayed test name. Pre-refactor and clean up. Signed-off-by: jaenrig-ifx <enriquezgarcia.external@infineon.com>
Signed-off-by: jaenrig-ifx <enriquezgarcia.external@infineon.com>
…ter. The class exports completed test output to files and does not render CLI output, so it belongs with the report observer API. Rename it to TestOutputExporter, update ottu/cli/cmd/run, and move its tests to tests/test_report with extra branch coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: jaenrig-ifx <enriquezgarcia.external@infineon.com>
…onfig. Fold the versioned DotOttu model and its ProjectConfig loader from config_models/project into one pydantic ProjectConfig in ottu/config.py. There is only one schema version, so the version-to-model dispatch is gone. The version field is checked by a validator that keeps the "Unsupported .ottu schema version" message. An empty .ottu file now fails validation instead of raising an AttributeError. Remove the config_models/project package, point backend, report and test_path at ottu.config, and move the tests to tests/test_config.py. Signed-off-by: jaenrig-ifx <enriquezgarcia.external@infineon.com>
Move the device list models into the device package. DeviceDefinition and DeviceList now live in ottu/device/device.py, together with the new DeviceInput model that describes the values a device must have. Device gains from_input() to resolve an input into a runtime device, and from_file() validates the YAML directly. The version adapter in config_models/device is removed; a new schema version will bring its own. Make DeviceQuery work on DeviceInput filters instead of parsed strings. The string and key=value parsing, and the combining of filters, are gone from the query; the CLI parses them into DeviceInput values instead. Device.from_string() and from_mapping() are replaced by from_input(). Remove config_models/device and move its tests to tests/device, and update the device and query tests for the typed inputs. Signed-off-by: jaenrig-ifx <enriquezgarcia.external@infineon.com>
Add the TestPathInput model, a test selector with an optional device role, and TestPath.from_input() to resolve it into test paths. Replace TestPathResolver.resolve_all() with two smaller pieces: exclude() removes already resolved exclude paths, and any path matching the context's own exclude patterns, from a list of test paths, and is_single_file() tells whether a selector names exactly one file that is not excluded. Callers now resolve their inputs and then exclude, instead of passing selectors through one combined call. Replace the resolve_all tests with tests for from_input(), exclude() and is_single_file(). Signed-off-by: jaenrig-ifx <enriquezgarcia.external@infineon.com>
Add SuiteReport, which describes a suite about to run with its devices already acquired, and SuiteReportObserver, a runtime-checkable protocol for observers that want to hear when a suite starts. SuiteReportNotifier hands the report to the observers that implement it and skips the rest, so existing test observers keep working unchanged. Drop the job_id from TestReport and QueueTestReportObserver. Concurrent replicas of a test run on distinct devices, so the device already tells their reports apart. The queue observer now forwards reports as they are. Update the queue observer test for the report being forwarded unchanged. Signed-off-by: jaenrig-ifx <enriquezgarcia.external@infineon.com>
Move backend.py to ottu/backend/backend.py and backend_builtins.py to ottu/backend/builtins.py. The package re-exports Backend and BackendCommandError, so importers are unchanged; the built-in definitions stay an internal module. Remove the 3 second sleeps from the debug backend commands, so debug runs finish at once and the tests no longer have to strip them. Move the tests to tests/backend and build their device with Device.from_input() instead of the removed Device.from_string(). Signed-off-by: jaenrig-ifx <enriquezgarcia.external@infineon.com>
Test.run() now uses the device assigned to the test and raises a ValueError when there is none, as it already does for a missing backend. It no longer falls back to an empty Device or acquires the device again: the suite books and acquires its devices once before running its tests. Remove Test.from_inputs(). The suite builder creates the tests from the resolved test paths, which keeps test selection and exclusion out of Test. Update the tests to run with an explicit device, add a test for the missing device, and drop the from_inputs tests. Signed-off-by: jaenrig-ifx <enriquezgarcia.external@infineon.com>
Turn suite.py into a package. suite/suite.py holds the runtime: the value types (RoleCount, SuiteOpts, DevicePool) and the suites. suite/builder.py holds what builds them from user inputs. The package re-exports every public name, so importers are unchanged. Replace the string-based SuiteBuilder, RoleSuiteBuilder and StandardSuiteBuilder with typed inputs. SuiteInput and SuiteDeviceInput describe a suite; SuiteInputValidator and SuiteRoleInputValidator check them; SuiteDeviceResolver and SuiteRoleDeviceResolver turn them into a device pool, one pool per role for role suites. SuiteBuilder.build() runs these steps and picks the suite class. Candidate pools are resolved and sized against count and jobs without touching hardware. Make Suite abstract. run() books the connected devices from the pool, acquires them, tells the observers with a SuiteReport and then runs. Each mode is a subclass that books its devices and assigns them to its tests: SuiteSequential, SuiteReplicated, SuiteRole and SuiteDistributed. This replaces the runner_* method names. A suite no longer keeps the requested and available devices, only its pool. Only connected devices are booked: a device without hardware access no longer counts as available. Move the tests to tests/suite and split them by suite and builder. Signed-off-by: jaenrig-ifx <enriquezgarcia.external@infineon.com>
Move the plan file models into plan.py. PlanFile validates a version 1 plan file; its suites are PlanSuiteInput values with PlanTestInput tests and a PlanSuiteRequires section. The version adapter in config_models/plan is removed; a new schema version will bring its own. Plan now turns each plan suite into a SuiteInput and builds it with SuiteBuilder.build(), so a plan suite is built the same way as one given on the command line. The command count overrides the plan count, and Plan.build_suites() takes the device inputs and the jobs of the command. Suite selection by name is now private to Plan. Remove config_models/plan, move its tests to tests/test_plan_file.py and update the plan tests for the typed inputs. Signed-off-by: jaenrig-ifx <enriquezgarcia.external@infineon.com>
Add cli/parse.py, which turns the argument and option strings into typed inputs: test paths, counts and device selectors, with the role qualifier for role suites. Bad values become click.BadParameter errors. run builds its suite with SuiteBuilder.build() from those inputs. For a plan, the --device, --count and --jobs options now override what the plan defines, instead of being rejected, and --tests and --exclude still select its suites. The suite acquires its own devices and announces itself to the observers, so run no longer acquires them. device parses its filters with parse_device_input, so a filter can be a bare identifier as well as key=value pairs. CliOutput follows suite events: suite_started() takes a SuiteReport instead of begin_suite(), and rows are keyed on test and device only, as the job id is gone. Document that --device replaces requires.device of every selected suite. Update the run, device and output tests, and add tests for the parsers. Signed-off-by: jaenrig-ifx <enriquezgarcia.external@infineon.com>
jaenrig-ifx
enabled auto-merge (rebase)
November 4, 2026 10:14
☂️ Python Coverage
Overall Coverage
New Files
Modified Files
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refactors the suite into a package with one Suite class per execution mode, and moves device, plan, backend, config and CLI parsing onto typed inputs. See the individual commits for details.