Skip to content

Commit 6d215aa

Browse files
committed
Add some preconditions
1 parent 6b639a9 commit 6d215aa

3 files changed

Lines changed: 151 additions & 20 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,8 @@ zypper -n install curl git tar gzip make gcc podman
160160
Install Go and Ginkgo
161161
```bash
162162
curl -LO https://go.dev/dl/go1.21.13.linux-amd64.tar.gz
163-
tar -C /root -xzf go1.21.13.linux-amd64.tar.gz
164-
export PATH="/root/go/bin:$PATH"
163+
tar -C $HOME -xzf go1.21.13.linux-amd64.tar.gz
164+
export PATH="$HOME/go/bin:$PATH"
165165
go install github.com/onsi/ginkgo/v2/ginkgo@v2.20.1
166166
```
167167

tests/e2e/mgradm_test.go

Lines changed: 123 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,49 +5,154 @@
55
package e2e_test
66

77
import (
8+
"bufio"
89
"bytes"
910
"fmt"
11+
"io"
12+
"os"
1013
"os/exec"
14+
"strings"
15+
"sync"
1116

1217
. "github.com/onsi/ginkgo/v2"
1318
. "github.com/onsi/gomega"
1419
)
1520

16-
// Define the mgradm binary path
17-
const mgradmPath = "/workspace/bin/mgradm"
21+
const mgradmPath = "./../../bin/mgradm"
22+
const mgradmConfigPath = "./../../utils/mgradm.yaml"
23+
const backend = "podman"
1824

