Skip to content

Commit 34dcff4

Browse files
committed
[WINC-1536] Add OTE extension binary skeleton for Windows Containers tests
Add initial OTE (OpenShift Tests Extension) binary following the same pattern as MCO and NTO, with OCP-37362 as a pilot test case. Changes: - cmd/windows-machine-config-operator-tests-ext/main.go: OTE binary entry point with four suites: windows/all, windows/conformance/parallel, windows/conformance/serial, windows/storage - test/extended/winc.go: OCP-37362 pilot test (wmco golang version check) - test/extended/utils/cli.go: minimal oc wrapper for Ginkgo-based tests - test/extended/suite_test.go: Ginkgo suite bootstrap - Makefile: add build-tests-ext target - go.mod: add openshift-tests-extension dependency + OpenShift ginkgo fork replace directive (required for OTE compatibility; TODO confirm with Mansi whether upstream Ginkgo can be used instead) 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 cluster, OCP 4.20, WMCO v10.20.1) Jira: WINC-1536
1 parent f3be5c1 commit 34dcff4

302 files changed

Lines changed: 196477 additions & 6 deletions

File tree

Some content is hidden

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

Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@ 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+
GO_COMPLIANCE_POLICY="exempt_all" go build -o ${OUTPUT_DIR}/bin/windows-machine-config-operator-tests-ext \
111+
./cmd/windows-machine-config-operator-tests-ext
112+
106113
.PHONY: run
107114
run: manifests generate fmt vet ## Run a controller from your host.
108115
go run cmd/operator/main.go
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// windows-machine-config-operator-tests-ext is the OTE (OpenShift Tests Extension)
2+
// binary for Windows Containers tests. It wraps WINC Ginkgo tests and exposes them
3+
// through the standardized OTE interface (info / list / run-test / run-suite).
4+
//
5+
// References:
6+
// - OTE Integration Guide: https://github.com/openshift-eng/openshift-tests-extension
7+
// - Similar implementation (NTO): https://github.com/openshift/cluster-node-tuning-operator/blob/main/cmd/cluster-node-tuning-operator-test-ext/main.go
8+
// - Similar implementation (MCO): https://github.com/openshift/machine-config-operator/blob/master/cmd/machine-config-tests-ext/main.go
9+
package main
10+
11+
import (
12+
"fmt"
13+
"os"
14+
"strings"
15+
16+
"github.com/spf13/cobra"
17+
otecmd "github.com/openshift-eng/openshift-tests-extension/pkg/cmd"
18+
e "github.com/openshift-eng/openshift-tests-extension/pkg/extension"
19+
et "github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests"
20+
g "github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo"
21+
22+
// Register WINC Ginkgo tests.
23+
_ "github.com/openshift/windows-machine-config-operator/test/extended"
24+
)
25+
26+
func main() {
27+
registry := e.NewRegistry()
28+
ext := e.NewExtension("openshift", "payload", "windows-machine-config-operator")
29+
30+
// All WINC tests - used for full runs and informing jobs.
31+
ext.AddSuite(e.Suite{
32+
Name: "windows/all",
33+
Qualifiers: []string{
34+
`name.contains("[sig-windows]")`,
35+
},
36+
})
37+
38+
// Parallel conformance subset.
39+
// Excludes [Serial], [Slow], and [Disruptive] tests.
40+
// Parents will be added once tests achieve >=99% pass rate.
41+
ext.AddSuite(e.Suite{
42+
Name: "windows/conformance/parallel",
43+
Qualifiers: []string{
44+
`name.contains("[sig-windows]") && !name.contains("[Serial]") && !name.contains("[Slow]") && !name.contains("[Disruptive]")`,
45+
},
46+
})
47+
48+
// Serial conformance subset.
49+
// Parents will be added once tests achieve >=99% pass rate.
50+
ext.AddSuite(e.Suite{
51+
Name: "windows/conformance/serial",
52+
Qualifiers: []string{
53+
`name.contains("[sig-windows]") && name.contains("[Serial]")`,
54+
},
55+
})
56+
57+
// Storage-specific tests.
58+
ext.AddSuite(e.Suite{
59+
Name: "windows/storage",
60+
Qualifiers: []string{
61+
`name.contains("[sig-windows]") && name.contains("storage")`,
62+
},
63+
})
64+
65+
specs, err := g.BuildExtensionTestSpecsFromOpenShiftGinkgoSuite()
66+
if err != nil {
67+
panic(fmt.Sprintf("couldn't build extension test specs from ginkgo: %v", err))
68+
}
69+
70+
applyPlatformFilters(specs)
71+
72+
ext.AddSpecs(specs)
73+
registry.Register(ext)
74+
75+
root := &cobra.Command{
76+
Use: "windows-machine-config-operator-tests-ext",
77+
Short: "OpenShift Windows Containers test extension (OTE)",
78+
Long: "Runs the WINC test suite as an OpenShift Tests Extension binary.",
79+
}
80+
81+
root.AddCommand(otecmd.DefaultExtensionCommands(registry)...)
82+
83+
if err := root.Execute(); err != nil {
84+
os.Exit(1)
85+
}
86+
}
87+
88+
// applyPlatformFilters converts "Platform:<name>" and "NoPlatform:<name>" Ginkgo
89+
// labels into OTE include/exclude constraints so that openshift-tests can filter
90+
// tests before execution rather than relying on g.Skip() inside the test body.
91+
func applyPlatformFilters(specs et.ExtensionTestSpecs) {
92+
specs.Walk(func(spec *et.ExtensionTestSpec) {
93+
for label := range spec.Labels {
94+
if strings.HasPrefix(label, "Platform:") {
95+
platform := strings.TrimPrefix(label, "Platform:")
96+
spec.Include(et.PlatformEquals(platform))
97+
}
98+
if strings.HasPrefix(label, "NoPlatform:") {
99+
platform := strings.TrimPrefix(label, "NoPlatform:")
100+
spec.Exclude(et.PlatformEquals(platform))
101+
}
102+
}
103+
})
104+
}

