Skip to content

Commit 038e9f0

Browse files
author
Peng Zhou
committed
MLE-22366: automation for upgrade tests
1 parent ac4791d commit 038e9f0

File tree

1 file changed

+235
-0
lines changed

1 file changed

+235
-0
lines changed
Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
package e2e
2+
3+
/********************************************************************************
4+
*
5+
* Test: MlImageUpgrade
6+
* This test verifies the upgrade of MarkLogic Docker images in a Kubernetes environment.
7+
*
8+
********************************************************************************/
9+
import (
10+
"io"
11+
"github.com/tidwall/gjson"
12+
"path/filepath"
13+
"strings"
14+
"testing"
15+
"time"
16+
17+
"github.com/gruntwork-io/terratest/modules/helm"
18+
"github.com/gruntwork-io/terratest/modules/k8s"
19+
"github.com/gruntwork-io/terratest/modules/random"
20+
"github.com/marklogic/marklogic-kubernetes/test/testUtil"
21+
"github.com/imroc/req/v3"
22+
23+
)
24+
25+
type DockerImage struct {
26+
Repo string
27+
Tag string
28+
Version string
29+
Type string
30+
Description string
31+
}
32+
33+
func TestMlImageUpgrade(t *testing.T) {
34+
var helmChartPath string
35+
var initialChartVersion string
36+
37+
adminUsername := "admin"
38+
adminPassword := "admin"
39+
40+
// Path to the helm chart we will test
41+
helmChartPath, err := filepath.Abs("../../charts")
42+
if err != nil {
43+
t.Fatalf(err.Error())
44+
}
45+
46+
upgradeImageList := [][]DockerImage{
47+
{
48+
DockerImage{Repo: "progressofficial/marklogic-db", Tag: "11.3.1-ubi-rootless-2.1.3", Version: "11030000", Type: "rootless", Description: "MarkLogic 11.3.1 UBI8 Rootless"},
49+
DockerImage{Repo: "ml-docker-db-dev-tierpoint.bed-artifactory.bedford.progress.com/marklogic/marklogic-server-ubi-rootless", Tag: "latest-12-ubi-rootless", Version: "12000000", Type: "rootless", Description: "MarkLogic 12 UBI8 Rootless"},
50+
},
51+
{
52+
DockerImage{Repo: "progressofficial/marklogic-db", Tag: "11.3.1-ubi9-rootless-2.1.3", Version: "11030000", Type: "rootless", Description: "MarkLogic 11.3.1 UBI9 Rootless"},
53+
DockerImage{Repo: "ml-docker-db-dev-tierpoint.bed-artifactory.bedford.progress.com/marklogic/marklogic-server-ubi9-rootless", Tag: "latest-12-ubi9-rootless", Version: "12000000", Type: "rootless", Description: "MarkLogic 12 UBI9 Rootless"},
54+
},
55+
{
56+
DockerImage{Repo: "progressofficial/marklogic-db", Tag: "11.3.1-ubi-rootless-2.1.3", Version: "11030000", Type: "rootless", Description: "MarkLogic 11.3.1 UBI8 Rootless"},
57+
DockerImage{Repo: "ml-docker-db-dev-tierpoint.bed-artifactory.bedford.progress.com/marklogic/marklogic-server-ubi9-rootless", Tag: "latest-12-ubi9-rootless", Version: "12000000", Type: "rootless", Description: "MarkLogic 12 UBI9 Rootless"},
58+
},
59+
{
60+
DockerImage{Repo: "progressofficial/marklogic-db", Tag: "11.3.1-ubi-2.1.3", Version: "11030000", Type: "root", Description: "MarkLogic 11.3.1 UBI8 Root"},
61+
DockerImage{Repo: "ml-docker-db-dev-tierpoint.bed-artifactory.bedford.progress.com/marklogic/marklogic-server-ubi", Tag: "latest-12", Version: "12000000", Type: "root", Description: "MarkLogic 12 UBI8 Root"},
62+
},
63+
{
64+
DockerImage{Repo: "progressofficial/marklogic-db", Tag: "11.3.1-ubi9-2.1.3", Version: "11030000", Type: "root", Description: "MarkLogic 11.3.1 UBI9 Root"},
65+
DockerImage{Repo: "ml-docker-db-dev-tierpoint.bed-artifactory.bedford.progress.com/marklogic/marklogic-server-ubi9", Tag: "latest-12", Version: "12000000", Type: "root", Description: "MarkLogic 12 UBI9 Root"},
66+
},
67+
{
68+
DockerImage{Repo: "progressofficial/marklogic-db", Tag: "11.3.1-ubi-2.1.3", Version: "11030000", Type: "root", Description: "MarkLogic 11.3.1 UBI8 Root"},
69+
DockerImage{Repo: "ml-docker-db-dev-tierpoint.bed-artifactory.bedford.progress.com/marklogic/marklogic-server-ubi9", Tag: "latest-12", Version: "12000000", Type: "root", Description: "MarkLogic 12 UBI9 Root"},
70+
},
71+
{
72+
DockerImage{Repo: "progressofficial/marklogic-db", Tag: "11.3.1-ubi-2.1.3", Version: "11030000", Type: "root", Description: "MarkLogic 11.3.1 UBI8 Root"},
73+
DockerImage{Repo: "ml-docker-db-dev-tierpoint.bed-artifactory.bedford.progress.com/marklogic/marklogic-server-ubi-rootless", Tag: "latest-12-ubi-rootless", Version: "12000000", Type: "rootless", Description: "MarkLogic 12 UBI8 Rootless"},
74+
},
75+
{
76+
DockerImage{Repo: "progressofficial/marklogic-db", Tag: "11.3.1-ubi9-2.1.3", Version: "11030000", Type: "root", Description: "MarkLogic 11.3.1 UBI9 Root"},
77+
DockerImage{Repo: "ml-docker-db-dev-tierpoint.bed-artifactory.bedford.progress.com/marklogic/marklogic-server-ubi9-rootless", Tag: "latest-12-ubi9-rootless", Version: "12000000", Type: "rootless", Description: "MarkLogic 12 UBI9 Rootless"},
78+
},
79+
{
80+
DockerImage{Repo: "progressofficial/marklogic-db", Tag: "11.3.1-ubi-2.1.3", Version: "11030000", Type: "root", Description: "MarkLogic 11.3.1 UBI8 Root"},
81+
DockerImage{Repo: "ml-docker-db-dev-tierpoint.bed-artifactory.bedford.progress.com/marklogic/marklogic-server-ubi9-rootless", Tag: "latest-12-ubi9-rootless", Version: "12000000", Type: "rootless", Description: "MarkLogic 12 UBI9 Rootless"},
82+
},
83+
}
84+
85+
for i, image := range upgradeImageList {
86+
originalImage := image[0]
87+
upgradeImage := image[1]
88+
t.Logf("Running upgrade test %d with images: %s -> %s", i+1, originalImage.Description, upgradeImage.Description)
89+
90+
namespaceName := "ml-" + strings.ToLower(random.UniqueId())
91+
kubectlOptions := k8s.NewKubectlOptions("", "", namespaceName)
92+
valuesMap := map[string]string{
93+
"persistence.enabled": "true",
94+
"replicaCount": "1",
95+
"image.repository": originalImage.Repo,
96+
"image.tag": originalImage.Tag,
97+
"auth.adminUsername": adminUsername,
98+
"auth.adminPassword": adminPassword,
99+
"auth.walletPassword": "admin",
100+
}
101+
if originalImage.Type == "root" {
102+
valuesMap["containerSecurityContext.allowPrivilegeEscalation"] = "true"
103+
}
104+
105+
options := &helm.Options{
106+
KubectlOptions: kubectlOptions,
107+
SetValues: valuesMap,
108+
Version: initialChartVersion,
109+
ExtraArgs: map[string][]string{
110+
"install": {"--hide-notes"},
111+
},
112+
}
113+
114+
t.Logf("====Creating namespace: " + namespaceName)
115+
k8s.CreateNamespace(t, kubectlOptions, namespaceName)
116+
117+
118+
t.Logf("====Setting helm chart path to %s", helmChartPath)
119+
t.Logf("====Installing Helm Chart")
120+
releaseName := "test-ml-upgrade"
121+
podName := testUtil.HelmInstall(t, options, releaseName, kubectlOptions, helmChartPath)
122+
123+
tunnel := k8s.NewTunnel(
124+
kubectlOptions, k8s.ResourceTypePod, podName, 8002, 8002)
125+
tunnel.ForwardPort(t)
126+
client := req.C().EnableInsecureSkipVerify()
127+
128+
currentMLVersion := getMLVersion(t, client, adminUsername, adminPassword)
129+
if currentMLVersion != originalImage.Version {
130+
t.Fatalf("Expected ML version to start with %s, but got %s",
131+
originalImage.Version, currentMLVersion)
132+
} else {
133+
t.Logf("ML version successfully installed: %s", currentMLVersion)
134+
}
135+
tunnel.Close()
136+
137+
// create options for helm upgrade
138+
upgradeOptionsMap := map[string]string{
139+
"image.repository": upgradeImage.Repo,
140+
"image.tag": upgradeImage.Tag,
141+
"persistence.enabled": "true",
142+
"replicaCount": "1",
143+
"logCollection.enabled": "false",
144+
}
145+
146+
if upgradeImage.Type == "root" {
147+
upgradeOptionsMap["containerSecurityContext.allowPrivilegeEscalation"] = "true"
148+
}
149+
150+
if originalImage.Type == "root" && upgradeImage.Type == "rootless" {
151+
t.Logf("====Performing root to rootless upgrade")
152+
upgradeOptionsMap["rootToRootlessUpgrade"] = "true"
153+
}
154+
155+
//set helm options for upgrading helm chart version
156+
helmUpgradeOptions := &helm.Options{
157+
KubectlOptions: kubectlOptions,
158+
SetValues: upgradeOptionsMap,
159+
ExtraArgs: map[string][]string{
160+
"upgrade": {"--hide-notes"},
161+
},
162+
}
163+
164+
helm.Upgrade(t, helmUpgradeOptions, helmChartPath, releaseName)
165+
t.Logf("====Waiting for pod to be available after upgrade")
166+
167+
k8s.RunKubectl(t, kubectlOptions, "delete", "pod", podName)
168+
k8s.WaitUntilPodAvailable(t, kubectlOptions, podName, 15, 15*time.Second)
169+
170+
t.Logf("====Checking if the pod is running after upgrade")
171+
pod := k8s.GetPod(t, kubectlOptions, podName)
172+
if pod.Status.Phase != "Running" {
173+
t.Fatalf("Pod %s is not running after upgrade, status: %s", podName, pod.Status.Phase)
174+
}
175+
176+
tunnel8001 := k8s.NewTunnel(
177+
kubectlOptions, k8s.ResourceTypePod, podName, 8001, 8001)
178+
tunnel8001.ForwardPort(t)
179+
180+
tunnel8002 := k8s.NewTunnel(
181+
kubectlOptions, k8s.ResourceTypePod, podName, 8002, 8002)
182+
tunnel8002.ForwardPort(t)
183+
184+
resp, err := client.R().
185+
SetDigestAuth(adminUsername, adminPassword).
186+
Post("http://localhost:8001/security-upgrade-go.xqy")
187+
188+
if err != nil {
189+
t.Fatalf("Error in upgrading ML Security DB: %s", err.Error())
190+
}
191+
body, err := io.ReadAll(resp.Body)
192+
if err != nil {
193+
t.Logf("error in reading the response: %s", err.Error())
194+
}
195+
if resp.StatusCode != 200 {
196+
t.Logf("Expected status code 200, got %d. Response: %s",
197+
resp.StatusCode, string(body))
198+
}
199+
200+
t.Logf("====Checking if the image is updated after upgrade")
201+
upgradedMLVersion := getMLVersion(t, client, adminUsername, adminPassword)
202+
t.Logf("====Current ML Version after upgrade: %s", upgradedMLVersion)
203+
204+
if upgradedMLVersion != upgradeImage.Version {
205+
t.Fatalf("Expected ML version to start with %s, but got %s",
206+
upgradeImage.Version, upgradedMLVersion)
207+
} else {
208+
t.Logf("ML version successfully upgraded to %s", upgradedMLVersion)
209+
}
210+
t.Logf("====Deleting namespace: " + namespaceName)
211+
tunnel8001.Close()
212+
tunnel8002.Close()
213+
k8s.DeleteNamespace(t, kubectlOptions, namespaceName)
214+
}
215+
}
216+
217+
func getMLVersion(t *testing.T, client *req.Client, adminUsername, adminPassword string) string {
218+
resp, err := client.R().
219+
SetDigestAuth(adminUsername, adminPassword).
220+
Get("http://localhost:8002/manage/v2?format=json")
221+
222+
if err != nil {
223+
t.Fatalf(err.Error())
224+
}
225+
body, err := io.ReadAll(resp.Body)
226+
if err != nil {
227+
t.Logf("error in reading the response: %s", err.Error())
228+
}
229+
if resp.StatusCode != 200 {
230+
t.Fatalf("Expected status code 200, got %d. Response: %s",
231+
resp.StatusCode, string(body))
232+
}
233+
mlVersion := gjson.Get(string(body), `local-cluster-default.effective-version`).String()
234+
return mlVersion
235+
}

0 commit comments

Comments
 (0)