Skip to content
This repository was archived by the owner on Aug 19, 2024. It is now read-only.

Commit 1cf9757

Browse files
authored
chore: Switch the default operand image tag from latest to next and fix CI nightly job [RHIDP-3157] (#401)
* Switch the default operand image from 'quay.io/janus-idp/backstage-showcase:latest' to 'quay.io/rhdh/rhdh-hub-rhel9:latest' 'quay.io/rhdh/rhdh-hub-rhel9' is the downstream image of the Showcase image * Fix the E2E tests using the latest stable image of the operand User authentication is now needed to query the '/api/dynamic-plugins-info/loaded-plugins' API endpoint * wip: show controller logs in case CR status is not updated * Fix the upgrade path E2E tests by ensuring the CR on 1.1 is still using v1alpha1 as version Otherwise, the 1.x operator is not aware of the v1alpha2 version * Also display operand logs in case there is an assertion failure * Adjust timeouts because the operand image takes a bit longer to start * Bump setup-minikube action to the latest It should hopefully fix the random network connection issues * Separate upgrade and non-upgrade tests as different jobs This will reduce the likeliness of random connectivity failures * Revert "Switch the default operand image from 'quay.io/janus-idp/backstage-showcase:latest' to 'quay.io/rhdh/rhdh-hub-rhel9:latest'" This reverts commit 8b81157. * Switch the default operand image tag from 'latest' to 'next' 'next' is the development tag of the upstream Showcase image, and should hopefully be stable. The goal with this is to monitor how our tests behave against this 'next' tag. If it proves too unstable, we might want to switch back to using the downstream RHDH image (`quay.io/rhdh/rhdh-hub-rhel9:latest`).
1 parent 72f81ae commit 1cf9757

File tree

12 files changed

+159
-53
lines changed

12 files changed

+159
-53
lines changed

.github/workflows/nightly.yaml

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,13 @@ jobs:
1313
fail-fast: false
1414
matrix:
1515
branch: [ main, 1.2.x, 1.1.x ]
16-
name: E2E Tests - ${{ matrix.branch }}
16+
test_upgrade: [ 'true', 'false' ]
17+
exclude:
18+
- branch: 1.1.x # Testing upgrade from 1.1.x
19+
test_upgrade: 'true'
20+
name: 'E2E Tests - ${{ matrix.branch }} - upgrade=${{ matrix.test_upgrade }}'
1721
concurrency:
18-
group: ${{ github.workflow }}-${{ matrix.branch }}
22+
group: '${{ github.workflow }}-${{ matrix.branch }}-${{ matrix.test_upgrade }}'
1923
cancel-in-progress: true
2024
env:
2125
CONTAINER_ENGINE: podman
@@ -49,20 +53,17 @@ jobs:
4953
5054
- name: Start Minikube
5155
if: ${{ steps.operator-image-existence-checker.outputs.OPERATOR_IMAGE_EXISTS == 'true' }}
52-
uses: medyagh/setup-minikube@317d92317e473a10540357f1f4b2878b80ee7b95 # v0.0.16
53-
with:
54-
addons: ingress
56+
uses: medyagh/setup-minikube@d8c0eb871f6f455542491d86a574477bd3894533 # v0.0.18
5557

5658
- name: Run E2E tests (Operator Upgrade path)
57-
# Testing upgrade from 1.1.x
58-
if: ${{ matrix.branch != '1.1.x' && steps.operator-image-existence-checker.outputs.OPERATOR_IMAGE_EXISTS == 'true' }}
59+
if: ${{ matrix.test_upgrade == 'true' && steps.operator-image-existence-checker.outputs.OPERATOR_IMAGE_EXISTS == 'true' }}
5960
env:
6061
BACKSTAGE_OPERATOR_TESTS_PLATFORM: minikube
6162
IMG: ${{ env.OPERATOR_IMAGE }}
6263
run: make test-e2e-upgrade
6364

6465
- name: Run E2E tests
65-
if: ${{ steps.operator-image-existence-checker.outputs.OPERATOR_IMAGE_EXISTS == 'true' }}
66+
if: ${{ matrix.test_upgrade == 'false' && steps.operator-image-existence-checker.outputs.OPERATOR_IMAGE_EXISTS == 'true' }}
6667
env:
6768
BACKSTAGE_OPERATOR_TESTS_PLATFORM: minikube
6869
IMG: ${{ env.OPERATOR_IMAGE }}

bundle/manifests/backstage-default-config_v1_configmap.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,8 @@ data:
191191
command:
192192
- ./install-dynamic-plugins.sh
193193
- /dynamic-plugins-root
194-
image: quay.io/janus-idp/backstage-showcase:latest # will be replaced with the actual image quay.io/janus-idp/backstage-showcase:next
194+
# image will be replaced by the value of the `RELATED_IMAGE_backstage` env var, if set
195+
image: quay.io/janus-idp/backstage-showcase:next
195196
imagePullPolicy: IfNotPresent
196197
securityContext:
197198
runAsNonRoot: true
@@ -218,7 +219,7 @@ data:
218219
containers:
219220
- name: backstage-backend
220221
# image will be replaced by the value of the `RELATED_IMAGE_backstage` env var, if set
221-
image: quay.io/janus-idp/backstage-showcase:latest
222+
image: quay.io/janus-idp/backstage-showcase:next
222223
imagePullPolicy: IfNotPresent
223224
args:
224225
- "--config"

bundle/manifests/backstage-operator.clusterserviceversion.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ metadata:
2121
}
2222
]
2323
capabilities: Seamless Upgrades
24-
createdAt: "2024-07-08T12:45:16Z"
24+
createdAt: "2024-07-16T16:00:50Z"
2525
operatorframework.io/suggested-namespace: backstage-system
2626
operators.operatorframework.io/builder: operator-sdk-v1.33.0
2727
operators.operatorframework.io/project_layout: go.kubebuilder.io/v3
@@ -213,7 +213,7 @@ spec:
213213
- name: RELATED_IMAGE_postgresql
214214
value: quay.io/fedora/postgresql-15:latest
215215
- name: RELATED_IMAGE_backstage
216-
value: quay.io/janus-idp/backstage-showcase:latest
216+
value: quay.io/janus-idp/backstage-showcase:next
217217
image: quay.io/janus-idp/operator:0.3.0
218218
livenessProbe:
219219
httpGet:
@@ -317,6 +317,6 @@ spec:
317317
relatedImages:
318318
- image: quay.io/fedora/postgresql-15:latest
319319
name: postgresql
320-
- image: quay.io/janus-idp/backstage-showcase:latest
320+
- image: quay.io/janus-idp/backstage-showcase:next
321321
name: backstage
322322
version: 0.3.0

