Skip to content

Commit

Permalink
Initial E2E framework with HCP client.
Browse files Browse the repository at this point in the history
- start of E2E test suite and README
- client connects to development enviroment using port forwarding to localhost
- Draft of list and get test cases.
  • Loading branch information
patriksuba committed Feb 27, 2025
1 parent 7cf92f7 commit 369f89a
Show file tree
Hide file tree
Showing 12 changed files with 414 additions and 0 deletions.
1 change: 1 addition & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ go.work* @bennerv @mbarnes @SudoBrendan @mociarain @venkateshsredhat @nanyte25 @
/cluster-service/ @machi1990 @zgalor @miguelsorianod @JameelB
/observability/ @frzifus @simonpasquier @dinhxuanvu @mbarnes
/docs/ @geoberle @janboll @tony-schndr @jfchevrette @mmazur @weinong @whober0521 @jonathan34c @stevekuznetsov
/test/ @patriksuba @mbukatov @mgahagan73
1 change: 1 addition & 0 deletions go.work
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ use (
./tooling/mcerepkg
./tooling/templatize
tooling/prometheus-rules
./test
)
3 changes: 3 additions & 0 deletions go.work.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1549,6 +1549,7 @@ github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
github.com/onsi/ginkgo/v2 v2.13.2/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM=
github.com/onsi/ginkgo/v2 v2.20.1/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI=
github.com/onsi/ginkgo/v2 v2.22.1/go.mod h1:S6aTpoRsSq2cZOd+pssHAlKW/Q/jZt6cPrPlnj4a1xM=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
Expand Down Expand Up @@ -2110,6 +2111,7 @@ golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand Down Expand Up @@ -2168,6 +2170,7 @@ golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
Expand Down
69 changes: 69 additions & 0 deletions test/e2e/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Testing

## E2E test suite

