elastic / elastic/elastic-package

xUnit classname uses package folder name instead of manifest `name` field

Open
#3,586 0 comments 0 reactions 0 assignees View on GitHub
Team:Ecosystem
Dominant language
Go
Stars
72
Forks
141
Avg merge
19h 42m
Merged PRs (30d)
55

Description

## Summary

The `classname` attribute in xUnit/JUnit test reports is currently built from the **package folder name** (the last path component of the package root directory), not from the `name` field declared in `manifest.yml`.

This means that if a package folder is named `my_package_folder` but its `manifest.yml` declares `name: my_package`, the xUnit output will use `my_package_folder.logs` instead of `my_package.logs` — which is inconsistent with how the package identifies itself everywhere else.

## Root cause

The `Package` field in `TestFolder` is set in [`testrunner.FindTestFolders`](https://github.com/elastic/elastic-package/blob/808a6aedb1f76d677a64bddb520e0c1fdee93bb7/internal/testrunner/testrunner.go#L241) and [`testrunner.AssumeTestFolders`](https://github.com/elastic/elastic-package/blob/808a6aedb1f76d677a64bddb520e0c1fdee93bb7/internal/testrunner/testrunner.go#L204) (both in `internal/testrunner/testrunner.go`) using `filepath.Split` / `filepath.Base` on `packageRoot` — a purely filesystem-derived value ([L291](https://github.com/elastic/elastic-package/blob/808a6aedb1f76d677a64bddb520e0c1fdee93bb7/internal/testrunner/testrunner.go#L291), [L233](https://github.com/elastic/elastic-package/blob/808a6aedb1f76d677a64bddb520e0c1fdee93bb7/internal/testrunner/testrunner.go#L233)). It is never cross-referenced with the manifest.

This value then flows into each `TestResult.Package` via every tester that uses `r.testFolder.Package`:

- [`asset/tester.go#L164`](https://github.com/elastic/elastic-package/blob/808a6aedb1f76d677a64bddb520e0c1fdee93bb7/internal/testrunner/runners/asset/tester.go#L164)
- [`policy/tester.go#L95`](https://github.com/elastic/elastic-package/blob/808a6aedb1f76d677a64bddb520e0c1fdee93bb7/internal/testrunner/runners/policy/tester.go#L95)
- [`static/tester.go#L112`](https://github.com/elastic/elastic-package/blob/808a6aedb1f76d677a64bddb520e0c1fdee93bb7/internal/testrunner/runners/static/tester.go#L112)
- [`system/tester.go#L684`](https://github.com/elastic/elastic-package/blob/808a6aedb1f76d677a64bddb520e0c1fdee93bb7/internal/testrunner/runners/system/tester.go#L684)
- [`pipeline/tester.go#L305`](https://github.com/elastic/elastic-package/blob/808a6aedb1f76d677a64bddb520e0c1fdee93bb7/internal/testrunner/runners/pipeline/tester.go#L305)

And finally into [`xunit.go`](https://github.com/elastic/elastic-package/blob/808a6aedb1f76d677a64bddb520e0c1fdee93bb7/internal/testrunner/reporters/formats/xunit.go#L97):

```go
ClassName: fmt.Sprintf("%s.%s", r.Package, r.DataStream),
```

Note that the script tester already handles this correctly by reading the manifest name directly ([`script.go#L683`](https://github.com/elastic/elastic-package/blob/808a6aedb1f76d677a64bddb520e0c1fdee93bb7/internal/testrunner/script/script.go#L683), [`script.go#L418`](https://github.com/elastic/elastic-package/blob/808a6aedb1f76d677a64bddb520e0c1fdee93bb7/internal/testrunner/script/script.go#L418), [`cmd/testrunner.go#L793`](https://github.com/elastic/elastic-package/blob/808a6aedb1f76d677a64bddb520e0c1fdee93bb7/cmd/testrunner.go#L793)) — the fix should bring the other testers in line with that approach.

## Proposed fix

Read `manifest.yml` (via `packages.ReadPackageManifestFromPackageRoot`) when populating `TestFolder.Package` in `FindTestFolders` and `AssumeTestFolders`, and use `manifest.Name` instead of the directory name.

Alternatively, pass the manifest name down from [`cmd/testrunner.go`](https://github.com/elastic/elastic-package/blob/808a6aedb1f76d677a64bddb520e0c1fdee93bb7/cmd/testrunner.go#L172) (which already reads the manifest) through `TestOptions` into the runners, so it can be set on `TestFolder` without re-reading the manifest in every finder call.

## Impact

- xUnit `classname` values will consistently reflect the canonical package name, matching what Kibana, EPR, and Fleet use.
- If folder name and manifest `name` differ (e.g. during local development or in build pipelines that rename output directories), test report attribution will be correct.
- Existing CI pipelines that parse classnames by folder name may need updating.

## Note: impact on nested package directories (elastic/integrations#17403)

The integrations repository introduced support for an additional level of nesting under `packages/`, so that related packages can be grouped by technology (e.g. `packages/nginx/input_otel/`, `packages/apache/input_otel/`). In that layout, `filepath.Base(packageRoot)` returns only the innermost folder name (`input_otel`), which is **not guaranteed to be unique** across the repository — unlike the `name` field in `manifest.yml`, which must be unique.

Since the `classname` value is used to identify packages when reporting or notifying about flaky tests, using the folder name in this scenario can cause failures to be misattributed to the wrong package. Using `manifest.Name` instead would restore correctness, as package names are unique by definition.

## Related issues

- https://github.com/elastic/integrations/issues/17403 — Add support for an additional level of directories under `packages/`

---

*Generated with [Claude Code](https://claude.ai/claude-code)*

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in internal/testrunner/testrunner.go, especially FindTestFolders and AssumeTestFolders, and trace TestFolder.Package through the listed runners to internal/testrunner/reporters/formats/xunit.go. Compare this with the script tester's manifest handling. Done means xUnit classname values use manifest.Name rather than the package folder name, including nested package directories.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
cli, testing-qa
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.