config/manager/default-config/deployment.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ spec:
3838
command:
3939
- ./install-dynamic-plugins.sh
4040
- /dynamic-plugins-root
41-
image: quay.io/janus-idp/backstage-showcase:latest # will be replaced with the actual image quay.io/janus-idp/backstage-showcase:next
41+
# image will be replaced by the value of the `RELATED_IMAGE_backstage` env var, if set
42+
image: quay.io/janus-idp/backstage-showcase:next
4243
imagePullPolicy: IfNotPresent
4344
securityContext:
4445
runAsNonRoot: true
@@ -65,7 +66,7 @@ spec:
6566
containers:
6667
- name: backstage-backend
6768
# image will be replaced by the value of the `RELATED_IMAGE_backstage` env var, if set
68-
image: quay.io/janus-idp/backstage-showcase:latest
69+
image: quay.io/janus-idp/backstage-showcase:next
6970
imagePullPolicy: IfNotPresent
7071
args:
7172
- "--config"

config/manager/manager.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ spec:
7676
- name: RELATED_IMAGE_postgresql
7777
value: quay.io/fedora/postgresql-15:latest
7878
- name: RELATED_IMAGE_backstage
79-
value: quay.io/janus-idp/backstage-showcase:latest
79+
value: quay.io/janus-idp/backstage-showcase:next
8080
image: controller:latest
8181
name: manager
8282
securityContext:

examples/bs1.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,3 @@ apiVersion: rhdh.redhat.com/v1alpha2
22
kind: Backstage
33
metadata:
44
name: bs1
5-
6-
7-

