Skip to content

Commit ee0bc42

Browse files
committed
fix: Simulate rsync correctly
1 parent f4beb64 commit ee0bc42

File tree

2 files changed

+62
-19
lines changed

2 files changed

+62
-19
lines changed

backup/internal/job.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"strings"
88
)
99

10+
var execCommand = exec.Command
11+
1012
func buildRsyncCmd(job Job, simulate bool) *exec.Cmd {
1113
args := []string{"-aiv", "--info=progress2"}
1214
if job.Delete == nil || *job.Delete {
@@ -19,7 +21,7 @@ func buildRsyncCmd(job Job, simulate bool) *exec.Cmd {
1921
if simulate {
2022
args = append([]string{"--dry-run"}, args...)
2123
}
22-
return exec.Command("rsync", args...)
24+
return execCommand("rsync", args...)
2325
}
2426

2527
func ExecuteJob(job Job, simulate bool, logger *log.Logger) string {
@@ -31,13 +33,11 @@ func ExecuteJob(job Job, simulate bool, logger *log.Logger) string {
3133
cmd := buildRsyncCmd(job, simulate)
3234
fmt.Printf("Job: %s\n", job.Name)
3335
fmt.Printf("Command: %s\n", strings.Join(cmd.Args, " "))
34-
if !simulate {
35-
out, err := cmd.CombinedOutput()
36-
if err != nil {
37-
logger.Printf("ERROR [%s]: %v\nOutput: %s", job.Name, err, string(out))
38-
return "FAILURE"
39-
}
40-
logger.Printf("SUCCESS [%s]: %s", job.Name, string(out))
36+
out, err := cmd.CombinedOutput()
37+
if err != nil {
38+
logger.Printf("ERROR [%s]: %v\nOutput: %s", job.Name, err, string(out))
39+
return "FAILURE"
4140
}
41+
logger.Printf("SUCCESS [%s]: %s", job.Name, string(out))
4242
return "SUCCESS"
4343
}

backup/internal/job_test.go

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package internal
33
import (
44
"bytes"
55
"log"
6+
"os/exec"
67
"strings"
78
"testing"
89
)
@@ -12,15 +13,36 @@ func boolPtr(b bool) *bool {
1213
return &b
1314
}
1415

16+
var capturedArgs []string
17+
18+
var mockExecCommand = func(name string, args ...string) *exec.Cmd {
19+
capturedArgs = args // Capture arguments for assertions
20+
if name == "rsync" {
21+
if strings.Contains(strings.Join(args, " "), "/invalid/source/path") {
22+
cmd := exec.Command("false") // Simulate failure for invalid paths
23+
cmd.Args = append([]string{name}, args...)
24+
return cmd
25+
}
26+
cmd := exec.Command("echo")
27+
cmd.Args = append([]string{name}, args...)
28+
return cmd
29+
}
30+
return exec.Command(name, args...)
31+
}
32+
33+
func init() {
34+
execCommand = mockExecCommand
35+
}
36+
1537
func TestBuildRsyncCmd(t *testing.T) {
1638
job := Job{
1739
Source: "/home/user/Music/",
1840
Target: "/target/user/music/home",
1941
Delete: nil,
2042
Exclusions: []string{"*.tmp", "node_modules/"},
2143
}
22-
dryRun := true
23-
cmd := buildRsyncCmd(job, dryRun)
44+
simulate := true
45+
cmd := buildRsyncCmd(job, simulate)
2446

2547
expectedArgs := []string{
2648
"rsync", "--dry-run", "-aiv", "--info=progress2", "--delete",
@@ -41,10 +63,10 @@ func TestExecuteJob(t *testing.T) {
4163
Delete: nil,
4264
Exclusions: []string{"*.tmp"},
4365
}
44-
dryRun := true
66+
simulate := true
4567
logger := log.New(&bytes.Buffer{}, "", log.LstdFlags)
4668

47-
status := ExecuteJob(job, dryRun, logger)
69+
status := ExecuteJob(job, simulate, logger)
4870
if status != "SUCCESS" {
4971
t.Errorf("Expected status SUCCESS, got %s", status)
5072
}
@@ -56,7 +78,7 @@ func TestExecuteJob(t *testing.T) {
5678
Enabled: boolPtr(false),
5779
}
5880

59-
status = ExecuteJob(disabledJob, dryRun, logger)
81+
status = ExecuteJob(disabledJob, simulate, logger)
6082
if status != "SKIPPED" {
6183
t.Errorf("Expected status SKIPPED, got %s", status)
6284
}
@@ -81,10 +103,10 @@ func TestJobSkippedEnabledTrue(t *testing.T) {
81103
Target: "/mnt/backup1/test/",
82104
Enabled: boolPtr(true),
83105
}
84-
dryRun := true
106+
simulate := true
85107
logger := log.New(&bytes.Buffer{}, "", log.LstdFlags)
86108

87-
status := ExecuteJob(job, dryRun, logger)
109+
status := ExecuteJob(job, simulate, logger)
88110
if status != "SUCCESS" {
89111
t.Errorf("Expected status SUCCESS, got %s", status)
90112
}
@@ -97,10 +119,10 @@ func TestJobSkippedEnabledFalse(t *testing.T) {
97119
Target: "/mnt/backup1/disabled/",
98120
Enabled: boolPtr(false),
99121
}
100-
dryRun := true
122+
simulate := true
101123
logger := log.New(&bytes.Buffer{}, "", log.LstdFlags)
102124

103-
status := ExecuteJob(disabledJob, dryRun, logger)
125+
status := ExecuteJob(disabledJob, simulate, logger)
104126
if status != "SKIPPED" {
105127
t.Errorf("Expected status SKIPPED, got %s", status)
106128
}
@@ -112,11 +134,32 @@ func TestJobSkippedEnabledOmitted(t *testing.T) {
112134
Source: "/home/omitted/",
113135
Target: "/mnt/backup1/omitted/",
114136
}
115-
dryRun := true
137+
simulate := true
116138
logger := log.New(&bytes.Buffer{}, "", log.LstdFlags)
117139

118-
status := ExecuteJob(job, dryRun, logger)
140+
status := ExecuteJob(job, simulate, logger)
119141
if status != "SUCCESS" {
120142
t.Errorf("Expected status SUCCESS, got %s", status)
121143
}
122144
}
145+
146+
func TestExecuteJobWithMockedRsync(t *testing.T) {
147+
// Reset capturedArgs before the test
148+
capturedArgs = nil
149+
150+
job := Job{
151+
Name: "test_job",
152+
Source: "/home/test/",
153+
Target: "/mnt/backup1/test/",
154+
Delete: nil,
155+
Exclusions: []string{"*.tmp"},
156+
}
157+
simulate := true
158+
logger := log.New(&bytes.Buffer{}, "", log.LstdFlags)
159+
160+
_ = ExecuteJob(job, simulate, logger)
161+
162+
if len(capturedArgs) == 0 || capturedArgs[0] != "--dry-run" {
163+
t.Errorf("Expected --dry-run flag, got %v", capturedArgs)
164+
}
165+
}

0 commit comments

Comments
 (0)