feat(projectconfig): accept [tests] and [test-groups] schema in config#229
feat(projectconfig): accept [tests] and [test-groups] schema in config#229bhagyapathak wants to merge 20 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds support for a “new-shape” test configuration schema by introducing first-class project-level test definitions and groups, and enabling images/components to reference them.
Changes:
- Introduces
TestDefinition,TestGroup,TestRef, andComponentTestsConfigtypes for the new schema. - Extends
ConfigFile,ImageTestsConfig, andComponentConfigto carry new test/group references. - Updates fingerprint decision test to exclude component test-selection metadata from build inputs.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/projectconfig/tests.go | Adds the new schema types for tests, groups, and references. |
| internal/projectconfig/configfile.go | Adds top-level [tests] and [test-groups] maps to the config shape. |
| internal/projectconfig/image.go | Allows images to reference tests/groups via ImageTestsConfig.Tests. |
| internal/projectconfig/component.go | Allows components to reference tests/groups and deep-copies the new field. |
| internal/projectconfig/fingerprint_test.go | Excludes ComponentConfig.Tests from fingerprint build inputs. |
f0e30ee to
b44cb81
Compare
b44cb81 to
f7dbf0e
Compare
f7dbf0e to
c01da5d
Compare
c01da5d to
bd478bd
Compare
bd478bd to
fafc0c1
Compare
fafc0c1 to
f1e6eb3
Compare
f1e6eb3 to
86e4307
Compare
86e4307 to
9064645
Compare
| func (TestRef) JSONSchemaExtend(schema *jsonschema.Schema) { | ||
| // Exactly one of name|group: encoded as oneOf with `required` on each and | ||
| // `not` excluding the other, which forbids both `{}` and `{name, group}`. | ||
| schema.OneOf = []*jsonschema.Schema{ | ||
| {Required: []string{"name"}, Not: &jsonschema.Schema{Required: []string{"group"}}}, | ||
| {Required: []string{"group"}, Not: &jsonschema.Schema{Required: []string{"name"}}}, | ||
| } |
liunan-ms
left a comment
There was a problem hiding this comment.
The new shape seems a superset of tmt, lisa, and pytest, other fields like required-capabilities, reusable groups, and per-component references. Is this intended as the next-generation replacement for test-suites? If yes, is there a migration path designed?
|
Thanks for your patience -- I went through this in detail yesterday; lots of goodness here. I've created a branch based on the work that also adds some additional proposed changes. I'll be sending it out during my day today. Some of my main comments/questions:
I'll follow up with more details later today. |
9064645 to
8ab6361
Compare
| "kind": { | ||
| "items": { | ||
| "type": "string" | ||
| }, | ||
| "type": "array", | ||
| "title": "Kind", | ||
| "description": "Test kind hints (e.g. functional or performance)" | ||
| }, |
7693b03 to
c5fb905
Compare
| // Type identifies the framework/runner. Required, and constrained to the | ||
| // closed enum in the schema tag at the schema layer. The loader still | ||
| // accepts unknown values permissively; the resolver is the source of truth. | ||
| Type string `toml:"type" json:"type" jsonschema:"required,title=Type,description=Test framework type,enum=pytest,enum=lisa,enum=tmt"` |
| // TestRef is a reference to either a test (by name) or another group (by name). | ||
| // Exactly one of Name or Group should be set; semantic validation is the resolver's | ||
| // responsibility. |
| if err := validateTestDefinitions(f.Tests); err != nil { | ||
| return err | ||
| } | ||
|
|
||
| if err := validateNewTestReferences(f); err != nil { | ||
| return err | ||
| } |
Thank you @liunan-ms for pointing this out. |
Hi @reubeno For this iteration, I have already tightened a few areas:
One important migration concern is ControlTower compatibility. Today, ControlTower consumes testSuites and derives TestSuiteDetails from that contract. If we remove those fields before ControlTower is updated, we risk missing test metadata and skipping validation task wiring. To avoid breakage, I propose this rollout:
I agree with your points on unifying test-suites and tests strengthening validation and expanding unit coverage. I will incorporate those as part of the migration work. I am looking forward to your suggestions on the migration. |
… with 2 updates (microsoft#259) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…bot-github-actions group across 1 directory (microsoft#260) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…directories with 1 update (microsoft#265) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…crosoft#212) Co-authored-by: Nan Liu <108544011+liunan-ms@users.noreply.github.com>
Co-authored-by: Nan Liu <108544011+liunan-ms@users.noreply.github.com>
…ration (microsoft#261) Co-authored-by: Antonio Salinas <asalinas@microsoft.com>
…ommits and enum upstream-status - Rename OverlayCategoryBackportDistGit -> OverlayCategoryUpstreamBackport (value 'backport-dist-git' -> 'upstream-backport'). Widens the category to cover Fedora dist-git and native OSS backports alike. - Replace BugRef with reusable URLRef (URL-carrying struct with room for tracker/source-specific fields). Metadata.Commits is now []URLRef instead of []string; Metadata.Bugs is []URLRef. - Replace tri-state Upstreamable *bool with typed OverlayUpstreamStatus enum (upstreamed, upstreamable, needs-upstream-hook, inapplicable); empty string = not-yet-assessed. - Regenerate schema and scenario snapshots; update overlays.md user reference to match the new field names, enum values, and TOML examples.
…karound Broaden the category to cover any overlay that is explicitly intended to be dropped once an upstream or environmental fix lands, including (but not limited to) workarounds for dependencies not yet imported into AZL. Also broaden the azl-branding-policy to cover fixes for upstream code that hard-codes Fedora identity strings
Add an optional [component-groups.<name>.metadata] block reusing the existing OverlayMetadata schema (required category plus commits, bugs, and upstreamable). Metadata is documentation only and does not affect how group members are resolved or built. Validation is wired into ConfigFile.Validate. Regenerate JSON schema; update reference docs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…PI drift The component-groups metadata PR was based on the pre-rework OverlayMetadata API and landed after that rework, leaving main red: - loader_test.go referenced removed identifiers (`OverlayCategoryBackportDistGit`, `BugRef`, `Upstreamable`) and inline TOML using the old `upstreamable` field. Migrated it to `OverlayCategoryUpstreamBackport`, `URLRef`, and `upstream-status`. - component-groups.md linked to a nonexistent `#bug-references` anchor in overlays.md. Updated to the actual `#url-references` heading. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…crosoft#267) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Antonio Salinas <asalinas@microsoft.com>
| for _, ref := range refs { | ||
| switch { |
| // findRuff locates the ruff executable on the PATH. ruff is a Python tool and is not managed via the Go | ||
| // tools modules, so developers must install it themselves (the VS Code ruff extension bundles a copy that | ||
| // is not exposed on the PATH). | ||
| func findRuff() (string, error) { | ||
| ruffPath, err := exec.LookPath("ruff") | ||
| if err != nil { | ||
| return "", fmt.Errorf("%w: install it with 'pip install ruff' or see "+ | ||
| "https://docs.astral.sh/ruff/installation/: %w", ErrRuffNotFound, err) | ||
| } | ||
|
|
||
| return ruffPath, nil | ||
| } |
| // findPyright locates the pyright executable on the PATH. Like ruff, pyright is a Python tool that is not | ||
| // managed via the Go tools modules, so developers must install it themselves. | ||
| func findPyright() (string, error) { | ||
| pyrightPath, err := exec.LookPath("pyright") | ||
| if err != nil { | ||
| return "", fmt.Errorf("%w: install it with 'pip install pyright' or see "+ | ||
| "https://microsoft.github.io/pyright/#/installation: %w", ErrPyrightNotFnd, err) | ||
| } | ||
|
|
||
| return pyrightPath, nil | ||
| } |
| permissions: | ||
| contents: read | ||
| steps: | ||
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 |
| // mergeTests merges individual test definitions from a loaded config file into the | ||
| // resolved config. Duplicate test names are not allowed. | ||
| func mergeTests(resolvedCfg *ProjectConfig, loadedCfg *ConfigFile) error { | ||
| for testName, testDef := range loadedCfg.Tests { | ||
| if _, ok := resolvedCfg.Tests[testName]; ok { | ||
| return fmt.Errorf("%w: test %#q", ErrDuplicateTestSuites, testName) | ||
| } | ||
|
|
||
| resolvedCfg.Tests[testName] = testDef.WithAbsolutePaths(loadedCfg.dir) | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| // mergeTestGroups merges named test groups from a loaded config file into the | ||
| // resolved config. Duplicate group names are not allowed. | ||
| func mergeTestGroups(resolvedCfg *ProjectConfig, loadedCfg *ConfigFile) error { | ||
| for groupName, group := range loadedCfg.TestGroups { | ||
| if _, ok := resolvedCfg.TestGroups[groupName]; ok { | ||
| return fmt.Errorf("%w: test group %#q", ErrDuplicateTestSuites, groupName) | ||
| } |
| if cfg != nil { | ||
| resolvedTests, err := cfg.ResolveComponentTests(comp.GetConfig()) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("failed to resolve tests for component %q:\n%w", comp.GetName(), err) | ||
| } |
| // Changelog generates a draft changelog section for the next release from the Conventional Commit | ||
| // history and prepends it to 'CHANGELOG.md', using git-cliff and the repo's 'cliff.toml'. | ||
| // | ||
| // The output is a *draft*: review and curate it into user-facing notes before releasing. See | ||
| // docs/developer/how-to/releasing.md. | ||
| // | ||
| // git-cliff must be installed and on PATH; this target does not install it. The same target runs | ||
| // locally and in CI (CI just installs git-cliff first), so there is a single changelog flow. | ||
| func Changelog() error { |
Adds a parse-only schema for declaring tests and reusable test groups in project TOML, plus matching per-component and per-image test reference lists.