1
+ /** *******************************************************************
2
+ * copyright (c) 2025 Red Hat, Inc.
3
+ *
4
+ * This program and the accompanying materials are made
5
+ * available under the terms of the Eclipse Public License 2.0
6
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
7
+ *
8
+ * SPDX-License-Identifier: EPL-2.0
9
+ **********************************************************************/
10
+ import { expect } from 'chai' ;
11
+ import { e2eContainer } from '../../configs/inversify.config' ;
12
+ import { CLASSES , TYPES } from '../../configs/inversify.types' ;
13
+ import { BASE_TEST_CONSTANTS } from '../../constants/BASE_TEST_CONSTANTS' ;
14
+ import { WorkspaceHandlingTests } from '../../tests-library/WorkspaceHandlingTests' ;
15
+ import { ProjectAndFileTests } from '../../tests-library/ProjectAndFileTests' ;
16
+ import { LoginTests } from '../../tests-library/LoginTests' ;
17
+ import { registerRunningWorkspace } from '../MochaHooks' ;
18
+ import { BrowserTabsUtil } from '../../utils/BrowserTabsUtil' ;
19
+ import { KubernetesCommandLineToolsExecutor } from '../../utils/KubernetesCommandLineToolsExecutor' ;
20
+ import { ShellString } from 'shelljs' ;
21
+ import { ITestWorkspaceUtil } from '../../utils/workspace/ITestWorkspaceUtil' ;
22
+ import { Dashboard } from '../../pageobjects/dashboard/Dashboard' ;
23
+ import { ShellExecutor } from '../../utils/ShellExecutor' ;
24
+
25
+ suite (
26
+ `Test podman build container functionality ${ BASE_TEST_CONSTANTS . TEST_ENVIRONMENT } ` ,
27
+ function ( ) : void {
28
+ const projectAndFileTests : ProjectAndFileTests = e2eContainer . get ( CLASSES . ProjectAndFileTests ) ;
29
+ const workspaceHandlingTests : WorkspaceHandlingTests = e2eContainer . get ( CLASSES . WorkspaceHandlingTests ) ;
30
+ const loginTests : LoginTests = e2eContainer . get ( CLASSES . LoginTests ) ;
31
+ const browserTabsUtil : BrowserTabsUtil = e2eContainer . get ( CLASSES . BrowserTabsUtil ) ;
32
+ const testWorkspaceUtil : ITestWorkspaceUtil = e2eContainer . get ( TYPES . WorkspaceUtil ) ;
33
+ const dashboard : Dashboard = e2eContainer . get ( CLASSES . Dashboard ) ;
34
+ const shellExecutor : ShellExecutor = e2eContainer . get ( CLASSES . ShellExecutor ) ;
35
+
36
+ let kubernetesCommandLineToolsExecutor : KubernetesCommandLineToolsExecutor ;
37
+ let workspaceName : string = '' ;
38
+ let originalBuildCapabilitiesSetting : string = '' ;
39
+ let devSpacesNamespace : string = '' ;
40
+ let cheClusterName : string = '' ;
41
+
42
+ const buildPushScript : string = `
43
+ export ARCH=$(uname -m)
44
+ export DATE=$(date +"%m%d%y")
45
+ export USER=$(oc whoami)
46
+ export TKN=$(oc whoami -t)
47
+ export REG="image-registry.openshift-image-registry.svc:5000"
48
+ export PROJECT=$(oc project -q)
49
+ export IMG="\${REG}/\${PROJECT}/hello:\${DATE}"
50
+
51
+ # Create test directory and Dockerfile
52
+ mkdir -p /projects/dockerfile-test
53
+ cd /projects/dockerfile-test
54
+
55
+ cat > Dockerfile << EOF
56
+ FROM registry.access.redhat.com/ubi8/ubi-minimal:latest
57
+ RUN echo "Hello from Kubedock!" > /hello.txt
58
+ CMD ["cat", "/hello.txt"]
59
+ EOF
60
+
61
+ podman login --tls-verify=false --username "\${USER}" --password "\${TKN}" "\${REG}"
62
+ podman build -t "\${IMG}" .
63
+ podman push --tls-verify=false "\${IMG}"
64
+ ` ;
65
+
66
+ const runTestScript : string = `
67
+ export DATE=$(date +"%m%d%y")
68
+ export REG="image-registry.openshift-image-registry.svc:5000"
69
+ export PROJECT=$(oc project -q)
70
+ export IMG="\${REG}/\${PROJECT}/hello:\${DATE}"
71
+
72
+ oc delete pod test-hello-pod --ignore-not-found
73
+ oc run test-hello-pod --restart=Never --image="\${IMG}"
74
+
75
+ for i in {1..10}; do
76
+ PHASE=$(oc get pod test-hello-pod -o jsonpath='{.status.phase}')
77
+ if [[ "$PHASE" == "Succeeded" ]]; then
78
+ break
79
+ elif [[ "$PHASE" == "Failed" ]]; then
80
+ oc describe pod test-hello-pod
81
+ exit 1
82
+ fi
83
+ sleep 6
84
+ done
85
+
86
+ oc logs test-hello-pod
87
+ ` ;
88
+
89
+ suiteSetup ( 'Setup DevSpaces with container build capabilities enabled' , function ( ) : void {
90
+ // Configure CheCluster to enable container build capabilities
91
+ kubernetesCommandLineToolsExecutor = e2eContainer . get ( CLASSES . KubernetesCommandLineToolsExecutor ) ;
92
+ kubernetesCommandLineToolsExecutor . loginToOcp ( 'admin' ) ;
93
+
94
+ // Get the namespace where DevSpaces is installed
95
+ const getDevSpacesNamespaceCommand = `oc get checluster --all-namespaces -o jsonpath='{.items[0].metadata.namespace}'` ;
96
+ devSpacesNamespace = shellExecutor . executeCommand ( getDevSpacesNamespaceCommand ) . stdout . trim ( ) ;
97
+
98
+ // Get the name of the CheCluster
99
+ const getCheClusterNameCommand = `oc get checluster -n ${ devSpacesNamespace } -o jsonpath='{.items[0].metadata.name}'` ;
100
+ cheClusterName = shellExecutor . executeCommand ( getCheClusterNameCommand ) . stdout . trim ( ) ;
101
+
102
+ // Get the original value of disableContainerBuildCapabilities
103
+ const getOriginalSettingCommand = `oc get checluster/${ cheClusterName } -n ${ devSpacesNamespace } -o jsonpath='{.spec.devEnvironments.disableContainerBuildCapabilities}'` ;
104
+ originalBuildCapabilitiesSetting = shellExecutor . executeCommand ( getOriginalSettingCommand ) . stdout . trim ( ) ;
105
+
106
+ // Patch the CheCluster to enable container build capabilities (set to false)
107
+ const patchCommand = `oc patch checluster/${ cheClusterName } -n ${ devSpacesNamespace } --type=merge -p '{"spec":{"devEnvironments":{"disableContainerBuildCapabilities":false}}}'` ;
108
+ const patchResult = shellExecutor . executeCommand ( patchCommand ) ;
109
+
110
+ expect ( patchResult . code ) . to . equal ( 0 , 'Failed to patch CheCluster to enable container build capabilities' ) ;
111
+ } ) ;
112
+
113
+ suiteSetup ( 'Login into DevSpaces' , async function ( ) : Promise < void > {
114
+ await loginTests . loginIntoChe ( ) ;
115
+ } ) ;
116
+
117
+ test ( 'Create and open new Empty Workspace' , async function ( ) : Promise < void > {
118
+ await dashboard . waitPage ( ) ;
119
+ await workspaceHandlingTests . createAndOpenWorkspace ( 'Empty Workspace' ) ;
120
+ await workspaceHandlingTests . obtainWorkspaceNameFromStartingPage ( ) ;
121
+ workspaceName = WorkspaceHandlingTests . getWorkspaceName ( ) ;
122
+ expect ( workspaceName , 'Workspace name was not detected' ) . not . empty ;
123
+ registerRunningWorkspace ( workspaceName ) ;
124
+ } ) ;
125
+
126
+ test ( 'Wait for workspace readiness' , async function ( ) : Promise < void > {
127
+ await projectAndFileTests . waitWorkspaceReadinessForCheCodeEditor ( ) ;
128
+ } ) ;
129
+
130
+ test ( 'Build and push container image from workspace' , function ( ) : void {
131
+ kubernetesCommandLineToolsExecutor = e2eContainer . get ( CLASSES . KubernetesCommandLineToolsExecutor ) ;
132
+ kubernetesCommandLineToolsExecutor . workspaceName = workspaceName ;
133
+ kubernetesCommandLineToolsExecutor . loginToOcp ( ) ;
134
+ kubernetesCommandLineToolsExecutor . getPodAndContainerNames ( ) ;
135
+ kubernetesCommandLineToolsExecutor . execInContainerCommand ( buildPushScript ) ;
136
+ } ) ;
137
+
138
+ test ( 'Verify container image can be used in a pod' , function ( ) : void {
139
+ const runTestScriptOutput : ShellString = kubernetesCommandLineToolsExecutor . execInContainerCommand ( runTestScript ) ;
140
+ expect ( runTestScriptOutput . stdout ) . to . include ( 'Hello from Kubedock!' , 'Expected "Hello from Kubedock!" message not found in logs' ) ;
141
+ } ) ;
142
+
143
+ suiteTeardown ( 'Open dashboard and close all other tabs' , async function ( ) : Promise < void > {
144
+ await dashboard . openDashboard ( ) ;
145
+ await browserTabsUtil . closeAllTabsExceptCurrent ( ) ;
146
+ } ) ;
147
+
148
+ suiteTeardown ( 'Stop and delete the workspace by API' , async function ( ) : Promise < void > {
149
+ await testWorkspaceUtil . stopAndDeleteWorkspaceByName ( workspaceName ) ;
150
+ } ) ;
151
+
152
+ suiteTeardown ( 'Unregister running workspace' , function ( ) : void {
153
+ registerRunningWorkspace ( '' ) ;
154
+ } ) ;
155
+
156
+ suiteTeardown ( 'Restore DevSpaces container build capabilities setting' , function ( ) : void {
157
+ kubernetesCommandLineToolsExecutor = e2eContainer . get ( CLASSES . KubernetesCommandLineToolsExecutor ) ;
158
+ kubernetesCommandLineToolsExecutor . loginToOcp ( 'admin' ) ;
159
+
160
+ const restorePatchCommand = `oc patch checluster/${ cheClusterName } -n ${ devSpacesNamespace } --type=merge -p '{"spec":{"devEnvironments":{"disableContainerBuildCapabilities":${ originalBuildCapabilitiesSetting } }}}'` ;
161
+ const restorePatchResult = shellExecutor . executeCommand ( restorePatchCommand ) ;
162
+
163
+ expect ( restorePatchResult . code ) . to . equal ( 0 , 'Failed to restore CheCluster container build capabilities setting' ) ;
164
+ } ) ;
165
+ }
166
+ ) ;
0 commit comments