-
Notifications
You must be signed in to change notification settings - Fork 73
WINC-1777: [ote] Add OTE extension binary skeleton #3874
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| vendor/ | ||
| bin/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| reviewers: | ||
| - rrasouli | ||
| - weinliu | ||
| - mansikulkarni96 | ||
| approvers: | ||
| - rrasouli | ||
| - weinliu | ||
|
Comment on lines
+5
to
+7
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please also add @mansikulkarni96 as backup |
||
| - mansikulkarni96 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| // windows-machine-config-operator-tests-ext is the OTE (OpenShift Tests Extension) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider creating a nested OWNERS file so that you and @rrasouli are in the loop for everyting under
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done — added ote/OWNERS with rrasouli and weinliu as reviewers/approvers. |
||
| // binary for Windows Containers tests. Tests are registered as plain Go functions | ||
| // using upstream Ginkgo, without the OpenShift Ginkgo fork. | ||
| // | ||
| // References: | ||
| // - OTE Integration Guide: https://github.com/openshift-eng/openshift-tests-extension | ||
| package main | ||
|
|
||
| import ( | ||
| "context" | ||
| "os" | ||
|
|
||
| otecmd "github.com/openshift-eng/openshift-tests-extension/pkg/cmd" | ||
| e "github.com/openshift-eng/openshift-tests-extension/pkg/extension" | ||
| et "github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests" | ||
| "github.com/spf13/cobra" | ||
|
|
||
| "github.com/openshift/windows-machine-config-operator/ote/test/extended" | ||
| "github.com/openshift/windows-machine-config-operator/ote/test/extended/cli" | ||
| ) | ||
|
|
||
| func main() { | ||
| registry := e.NewRegistry() | ||
| ext := e.NewExtension("openshift", "payload", "windows-machine-config-operator") | ||
|
|
||
| // All WINC tests - used for full runs and informing jobs. | ||
| // No qualifier needed: all tests in this binary are WINC tests. | ||
| ext.AddSuite(e.Suite{ | ||
| Name: "windows/all", | ||
| }) | ||
|
|
||
| // Parallel subset: non-Serial, non-Slow, non-Disruptive tests. | ||
| ext.AddSuite(e.Suite{ | ||
| Name: "windows/parallel", | ||
| Qualifiers: []string{ | ||
| `!name.contains("[Serial]") && !name.contains("[Slow]") && !name.contains("[Disruptive]")`, | ||
| }, | ||
| }) | ||
|
|
||
| // Serial subset: tests that must run in isolation. | ||
| ext.AddSuite(e.Suite{ | ||
| Name: "windows/serial", | ||
| Qualifiers: []string{ | ||
| `name.contains("[Serial]")`, | ||
| }, | ||
| }) | ||
|
|
||
| // Storage-specific tests. | ||
| ext.AddSuite(e.Suite{ | ||
| Name: "windows/storage", | ||
| Qualifiers: []string{ | ||
| `name.contains("storage")`, | ||
| }, | ||
| }) | ||
|
|
||
| // Register test specs manually — no OpenShift Ginkgo fork required. | ||
| specs := et.ExtensionTestSpecs{ | ||
| { | ||
| Name: "[sig-windows] Windows_Containers Author:rrasouli-Smokerun-Medium-37362-[wmco] wmco using correct golang version [OTP]", | ||
| Run: func(ctx context.Context) *et.ExtensionTestResult { | ||
| if err := extended.CheckWmcoGolangVersion(ctx, cli.NewCLIWithoutNamespace()); err != nil { | ||
| return &et.ExtensionTestResult{Result: et.ResultFailed, Output: err.Error()} | ||
| } | ||
| return &et.ExtensionTestResult{Result: et.ResultPassed} | ||
| }, | ||
| }, | ||
| } | ||
|
|
||
| ext.AddSpecs(specs) | ||
| registry.Register(ext) | ||
|
|
||
| root := &cobra.Command{ | ||
| Use: "windows-machine-config-operator-tests-ext", | ||
| Short: "OpenShift Windows Containers test extension (OTE)", | ||
| Long: "Runs the WINC test suite as an OpenShift Tests Extension binary.", | ||
| } | ||
|
|
||
| root.AddCommand(otecmd.DefaultExtensionCommands(registry)...) | ||
|
|
||
| if err := root.Execute(); err != nil { | ||
| os.Exit(1) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| module github.com/openshift/windows-machine-config-operator/ote | ||
|
|
||
| go 1.24.0 | ||
|
|
||
| require ( | ||
| github.com/openshift-eng/openshift-tests-extension v0.0.0-20260127124016-0fed2b824818 | ||
| github.com/spf13/cobra v1.10.2 | ||
| ) | ||
|
|
||
| require ( | ||
| github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect | ||
| github.com/google/cel-go v0.17.8 // indirect | ||
| github.com/inconshreveable/mousetrap v1.1.0 // indirect | ||
| github.com/pkg/errors v0.9.1 // indirect | ||
| github.com/spf13/pflag v1.0.9 // indirect | ||
| github.com/stoewer/go-strcase v1.2.0 // indirect | ||
| golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc // indirect | ||
| golang.org/x/text v0.19.0 // indirect | ||
| google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect | ||
| google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect | ||
| google.golang.org/protobuf v1.35.1 // indirect | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df h1:7RFfzj4SSt6nnvCPbCqijJi1nWCd+TqAT3bYCStRC18= | ||
| github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= | ||
| github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= | ||
| github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
| github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= | ||
| github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
| github.com/google/cel-go v0.17.8 h1:j9m730pMZt1Fc4oKhCLUHfjj6527LuhYcYw0Rl8gqto= | ||
| github.com/google/cel-go v0.17.8/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY= | ||
| github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= | ||
| github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= | ||
| github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= | ||
| github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= | ||
| github.com/openshift-eng/openshift-tests-extension v0.0.0-20260127124016-0fed2b824818 h1:jJLE/aCAqDf8U4wc3bE1IEKgIxbb0ICjCNVFA49x/8s= | ||
| github.com/openshift-eng/openshift-tests-extension v0.0.0-20260127124016-0fed2b824818/go.mod h1:6gkP5f2HL0meusT0Aim8icAspcD1cG055xxBZ9yC68M= | ||
| github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= | ||
| github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | ||
| github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
| github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= | ||
| github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
| github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= | ||
| github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= | ||
| github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= | ||
| github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= | ||
| github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= | ||
| github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= | ||
| github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= | ||
| github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
| github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= | ||
| github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= | ||
| github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= | ||
| go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= | ||
| golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU= | ||
| golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= | ||
| golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= | ||
| golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= | ||
| google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw= | ||
| google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= | ||
| google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= | ||
| google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= | ||
| google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= | ||
| google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= | ||
| gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
| gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||
| gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||
| gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| package cli | ||
|
|
||
| import ( | ||
| "bytes" | ||
| "fmt" | ||
| "os" | ||
| "os/exec" | ||
| "path/filepath" | ||
| "strings" | ||
| ) | ||
|
|
||
| // CLI wraps the oc command-line tool for use in OTE Ginkgo tests. | ||
| type CLI struct { | ||
| namespace string | ||
| asAdmin bool | ||
| kubeconfig string | ||
| } | ||
|
|
||
| // NewCLI creates a CLI instance with the given namespace. | ||
| func NewCLI(namespace string) *CLI { | ||
| return &CLI{ | ||
| namespace: namespace, | ||
| kubeconfig: kubeconfig(), | ||
| } | ||
| } | ||
|
|
||
| // NewCLIWithoutNamespace creates a CLI instance without a namespace (for cluster-scoped resources). | ||
| func NewCLIWithoutNamespace() *CLI { | ||
| return NewCLI("") | ||
| } | ||
|
|
||
| // AsAdmin returns a copy of the CLI that runs as cluster-admin. | ||
| func (c *CLI) AsAdmin() *CLI { | ||
| copy := *c | ||
| copy.asAdmin = true | ||
| return © | ||
| } | ||
|
|
||
| // Run executes an oc subcommand with the given arguments and returns stdout, stderr, and any error. | ||
| func (c *CLI) Run(verb string, args ...string) (string, string, error) { | ||
| cmdArgs := []string{verb} | ||
| if c.asAdmin { | ||
| cmdArgs = append(cmdArgs, "--as=system:admin") | ||
| } | ||
| if c.namespace != "" { | ||
| cmdArgs = append(cmdArgs, "-n", c.namespace) | ||
| } | ||
| cmdArgs = append(cmdArgs, args...) | ||
|
|
||
| cmd := exec.Command("oc", cmdArgs...) | ||
| if c.kubeconfig != "" { | ||
| cmd.Env = append(os.Environ(), "KUBECONFIG="+c.kubeconfig) | ||
| } | ||
|
|
||
| var stdout, stderr bytes.Buffer | ||
| cmd.Stdout = &stdout | ||
| cmd.Stderr = &stderr | ||
|
|
||
| err := cmd.Run() | ||
| return strings.TrimSpace(stdout.String()), strings.TrimSpace(stderr.String()), err | ||
| } | ||
|
|
||
| // Output is a convenience wrapper that returns stdout or an error combining stderr. | ||
| func (c *CLI) Output(verb string, args ...string) (string, error) { | ||
| out, errOut, err := c.Run(verb, args...) | ||
| if err != nil { | ||
| return "", fmt.Errorf("%w\nstderr: %s", err, errOut) | ||
| } | ||
| return out, nil | ||
| } | ||
|
|
||
| func kubeconfig() string { | ||
| if kc := os.Getenv("KUBECONFIG"); kc != "" { | ||
| return kc | ||
| } | ||
| return filepath.Join(os.Getenv("HOME"), ".kube", "config") | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| package extended | ||
|
|
||
| import ( | ||
| "context" | ||
| "encoding/json" | ||
| "fmt" | ||
| "strings" | ||
|
|
||
| "github.com/openshift/windows-machine-config-operator/ote/test/extended/cli" | ||
| ) | ||
|
|
||
| const ( | ||
| wmcoNamespace = "openshift-windows-machine-config-operator" | ||
| ) | ||
|
|
||
| // CheckWmcoGolangVersion verifies that the golang version reported by the cluster | ||
| // matches the version used to build the WMCO binary (OCP-37362). | ||
| func CheckWmcoGolangVersion(_ context.Context, oc *cli.CLI) error { | ||
| serverVersion, err := oc.AsAdmin().Output("get", "--raw", "/version") | ||
| if err != nil { | ||
| return fmt.Errorf("failed to get cluster version: %w", err) | ||
| } | ||
|
|
||
| var versionInfo struct { | ||
| GoVersion string `json:"goVersion"` | ||
| } | ||
| if err := json.Unmarshal([]byte(serverVersion), &versionInfo); err != nil { | ||
| return fmt.Errorf("failed to parse /version JSON: %w", err) | ||
| } | ||
| if versionInfo.GoVersion == "" { | ||
| return fmt.Errorf("goVersion not found in /version response") | ||
| } | ||
|
|
||
| parts := strings.Split(versionInfo.GoVersion, ".") | ||
| if len(parts) < 2 { | ||
| return fmt.Errorf("unexpected golang version format: %s", versionInfo.GoVersion) | ||
| } | ||
| truncated := strings.Join(parts[:2], ".") | ||
|
|
||
| logs, err := oc.AsAdmin().Output("logs", | ||
| "deployment.apps/windows-machine-config-operator", | ||
| "-n", wmcoNamespace, | ||
| ) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to get WMCO logs: %w", err) | ||
| } | ||
|
|
||
| if !strings.Contains(logs, truncated) { | ||
| return fmt.Errorf("WMCO logs do not contain expected golang version %s (full: %s)", | ||
| truncated, versionInfo.GoVersion) | ||
| } | ||
| return nil | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for my own education; where/who is invoking
make build-tests-ext?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently for local development only —
make build-tests-extlets developers build and test the OTE binary locally. Including it in the final image is planned as a follow-up once this PoC is merged.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently for local development only —
make build-tests-extlets developers build and test the OTE binary locally. Including it in the final image is planned as a follow-up once this PoC is merged.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I highly recommend also including this in this PR, IMO it must be part of the PoC, given it proves the concept works and we can get a CI signal on it.
Consuming the OTE binary is a key part of the proposal and would be great to have it in this PR.
is there any external blocker on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jrvaldes Is adding a standalone presubmit that runs wmco-tests-ext list sufficient as CI signal, or do you need the full OTE integration via openshift/origin registration? Happy to do either — just want to confirm scope before implementing.