Skip to content

Commit 86b797c

Browse files
Merge pull request #704 from camilamacedo86/ote-improve-output
OPRUN-4587: Make OTE local output easier to read
2 parents eb20885 + 510ce9a commit 86b797c

11 files changed

Lines changed: 754 additions & 51 deletions

File tree

openshift/tests-extension/Makefile

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,11 @@ build: #HELP Build the extended tests binary
181181
@mkdir -p $(TOOLS_BIN_DIR)
182182
GO_COMPLIANCE_POLICY="exempt_all" go build -ldflags "$(LDFLAGS)" -mod=vendor -o $(TOOLS_BIN_DIR)/olmv1-tests-ext ./cmd/...
183183

184+
.PHONY: build-local-dev
185+
build-local-dev: #HELP Build the extended tests binary with local dev commands (for local development only)
186+
@mkdir -p $(TOOLS_BIN_DIR)
187+
GO_COMPLIANCE_POLICY="exempt_all" go build -tags dev -ldflags "$(LDFLAGS)" -mod=vendor -o $(TOOLS_BIN_DIR)/olmv1-tests-ext ./cmd/...
188+
184189
.PHONY: update-metadata
185190
update-metadata: #HELP Build and run 'update-metadata' to generate test metadata
186191
$(TOOLS_BIN_DIR)/olmv1-tests-ext update --component openshift:payload:olmv1
@@ -245,3 +250,21 @@ verify-metadata: update-metadata
245250
.PHONY: verify-images-json #HELP Verify that 'images' command outputs valid JSON
246251
verify-images-json:
247252
@./hack/verify-images-json.sh $(TOOLS_BIN_DIR)/olmv1-tests-ext
253+
254+
#SECTION Local Testing (Human-Readable Output)
255+
256+
.PHONY: test-local
257+
test-local: build-local-dev #HELP Run tests locally with clean, human-readable output (usage: make test-local SUITE=olmv1/all)
258+
@if [ -z "$(SUITE)" ]; then \
259+
echo "ERROR: Please specify SUITE. Example: make test-local SUITE=olmv1/all"; \
260+
exit 1; \
261+
fi
262+
@$(TOOLS_BIN_DIR)/olmv1-tests-ext run-suite-dev "$(SUITE)"
263+
264+
.PHONY: test-local-single
265+
test-local-single: build-local-dev #HELP Run a single test with clean output (usage: make test-local-single TEST="test name")
266+
@if [ -z "$(TEST)" ]; then \
267+
echo "ERROR: Please specify TEST. Example: make test-local-single TEST=\"[sig-olmv1] OLMv1 should pass\""; \
268+
exit 1; \
269+
fi
270+
@$(TOOLS_BIN_DIR)/olmv1-tests-ext run-test-dev -n "$(TEST)"

openshift/tests-extension/README.md

