v2.0.0 ae3e752

manager_test.go RawHistoryFolder

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}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close