Skip to content

Commit 66c1411

Browse files
committed
systemd: implement 'Start()' function
Implement and test the 'Start()' function for a systemd-managed daemon service. As in the 'launchd' daemon provider, the 'Start()' function does not check whether the service is already running; if it is, the operation is a no-op. Signed-off-by: Victoria Dye <[email protected]>
1 parent 92237dd commit 66c1411

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

internal/daemon/systemd.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,17 @@ func (s *systemd) Create(config *DaemonConfig, force bool) error {
8282
}
8383

8484
func (s *systemd) Start(label string) error {
85-
return fmt.Errorf("not implemented")
85+
// TODO: warn user if already running
86+
exitCode, err := s.cmdExec.Run("systemctl", "--user", "start", label)
87+
if err != nil {
88+
return err
89+
}
90+
91+
if exitCode != 0 {
92+
return fmt.Errorf("'systemctl stop' exited with status %d", exitCode)
93+
}
94+
95+
return nil
8696
}
8797

8898
func (s *systemd) Stop(label string) error {

internal/daemon/systemd_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,3 +162,45 @@ func TestSystemd_Create(t *testing.T) {
162162
assert.Contains(t, fileContents, fmt.Sprintf("Description=%s", basicDaemonConfig.Description))
163163
})
164164
}
165+
166+
func TestSystemd_Start(t *testing.T) {
167+
// Set up mocks
168+
testUser := &user.User{
169+
Uid: "123",
170+
Username: "testuser",
171+
HomeDir: "/my/test/dir",
172+
}
173+
testUserProvider := &mockUserProvider{}
174+
testUserProvider.On("CurrentUser").Return(testUser, nil)
175+
176+
testCommandExecutor := &mockCommandExecutor{}
177+
178+
systemd := daemon.NewSystemdProvider(testUserProvider, testCommandExecutor, nil)
179+
180+
// Test #1: systemctl succeeds
181+
t.Run("Calls correct systemctl command", func(t *testing.T) {
182+
testCommandExecutor.On("Run",
183+
"systemctl",
184+
[]string{"--user", "start", basicDaemonConfig.Label},
185+
).Return(0, nil).Once()
186+
187+
err := systemd.Start(basicDaemonConfig.Label)
188+
assert.Nil(t, err)
189+
mock.AssertExpectationsForObjects(t, testCommandExecutor)
190+
})
191+
192+
// Reset the mock structure between tests
193+
testCommandExecutor.Mock = mock.Mock{}
194+
195+
// Test #2: systemctl fails
196+
t.Run("Returns error when systemctl fails", func(t *testing.T) {
197+
testCommandExecutor.On("Run",
198+
mock.AnythingOfType("string"),
199+
mock.AnythingOfType("[]string"),
200+
).Return(1, nil).Once()
201+
202+
err := systemd.Start(basicDaemonConfig.Label)
203+
assert.NotNil(t, err)
204+
mock.AssertExpectationsForObjects(t, testCommandExecutor)
205+
})
206+
}

0 commit comments

Comments
 (0)