19-
// runMgradmCommand is a helper function to execute mgradm and capture its output.
20-
// It returns the combined stdout+stderr and an error if the command fails to run.
21-
func runMgradmCommand(args []string) (string, error) {
25+
// interaction defines a prompt to look for and the corresponding response to send.
26+
type interaction struct {
27+
Prompt string
28+
Response string
29+
}
30+
31+
// runMgradmCommand executes mgradm, handling an ordered sequence of interactive prompts.
32+
func runMgradmCommand(args []string, interactions ...interaction) (string, error) {
2233
cmd := exec.Command(mgradmPath, args...)
2334

24-
var stdoutBuffer bytes.Buffer
25-
var stderrBuffer bytes.Buffer
26-
cmd.Stdout = &stdoutBuffer
27-
cmd.Stderr = &stderrBuffer
35+
var combinedOutputBuffer bytes.Buffer
36+
var wg sync.WaitGroup
37+
38+
stdoutPipe, err := cmd.StdoutPipe()
39+
if err != nil {
40+
return "", fmt.Errorf("error creating stdout pipe: %w", err)
41+
}
42+
43+
stderrPipe, err := cmd.StderrPipe()
44+
if err != nil {
45+
return "", fmt.Errorf("error creating stderr pipe: %w", err)
46+
}
47+
48+
stdinPipe, err := cmd.StdinPipe()
49+
if err != nil {
50+
return "", fmt.Errorf("error creating stdin pipe: %w", err)
51+
}
52+
53+
interactionReader, interactionWriter := io.Pipe()
54+
mainWriter := io.MultiWriter(&combinedOutputBuffer, GinkgoWriter, interactionWriter)
2855

2956
By(fmt.Sprintf("Running command: %s %v", mgradmPath, args))
57+
if err := cmd.Start(); err != nil {
58+
err := interactionWriter.Close()
59+
if err != nil {
60+
return "", err
61+
}
62+
return "", fmt.Errorf("error starting command: %w", err)
63+
}
64+
65+
// This goroutine handles the ordered sequence of interactions.
66+
wg.Add(1)
67+
go func() {
68+
defer wg.Done()
69+
defer func(stdinPipe io.WriteCloser) {
70+
err := stdinPipe.Close()
71+
if err != nil {
72+
GinkgoWriter.Printf("Error closing stdin pipe: %v", err)
73+
}
74+
}(stdinPipe)
3075

31-
err := cmd.Run()
32-
output := stdoutBuffer.String() + stderrBuffer.String()
76+
interactionIndex := 0
77+
scanner := bufio.NewScanner(interactionReader)
78+
for scanner.Scan() {
79+
line := scanner.Text()
80+
// Check if there are still interactions left to perform.
81+
if interactionIndex < len(interactions) {
82+
currentInteraction := interactions[interactionIndex]
83+
if strings.Contains(line, currentInteraction.Prompt) {
84+
By(fmt.Sprintf("Answering prompt '%s' with '%s'", currentInteraction.Prompt, currentInteraction.Response))
85+
_, err := io.WriteString(stdinPipe, currentInteraction.Response+"\n")
86+
if err != nil {
87+
GinkgoWriter.Printf("Error writing to stdin: %v", err)
88+
}
89+
// Move to the next expected interaction.
90+
interactionIndex++
91+
}
92+
}
93+
}
94+
}()
3395

34-
return output, err
96+
// Goroutines to copy stdout and stderr to the main writer.
97+
wg.Add(2)
98+
go func() {
99+
defer wg.Done()
100+
_, err := io.Copy(mainWriter, stdoutPipe)
101+
if err != nil {
102+
return
103+
}
104+
}()
105+
go func() {
106+
defer wg.Done()
107+
_, err := io.Copy(mainWriter, stderrPipe)
108+
if err != nil {
109+
return
110+
}
111+
}()
112+
113+
err = cmd.Wait()
114+
err = interactionWriter.Close()
115+
if err != nil {
116+
return "", err
117+
}
118+
wg.Wait()
119+
120+
return combinedOutputBuffer.String(), err
35121
}
36122

123+
var _ = BeforeSuite(func() {
124+
_, err := os.Stat(mgradmPath)
125+
Expect(err).To(Succeed(), "mgradm binary not found at %s. Error: %v", mgradmPath, err)
126+
127+
GinkgoWriter.Printf("Using mgradm: %s\n", mgradmPath)
128+
})
129+
37130
var _ = Describe("mgradm tests", func() {
131+
// Ensure that the environment is clean before each test.
132+
BeforeEach(func() {
133+
By(fmt.Sprintf("Running mgradm cleanup: uninstall --backend %s --force --purge-volumes --purge-images", backend))
134+
cleanupArgs := []string{"uninstall", "--backend", backend, "--force", "--purge-volumes", "--purge-images"}
135+
output, err := runMgradmCommand(cleanupArgs)
136+
Expect(err).To(Succeed(), "Failed to run mgradm cleanup command. Error: %v\nOutput: %s", err, output)
137+
})
38138

39139
Context("install command", func() {
40-
It("should run without error with default options", func() {
41-
args := []string{"install", "podman", "--logLevel", "debug"}
140+
It("should run without error and handle repeated prompts", func() {
141+
args := []string{"install", backend, "--config", mgradmConfigPath, "--logLevel", "debug"}
42142
output, err := runMgradmCommand(args)
43-
44143
Expect(err).To(Succeed(), "Command failed with error: %v\nOutput: %s", err, output)
45-
Expect(output).To(ContainSubstring("Starting /workspace/bin/mgradm install podman --logLevel debug"))
46-
Expect(output).To(ContainSubstring("Use of this software implies acceptance of the End User License Agreement."))
47-
Expect(output).To(ContainSubstring("application log level=debug"))
144+
Expect(output).Should(ContainSubstring("mgradm install %s --logLevel debug", backend))
145+
Expect(output).Should(ContainSubstring("Setting up uyuni network"))
146+
Expect(output).Should(ContainSubstring("Enabling system service"))
147+
Expect(output).Should(ContainSubstring("Waiting for the server to start"))
148+
Expect(output).Should(ContainSubstring("Run setup command in the container"))
149+
Expect(output).Should(ContainSubstring("Populating the database"))
150+
Expect(output).ShouldNot(MatchRegexp(`(?i)\berr(or)?\b`))
151+
Expect(output).Should(ContainSubstring("Server configuration finished"))
48152
})
49153

50154
It("should show help for install command", func() {
155+
Skip("Skipping until we fix the previous test case")
51156
args := []string{"install", "--help"}
52157
output, err := runMgradmCommand(args)
53158
Expect(err).To(Succeed())

tests/e2e/utils/mgradm.yaml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
db:
2+
password: spacewalk
3+
ssl:
4+
password: spacewalk
5+
6+
email: galaxy-noise@suse.de
7+
emailFrom: root@suse.de
8+
registry: registry.opensuse.org/systemsmanagement/uyuni/master/containerfile
9+
10+
tag: latest
11+
12+
mirror: /srv/mirror
13+
debug:
14+
java: true
15+
16+
17+
18+
organization: SUSE Test
19+
admin:
20+
password: admin
21+
login: admin
22+
firstName: Admin
23+
lastName: Admin
24+
email: galaxy-noise@suse.de
25+
tz:
26+
Europe/Berlin

0 commit comments

Comments
 (0)