1package container
2
3import (
4 "testing"
5
6 "github.com/stretchr/testify/assert"
7 "github.com/stretchr/testify/require"
8 "go.uber.org/mock/gomock"
9
10 "gordon/internal/config"
11 "gordon/internal/testutils"
12 "gordon/internal/testutils/mocks"
13 "gordon/pkg/runtime"
14)
15
16func TestManager_GetContainer(t *testing.T) {
17 container := &runtime.Container{
18 ID: "test123",
19 Name: "test-container",
20 }
21
22 manager := &Manager{
23 containers: map[string]*runtime.Container{
24 "test.example.com": container,
25 },
26 }
27
28 // Test existing container
29 found, exists := manager.GetContainer("test.example.com")
30 assert.True(t, exists)
31 assert.Equal(t, container, found)
32
33 // Test non-existent container
34 notFound, exists := manager.GetContainer("nonexistent.example.com")
35 assert.False(t, exists)
36 assert.Nil(t, notFound)
37}
38
39func TestManager_ListContainers(t *testing.T) {
40 container1 := &runtime.Container{ID: "test1", Name: "container1"}
41 container2 := &runtime.Container{ID: "test2", Name: "container2"}
42
43 manager := &Manager{
44 containers: map[string]*runtime.Container{
45 "app1.example.com": container1,
46 "app2.example.com": container2,
47 },
48 }
49
50 containers := manager.ListContainers()
51
52 assert.Len(t, containers, 2)
53 assert.Contains(t, containers, "app1.example.com")
54 assert.Contains(t, containers, "app2.example.com")
55 assert.Equal(t, container1, containers["app1.example.com"])
56 assert.Equal(t, container2, containers["app2.example.com"])
57}
58
59func TestManager_HealthCheck(t *testing.T) {
60 ctrl := gomock.NewController(t)
61 defer ctrl.Finish()
62
63 ctx := testutils.TestContext(t)
64
65 mockRuntime := mocks.NewMockRuntime(ctrl)
66 mockRuntime.EXPECT().IsContainerRunning(ctx, "container1").Return(true, nil)
67 mockRuntime.EXPECT().IsContainerRunning(ctx, "container2").Return(false, nil)
68
69 manager := &Manager{
70 runtime: mockRuntime,
71 containers: map[string]*runtime.Container{
72 "app1.example.com": {ID: "container1"},
73 "app2.example.com": {ID: "container2"},
74 },
75 }
76
77 health := manager.HealthCheck(ctx)
78
79 assert.Len(t, health, 2)
80 assert.True(t, health["app1.example.com"])
81 assert.False(t, health["app2.example.com"])
82}
83
84func TestManager_GetNetworkForApp(t *testing.T) {
85 manager := &Manager{
86 config: &config.Config{
87 NetworkIsolation: config.NetworkIsolationConfig{
88 Enabled: true,
89 NetworkPrefix: "gordon",
90 },
91 NetworkGroups: map[string][]string{
92 "backend": {"api.example.com", "worker.example.com"},
93 },
94 },
95 }
96
97 // Test app in network group
98 network := manager.GetNetworkForApp("api.example.com")
99 assert.Equal(t, "gordon-backend", network)
100
101 // Test standalone app
102 network = manager.GetNetworkForApp("frontend.example.com")
103 assert.Equal(t, "gordon-frontend-example-com", network)
104
105 // Test disabled network isolation
106 manager.config.NetworkIsolation.Enabled = false
107 network = manager.GetNetworkForApp("test.example.com")
108 assert.Equal(t, "bridge", network)
109}
110
111func TestManager_Runtime(t *testing.T) {
112 ctrl := gomock.NewController(t)
113 defer ctrl.Finish()
114
115 mockRuntime := mocks.NewMockRuntime(ctrl)
116 manager := &Manager{
117 runtime: mockRuntime,
118 }
119
120 result := manager.Runtime()
121 assert.Equal(t, mockRuntime, result)
122}
123
124func TestManager_DeployContainer(t *testing.T) {
125 ctrl := gomock.NewController(t)
126 defer ctrl.Finish()
127
128 ctx := testutils.TestContext(t)
129 mockRuntime := mocks.NewMockRuntime(ctrl)
130
131 cfg := &config.Config{
132 Server: config.ServerConfig{
133 Runtime: "docker",
134 },
135 Volumes: config.VolumeConfig{
136 AutoCreate: true,
137 Prefix: "gordon",
138 Preserve: false,
139 },
140 NetworkIsolation: config.NetworkIsolationConfig{
141 Enabled: true,
142 NetworkPrefix: "gordon",
143 },
144 }
145
146 manager, err := NewManagerWithRuntime(cfg, mockRuntime)
147 require.NoError(t, err)
148
149 route := config.Route{
150 Domain: "test.example.com",
151 Image: "nginx:latest",
152 }
153
154 // Set up expectations for successful deployment
155 mockRuntime.EXPECT().ListContainers(ctx, true).Return([]*runtime.Container{}, nil)
156 mockRuntime.EXPECT().ListImages(ctx).Return([]string{"nginx:latest"}, nil)
157 mockRuntime.EXPECT().GetImageExposedPorts(ctx, "nginx:latest").Return([]int{80}, nil)
158 mockRuntime.EXPECT().InspectImageEnv(ctx, "nginx:latest").Return([]string{"PATH=/usr/local/sbin:/usr/local/bin"}, nil)
159 mockRuntime.EXPECT().InspectImageVolumes(ctx, "nginx:latest").Return([]string{"/var/log/nginx"}, nil)
160 varLogNginxVolume := generateVolumeName("gordon", "test.example.com", "/var/log/nginx")
161 mockRuntime.EXPECT().VolumeExists(ctx, varLogNginxVolume).Return(false, nil)
162 mockRuntime.EXPECT().CreateVolume(ctx, varLogNginxVolume).Return(nil)
163 mockRuntime.EXPECT().NetworkExists(ctx, "gordon-test-example-com").Return(false, nil)
164 mockRuntime.EXPECT().CreateNetwork(ctx, "gordon-test-example-com", gomock.Any()).Return(nil)
165
166 expectedContainer := &runtime.Container{
167 ID: "container123",
168 Name: "gordon-test.example.com",
169 Image: "nginx:latest",
170 Status: "running",
171 Ports: []int{80},
172 }
173
174 mockRuntime.EXPECT().CreateContainer(ctx, gomock.Any()).Return(expectedContainer, nil)
175 mockRuntime.EXPECT().StartContainer(ctx, "container123").Return(nil)
176 mockRuntime.EXPECT().InspectContainer(ctx, "container123").Return(expectedContainer, nil)
177
178 container, err := manager.DeployContainer(ctx, route)
179
180 assert.NoError(t, err)
181 assert.Equal(t, expectedContainer, container)
182 assert.Equal(t, expectedContainer, manager.containers["test.example.com"])
183}