Lines changed: 130 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ opts out with a skip label like `[Skipped:Disconnected]`.
3333
| Release jobs | [amd64.ocp.releases.ci.openshift.org](https://amd64.ocp.releases.ci.openshift.org/) | Click any build to see all validation jobs run against it |
3434
| Component Readiness | [Sippy](https://sippy.dptools.openshift.org/sippy-ng/component_readiness/main) | Test results feed here. Failures trigger a red alert and a Slack notification to the team |
3535
| OpenShift CI docs | [docs.ci.openshift.org](https://docs.ci.openshift.org/) | General documentation on how OpenShift CI works |
36+
| OTE Framework | [github.com/openshift-eng/openshift-tests-extension](https://github.com/openshift-eng/openshift-tests-extension) | OpenShift Tests Extension framework - wraps Ginkgo and exposes test commands |
37+
| OTE Enhancement | [OTE Enhancement Proposal](https://github.com/openshift/enhancements/blob/master/enhancements/testing/openshift-tests-extension.md) | Official design doc for the OpenShift Tests Extension framework |
38+
| Ginkgo v2 docs | [onsi.github.io/ginkgo](https://onsi.github.io/ginkgo/) | Official Ginkgo BDD testing framework documentation |
39+
| Ginkgo CLI reference | [Ginkgo CLI flags](https://onsi.github.io/ginkgo/#the-ginkgo-cli) | Complete reference for Ginkgo command-line flags and options |
3640
| Help with alerts | `#forum-ocp-testplatform` on Slack | Managed by the TRT team |
3741
| Help with OTE | `#wg-openshift-tests-extension` on Slack | Questions about the OpenShift Tests Extension framework |
3842

@@ -106,55 +110,145 @@ Example ([source](https://github.com/openshift/release/blob/main/ci-operator/con
106110
107111
## How to Run the Tests Locally
108112
109-
| Command | Description |
110-
|-------------------------------------------------|--------------------------------------------------------------------------|
111-
| `make build` | Builds the OLMv1 test binary. |
112-
| `./bin/olmv1-tests-ext info` | Shows info about the test binary and registered test suites. |
113-
| `./bin/olmv1-tests-ext list` | Lists all available test cases. |
114-
| `./bin/olmv1-tests-ext run-suite olmv1/all` | Runs the full OLMv1 test suite. |
115-
| `./bin/olmv1-tests-ext run-test -n <test-name>` | Runs one specific test. Replace <test-name> with the test's full name. |
113+
You must run OTE tests (`./bin/olmv1-tests-ext`) against an OCP Cluster with TechPreview Features enabled.
116114

115+
### Setup: Get an OpenShift Cluster
117116

118-
## How to Run the Tests Locally
117+
Use Cluster Bot to create an OpenShift cluster with OLMv1 installed:
119118

120-
The tests can be run locally using the `olmv1-tests-ext` binary against an OpenShift cluster.
121-
These tests are specifically designed for OpenShift and require OpenShift-specific APIs and features.
119+
```shell
120+
launch 4.20 gcp,techpreview
121+
```
122122

123-
Use the environment variable `KUBECONFIG` to point to your cluster configuration file such as:
123+
Set `KUBECONFIG`:
124124

125125
```shell
126-
KUBECONFIG=path/to/kubeconfig ./bin/olmv1-tests-ext run-test -n <test-name>
126+
mv ~/Downloads/cluster-bot-2025-08-06-082741.kubeconfig ~/.kube/cluster-bot.kubeconfig
127+
export KUBECONFIG=~/.kube/cluster-bot.kubeconfig
127128
```
128129

129-
To run tests that include tech preview features,
130-
you need an OpenShift cluster with OLMv1 installed and those features enabled.
130+
### Two Ways to Run Tests
131131

132-
### Local Test using OLMv1 on OpenShift
132+
#### 1. **Developer-Friendly Output** (For local development)
133133

134-
1. Use the `Cluster Bot` to create an OpenShift cluster with OLMv1 installed.
134+
Use the local dev commands (`run-suite-dev`, `run-test-dev`) that provide clean, human-readable output:
135135

136-
**Example:**
136+
**Implementation:** Local dev commands in `localdevoutput/` are excluded from production builds using Go build tags. Only included with `make build-local-dev`. See [localdevoutput/README.md](localdevoutput/README.md).
137137

138-
```shell
139-
launch 4.20 gcp,techpreview
138+
| Command | Description |
139+
|---------|-------------|
140+
| `make build-local-dev` | Builds the test binary with local dev commands |
141+
| `make test-local SUITE=olmv1/all` | Runs a test suite with clean, color-coded output |
142+
| `make test-local-single TEST="test name"` | Runs a single test with clean output |
143+
| `make list-test-names` | Lists all available test names |
144+
145+
**Example**
146+
147+
```bash
148+
export KUBECONFIG=~/.kube/cluster-bot.kubeconfig
149+
make build-local-dev
150+
make test-local SUITE=olmv1/all
140151
```
141152

142-
2. Set the `KUBECONFIG` environment variable to point to your OpenShift cluster configuration file.
153+
**Output:** Clean, color-coded summary with live progress:
154+
```text
155+
[46/46] ▶ Running: [sig-olmv1][OCPFeatureGate:NewOLMWebhookProviderOpenshiftServiceCA] OLMv1 operator with webhooks should have a working validating webhook
156+
✓ PASSED [194.1 seconds] (Total: ✓45 ✗0)
143157
144-
**Example:**
145158
146-
```shell
147-
mv ~/Downloads/cluster-bot-2025-08-06-082741.kubeconfig ~/.kube/cluster-bot.kubeconfig
148-
export KUBECONFIG=~/.kube/cluster-bot.kubeconfig
159+
════════════════════════════════════════════════════════
160+
Final Summary
161+
════════════════════════════════════════════════════════
162+
✓ Passed: 45
163+
✗ Failed: 0
164+
⊘ Skipped: 1
165+
166+
✓ ALL TESTS PASSED!
149167
```
150168

151-
3. Run the tests using the `olmv1-tests-ext` binary.
169+
#### 2. **Raw OTE Framework Output** (For CI/CD integration)
170+
171+
Run the binary directly for structured JSON reports:
172+
173+
| Command | Description |
174+
|---------|-------------|
175+
| `./bin/olmv1-tests-ext info` | Shows info about the test binary and registered test suites |
176+
| `./bin/olmv1-tests-ext list` | Lists all available test cases |
177+
| `./bin/olmv1-tests-ext run-suite olmv1/all` | Runs the full OLMv1 test suite with JSON output |
178+
| `./bin/olmv1-tests-ext run-test -n <test-name>` | Runs one specific test with JSON output |
152179

153180
**Example:**
154-
```shell
181+
182+
```bash
183+
export KUBECONFIG=~/.kube/cluster-bot.kubeconfig
184+
make build
155185
./bin/olmv1-tests-ext run-suite olmv1/all
156186
```
157187

188+
**Output:** Structured JSON report (as used by Component Readiness and other integrated solutions):
189+
```text
190+
Running Suite: - /Users/camilam/go/src/github/operator-framework-operator-controller/openshift/tests-extension
191+
===============================================================================================================
192+
Random Seed: 1753508546 - will randomize all specs
193+
194+
Will run 1 of 1 specs
195+
------------------------------
196+
[sig-olmv1] OLMv1 should pass a trivial sanity check
197+
/Users/camilam/go/src/github/operator-framework-operator-controller/openshift/tests-extension/test/olmv1.go:26
198+
• [0.000 seconds]
199+
------------------------------
200+
201+
Ran 1 of 1 Specs in 0.000 seconds
202+
SUCCESS! -- 1 Passed | 0 Failed | 0 Pending | 0 Skipped
203+
[
204+
{
205+
"name": "[sig-olmv1] OLMv1 should pass a trivial sanity check",
206+
"lifecycle": "blocking",
207+
"duration": 0,
208+
"startTime": "2025-07-26 05:42:26.553852 UTC",
209+
"endTime": "2025-07-26 05:42:26.580263 UTC",
210+
"result": "passed",
211+
"output": ""
212+
}
213+
]
214+
```
215+
216+
This is the same output format used by:
217+
- **Component Readiness** ([Sippy](https://sippy.dptools.openshift.org/sippy-ng/component_readiness/main))
218+
- **OpenShift CI/CD** pipeline
219+
- **Release validation jobs**
220+
- Any automated test processing tools
221+
222+
**When to use which:**
223+
- Use **clean output** (`make test-local` or `make test-local-single`) for local development, debugging, and quick visual feedback
224+
- Use **raw output** (direct binary execution with `./bin/olmv1-tests-ext`) when you need JSON reports, CI/CD integration, or programmatic processing
225+
226+
### Discovering Available Flags
227+
228+
The OTE framework wraps Ginkgo and exposes its own set of commands and flags. To see what's available:
229+
230+
```bash
231+
# See all available commands
232+
./bin/olmv1-tests-ext --help
233+
234+
# See flags for running test suites
235+
./bin/olmv1-tests-ext run-suite --help
236+
237+
# See flags for running individual tests
238+
./bin/olmv1-tests-ext run-test --help
239+
```
240+
241+
**Available OTE-specific flags:**
242+
- `--component string` - Specify the component to enable (default "default")
243+
- `--max-concurrency int` - Maximum number of tests to run in parallel (default 10)
244+
- `--output string` - Output mode (default "json")
245+
- `--junit-path string` - Write results to JUnit XML (for `run-suite`)
246+
- `--names stringArray` - Specify test name, can be used multiple times (for `run-test`)
247+
248+
**Note:** The OTE framework does not expose all Ginkgo CLI flags.
249+
It provides a simplified interface focused on running tests in OpenShift environments.
250+
For full Ginkgo flag reference, see the [Ginkgo CLI documentation](https://onsi.github.io/ginkgo/#the-ginkgo-cli).
251+
158252
## Development Workflow
159253

160254
- Add or update tests in: `openshift/tests-extension/tests/`
@@ -283,14 +377,16 @@ that the metadata is up to date:
283377

284378
## Makefile Commands
285379

286-
| Target | Description |
287-
|--------------------------|------------------------------------------------------------------------------|
288-
| `make build` | Builds the test binary. |
289-
| `make update-metadata` | Updates the metadata JSON file. |
290-
| `make build-update` | Runs build + update-metadata + cleans codeLocations. |
291-
| `make verify` | Runs formatting, vet, and linter. |
292-
| `make list-test-names` | Shows all test names in the binary. |
293-
| `make clean-metadata` | Removes machine-specific codeLocations from the JSON metadata. [More info](https://issues.redhat.com/browse/TRT-2186) |
380+
| Target | Description |
381+
|----------------------------------|------------------------------------------------------------------------------|
382+
| `make build` | Builds the test binary. |
383+
| `make test-local SUITE=<suite>` | Runs a test suite with clean, human-readable output for local development. |
384+
| `make test-local-single TEST="<name>"` | Runs a single test with clean, human-readable output. |
385+
| `make list-test-names` | Shows all test names in the binary. |
386+
| `make update-metadata` | Updates the metadata JSON file. |
387+
| `make build-update` | Runs build + update-metadata + cleans codeLocations. |
388+
| `make verify` | Runs formatting, vet, and linter. |
389+
| `make clean-metadata` | Removes machine-specific codeLocations from the JSON metadata. [More info](https://issues.redhat.com/browse/TRT-2186) |
294390

295391
**Note:** Metadata is stored in: `.openshift-tests-extension/openshift_payload_olmv1.json`
296392

openshift/tests-extension/cmd/main.go

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ import (
1414
"os"
1515
"strings"
1616

17-
"github.com/openshift-eng/openshift-tests-extension/pkg/cmd"
17+
otecmd "github.com/openshift-eng/openshift-tests-extension/pkg/cmd"
1818
e "github.com/openshift-eng/openshift-tests-extension/pkg/extension"
1919
et "github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests"
2020
g "github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo"
2121
"github.com/spf13/cobra"
2222

23+
localdevcmd "github.com/openshift/operator-framework-operator-controller/openshift/tests-extension/localdevoutput/cmd"
2324
"github.com/openshift/operator-framework-operator-controller/openshift/tests-extension/pkg/env"
2425
_ "github.com/openshift/operator-framework-operator-controller/openshift/tests-extension/test"
2526
_ "github.com/openshift/operator-framework-operator-controller/openshift/tests-extension/test/qe/specs"
@@ -300,33 +301,38 @@ func main() {
300301
}
301302

302303
// Get all default commands from the extension framework
303-
allCommands := cmd.DefaultExtensionCommands(registry)
304+
allCommands := otecmd.DefaultExtensionCommands(registry)
304305

305-
// Add KUBECONFIG check to run-suite and run-test commands only.
306+
// Add local dev commands for local development (only included when built with -tags dev)
307+
allCommands = append(allCommands, localdevcmd.RegisterLocalDevCommands(registry)...)
308+
309+
// Add KUBECONFIG check to run-suite, run-test, and dev variants.
306310
// Other commands (list, info, images, update, completion, help) don't need KUBECONFIG.
307311
for _, command := range allCommands {
308-
// Identify run-suite and run-test commands by their Use field
309-
if command.Use == "run-suite NAME" || command.Use == "run-test [-n NAME...] [NAME]" {
310-
// Save the original RunE function
311-
originalRunE := command.RunE
312-
313-
// Wrap it with KUBECONFIG check
314-
command.RunE = func(cmd *cobra.Command, args []string) error {
315-
// Check KUBECONFIG before running the test
312+
switch command.Name() {
313+
case "run-suite", "run-test", "run-suite-dev", "run-test-dev":
314+
localCmd := command
315+
originalRunE := localCmd.RunE
316+
317+
localCmd.RunE = func(cmd *cobra.Command, args []string) error {
316318
if err := exutil.CheckKubeconfigSet(); err != nil {
317319
return err
318320
}
319-
// Call the original RunE function
320-
return originalRunE(cmd, args)
321+
if originalRunE != nil {
322+
return originalRunE(cmd, args)
323+
}
324+
if localCmd.Run != nil {
325+
localCmd.Run(cmd, args)
326+
return nil
327+
}
328+
return fmt.Errorf("command %s has no Run or RunE function", localCmd.Name())
321329
}
322330
}
323331
}
324332

325333
root.AddCommand(allCommands...)
326334

327-
if err := func() error {
328-
return root.Execute()
329-
}(); err != nil {
335+
if err := root.Execute(); err != nil {
330336
os.Exit(1)
331337
}
332338
}

openshift/tests-extension/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ require (
1313
github.com/openshift/origin v1.5.0-alpha.3.0.20251010041851-79ff1dbbe815
1414
github.com/operator-framework/operator-controller v1.8.1-0.20260319123036-8ccea5a0cf67
1515
github.com/pborman/uuid v1.2.1
16+
github.com/pkg/errors v0.9.1
1617
github.com/spf13/cobra v1.10.2
1718
github.com/tidwall/gjson v1.18.0
1819
github.com/tidwall/pretty v1.2.1
@@ -73,7 +74,6 @@ require (
7374
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
7475
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
7576
github.com/opencontainers/go-digest v1.0.0 // indirect
76-
github.com/pkg/errors v0.9.1 // indirect
7777
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
7878
github.com/prometheus/client_golang v1.23.2 // indirect
7979
github.com/prometheus/client_model v0.6.2 // indirect
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Local Dev Output Commands
2+
3+
Developer-friendly test commands with clean, human-readable output for local execution.
4+
5+
## Structure
6+
7+
```text
8+
localdevoutput/
9+
├── cmd/ # Cobra commands for local development
10+
│ ├── register.go # Returns nil (production build)
11+
│ ├── register_local_dev.go # Registers local dev commands (with -tags dev)
12+
│ ├── run_suite_local_dev.go # run-suite-dev command
13+
│ └── run_test_local_dev.go # run-test-dev command
14+
└── pkg/output/ # Output formatting
15+
├── formatter.go # ANSI colors, progress, summaries
16+
└── writer.go # OTE ResultWriter implementation
17+
```
18+
19+
## Purpose
20+
21+
These commands are **for local execution only**. They provide human-readable output when testing against OCP clusters locally.
22+
23+
## Build Separation
24+
25+
- **Production build**: `make build` → Excludes local dev commands (ships to OCP payload)
26+
- **Local dev build**: `make build-local-dev` → Includes local dev commands (for developers)
27+
28+
Build tags (`//go:build dev`) ensure dev commands are only compiled when explicitly requested with `-tags dev`.
29+
30+
### Output Flow
31+
32+
```text
33+
Test Run → ResultWriter.Write(result) → Formatter → Colored Terminal Output
34+
```
35+
36+
The `CleanResultWriter` implements OTE's `ResultWriter` interface to intercept test results and format them with colors and progress indicators.
37+
38+
## Usage
39+
40+
```bash
41+
# Run test suite with clean output
42+
make test-local SUITE=olmv1/all
43+
44+
# Run single test
45+
make test-local-single TEST="[sig-olmv1] test name"
46+
47+
# Direct binary usage
48+
./bin/olmv1-tests-ext run-suite-dev olmv1/all
49+
./bin/olmv1-tests-ext run-test-dev -n "test name"
50+
```
51+
52+
## Why Separate Directory?
53+
54+
Isolated in `localdevoutput/` to keep local development tools separate from the core test framework that ships to production.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//go:build !dev
2+
3+
package cmd
4+
5+
import (
6+
"github.com/openshift-eng/openshift-tests-extension/pkg/extension"
7+
"github.com/spf13/cobra"
8+
)
9+
10+
func RegisterLocalDevCommands(registry *extension.Registry) []*cobra.Command {
11+
return nil
12+
}

0 commit comments

Comments
 (0)