The E2E test suite will work in every environment of the ARO-HCP project. Its main purpose is to ensure specific functionality based on the environment and its usage. You can find more details about the test suite design in [ARO-12804](https://issues.redhat.com/browse/ARO-12804).

- The test suite client connects to the RP frontend in the development environment using port forwarding to localhost.
- In the integration environment, the client will connect to the RP frontend using a public IP (when available) but only within the MSFT corporate network.
- For stage and production environments, the client will connect through ARM once they are set up.

The client expects a subscription to be already registered. To assign the client to a specific subscription, set its ID in the environment variable **CUSTOMER_SUBSCRIPTION**. If not set, the default all-zero subscription will be used.

Test cases expect resource group name, where cluster resources (vnet, managed identity, ...) are located, to be set in the environment variable **CUSTOMER_RG_NAME**.

### Run E2E tests locally against development environment

1. Login with AZ CLI
2. Port-forward RP running on SC: `kubectl port-forward -n aro-hcp svc/aro-hcp-frontend 8443:8443`
3. Export environment variables LOCAL_DEVELOPMENT, CUSTOMER_SUBSCRIPTION and CUSTOMER_RG_NAME

```bash
export LOCAL_DEVELOPMENT=true
export CUSTOMER_SUBSCRIPTION=<subscriptionId>
export CUSTOMER_RG_NAME=<resourceGroupName>
```

4. Run test suite with command

Run all test cases: `ginkgo ./e2e`

Run specific test case: `ginkgo --focus "<regex>" ./e2e`

Run in debug mode: `ginkgo ./e2e --vv`

### Writing E2E test with ginkgo

[Ginkgo documentation](https://onsi.github.io/ginkgo/)

[Gomega documentation](https://onsi.github.io/gomega/)

#### Writing specs

Ginkgo consist of specs nodes structure which can look like:

- Describe -> It
- Describe -> Context -> It
- Describe -> Describe -> ...

Every node consist of arguments:
- description
- labels (optional, but very important)
- function.

Node *It* is last node and contains test itself. To describe useful test steps use function **By(message)**. Decorator **defer** is used to call funtions after test finish (cleanup). To skip a test use function **Skip(message)** with appropriate message.

In higher level nodes, **BeforeEach** and **AfterEach** functions can be used to run same code before and after every test.

#### Labels
Create a label with function **Label(name)** in file *util/labels/labels.go*.

To run tests with specified labels use ginkgo with option --label-filter. Example: `ginkgo --label-filter=QUERY`

#### Assertions

To assert values GOMEGA module is used.

Example:
**Expect(variable).To/ToNot(BeNil(), BeEmpty(), BeTrue(), BeNumerically, ContainString ...)**

20 changes: 20 additions & 0 deletions test/e2e/e2e_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package e2e

import (
"context"
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

func TestE2E(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "ARO-HCP E2E Tests")
}

var _ = BeforeSuite(func() {
if err := setup(context.Background()); err != nil {
panic(err)
}
})
32 changes: 32 additions & 0 deletions test/e2e/get_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package e2e

import (
"context"
"fmt"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

api "github.com/Azure/ARO-HCP/internal/api/v20240610preview/generated"
"github.com/Azure/ARO-HCP/test/util/labels"
)

var _ = Describe("Get operation", func() {
var (
clustersClient *api.HcpOpenShiftClustersClient
)

BeforeEach(func() {
By("Prepare HCP clusters client")
clustersClient = clients.NewHcpOpenShiftClustersClient()
})

It("Get non existing cluster", labels.Medium, labels.Negative, func(ctx context.Context) {
clusterName := "non-existing-cluster"
By("Send get request for cluster")
_, err := clustersClient.Get(ctx, customerRGName, clusterName, nil)
Expect(err).ToNot(BeNil())
errMessage := fmt.Sprintf("The resource 'hcpOpenShiftClusters/%s' under resource group '%s' was not found.", clusterName, customerRGName)
Expect(err.Error()).To(ContainSubstring(errMessage))
})
})
58 changes: 58 additions & 0 deletions test/e2e/list_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package e2e

import (
"context"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

api "github.com/Azure/ARO-HCP/internal/api/v20240610preview/generated"
"github.com/Azure/ARO-HCP/test/util/labels"
"github.com/Azure/ARO-HCP/test/util/log"
)

var _ = Describe("List operations", func() {
defer GinkgoRecover()

var (
clustersClient *api.HcpOpenShiftClustersClient
)

BeforeEach(func() {
By("Prepare HCP clusters client")
clustersClient = clients.NewHcpOpenShiftClustersClient()
})

Context("List clusters", func() {
It("List clusters by subscription", labels.Medium, func(ctx context.Context) {
By("Prepare pager to list clusters")
listOptions := &api.HcpOpenShiftClustersClientListBySubscriptionOptions{}
pager := clustersClient.NewListBySubscriptionPager(listOptions)
By("Access IDs of all fetched clusters")
for pager.More() {
clusterList, err := pager.NextPage(ctx)
Expect(err).To(BeNil())
log.Logger.Infoln("Number of clusters:", len(clusterList.Value))
for _, val := range clusterList.Value {
Expect(*val.ID).ToNot(BeEmpty())
log.Logger.Infoln(*val.ID)
}
}
})

It("List clusters by resource group", labels.Medium, func(ctx context.Context) {
By("Prepare pager to list clusters")
pager := clustersClient.NewListByResourceGroupPager(customerRGName, nil)
By("Access IDs of all fetched clusters")
for pager.More() {
clusterList, err := pager.NextPage(ctx)
Expect(err).To(BeNil())
log.Logger.Infoln("Number of clusters:", len(clusterList.Value))
for _, val := range clusterList.Value {
Expect(*val.ID).ToNot(BeEmpty())
log.Logger.Infoln(*val.ID)
}
}
})
})
})
74 changes: 74 additions & 0 deletions test/e2e/setup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package e2e

import (
"context"
"os"

api "github.com/Azure/ARO-HCP/internal/api/v20240610preview/generated"
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
azcorearm "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
)

var (
clients *api.ClientFactory
subscriptionID string
customerRGName string
)

func prepareDevelopmentConf() azcore.ClientOptions {
c := cloud.Configuration{
ActiveDirectoryAuthorityHost: "https://login.microsoftonline.com/",
Services: map[cloud.ServiceName]cloud.ServiceConfiguration{
cloud.ResourceManager: {
Audience: "https://management.core.windows.net/",
Endpoint: "http://localhost:8443",
},
},
}
opts := azcore.ClientOptions{
Cloud: c,
InsecureAllowCredentialWithHTTP: true,
}

return opts
}

func setup(ctx context.Context) error {
var (
found bool
creds azcore.TokenCredential
err error
)

if subscriptionID, found = os.LookupEnv("CUSTOMER_SUBSCRIPTION"); !found {
subscriptionID = "00000000-0000-0000-0000-000000000000"
}

customerRGName = os.Getenv("CUSTOMER_RG_NAME")

opts := prepareDevelopmentConf()

envOptions := &azidentity.EnvironmentCredentialOptions{
ClientOptions: opts,
}
creds, err = azidentity.NewEnvironmentCredential(envOptions)

if _, found := os.LookupEnv("LOCAL_DEVELOPMENT"); found {
creds, err = azidentity.NewAzureCLICredential(nil)
}
if err != nil {
return err
}

armOptions := &azcorearm.ClientOptions{
ClientOptions: opts,
}
clients, err = api.NewClientFactory(subscriptionID, creds, armOptions)
if err != nil {
return err
}

return nil
}
39 changes: 39 additions & 0 deletions test/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module github.com/Azure/ARO-HCP/test

go 1.23.3

require (
github.com/Azure/ARO-HCP/internal v0.0.0-20250205092925-ef76031a2bc1
github.com/onsi/ginkgo/v2 v2.22.2
github.com/onsi/gomega v1.36.2
github.com/sirupsen/logrus v1.9.3
)

require (
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3 // indirect
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
golang.org/x/crypto v0.33.0 // indirect
)

require (
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
)

require (
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect
golang.org/x/net v0.35.0 // indirect
golang.org/x/sys v0.30.0 // indirect
golang.org/x/text v0.22.0 // indirect
golang.org/x/tools v0.28.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

replace github.com/Azure/ARO-HCP/internal => ../internal
Loading

0 comments on commit 369f89a

Please sign in to comment.