Skip to content

Commit 74d9113

Browse files
committed
[WINC-1777] Add OTE extension binary skeleton for Windows Containers tests
Add initial OTE (OpenShift Tests Extension) binary using upstream Ginkgo (github.com/onsi/ginkgo/v2) without the OpenShift fork. Tests are registered as plain Go functions via et.ExtensionTestSpecs instead of BuildExtensionTestSpecsFromOpenShiftGinkgoSuite(), which requires the OpenShift Ginkgo fork's internal APIs. This keeps WMCO's go.mod clean. Changes: - cmd/windows-machine-config-operator-tests-ext/main.go: OTE binary with four suites (windows/all, windows/parallel, windows/serial, windows/storage). Specs registered manually; no OpenShift Ginkgo fork required. - test/extended/winc.go: OCP-37362 as a plain Go function returning error - test/extended/utils/cli.go: lightweight oc wrapper; AsAdmin() wired to --as=system:admin; NewCLIWithoutNamespace delegates to NewCLI(""); filepath.Join used for default kubeconfig path - Makefile: add build-tests-ext target with mkdir -p guard - Containerfile: add COPY test test for Konflux build - go.mod: add openshift-tests-extension dependency Verified locally: make build-tests-ext OK ./windows-machine-config-operator-tests-ext list 1 test listed ./windows-machine-config-operator-tests-ext run-test OCP-37362 PASSED (Azure IPI, OCP 4.20, WMCO v10.20.1) Jira: WINC-1777
1 parent 282a862 commit 74d9113

File tree

54 files changed

+6351
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+6351
-0
lines changed

Containerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ COPY cmd cmd
8888
COPY controllers controllers
8989
COPY hack hack
9090
COPY pkg pkg
91+
COPY test test
9192
RUN make build
9293
RUN make build-daemon
9394

Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,14 @@ build: fmt vet
103103
build-daemon:
104104
env GOOS=windows GOARCH=amd64 go build -o ${OUTPUT_DIR}/bin/windows-instance-config-daemon.exe ./cmd/daemon
105105