go.mod

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ replace (
88
// fix CVE-2025-30204 transitive deps still using older v4. Remove once `go mod graph` shows only 4.5.2 or higher
99
github.com/golang-jwt/jwt/v4 => github.com/golang-jwt/jwt/v4 v4.5.2
1010
github.com/golang-jwt/jwt/v5 => github.com/golang-jwt/jwt/v5 v5.2.2
11+
// Required for openshift-tests-extension compatibility (uses OpenShift's ginkgo fork).
12+
// TODO: confirm with Mansi whether this can be avoided with upstream Ginkgo.
13+
github.com/onsi/ginkgo/v2 => github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20241205171354-8006f302fd12
1114
)
1215

1316
require (
@@ -16,6 +19,9 @@ require (
1619
github.com/coreos/ignition/v2 v2.23.0
1720
github.com/go-imports-organizer/goio v1.5.0
1821
github.com/go-logr/logr v1.4.3
22+
github.com/onsi/ginkgo/v2 v2.22.2
23+
github.com/onsi/gomega v1.36.2
24+
github.com/openshift-eng/openshift-tests-extension v0.0.0-20260127124016-0fed2b824818
1925
github.com/openshift/api v0.0.0-20260213204242-d34f11c515b3
2026
github.com/openshift/client-go v0.0.0-20260213141500-06efc6dce93b
2127
github.com/openshift/library-go v0.0.0-20260213153706-03f1709971c5
@@ -86,11 +92,13 @@ require (
8692
github.com/go-openapi/swag/stringutils v0.25.4 // indirect
8793
github.com/go-openapi/swag/typeutils v0.25.4 // indirect
8894
github.com/go-openapi/swag/yamlutils v0.25.4 // indirect
95+
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
8996
github.com/gogo/protobuf v1.3.2 // indirect
9097
github.com/google/btree v1.1.3 // indirect
9198
github.com/google/cel-go v0.26.0 // indirect
9299
github.com/google/gnostic-models v0.7.1 // indirect
93100
github.com/google/go-cmp v0.7.0 // indirect
101+
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect
94102
github.com/google/uuid v1.6.0 // indirect
95103
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
96104
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
@@ -109,9 +117,8 @@ require (
109117
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
110118
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
111119
github.com/onsi/ginkgo v1.16.5 // indirect
112-
github.com/onsi/ginkgo/v2 v2.22.2 // indirect
113-
github.com/onsi/gomega v1.36.2 // indirect
114120
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
121+
github.com/pkg/errors v0.9.1 // indirect
115122
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
116123
github.com/prometheus/client_golang v1.23.2 // indirect
117124
github.com/prometheus/client_model v0.6.2 // indirect
@@ -143,6 +150,7 @@ require (
143150
golang.org/x/term v0.40.0 // indirect
144151
golang.org/x/text v0.34.0 // indirect
145152
golang.org/x/time v0.14.0 // indirect
153+
golang.org/x/tools v0.41.0 // indirect
146154
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
147155
google.golang.org/genproto/googleapis/api v0.0.0-20250721164621-a45f3dfb1074 // indirect
148156
google.golang.org/genproto/googleapis/rpc v0.0.0-20250721164621-a45f3dfb1074 // indirect

go.sum

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,6 @@ github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85n
275275
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
276276
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
277277
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
278-
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
279278
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
280279
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
281280
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
@@ -505,8 +504,6 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108
505504
github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
506505
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
507506
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
508-
github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU=
509-
github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk=
510507
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
511508
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
512509
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
@@ -515,12 +512,16 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
515512
github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
516513
github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
517514
github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
515+
github.com/openshift-eng/openshift-tests-extension v0.0.0-20260127124016-0fed2b824818 h1:jJLE/aCAqDf8U4wc3bE1IEKgIxbb0ICjCNVFA49x/8s=
516+
github.com/openshift-eng/openshift-tests-extension v0.0.0-20260127124016-0fed2b824818/go.mod h1:6gkP5f2HL0meusT0Aim8icAspcD1cG055xxBZ9yC68M=
518517
github.com/openshift/api v0.0.0-20260213204242-d34f11c515b3 h1:SZ8+jxtkMvpb4HDTjSAbaOyhFsw5PiWhjBog+XLY7jc=
519518
github.com/openshift/api v0.0.0-20260213204242-d34f11c515b3/go.mod h1:d5uzF0YN2nQQFA0jIEWzzOZ+edmo6wzlGLvx5Fhz4uY=
520519
github.com/openshift/client-go v0.0.0-20260213141500-06efc6dce93b h1:7rTnxq+haKrzUFKQQDylkklyFRtGFox73dlawRlnTA8=
521520
github.com/openshift/client-go v0.0.0-20260213141500-06efc6dce93b/go.mod h1:V3s8weD4bKXGXaN7d9g3V1QS2gmlYBRI2i/lfIwmroM=
522521
github.com/openshift/library-go v0.0.0-20260213153706-03f1709971c5 h1:9Pe6iVOMjt9CdA/vaKBNUSoEIjIe1po5Ha3ABRYXLJI=
523522
github.com/openshift/library-go v0.0.0-20260213153706-03f1709971c5/go.mod h1:K3FoNLgNBFYbFuG+Kr8usAnQxj1w84XogyUp2M8rK8k=
523+
github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20241205171354-8006f302fd12 h1:AKx/w1qpS8We43bsRgf8Nll3CGlDHpr/WAXvuedTNZI=
524+
github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20241205171354-8006f302fd12/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
524525
github.com/operator-framework/api v0.5.2/go.mod h1:L7IvLd/ckxJEJg/t4oTTlnHKAJIP/p51AvEslW3wYdY=
525526
github.com/operator-framework/api v0.16.0 h1:swUOhVv7QDszxBTwYM8QAtyeqI4EQHNVAiKMS+xjakY=
526527
github.com/operator-framework/api v0.16.0/go.mod h1:kk8xJahHJR3bKqrA+A+1VIrhOTmyV76k+ARv+iV+u1Q=

test/extended/suite_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package extended
2+
3+
import (
4+
"testing"
5+
6+
g "github.com/onsi/ginkgo/v2"
7+
o "github.com/onsi/gomega"
8+
)
9+
10+
func TestExtended(t *testing.T) {
11+
o.RegisterFailHandler(g.Fail)
12+
g.RunSpecs(t, "Windows Containers Extended Test Suite")
13+
}

test/extended/utils/cli.go

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

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+
"strings"
5+
6+
"github.com/openshift/windows-machine-config-operator/test/extended/utils"
7+
8+
g "github.com/onsi/ginkgo/v2"
9+
o "github.com/onsi/gomega"
10+
)
11+
12+
const (
13+
wmcoNamespace = "openshift-windows-machine-config-operator"
14+
)
15+
16+
var _ = g.Describe("[sig-windows] Windows_Containers", func() {
17+
var oc = utils.NewCLIWithoutNamespace()
18+
19+
// author: rrasouli@redhat.com
20+
// OCP-37362 - Pilot case for OTE migration to WMCO
21+
g.It("Author:rrasouli-Smokerun-Medium-37362-[wmco] wmco using correct golang version [OTP]", func() {
22+
g.By("Fetch the correct golang version from cluster")
23+
serverVersion, err := oc.AsAdmin().Output("get", "--raw", "/version")
24+
o.Expect(err).NotTo(o.HaveOccurred())
25+
26+
// Extract goVersion field
27+
var goVersion string
28+
for _, line := range strings.Split(serverVersion, "\n") {
29+
if strings.Contains(line, "goVersion") {
30+
parts := strings.SplitN(line, ":", 2)
31+
if len(parts) == 2 {
32+
goVersion = strings.Trim(strings.TrimSpace(parts[1]), `",`)
33+
}
34+
break
35+
}
36+
}
37+
o.Expect(goVersion).NotTo(o.BeEmpty(), "goVersion not found in /version response")
38+
39+
// Truncate to major.minor (e.g. "go1.24.6" -> "go1.24")
40+
parts := strings.Split(goVersion, ".")
41+
truncated := strings.Join(parts[:2], ".")
42+
g.GinkgoWriter.Printf("Golang version: %s, truncated: %s\n", goVersion, truncated)
43+
44+
g.By("Compare with golang version in WMCO logs")
45+
logs, err := oc.AsAdmin().Output("logs",
46+
"deployment.apps/windows-machine-config-operator",
47+
"-n", wmcoNamespace,
48+
)
49+
o.Expect(err).NotTo(o.HaveOccurred())
50+
o.Expect(logs).To(o.ContainSubstring(truncated),
51+
"WMCO logs do not contain expected golang version %s", truncated)
52+
})
53+
})

vendor/github.com/go-task/slim-sprig/v3/.editorconfig

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/go-task/slim-sprig/v3/.gitattributes

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/go-task/slim-sprig/v3/.gitignore

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)