Skip to content

Commit

Permalink
test: Add support for systemd and launchd services
Browse files Browse the repository at this point in the history
  • Loading branch information
mattevans committed Dec 20, 2024
1 parent 06a4f1c commit 6a4e7d9
Show file tree
Hide file tree
Showing 10 changed files with 543 additions and 103 deletions.
3 changes: 2 additions & 1 deletion cmd/cli/commands/start/start_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,14 @@ func TestStartContributoor(t *testing.T) {
mockConfig := mock.NewMockConfigManager(ctrl)
mockDocker := mock.NewMockDockerSidecar(ctrl)
mockBinary := mock.NewMockBinarySidecar(ctrl)
mockSystemd := mock.NewMockSystemdSidecar(ctrl)

tt.setupMocks(mockConfig, mockDocker, mockBinary)

app := cli.NewApp()
ctx := cli.NewContext(app, nil, nil)

err := startContributoor(ctx, logrus.New(), mockConfig, mockDocker, mockBinary)
err := startContributoor(ctx, logrus.New(), mockConfig, mockDocker, mockSystemd, mockBinary)

if tt.expectedError != "" {
assert.ErrorContains(t, err, tt.expectedError)
Expand Down
11 changes: 11 additions & 0 deletions cmd/cli/commands/status/status_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ func TestShowStatus(t *testing.T) {
// Create mock binary sidecar (shouldn't be used)
mockBinary := mock.NewMockBinarySidecar(ctrl)

// Create mock systemd sidecar (shouldn't be used)
mockSystemd := mock.NewMockSystemdSidecar(ctrl)

// Create mock GitHub service
mockGithub := servicemock.NewMockGitHubService(ctrl)
mockGithub.EXPECT().GetLatestVersion().Return("1.0.1", nil)
Expand All @@ -47,6 +50,7 @@ func TestShowStatus(t *testing.T) {
logrus.New(),
mockConfig,
mockDocker,
mockSystemd,
mockBinary,
mockGithub,
)
Expand Down Expand Up @@ -75,6 +79,9 @@ func TestShowStatus(t *testing.T) {
mockBinary := mock.NewMockBinarySidecar(ctrl)
mockBinary.EXPECT().IsRunning().Return(false, nil)

// Create mock systemd sidecar (shouldn't be used)
mockSystemd := mock.NewMockSystemdSidecar(ctrl)

// Create mock GitHub service with same version (shouldn't show update)
mockGithub := servicemock.NewMockGitHubService(ctrl)
mockGithub.EXPECT().GetLatestVersion().Return("1.0.0", nil)
Expand All @@ -84,6 +91,7 @@ func TestShowStatus(t *testing.T) {
logrus.New(),
mockConfig,
mockDocker,
mockSystemd,
mockBinary,
mockGithub,
)
Expand All @@ -105,6 +113,7 @@ func TestShowStatus(t *testing.T) {

mockDocker := mock.NewMockDockerSidecar(ctrl)
mockDocker.EXPECT().IsRunning().Return(true, nil)
mockSystemd := mock.NewMockSystemdSidecar(ctrl)

// Create mock GitHub service that returns an error
mockGithub := servicemock.NewMockGitHubService(ctrl)
Expand All @@ -115,6 +124,7 @@ func TestShowStatus(t *testing.T) {
logrus.New(),
mockConfig,
mockDocker,
mockSystemd,
mock.NewMockBinarySidecar(ctrl),
mockGithub,
)
Expand All @@ -139,6 +149,7 @@ func TestShowStatus(t *testing.T) {
nil,
nil,
nil,
nil,
)

assert.Error(t, err)
Expand Down
3 changes: 2 additions & 1 deletion cmd/cli/commands/stop/stop_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,14 @@ func TestStopContributoor(t *testing.T) {
mockConfig := mock.NewMockConfigManager(ctrl)
mockDocker := mock.NewMockDockerSidecar(ctrl)
mockBinary := mock.NewMockBinarySidecar(ctrl)
mockSystemd := mock.NewMockSystemdSidecar(ctrl)

tt.setupMocks(mockConfig, mockDocker, mockBinary)

app := cli.NewApp()
ctx := cli.NewContext(app, nil, nil)

err := stopContributoor(ctx, logrus.New(), mockConfig, mockDocker, mockBinary)
err := stopContributoor(ctx, logrus.New(), mockConfig, mockDocker, mockSystemd, mockBinary)

if tt.expectedError != "" {
assert.ErrorContains(t, err, tt.expectedError)
Expand Down
23 changes: 12 additions & 11 deletions cmd/cli/commands/update/update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ func TestUpdateContributoor(t *testing.T) {
runMethod string
version string
confirmPrompt bool
setupMocks func(*mock.MockConfigManager, *mock.MockDockerSidecar, *mock.MockBinarySidecar, *smock.MockGitHubService)
setupMocks func(*mock.MockConfigManager, *mock.MockDockerSidecar, *mock.MockSystemdSidecar, *mock.MockBinarySidecar, *smock.MockGitHubService)
expectedError string
}{
{
name: "docker - updates service successfully",
runMethod: sidecar.RunMethodDocker,
confirmPrompt: true,
setupMocks: func(cfg *mock.MockConfigManager, d *mock.MockDockerSidecar, b *mock.MockBinarySidecar, g *smock.MockGitHubService) {
setupMocks: func(cfg *mock.MockConfigManager, d *mock.MockDockerSidecar, s *mock.MockSystemdSidecar, b *mock.MockBinarySidecar, g *smock.MockGitHubService) {
cfg.EXPECT().Get().Return(&sidecar.Config{
RunMethod: sidecar.RunMethodDocker,
Version: "v1.0.0",
Expand All @@ -67,7 +67,7 @@ func TestUpdateContributoor(t *testing.T) {
{
name: "docker - already at latest version",
runMethod: sidecar.RunMethodDocker,
setupMocks: func(cfg *mock.MockConfigManager, d *mock.MockDockerSidecar, b *mock.MockBinarySidecar, g *smock.MockGitHubService) {
setupMocks: func(cfg *mock.MockConfigManager, d *mock.MockDockerSidecar, s *mock.MockSystemdSidecar, b *mock.MockBinarySidecar, g *smock.MockGitHubService) {
cfg.EXPECT().Get().Return(&sidecar.Config{
RunMethod: sidecar.RunMethodDocker,
Version: "v1.0.0",
Expand All @@ -78,7 +78,7 @@ func TestUpdateContributoor(t *testing.T) {
{
name: "docker - update fails",
runMethod: sidecar.RunMethodDocker,
setupMocks: func(cfg *mock.MockConfigManager, d *mock.MockDockerSidecar, b *mock.MockBinarySidecar, g *smock.MockGitHubService) {
setupMocks: func(cfg *mock.MockConfigManager, d *mock.MockDockerSidecar, s *mock.MockSystemdSidecar, b *mock.MockBinarySidecar, g *smock.MockGitHubService) {
cfg.EXPECT().Get().Return(&sidecar.Config{
RunMethod: sidecar.RunMethodDocker,
Version: "v1.0.0",
Expand All @@ -101,7 +101,7 @@ func TestUpdateContributoor(t *testing.T) {
version: "v1.1.0",
confirmPrompt: true,
runMethod: sidecar.RunMethodDocker,
setupMocks: func(cfg *mock.MockConfigManager, d *mock.MockDockerSidecar, b *mock.MockBinarySidecar, g *smock.MockGitHubService) {
setupMocks: func(cfg *mock.MockConfigManager, d *mock.MockDockerSidecar, s *mock.MockSystemdSidecar, b *mock.MockBinarySidecar, g *smock.MockGitHubService) {
cfg.EXPECT().Get().Return(&sidecar.Config{
RunMethod: sidecar.RunMethodDocker,
Version: "v1.0.0",
Expand All @@ -125,7 +125,7 @@ func TestUpdateContributoor(t *testing.T) {
name: "specific version - does not exist",
version: "v999.0.0",
runMethod: sidecar.RunMethodDocker,
setupMocks: func(cfg *mock.MockConfigManager, d *mock.MockDockerSidecar, b *mock.MockBinarySidecar, g *smock.MockGitHubService) {
setupMocks: func(cfg *mock.MockConfigManager, d *mock.MockDockerSidecar, s *mock.MockSystemdSidecar, b *mock.MockBinarySidecar, g *smock.MockGitHubService) {
cfg.EXPECT().Get().Return(&sidecar.Config{
RunMethod: sidecar.RunMethodDocker,
Version: "v1.0.0",
Expand All @@ -137,7 +137,7 @@ func TestUpdateContributoor(t *testing.T) {
name: "binary - updates service successfully",
runMethod: sidecar.RunMethodBinary,
confirmPrompt: true,
setupMocks: func(cfg *mock.MockConfigManager, d *mock.MockDockerSidecar, b *mock.MockBinarySidecar, g *smock.MockGitHubService) {
setupMocks: func(cfg *mock.MockConfigManager, d *mock.MockDockerSidecar, s *mock.MockSystemdSidecar, b *mock.MockBinarySidecar, g *smock.MockGitHubService) {
cfg.EXPECT().Get().Return(&sidecar.Config{
RunMethod: sidecar.RunMethodBinary,
Version: "v1.0.0",
Expand All @@ -160,7 +160,7 @@ func TestUpdateContributoor(t *testing.T) {
{
name: "binary - already at latest version",
runMethod: sidecar.RunMethodBinary,
setupMocks: func(cfg *mock.MockConfigManager, d *mock.MockDockerSidecar, b *mock.MockBinarySidecar, g *smock.MockGitHubService) {
setupMocks: func(cfg *mock.MockConfigManager, d *mock.MockDockerSidecar, s *mock.MockSystemdSidecar, b *mock.MockBinarySidecar, g *smock.MockGitHubService) {
cfg.EXPECT().Get().Return(&sidecar.Config{
RunMethod: sidecar.RunMethodBinary,
Version: "v1.0.0",
Expand All @@ -172,7 +172,7 @@ func TestUpdateContributoor(t *testing.T) {
name: "binary - update fails",
runMethod: sidecar.RunMethodBinary,
confirmPrompt: true,
setupMocks: func(cfg *mock.MockConfigManager, d *mock.MockDockerSidecar, b *mock.MockBinarySidecar, g *smock.MockGitHubService) {
setupMocks: func(cfg *mock.MockConfigManager, d *mock.MockDockerSidecar, s *mock.MockSystemdSidecar, b *mock.MockBinarySidecar, g *smock.MockGitHubService) {
cfg.EXPECT().Get().Return(&sidecar.Config{
RunMethod: sidecar.RunMethodBinary,
Version: "v1.0.0",
Expand Down Expand Up @@ -201,10 +201,11 @@ func TestUpdateContributoor(t *testing.T) {

mockConfig := mock.NewMockConfigManager(ctrl)
mockDocker := mock.NewMockDockerSidecar(ctrl)
mockSystemd := mock.NewMockSystemdSidecar(ctrl)
mockBinary := mock.NewMockBinarySidecar(ctrl)
mockGithub := smock.NewMockGitHubService(ctrl)

tt.setupMocks(mockConfig, mockDocker, mockBinary, mockGithub)
tt.setupMocks(mockConfig, mockDocker, mockSystemd, mockBinary, mockGithub)

app := cli.NewApp()
app.Flags = []cli.Flag{
Expand All @@ -220,7 +221,7 @@ func TestUpdateContributoor(t *testing.T) {
}
context := cli.NewContext(app, set, nil)

err := updateContributoor(context, logrus.New(), mockConfig, mockDocker, mockBinary, mockGithub)
err := updateContributoor(context, logrus.New(), mockConfig, mockDocker, mockSystemd, mockBinary, mockGithub)

if tt.expectedError != "" {
assert.ErrorContains(t, err, tt.expectedError)
Expand Down
147 changes: 126 additions & 21 deletions install.bats
Original file line number Diff line number Diff line change
Expand Up @@ -575,8 +575,14 @@ EOF
[ -z "$output" ]
}

@test "setup_systemd_contributoor creates service file correctly" {
# Mock sudo to capture commands.
@test "[linux] setup_systemd_contributoor creates service file correctly" {
# Set platform for test
function detect_platform() {
echo "linux"
}
export -f detect_platform

# Mock sudo to capture commands
function sudo() {
case "$1" in
"tee")
Expand All @@ -587,22 +593,27 @@ EOF
esac
}
export -f sudo

# Run the setup.

run setup_systemd_contributoor
# Check status.

# Check status
[ "$status" -eq 0 ]
# Verify service file was created and has correct content.

# Verify service file was created and has correct content
[ -f "$TEST_DIR/contributoor.service" ]
grep -q "Description=Contributoor Service" "$TEST_DIR/contributoor.service"
grep -q "User=$USER" "$TEST_DIR/contributoor.service"
grep -q "ExecStart=$CONTRIBUTOOR_BIN/sentry" "$TEST_DIR/contributoor.service"
}

@test "setup_systemd_contributoor removes any existing systemd service before installing" {
# Mock sudo and systemctl.
@test "[linux] setup_systemd_contributoor removes any existing systemd service before installing" {
# Set platform for test
function detect_platform() {
echo "linux"
}
export -f detect_platform

# Mock sudo and systemctl
function sudo() {
case "$1" in
"systemctl")
Expand All @@ -615,32 +626,126 @@ EOF
esac
}
export -f sudo

run setup_systemd_contributoor
# Check status.

# Check status
[ "$status" -eq 0 ]
# Verify it detected and handled existing service.

# Verify it detected and handled existing service
echo "$output" | grep -q "Stopped and disabled existing systemd service"
}

@test "check_systemd validates systemd availability" {
# Mock commands to simulate working systemd.
@test "[linux] check_systemd validates systemd availability" {
# Set platform for test
function detect_platform() {
echo "linux"
}
export -f detect_platform

# Mock commands to simulate working systemd
function pidof() { echo "1"; }
function systemctl() { return 0; }
export -f pidof systemctl

run check_systemd
run check_systemd_or_launchd
[ "$status" -eq 0 ]
}

@test "check_systemd fails when systemd not available" {
# Mock pidof to simulate no systemd.
@test "[linux] check_systemd fails when systemd not available" {
# Set platform for test
function detect_platform() {
echo "linux"
}
export -f detect_platform

# Mock pidof to simulate no systemd
function pidof() { return 1; }
export -f pidof

run check_systemd
run check_systemd_or_launchd
[ "$status" -eq 1 ]
echo "$output" | grep -q "Systemd is not available on this system. Please choose a different installation mode."
}

@test "[darwin] check_systemd_or_launchd validates launchd availability" {
# Set platform for test
function detect_platform() {
echo "darwin"
}
export -f detect_platform

# Mock launchctl to simulate working launchd
function command() {
case "$2" in
"launchctl") return 0 ;;
"sudo") return 0 ;;
*) command "$@" ;;
esac
}
export -f command

run check_systemd_or_launchd
[ "$status" -eq 0 ]
}

@test "[darwin] setup_systemd_contributoor removes any existing launchd service before installing" {
# Set platform for test
function detect_platform() {
echo "darwin"
}
export -f detect_platform

# Mock sudo and launchctl
function sudo() {
case "$1" in
"launchctl")
case "$2" in
"list") echo "12345 0 io.ethpandaops.contributoor" ;;
*) return 0 ;;
esac
;;
*) return 0 ;;
esac
}
export -f sudo

run setup_systemd_contributoor

# Check status
[ "$status" -eq 0 ]

# Verify it detected and handled existing service
echo "$output" | grep -q "Stopped and unloaded existing launchd service"
}

@test "[darwin] setup_systemd_contributoor creates launchd service file correctly" {
# Set platform for test
function detect_platform() {
echo "darwin"
}
export -f detect_platform

# Mock sudo to capture commands
function sudo() {
case "$1" in
"tee")
# Capture service file content
cat > "$TEST_DIR/io.ethpandaops.contributoor.plist"
;;
*) return 0 ;;
esac
}
export -f sudo

run setup_systemd_contributoor

# Check status
[ "$status" -eq 0 ]

# Verify service file was created and has correct content
[ -f "$TEST_DIR/io.ethpandaops.contributoor.plist" ]
grep -q "<string>io.ethpandaops.contributoor</string>" "$TEST_DIR/io.ethpandaops.contributoor.plist"
grep -q "<string>$CONTRIBUTOOR_BIN/sentry</string>" "$TEST_DIR/io.ethpandaops.contributoor.plist"
grep -q "<string>$USER</string>" "$TEST_DIR/io.ethpandaops.contributoor.plist"
}
Loading

0 comments on commit 6a4e7d9

Please sign in to comment.