examples/rhdh-cr-with-app-configs.yaml

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,16 @@ data:
4747
backend:
4848
auth:
4949
externalAccess:
50-
- type: legacy
51-
options:
52-
subject: legacy-default-config
53-
secret: "${BACKEND_SECRET}"
50+
- type: legacy
51+
options:
52+
subject: legacy-default-config
53+
secret: "${BACKEND_SECRET}"
54+
auth:
55+
environment: development
56+
providers:
57+
guest:
58+
# using the guest user to query the '/api/dynamic-plugins-info/loaded-plugins' endpoint.
59+
dangerouslyAllowOutsideDevelopment: true
5460
---
5561
apiVersion: v1
5662
kind: Secret
@@ -128,7 +134,7 @@ data:
128134
initialDelay: { seconds: 15}
129135
- package: ./dynamic-plugins/dist/backstage-plugin-techdocs-backend-dynamic
130136
pluginConfig:
131-
# Reference documentation http://backstage.io/docs/features/techdocs/configuration
137+
# Reference documentation https://backstage.io/docs/features/techdocs/configuration
132138
# Note: After experimenting with basic setup, use CI/CD to generate docs
133139
# and an external cloud storage when deploying TechDocs for production use-case.
134140
# https://backstage.io/docs/features/techdocs/how-to-guides#how-to-migrate-from-techdocs-basic-to-recommended-deployment-approach

tests/e2e/e2e_suite_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,15 @@ func verifyControllerUp(g Gomega, managerPodLabel string) {
223223
g.Expect(string(status)).Should(Equal("Running"), fmt.Sprintf("controller pod in %s status", status))
224224
}
225225

