Skip to content

Commit 3f7d8b1

Browse files
chore: add an e2e test with 5 airgapped nodes (#836)
add an e2e test with 5 controller nodes in an airgap environment.
1 parent 4a1ca8f commit 3f7d8b1

File tree

2 files changed

+136
-0
lines changed

2 files changed

+136
-0
lines changed

.github/workflows/ci.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,8 @@ jobs:
359359
runner: embedded-cluster
360360
- test: TestMultiNodeAirgapHADisasterRecovery
361361
runner: embedded-cluster
362+
- test: TestFiveNodesAirgapUpgrade
363+
runner: embedded-cluster
362364
steps:
363365
- name: Checkout
364366
uses: actions/checkout@v4

e2e/install_test.go

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1871,6 +1871,13 @@ func maybeDownloadAirgapBundle(t *testing.T, versionLabel string, destPath strin
18711871
return airgapBundlePath, size
18721872
}
18731873

1874+
func setupPlaywrightAndRunTest(t *testing.T, tc *cluster.Output, testName string, args ...string) (stdout, stderr string, err error) {
1875+
if err := setupPlaywright(t, tc); err != nil {
1876+
return "", "", fmt.Errorf("failed to setup playwright: %w", err)
1877+
}
1878+
return runPlaywrightTest(t, tc, testName, args...)
1879+
}
1880+
18741881
func setupPlaywright(t *testing.T, tc *cluster.Output) error {
18751882
t.Logf("%s: bypassing kurl-proxy on node 0", time.Now().Format(time.RFC3339))
18761883
line := []string{"bypass-kurl-proxy.sh"}
@@ -1973,3 +1980,130 @@ func cleanupCluster(t *testing.T, tc *cluster.Output) {
19731980
generateAndCopySupportBundle(t, tc)
19741981
copyPlaywrightReport(t, tc)
19751982
}
1983+
1984+
func TestFiveNodesAirgapUpgrade(t *testing.T) {
1985+
t.Parallel()
1986+
1987+
RequireEnvVars(t, []string{"SHORT_SHA", "AIRGAP_LICENSE_ID"})
1988+
1989+
t.Logf("%s: downloading airgap files", time.Now().Format(time.RFC3339))
1990+
airgapInstallBundlePath := "/tmp/airgap-install-bundle.tar.gz"
1991+
airgapUpgradeBundlePath := "/tmp/airgap-upgrade-bundle.tar.gz"
1992+
wg := sync.WaitGroup{}
1993+
wg.Add(2)
1994+
go func() {
1995+
downloadAirgapBundle(t, fmt.Sprintf("appver-%s-previous-k0s", os.Getenv("SHORT_SHA")), airgapInstallBundlePath, os.Getenv("AIRGAP_LICENSE_ID"))
1996+
wg.Done()
1997+
}()
1998+
go func() {
1999+
downloadAirgapBundle(t, fmt.Sprintf("appver-%s-upgrade", os.Getenv("SHORT_SHA")), airgapUpgradeBundlePath, os.Getenv("AIRGAP_LICENSE_ID"))
2000+
wg.Done()
2001+
}()
2002+
wg.Wait()
2003+
2004+
tc := cluster.NewTestCluster(&cluster.Input{
2005+
T: t,
2006+
Nodes: 5,
2007+
Image: "debian/12",
2008+
WithProxy: true,
2009+
AirgapInstallBundlePath: airgapInstallBundlePath,
2010+
AirgapUpgradeBundlePath: airgapUpgradeBundlePath,
2011+
})
2012+
defer cleanupCluster(t, tc)
2013+
2014+
// install "curl" dependency on node 0 for app version checks.
2015+
t.Logf("%s: installing test dependencies on node 0", time.Now().Format(time.RFC3339))
2016+
commands := [][]string{
2017+
{"apt-get", "update", "-y"},
2018+
{"apt-get", "install", "curl", "-y"},
2019+
}
2020+
withEnv := WithEnv(map[string]string{
2021+
"http_proxy": cluster.HTTPProxy,
2022+
"https_proxy": cluster.HTTPProxy,
2023+
})
2024+
if err := RunCommandsOnNode(t, tc, 0, commands, withEnv); err != nil {
2025+
t.Fatalf("fail to install test dependencies on node %s: %v", tc.Nodes[2], err)
2026+
}
2027+
2028+
// delete airgap bundles once they've been copied to the nodes
2029+
os.Remove(airgapInstallBundlePath)
2030+
os.Remove(airgapUpgradeBundlePath)
2031+
2032+
t.Logf("%s: preparing and installing embedded cluster on node 0", time.Now().Format(time.RFC3339))
2033+
installCommands := [][]string{
2034+
{"airgap-prepare.sh"},
2035+
{"single-node-airgap-install.sh"},
2036+
{"rm", "/assets/release.airgap"},
2037+
{"rm", "/usr/local/bin/embedded-cluster"},
2038+
}
2039+
if err := RunCommandsOnNode(t, tc, 0, installCommands); err != nil {
2040+
t.Fatalf("failed to install on node %s: %v", tc.Nodes[0], err)
2041+
}
2042+
2043+
if _, _, err := setupPlaywrightAndRunTest(t, tc, "deploy-app"); err != nil {
2044+
t.Fatalf("fail to run playwright test deploy-app: %v", err)
2045+
}
2046+
2047+
// generate controller node join command.
2048+
t.Logf("%s: generating a new controller token command", time.Now().Format(time.RFC3339))
2049+
stdout, stderr, err := runPlaywrightTest(t, tc, "get-join-controller-command")
2050+
if err != nil {
2051+
t.Fatalf("fail to generate controller join token:\nstdout: %s\nstderr: %s", stdout, stderr)
2052+
}
2053+
controllerCommand, err := findJoinCommandInOutput(stdout)
2054+
if err != nil {
2055+
t.Fatalf("fail to find the join command in the output: %v", err)
2056+
}
2057+
t.Log("controller join token command:", controllerCommand)
2058+
2059+
// join the controller nodes
2060+
joinCommandsSequence := [][]string{
2061+
{"rm", "/assets/ec-release-upgrade.tgz"},
2062+
{"airgap-prepare.sh"},
2063+
strings.Split(controllerCommand, " "),
2064+
{"rm", "/assets/release.airgap"},
2065+
{"rm", "/usr/local/bin/embedded-cluster"},
2066+
}
2067+
for i := 1; i < 5; i++ {
2068+
if err := RunCommandsOnNode(t, tc, i, joinCommandsSequence); err != nil {
2069+
t.Fatalf("fail to join controller node %s: %v", tc.Nodes[i], err)
2070+
}
2071+
}
2072+
2073+
// wait for the nodes to report as ready.
2074+
t.Logf("%s: all nodes joined, waiting for them to be ready", time.Now().Format(time.RFC3339))
2075+
if stdout, _, err = RunCommandOnNode(t, tc, 0, []string{"wait-for-ready-nodes.sh", "5"}); err != nil {
2076+
t.Log(stdout)
2077+
t.Fatalf("fail to wait for ready nodes: %v", err)
2078+
}
2079+
2080+
t.Logf("%s: checking installation state after app deployment", time.Now().Format(time.RFC3339))
2081+
line := []string{"check-airgap-installation-state.sh", fmt.Sprintf("%s-previous-k0s", os.Getenv("SHORT_SHA"))}
2082+
if _, _, err := RunCommandOnNode(t, tc, 0, line); err != nil {
2083+
t.Fatalf("fail to check installation state: %v", err)
2084+
}
2085+
2086+
t.Logf("%s: running airgap update", time.Now().Format(time.RFC3339))
2087+
upgradeCommands := [][]string{
2088+
{"airgap-update.sh"},
2089+
{"rm", "/assets/upgrade/release.airgap"},
2090+
{"rm", "/usr/local/bin/embedded-cluster-upgrade"},
2091+
}
2092+
if err := RunCommandsOnNode(t, tc, 0, upgradeCommands); err != nil {
2093+
t.Fatalf("fail to run airgap update: %v", err)
2094+
}
2095+
2096+
t.Logf("%s: upgrading cluster", time.Now().Format(time.RFC3339))
2097+
testArgs := []string{fmt.Sprintf("appver-%s-upgrade", os.Getenv("SHORT_SHA"))}
2098+
if _, _, err := runPlaywrightTest(t, tc, "deploy-upgrade", testArgs...); err != nil {
2099+
t.Fatalf("fail to run playwright test deploy-app: %v", err)
2100+
}
2101+
2102+
t.Logf("%s: checking installation state after upgrade", time.Now().Format(time.RFC3339))
2103+
line = []string{"check-postupgrade-state.sh", k8sVersion()}
2104+
if _, _, err := RunCommandOnNode(t, tc, 0, line); err != nil {
2105+
t.Fatalf("fail to check postupgrade state: %v", err)
2106+
}
2107+
2108+
t.Logf("%s: test complete", time.Now().Format(time.RFC3339))
2109+
}

0 commit comments

Comments
 (0)