1package volumes
2
3import (
4 "context"
5 "fmt"
6 "testing"
7
8 "github.com/stretchr/testify/assert"
9 "github.com/stretchr/testify/require"
10
11 outmocks "github.com/bnema/gordon/internal/boundaries/out/mocks"
12 "github.com/bnema/gordon/internal/domain"
13)
14
15func TestService_ListVolumes(t *testing.T) {
16 runtime := outmocks.NewMockContainerRuntime(t)
17
18 vols := []*domain.VolumeInfo{
19 {Name: "vol1", InUse: true, Containers: []string{"web"}},
20 {Name: "vol2", InUse: false},
21 }
22 runtime.EXPECT().ListVolumes(context.Background()).Return(vols, nil)
23
24 svc := NewService(runtime)
25 result, err := svc.ListVolumes(context.Background())
26 require.NoError(t, err)
27 assert.Len(t, result, 2)
28}
29
30func TestService_PruneVolumes_RemovesOrphaned(t *testing.T) {
31 runtime := outmocks.NewMockContainerRuntime(t)
32
33 vols := []*domain.VolumeInfo{
34 {Name: "vol-in-use", InUse: true, Containers: []string{"web"}},
35 {Name: "vol-orphaned", InUse: false, Size: 1024},
36 }
37 runtime.EXPECT().ListVolumes(context.Background()).Return(vols, nil)
38 runtime.EXPECT().RemoveVolume(context.Background(), "vol-orphaned", false).Return(nil)
39
40 svc := NewService(runtime)
41 report, removed, err := svc.PruneVolumes(context.Background(), false)
42 require.NoError(t, err)
43 assert.Equal(t, 1, report.VolumesRemoved)
44 assert.Equal(t, int64(1024), report.SpaceReclaimed)
45 assert.Len(t, removed, 1)
46 assert.Equal(t, "vol-orphaned", removed[0].Name)
47}
48
49func TestService_PruneVolumes_DryRunDoesNotRemove(t *testing.T) {
50 runtime := outmocks.NewMockContainerRuntime(t)
51
52 vols := []*domain.VolumeInfo{
53 {Name: "vol-orphaned", InUse: false, Size: 2048},
54 }
55 runtime.EXPECT().ListVolumes(context.Background()).Return(vols, nil)
56
57 svc := NewService(runtime)
58 report, removed, err := svc.PruneVolumes(context.Background(), true)
59 require.NoError(t, err)
60 assert.Equal(t, 1, report.VolumesRemoved)
61 assert.Equal(t, int64(2048), report.SpaceReclaimed)
62 assert.Len(t, removed, 1)
63}
64
65func TestService_PruneVolumes_AllInUse(t *testing.T) {
66 runtime := outmocks.NewMockContainerRuntime(t)
67
68 vols := []*domain.VolumeInfo{
69 {Name: "vol1", InUse: true, Containers: []string{"web"}},
70 }
71 runtime.EXPECT().ListVolumes(context.Background()).Return(vols, nil)
72
73 svc := NewService(runtime)
74 report, removed, err := svc.PruneVolumes(context.Background(), false)
75 require.NoError(t, err)
76 assert.Equal(t, 0, report.VolumesRemoved)
77 assert.Empty(t, removed)
78}
79
80func TestService_ListVolumes_PropagatesError(t *testing.T) {
81 runtime := outmocks.NewMockContainerRuntime(t)
82 runtime.EXPECT().ListVolumes(context.Background()).Return(nil, fmt.Errorf("connection refused"))
83
84 svc := NewService(runtime)
85 _, err := svc.ListVolumes(context.Background())
86 require.Error(t, err)
87 assert.Contains(t, err.Error(), "connection refused")
88}
89
90func TestService_PruneVolumes_SkipsFailedRemoval(t *testing.T) {
91 runtime := outmocks.NewMockContainerRuntime(t)
92
93 vols := []*domain.VolumeInfo{
94 {Name: "vol-fail", InUse: false, Size: 1024},
95 {Name: "vol-ok", InUse: false, Size: 2048},
96 }
97 runtime.EXPECT().ListVolumes(context.Background()).Return(vols, nil)
98 runtime.EXPECT().RemoveVolume(context.Background(), "vol-fail", false).Return(fmt.Errorf("volume in use"))
99 runtime.EXPECT().RemoveVolume(context.Background(), "vol-ok", false).Return(nil)
100
101 svc := NewService(runtime)
102 report, removed, err := svc.PruneVolumes(context.Background(), false)
103 require.NoError(t, err)
104 assert.Equal(t, 1, report.VolumesRemoved)
105 assert.Equal(t, int64(2048), report.SpaceReclaimed)
106 assert.Len(t, removed, 1)
107 assert.Equal(t, "vol-ok", removed[0].Name)
108}