226+
func getPodLogs(ns string, label string) string {
227+
cmd := exec.Command(helper.GetPlatformTool(), "logs",
228+
"-l", label,
229+
"-n", ns,
230+
)
231+
output, _ := helper.Run(cmd)
232+
return string(output)
233+
}
234+
226235
func uninstallOperator() {
227236
switch testMode {
228237
case rhdhLatestTestMode, rhdhNextTestMode, rhdhAirgapTestMode:

tests/e2e/e2e_test.go

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@
1515
package e2e
1616

1717
import (
18+
"crypto/tls"
19+
"encoding/json"
1820
"fmt"
21+
"io"
22+
"net/http"
1923
"os/exec"
2024
"path/filepath"
2125
"strconv"
@@ -78,9 +82,44 @@ var _ = Describe("Backstage Operator E2E", func() {
7882
crName: "bs-app-config",
7983
additionalApiEndpointTests: []helper.ApiEndpointTest{
8084
{
81-
Endpoint: "/api/dynamic-plugins-info/loaded-plugins",
85+
Endpoint: "/api/dynamic-plugins-info/loaded-plugins",
86+
BearerTokenRetrievalFn: func(baseUrl string) (string, error) { // Authenticated endpoint that does not accept service tokens
87+
url := fmt.Sprintf("%s/api/auth/guest/refresh", baseUrl)
88+
tr := &http.Transport{
89+
TLSClientConfig: &tls.Config{
90+
InsecureSkipVerify: true, // #nosec G402 -- test code only, not used in production
91+
},
92+
}
93+
httpClient := &http.Client{Transport: tr}
94+
req, err := http.NewRequest("GET", url, nil)
95+
if err != nil {
96+
return "", fmt.Errorf("error while building request to GET %q: %w", url, err)
97+
}
98+
req.Header.Add("Accept", "application/json")
99+
resp, err := httpClient.Do(req)
100+
if err != nil {
101+
return "", fmt.Errorf("error while trying to GET %q: %w", url, err)
102+
}
103+
defer resp.Body.Close()
104+
body, err := io.ReadAll(resp.Body)
105+
if err != nil {
106+
return "", fmt.Errorf("error while trying to read response body from 'GET %q': %w", url, err)
107+
}
108+
if resp.StatusCode != 200 {
109+
return "", fmt.Errorf("expected status code 200, but got %d in response to 'GET %q', body: %s", resp.StatusCode, url, string(body))
110+
}
111+
var authResponse helper.BackstageAuthRefreshResponse
112+
err = json.Unmarshal(body, &authResponse)
113+
if err != nil {
114+
return "", fmt.Errorf("error while trying to decode response body from 'GET %q': %w", url, err)
115+
}
116+
return authResponse.BackstageIdentity.Token, nil
117+
},
82118
ExpectedHttpStatusCode: 200,
83119
BodyMatcher: SatisfyAll(
120+
ContainSubstring("@janus-idp/backstage-scaffolder-backend-module-quay-dynamic"),
121+
ContainSubstring("@janus-idp/backstage-scaffolder-backend-module-regex-dynamic"),
122+
ContainSubstring("roadiehq-scaffolder-backend-module-utils-dynamic"),
84123
ContainSubstring("backstage-plugin-catalog-backend-module-github-dynamic"),
85124
ContainSubstring("backstage-plugin-techdocs-backend-dynamic"),
86125
ContainSubstring("backstage-plugin-catalog-backend-module-gitlab-dynamic")),
@@ -187,7 +226,7 @@ var _ = Describe("Backstage Operator E2E", func() {
187226
})
188227

189228
func ensureRouteIsReachable(ns string, crName string, additionalApiEndpointTests []helper.ApiEndpointTest) {
190-
Eventually(helper.VerifyBackstageRoute, time.Minute, time.Second).
229+
Eventually(helper.VerifyBackstageRoute, 5*time.Minute, time.Second).
191230
WithArguments(ns, crName, additionalApiEndpointTests).
192231
Should(Succeed())
193232
}

tests/e2e/e2e_upgrade_test.go

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package e2e
1616

1717
import (
1818
"fmt"
19+
"io"
1920
"os/exec"
2021
"path/filepath"
2122
"time"
@@ -49,13 +50,10 @@ var _ = Describe("Operator upgrade with existing instances", func() {
4950
When("Previous version of operator is installed and CR is created", func() {
5051

5152
const managerPodLabel = "control-plane=controller-manager"
53+
const crName = "my-backstage-app"
5254

5355
// 0.1.3 is the version of the operator in the 1.1.x branch
5456
var fromDeploymentManifest = filepath.Join(projectDir, "tests", "e2e", "testdata", "backstage-operator-0.1.3.yaml")
55-
var (
56-
crName = "bs1"
57-
crPath = filepath.Join(projectDir, "examples", "bs1.yaml")
58-
)
5957

6058
BeforeEach(func() {
6159
if testMode != defaultDeployTestMode {
@@ -71,9 +69,22 @@ var _ = Describe("Operator upgrade with existing instances", func() {
7169
Expect(err).ShouldNot(HaveOccurred())
7270
EventuallyWithOffset(1, verifyControllerUp, 5*time.Minute, time.Second).WithArguments(managerPodLabel).Should(Succeed())
7371

74-
cmd = exec.Command(helper.GetPlatformTool(), "apply", "-f", crPath, "-n", ns)
72+
cmd = exec.Command(helper.GetPlatformTool(), "-n", ns, "create", "-f", "-")
73+
stdin, err := cmd.StdinPipe()
74+
ExpectWithOffset(1, err).NotTo(HaveOccurred())
75+
go func() {
76+
defer stdin.Close()
77+
_, _ = io.WriteString(stdin, fmt.Sprintf(`
78+
apiVersion: rhdh.redhat.com/v1alpha1
79+
kind: Backstage
80+
metadata:
81+
name: my-backstage-app
82+
namespace: %s
83+
`, ns))
84+
}()
7585
_, err = helper.Run(cmd)
7686
Expect(err).ShouldNot(HaveOccurred())
87+
7788
// Reason is DeployOK in 1.1.x, but was renamed to Deployed in 1.2
7889
Eventually(helper.VerifyBackstageCRStatus, time.Minute, time.Second).WithArguments(ns, crName, `"reason":"DeployOK"`).Should(Succeed())
7990
})
@@ -89,17 +100,21 @@ var _ = Describe("Operator upgrade with existing instances", func() {
89100
It("should successfully reconcile existing CR when upgrading the operator", func() {
90101
By("Upgrading the operator", func() {
91102
installOperatorWithMakeDeploy(false)
92-
EventuallyWithOffset(1, verifyControllerUp, 5*time.Minute, time.Second).WithArguments(managerPodLabel).Should(Succeed())
103+
EventuallyWithOffset(1, verifyControllerUp, 5*time.Minute, 3*time.Second).WithArguments(managerPodLabel).Should(Succeed())
93104
})
94105

95106
By("checking the status of the existing CR")
96-
Eventually(helper.VerifyBackstageCRStatus, time.Minute, time.Second).WithArguments(ns, crName, `"reason":"Deployed"`).Should(Succeed())
107+
Eventually(helper.VerifyBackstageCRStatus, 5*time.Minute, 3*time.Second).WithArguments(ns, crName, `"reason":"Deployed"`).
108+
Should(Succeed(), func() string {
109+
return fmt.Sprintf("=== Operator logs ===\n%s\n", getPodLogs(_namespace, managerPodLabel))
110+
})
97111

98112
By("checking the Backstage operand pod")
113+
crLabel := fmt.Sprintf("rhdh.redhat.com/app=backstage-%s", crName)
99114
Eventually(func(g Gomega) {
100115
// Get pod name
101116
cmd := exec.Command(helper.GetPlatformTool(), "get",
102-
"pods", "-l", fmt.Sprintf("rhdh.redhat.com/app=backstage-%s", crName),
117+
"pods", "-l", crLabel,
103118
"-o", "go-template={{ range .items }}{{ if not .metadata.deletionTimestamp }}{{ .metadata.name }}"+
104119
"{{ \"\\n\" }}{{ end }}{{ end }}",
105120
"-n", ns,
@@ -108,7 +123,9 @@ var _ = Describe("Operator upgrade with existing instances", func() {
108123
g.Expect(err).ShouldNot(HaveOccurred())
109124
podNames := helper.GetNonEmptyLines(string(podOutput))
110125
g.Expect(podNames).Should(HaveLen(1), fmt.Sprintf("expected 1 Backstage operand pod(s) running, but got %d", len(podNames)))
111-
}, 5*time.Minute, time.Second).Should(Succeed())
126+
}, 10*time.Minute, 5*time.Second).Should(Succeed(), func() string {
127+
return fmt.Sprintf("=== Operand logs ===\n%s\n", getPodLogs(ns, crLabel))
128+
})
112129
})
113130
})
114131

tests/e2e/testdata/backstage-operator-0.1.3.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,7 @@ data:
739739
- name: NPM_CONFIG_USERCONFIG
740740
value: /opt/app-root/src/.npmrc.dynamic-plugins
741741
# image will be replaced by the value of the `RELATED_IMAGE_backstage` env var, if set
742-
image: quay.io/janus-idp/backstage-showcase:latest
742+
image: quay.io/janus-idp/backstage-showcase:next
743743
imagePullPolicy: IfNotPresent
744744
name: install-dynamic-plugins
745745
volumeMounts:
@@ -761,7 +761,7 @@ data:
761761
containers:
762762
- name: backstage-backend
763763
# image will be replaced by the value of the `RELATED_IMAGE_backstage` env var, if set
764-
image: quay.io/janus-idp/backstage-showcase:latest
764+
image: quay.io/janus-idp/backstage-showcase:next
765765
imagePullPolicy: IfNotPresent
766766
args:
767767
- "--config"
@@ -949,7 +949,7 @@ spec:
949949
- name: RELATED_IMAGE_postgresql
950950
value: quay.io/fedora/postgresql-15:latest
951951
- name: RELATED_IMAGE_backstage
952-
value: quay.io/janus-idp/backstage-showcase:latest
952+
value: quay.io/janus-idp/backstage-showcase:next
953953
# TODO(asoro): Default image is 'quay.io/janus-idp/operator:0.1.3' on 1.1.x,
954954
# but replaced by the one from RHDH, because the Janus-IDP image expires after 14d if not updated.
955955
image: quay.io/rhdh/rhdh-rhel9-operator:1.1

0 commit comments

Comments
 (0)