Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[
{
"name": "[Jira:Cluster Version Operator] cluster-version-operator-tests should support passing tests",
"name": "[Jira:\"Cluster Version Operator\"] cluster-version-operator-tests should support passing tests the sanity test should pass",
"labels": {},
"resources": {
"isolation": {}
Expand Down
20 changes: 16 additions & 4 deletions cmd/cluster-version-operator-tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,28 @@ It integrates [openshift-tests-extension](https://github.com/openshift-eng/opens
cluster-version-operator which allows openshift components to contribute tests to openshift-tests' suites with
extension binaries.

## Build the executable binary
In root folder, run below command to build executable binary:
```console
$ make build
```

## Run the tests locally

## Using the framework
### Using the binary
- run a test-suite
```console
$ _output/<OS>/<ARCH>/cluster-version-operator-tests run-suite <test suite name>
```
where test suites can be listed by `_output/<OS>/<ARCH>/cluster-version-operator-tests info`.

- run a single test case
```console
$ hack/build-go.sh
$ _output/<OS>/<ARCH>/cluster-version-operator-tests run-suite cluster-version-operator
$ _output/<OS>/<ARCH>/cluster-version-operator-tests run-test <test case name>
```
where test names can be listed by `_output/<OS>/<ARCH>/cluster-version-operator-tests list`.

## Using ginko-cli
### Using ginko-cli

After [installing-ginkgo](https://onsi.github.io/ginkgo/#installing-ginkgo):

Expand Down
10 changes: 5 additions & 5 deletions test/cvo/cvo.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package cvo

Copy link
Contributor

@DavidHurta DavidHurta Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment not related to the code

I will hold us to a higher standard regarding the git hygiene, if I may.

Please see the Contributing guide for the cluster-version-operator repository.

I am mainly concerned about the following points:

  • Make commits of logical units.

  • Make sure your commit messages are in the proper format (see below).

  • The PR title.

Currently, the PR consists of a single commit jianl - First e2e test, which consists of multiple logical units, and the commit title does not follow the recommended format. While PR titles are not explicitly mentioned in the guide, a PR title should state what a PR distinctly and briefly does.

Please keep in mind that these guidelines have their practical purposes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the commit, because this is the first OTE PR, it contains many logic, so the description may not describes everything. I will keep PR simple and describe the logic in the future.

import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
g "github.com/onsi/ginkgo/v2"
o "github.com/onsi/gomega"
)

var _ = Describe("[Jira:Cluster Version Operator] cluster-version-operator-tests", func() {
It("should support passing tests", func() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is my sanity test being removed? :(

Copy link
Contributor

@DavidHurta DavidHurta Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its future usefulness is questionable. However, for the moment, I am using it to validate that the openshift/origin#30316 PR is functional. Would it be okay for me rename to the component in the [Jira:Cluster Version Operator] cluster-version-operator-tests should support passing tests test case in another PR to get it merged quickly, then merge the origin PR, and for this PR to just ignore the test case? The test case is not resource-intensive, and it provides a useful "if you can't see this test, then something is wrong with the integration" signal.

/cc @hongkailiu

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can then validate this PR with an integrated OTE in the CVO repository.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to keep "should support passing tests" only temporarily (to validate and merge openshift/origin#30316), and then do ext.IgnoreObsoleteTests() to ignore it with this pull?
😄

I would not practice ext.IgnoreObsoleteTests() this way as it creates codes it stays forever in our CVO repo.
I would avoid renaming, or deleting if i could.

Maybe it is not a big deal, and it is OK delete as long as having them ignored?
Honestly, I do not see that far. So if it makes your work much easier, I am fine with it too.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind just keeping the test forever.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and for this PR to just ignore the test case?

I meant "ignore" as is in, do not touch. Not as in utilizing the ext.IgnoreObsoleteTests functionality.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack.

Jian has reverted the deleting.
Let us keep it forever. 😃

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DavidHurta I just added back the case and rename it as you mentioned. It is a independent test suite.

Copy link
Contributor

@DavidHurta DavidHurta Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. It helps with the integration. It also provides a signal of the integration working in the future. Such sanity tests are also in several other OpenShift repositories that already integrated the OTE or are in the process of the integration.

Expect(true).To(BeTrue())
var _ = g.Describe(`[Jira:"Cluster Version Operator"] cluster-version-operator-tests should support passing tests`, func() {
g.It("the sanity test should pass", func() {
o.Expect(true).To(o.BeTrue())
})
})
122 changes: 122 additions & 0 deletions test/utilities/connection.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package utilities

import (
"errors"
"fmt"
"os"

"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"

configclient "github.com/openshift/client-go/config/clientset/versioned"
configclientv1 "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
configv1alpha1 "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1alpha1"
configv1alpha2 "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1alpha2"
)

// getKubeConfig get KUBECONFIG file from environment variable
func getKubeConfig() (*rest.Config, error) {
configPath, present := os.LookupEnv("KUBECONFIG")
fmt.Print("configPath: ", configPath)
if !present {
return nil, errors.New("the environment variable KUBECONFIG must be set")
}
config, err := clientcmd.BuildConfigFromFlags("", configPath)
return config, err
}

// getClient creates a configclient.Clientset instance.
func getClient() (*configclient.Clientset, error) {
config, err := getKubeConfig()
if err != nil {
return nil, fmt.Errorf("unable to load build config: %w", err)
}
// Create the Clientset
clientset, err := configclient.NewForConfig(config)
if err != nil {
return nil, fmt.Errorf("unable to create a Kubernetes clientset: %w", err)
}

return clientset, nil
}

// getV1Client creates a configclientv1.ConfigV1Client instance.
func getV1Client() (*configclientv1.ConfigV1Client, error) {
config, err := getKubeConfig()
if err != nil {
return nil, fmt.Errorf("unable to load build config: %w", err)
}
// Create the Clientset
clientset, err := configclientv1.NewForConfig(config)
if err != nil {
return nil, fmt.Errorf("unable to create a Kubernetes clientset: %w", err)
}

return clientset, nil
}

// getV1alpha1Client creates a configv1alpha1.ConfigV1alpha1Client instance.
func getV1alpha1Client() (*configv1alpha1.ConfigV1alpha1Client, error) {
// Create the Clientset
config, err := getKubeConfig()
if err != nil {
return nil, fmt.Errorf("unable to load build config: %w", err)
}
clientset, err := configv1alpha1.NewForConfig(config)
if err != nil {
return nil, fmt.Errorf("unable to create a Kubernetes clientset: %w", err)
}

return clientset, nil
}

// getV1alpha2Client creates a configv1alpha2.ConfigV1alpha2Client instance.
func getV1alpha2Client() (*configv1alpha2.ConfigV1alpha2Client, error) {
// Create the Clientset
config, err := getKubeConfig()
if err != nil {
return nil, fmt.Errorf("unable to load build config: %w", err)
}
clientset, err := configv1alpha2.NewForConfig(config)
if err != nil {
return nil, fmt.Errorf("unable to create a Kubernetes clientset: %w", err)
}

return clientset, nil
}

// MustGetClient creates a configclient.Clientset instance, or panics on failures.
func MustGetClient() *configclient.Clientset {
clientset, err := getClient()
if err != nil {
panic("unable to create a Kubernetes clientset: " + err.Error())
}
return clientset
}

// MustGetV1Client creates a configclientv1.ConfigV1Client instance, or panics on failures.
func MustGetV1Client() *configclientv1.ConfigV1Client {
clientset, err := getV1Client()
if err != nil {
panic("unable to create a Kubernetes clientset: " + err.Error())
}
return clientset
}

// MUSTGetV1alpha1Client creates a configv1alpha1.ConfigV1alpha1Client instance, or panics on failures.
func MUSTGetV1alpha1Client() *configv1alpha1.ConfigV1alpha1Client {
clientset, err := getV1alpha1Client()
if err != nil {
panic("unable to create a Kubernetes clientset: " + err.Error())
}
return clientset
}

// MUSTGetV1alpha2Client creates a configv1alpha2.ConfigV1alpha2Client instance, or panics on failures.
func MUSTGetV1alpha2Client() *configv1alpha2.ConfigV1alpha2Client {
clientset, err := getV1alpha2Client()
if err != nil {
panic("unable to create a Kubernetes clientset: " + err.Error())
}
return clientset
}