Skip to content

Commit d284273

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 v2.22.2) 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 - Makefile: add build-tests-ext target with mkdir -p guard - go.mod: add openshift-tests-extension; no ginkgo fork replace directive 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 f3be5c1 commit d284273

53 files changed

Lines changed: 6355 additions & 0 deletions

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: 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: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
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+
"github.com/spf13/cobra"
14+
15+
otecmd "github.com/openshift-eng/openshift-tests-extension/pkg/cmd"
16+
e "github.com/openshift-eng/openshift-tests-extension/pkg/extension"
17+
et "github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests"
18+
19+
"github.com/openshift/windows-machine-config-operator/test/extended"
20+
"github.com/openshift/windows-machine-config-operator/test/extended/utils"
21+
)
22+
23+
func main() {
24+
registry := e.NewRegistry()
25+
ext := e.NewExtension("openshift", "payload", "windows-machine-config-operator")
26+
27+
// All WINC tests - used for full runs and informing jobs.
28+
ext.AddSuite(e.Suite{
29+
Name: "windows/all",
30+
Qualifiers: []string{
31+
`name.contains("[sig-windows]")`,
32+
},
33+
})
34+
35+
// Parallel subset: non-Serial, non-Slow, non-Disruptive tests.
36+
ext.AddSuite(e.Suite{
37+
Name: "windows/parallel",
38+
Qualifiers: []string{
39+
`name.contains("[sig-windows]") && !name.contains("[Serial]") && !name.contains("[Slow]") && !name.contains("[Disruptive]")`,
40+
},
41+
})
42+
43+
// Serial subset: tests that must run in isolation.
44+
ext.AddSuite(e.Suite{
45+
Name: "windows/serial",
46+
Qualifiers: []string{
47+
`name.contains("[sig-windows]") && name.contains("[Serial]")`,
48+
},
49+
})
50+
51+
// Storage-specific tests.
52+
ext.AddSuite(e.Suite{
53+
Name: "windows/storage",
54+
Qualifiers: []string{
55+
`name.contains("[sig-windows]") && name.contains("storage")`,
56+
},
57+
})
58+
59+
// Register test specs manually — no OpenShift Ginkgo fork required.
60+
specs := et.ExtensionTestSpecs{
61+
{
62+
Name: "[sig-windows] Windows_Containers Author:rrasouli-Smokerun-Medium-37362-[wmco] wmco using correct golang version [OTP]",
63+
Run: func(ctx context.Context) *et.ExtensionTestResult {
64+
if err := extended.CheckWmcoGolangVersion(ctx, utils.NewCLIWithoutNamespace()); err != nil {
65+
return &et.ExtensionTestResult{Result: et.ResultFailed, Output: err.Error()}
66+
}
67+
return &et.ExtensionTestResult{Result: et.ResultPassed}
68+
},
69+
},
70+
}
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+
}

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ require (
1616
github.com/coreos/ignition/v2 v2.23.0
1717
github.com/go-imports-organizer/goio v1.5.0
1818
github.com/go-logr/logr v1.4.3
19+
github.com/openshift-eng/openshift-tests-extension v0.0.0-20260127124016-0fed2b824818
1920
github.com/openshift/api v0.0.0-20260213204242-d34f11c515b3
2021
github.com/openshift/client-go v0.0.0-20260213141500-06efc6dce93b
2122
github.com/openshift/library-go v0.0.0-20260213153706-03f1709971c5
@@ -112,6 +113,7 @@ require (
112113
github.com/onsi/ginkgo/v2 v2.22.2 // indirect
113114
github.com/onsi/gomega v1.36.2 // indirect
114115
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
116+
github.com/pkg/errors v0.9.1 // indirect
115117
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
116118
github.com/prometheus/client_golang v1.23.2 // indirect
117119
github.com/prometheus/client_model v0.6.2 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,8 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
515515
github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
516516
github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
517517
github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
518+
github.com/openshift-eng/openshift-tests-extension v0.0.0-20260127124016-0fed2b824818 h1:jJLE/aCAqDf8U4wc3bE1IEKgIxbb0ICjCNVFA49x/8s=
519+
github.com/openshift-eng/openshift-tests-extension v0.0.0-20260127124016-0fed2b824818/go.mod h1:6gkP5f2HL0meusT0Aim8icAspcD1cG055xxBZ9yC68M=
518520
github.com/openshift/api v0.0.0-20260213204242-d34f11c515b3 h1:SZ8+jxtkMvpb4HDTjSAbaOyhFsw5PiWhjBog+XLY7jc=
519521
github.com/openshift/api v0.0.0-20260213204242-d34f11c515b3/go.mod h1:d5uzF0YN2nQQFA0jIEWzzOZ+edmo6wzlGLvx5Fhz4uY=
520522
github.com/openshift/client-go v0.0.0-20260213141500-06efc6dce93b h1:7rTnxq+haKrzUFKQQDylkklyFRtGFox73dlawRlnTA8=

test/extended/utils/cli.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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.asAdmin {
46+
cmdArgs = append(cmdArgs, "--as=system:admin")
47+
}
48+
if c.noNamespace {
49+
// no -n flag
50+
} else if c.namespace != "" {
51+
cmdArgs = append(cmdArgs, "-n", c.namespace)
52+
}
53+
cmdArgs = append(cmdArgs, args...)
54+
55+
cmd := exec.Command("oc", cmdArgs...)
56+
if c.kubeconfig != "" {
57+
cmd.Env = append(os.Environ(), "KUBECONFIG="+c.kubeconfig)
58+
}
59+
60+
var stdout, stderr bytes.Buffer
61+
cmd.Stdout = &stdout
62+
cmd.Stderr = &stderr
63+
64+
err := cmd.Run()
65+
return strings.TrimSpace(stdout.String()), strings.TrimSpace(stderr.String()), err
66+
}
67+
68+
// Output is a convenience wrapper that returns stdout or an error combining stderr.
69+
func (c *CLI) Output(verb string, args ...string) (string, error) {
70+
out, errOut, err := c.Run(verb, args...)
71+
if err != nil {
72+
return "", fmt.Errorf("%w\nstderr: %s", err, errOut)
73+
}
74+
return out, nil
75+
}
76+
77+
func kubeconfig() string {
78+
if kc := os.Getenv("KUBECONFIG"); kc != "" {
79+
return kc
80+
}
81+
return os.Getenv("HOME") + "/.kube/config"
82+
}

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)