106+
# Build the OTE (OpenShift Tests Extension) binary for Windows Containers tests.
107+
# GO_COMPLIANCE_POLICY=exempt_all is required for test binaries per ART compliance policy.
108+
.PHONY: build-tests-ext
109+
build-tests-ext:
110+
mkdir -p ${OUTPUT_DIR}/bin
111+
GO_COMPLIANCE_POLICY="exempt_all" go build -o ${OUTPUT_DIR}/bin/windows-machine-config-operator-tests-ext \
112+
./cmd/windows-machine-config-operator-tests-ext
113+
106114
.PHONY: run
107115
run: manifests generate fmt vet ## Run a controller from your host.
108116
go run cmd/operator/main.go
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// windows-machine-config-operator-tests-ext is the OTE (OpenShift Tests Extension)
2+
// binary for Windows Containers tests. Tests are registered as plain Go functions
3+
// using upstream Ginkgo, without the OpenShift Ginkgo fork.
4+
//
5+
// References:
6+
// - OTE Integration Guide: https://github.com/openshift-eng/openshift-tests-extension
7+
package main
8+
9+
import (
10+
"context"
11+
"os"
12+
13+
otecmd "github.com/openshift-eng/openshift-tests-extension/pkg/cmd"
14+
e "github.com/openshift-eng/openshift-tests-extension/pkg/extension"
15+
et "github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests"
16+
"github.com/spf13/cobra"
17+
18+
"github.com/openshift/windows-machine-config-operator/test/extended"
19+
"github.com/openshift/windows-machine-config-operator/test/extended/utils"
20+
)
21+
22+
func main() {
23+
registry := e.NewRegistry()
24+
ext := e.NewExtension("openshift", "payload", "windows-machine-config-operator")
25+
26+
// All WINC tests - used for full runs and informing jobs.
27+
ext.AddSuite(e.Suite{
28+
Name: "windows/all",
29+
Qualifiers: []string{
30+
`name.contains("[sig-windows]")`,
31+
},
32+
})
33+
34+
// Parallel subset: non-Serial, non-Slow, non-Disruptive tests.
35+
ext.AddSuite(e.Suite{
36+
Name: "windows/parallel",
37+
Qualifiers: []string{
38+
`name.contains("[sig-windows]") && !name.contains("[Serial]") && !name.contains("[Slow]") && !name.contains("[Disruptive]")`,
39+
},
40+
})
41+
42+
// Serial subset: tests that must run in isolation.
43+
ext.AddSuite(e.Suite{
44+
Name: "windows/serial",
45+
Qualifiers: []string{
46+
`name.contains("[sig-windows]") && name.contains("[Serial]")`,
47+
},
48+
})
49+
50+
// Storage-specific tests.
51+
ext.AddSuite(e.Suite{
52+
Name: "windows/storage",
53+
Qualifiers: []string{
54+
`name.contains("[sig-windows]") && name.contains("storage")`,
55+
},
56+
})
57+
58+
// Register test specs manually — no OpenShift Ginkgo fork required.
59+
specs := et.ExtensionTestSpecs{
60+
{
61+
Name: "[sig-windows] Windows_Containers Author:rrasouli-Smokerun-Medium-37362-[wmco] wmco using correct golang version [OTP]",
62+
Run: func(ctx context.Context) *et.ExtensionTestResult {
63+
if err := extended.CheckWmcoGolangVersion(ctx, utils.NewCLIWithoutNamespace()); err != nil {
64+
return &et.ExtensionTestResult{Result: et.ResultFailed, Output: err.Error()}
65+
}
66+
return &et.ExtensionTestResult{Result: et.ResultPassed}
67+
},
68+
},
69+
}
70+
71+
ext.AddSpecs(specs)
72+
registry.Register(ext)
73+
74+
root := &cobra.Command{
75+
Use: "windows-machine-config-operator-tests-ext",
76+
Short: "OpenShift Windows Containers test extension (OTE)",
77+
Long: "Runs the WINC test suite as an OpenShift Tests Extension binary.",
78+
}
79+
80+
root.AddCommand(otecmd.DefaultExtensionCommands(registry)...)
81+
82+
if err := root.Execute(); err != nil {
83+
os.Exit(1)
84+
}
85+
}

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ require (
88
github.com/coreos/ignition/v2 v2.26.0
99
github.com/go-imports-organizer/goio v1.5.0
1010
github.com/go-logr/logr v1.4.3
11+
github.com/openshift-eng/openshift-tests-extension v0.0.0-20260127124016-0fed2b824818
1112
github.com/openshift/api v0.0.0-20260311132013-1d84ab4f6a62
1213
github.com/openshift/client-go v0.0.0-20260306160707-3935d929fc7d
1314
github.com/openshift/library-go v0.0.0-20260311094140-ac826d10cb40
@@ -98,6 +99,7 @@ require (
9899
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
99100
github.com/onsi/ginkgo v1.16.5 // indirect
100101
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
102+
github.com/pkg/errors v0.9.1 // indirect
101103
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
102104
github.com/prometheus/client_golang v1.23.2 // indirect
103105
github.com/prometheus/client_model v0.6.2 // indirect

go.sum

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,8 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
506506
github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
507507
github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28=
508508
github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg=
509+
github.com/openshift-eng/openshift-tests-extension v0.0.0-20260127124016-0fed2b824818 h1:jJLE/aCAqDf8U4wc3bE1IEKgIxbb0ICjCNVFA49x/8s=
510+
github.com/openshift-eng/openshift-tests-extension v0.0.0-20260127124016-0fed2b824818/go.mod h1:6gkP5f2HL0meusT0Aim8icAspcD1cG055xxBZ9yC68M=
509511
github.com/openshift/api v0.0.0-20260311132013-1d84ab4f6a62 h1:Y5bgh8kcu6XujKNCASYNWdn8COBlfdgZpmwOaZqKD4E=
510512
github.com/openshift/api v0.0.0-20260311132013-1d84ab4f6a62/go.mod h1:pyVjK0nZ4sRs4fuQVQ4rubsJdahI1PB94LnQ8sGdvxo=
511513
github.com/openshift/client-go v0.0.0-20260306160707-3935d929fc7d h1:T+9HFgEEcnu1TDDfsO5JcJC6N0/Kzob5AtG9IpITHJ8=
@@ -526,6 +528,7 @@ github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+v
526528
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
527529
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
528530
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
531+
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
529532
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
530533
github.com/pkg/sftp v1.13.10 h1:+5FbKNTe5Z9aspU88DPIKJ9z2KZoaGCu6Sr6kKR/5mU=
531534
github.com/pkg/sftp v1.13.10/go.mod h1:bJ1a7uDhrX/4OII+agvy28lzRvQrmIQuaHrcI1HbeGA=

test/extended/utils/cli.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package utils
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"os"
7+
"os/exec"
8+
"path/filepath"
9+
"strings"
10+
)
11+
12+
// CLI wraps the oc command-line tool for use in OTE Ginkgo tests.
13+
type CLI struct {
14+
namespace string
15+
asAdmin bool
16+
kubeconfig string
17+
}
18+
19+
// NewCLI creates a CLI instance with the given namespace.
20+
func NewCLI(namespace string) *CLI {
21+
return &CLI{
22+
namespace: namespace,
23+
kubeconfig: kubeconfig(),
24+
}
25+
}
26+
27+
// NewCLIWithoutNamespace creates a CLI instance without a namespace (for cluster-scoped resources).
28+
func NewCLIWithoutNamespace() *CLI {
29+
return NewCLI("")
30+
}
31+
32+
// AsAdmin returns a copy of the CLI that runs as cluster-admin.
33+
func (c *CLI) AsAdmin() *CLI {
34+
copy := *c
35+
copy.asAdmin = true
36+
return &copy
37+
}
38+
39+
// Run executes an oc subcommand with the given arguments and returns stdout, stderr, and any error.
40+
func (c *CLI) Run(verb string, args ...string) (string, string, error) {
41+
cmdArgs := []string{verb}
42+
if c.asAdmin {
43+
cmdArgs = append(cmdArgs, "--as=system:admin")
44+
}
45+
if c.namespace != "" {
46+
cmdArgs = append(cmdArgs, "-n", c.namespace)
47+
}
48+
cmdArgs = append(cmdArgs, args...)
49+
50+
cmd := exec.Command("oc", cmdArgs...)
51+
if c.kubeconfig != "" {
52+
cmd.Env = append(os.Environ(), "KUBECONFIG="+c.kubeconfig)
53+
}
54+
55+
var stdout, stderr bytes.Buffer
56+
cmd.Stdout = &stdout
57+
cmd.Stderr = &stderr
58+
59+
err := cmd.Run()
60+
return strings.TrimSpace(stdout.String()), strings.TrimSpace(stderr.String()), err
61+
}
62+
63+
// Output is a convenience wrapper that returns stdout or an error combining stderr.
64+
func (c *CLI) Output(verb string, args ...string) (string, error) {
65+
out, errOut, err := c.Run(verb, args...)
66+
if err != nil {
67+
return "", fmt.Errorf("%w\nstderr: %s", err, errOut)
68+
}
69+
return out, nil
70+
}
71+
72+
func kubeconfig() string {
73+
if kc := os.Getenv("KUBECONFIG"); kc != "" {
74+
return kc
75+
}
76+
return filepath.Join(os.Getenv("HOME"), ".kube", "config")
77+
}

test/extended/winc.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package extended
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"fmt"
7+
"strings"
8+
9+
"github.com/openshift/windows-machine-config-operator/test/extended/utils"
10+
)
11+
12+
const (
13+
wmcoNamespace = "openshift-windows-machine-config-operator"
14+
)
15+
16+
// CheckWmcoGolangVersion verifies that the golang version reported by the cluster
17+
// matches the version used to build the WMCO binary (OCP-37362).
18+
func CheckWmcoGolangVersion(_ context.Context, oc *utils.CLI) error {
19+
serverVersion, err := oc.AsAdmin().Output("get", "--raw", "/version")
20+
if err != nil {
21+
return fmt.Errorf("failed to get cluster version: %w", err)
22+
}
23+
24+
var versionInfo struct {
25+
GoVersion string `json:"goVersion"`
26+
}
27+
if err := json.Unmarshal([]byte(serverVersion), &versionInfo); err != nil {
28+
return fmt.Errorf("failed to parse /version JSON: %w", err)
29+
}
30+
if versionInfo.GoVersion == "" {
31+
return fmt.Errorf("goVersion not found in /version response")
32+
}
33+
34+
parts := strings.Split(versionInfo.GoVersion, ".")
35+
if len(parts) < 2 {
36+
return fmt.Errorf("unexpected golang version format: %s", versionInfo.GoVersion)
37+
}
38+
truncated := strings.Join(parts[:2], ".")
39+
40+
logs, err := oc.AsAdmin().Output("logs",
41+
"deployment.apps/windows-machine-config-operator",
42+
"-n", wmcoNamespace,
43+
)
44+
if err != nil {
45+
return fmt.Errorf("failed to get WMCO logs: %w", err)
46+
}
47+
48+
if !strings.Contains(logs, truncated) {
49+
return fmt.Errorf("WMCO logs do not contain expected golang version %s (full: %s)",
50+
truncated, versionInfo.GoVersion)
51+
}
52+
return nil
53+
}

0 commit comments

Comments
 (0)