-
-
Notifications
You must be signed in to change notification settings - Fork 580
/
router_test.go
279 lines (233 loc) · 8.99 KB
/
router_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
package ddevapp_test
import (
"os"
"path/filepath"
"strconv"
"strings"
"testing"
"github.com/ddev/ddev/pkg/ddevapp"
"github.com/ddev/ddev/pkg/dockerutil"
"github.com/ddev/ddev/pkg/exec"
"github.com/ddev/ddev/pkg/fileutil"
"github.com/ddev/ddev/pkg/globalconfig"
"github.com/ddev/ddev/pkg/netutil"
"github.com/ddev/ddev/pkg/nodeps"
"github.com/ddev/ddev/pkg/testcommon"
asrt "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// TestGlobalPortOverride tests global router_http_port and router_https_port
func TestGlobalPortOverride(t *testing.T) {
assert := asrt.New(t)
origGlobalHTTPPort := globalconfig.DdevGlobalConfig.RouterHTTPPort
origGlobalHTTPSPort := globalconfig.DdevGlobalConfig.RouterHTTPSPort
globalconfig.DdevGlobalConfig.RouterHTTPPort = "8553"
globalconfig.DdevGlobalConfig.RouterHTTPSPort = "8554"
site := TestSites[0]
app, err := ddevapp.NewApp(site.Dir, false)
require.NoError(t, err)
t.Cleanup(func() {
err = app.Stop(true, false)
assert.NoError(err)
globalconfig.DdevGlobalConfig.RouterHTTPPort = origGlobalHTTPPort
globalconfig.DdevGlobalConfig.RouterHTTPSPort = origGlobalHTTPSPort
err := globalconfig.WriteGlobalConfig(globalconfig.DdevGlobalConfig)
assert.NoError(err)
})
err = app.Restart()
require.NoError(t, err)
require.Equal(t, globalconfig.DdevGlobalConfig.RouterHTTPPort, app.GetRouterHTTPPort())
require.Equal(t, globalconfig.DdevGlobalConfig.RouterHTTPSPort, app.GetRouterHTTPSPort())
desc, err := app.Describe(false)
require.NoError(t, err)
require.Equal(t, globalconfig.DdevGlobalConfig.RouterHTTPPort, desc["router_http_port"])
require.Equal(t, globalconfig.DdevGlobalConfig.RouterHTTPSPort, desc["router_https_port"])
}
// TestProjectPortOverride makes sure that the project-level
// router_http_port and router_https_port
// port overrides work correctly.
// It starts up three DDEV projects, looks to see if the config is set right,
// then tests to see that the right ports have been started up on the router.
func TestProjectPortOverride(t *testing.T) {
assert := asrt.New(t)
origDir, _ := os.Getwd()
// Try some different combinations of ports. The first (offset 0) will
// share ports with already-started test sites.
for i := 0; i < 3; i++ {
testDir := testcommon.CreateTmpDir("TestProjectPortOverride")
t.Cleanup(func() {
err := os.Chdir(origDir)
assert.NoError(err)
_ = os.RemoveAll(testDir)
})
testcommon.ClearDockerEnv()
app, err := ddevapp.NewApp(testDir, true)
assert.NoError(err)
app.RouterHTTPPort = strconv.Itoa(80 + i)
// Note that we start with port 453 instead of 443 here because Windows
// by default has port 445 occupied by NetBT (Netbios over TCP)
// So the test will fail because of that.
app.RouterHTTPSPort = strconv.Itoa(453 + i)
app.Name = "TestProjectPortOverride-" + strconv.Itoa(i)
app.Type = nodeps.AppTypePHP
err = app.WriteConfig()
assert.NoError(err)
_, err = app.ReadConfig(false)
assert.NoError(err)
stringFound, err := fileutil.FgrepStringInFile(app.ConfigPath, "router_http_port: \""+app.RouterHTTPPort+"\"")
assert.NoError(err)
assert.True(stringFound)
stringFound, err = fileutil.FgrepStringInFile(app.ConfigPath, "router_https_port: \""+app.RouterHTTPSPort+"\"")
assert.NoError(err)
assert.True(stringFound)
// These ports will already be active if on the standard port, because
// the TestMain has started stuff up on the standard ports.
if i != 0 {
assert.False(netutil.IsPortActive(app.RouterHTTPPort))
assert.False(netutil.IsPortActive(app.RouterHTTPSPort))
}
err = app.Start()
require.NoError(t, err)
// defer the app.Stop() so we have a more diverse set of tests. If we brought
// each down before testing the next that would be a more trivial test.
// Don't worry about the possible error case as this is a test cleanup
t.Cleanup(func() {
err = app.Stop(true, false)
assert.NoError(err)
})
assert.True(netutil.IsPortActive(app.RouterHTTPPort), "port "+app.RouterHTTPPort+" should be active")
assert.True(netutil.IsPortActive(app.RouterHTTPSPort), "port "+app.RouterHTTPSPort+" should be active")
}
}
// Do a modest test of Lets Encrypt functionality
// This checks to see that Certbot ran and populated /etc/letsencrypt and
// that /etc/letsencrypt is mounted on volume.
func TestLetsEncrypt(t *testing.T) {
if globalconfig.DdevGlobalConfig.IsTraefikRouter() {
t.Skip("Skipping because router=traefik set and not yet supported")
}
assert := asrt.New(t)
savedGlobalconfig := globalconfig.DdevGlobalConfig
globalconfig.DdevGlobalConfig.UseLetsEncrypt = true
globalconfig.DdevGlobalConfig.LetsEncryptEmail = "nobody@example.com"
globalconfig.DdevGlobalConfig.RouterBindAllInterfaces = true
err := globalconfig.WriteGlobalConfig(globalconfig.DdevGlobalConfig)
require.NoError(t, err)
site := TestSites[0]
switchDir := site.Chdir()
defer switchDir()
// Force router stop so it will start up with Lets Encrypt mount
dest := ddevapp.RouterComposeYAMLPath()
_, _, err = dockerutil.ComposeCmd(&dockerutil.ComposeCmdOpts{
ComposeFiles: []string{dest},
Action: []string{"-p", ddevapp.RouterProjectName, "down"},
})
assert.NoError(err)
err = dockerutil.RemoveVolume("ddev-router-letsencrypt")
assert.NoError(err)
app, err := ddevapp.NewApp(site.Dir, false)
assert.NoError(err)
err = app.Start()
assert.NoError(err)
t.Cleanup(func() {
globalconfig.DdevGlobalConfig = savedGlobalconfig
err = globalconfig.WriteGlobalConfig(globalconfig.DdevGlobalConfig)
assert.NoError(err)
_, _, err = dockerutil.ComposeCmd(&dockerutil.ComposeCmdOpts{
ComposeFiles: []string{dest},
Action: []string{"-p", ddevapp.RouterProjectName, "down"},
})
assert.NoError(err)
err = app.Stop(true, false)
assert.NoError(err)
err = dockerutil.RemoveVolume("ddev-router-letsencrypt")
assert.NoError(err)
})
container, err := dockerutil.FindContainerByName("ddev-router")
require.NoError(t, err)
require.NotNil(t, container)
stdout, _, err := dockerutil.Exec(container.ID, "df -T /etc/letsencrypt | awk 'NR==2 {print $7;}'", "")
assert.NoError(err)
stdout = strings.Trim(stdout, "\r\n")
assert.Equal("/etc/letsencrypt", stdout)
_, _, err = dockerutil.Exec(container.ID, "test -f /etc/letsencrypt/options-ssl-nginx.conf", "")
assert.NoError(err)
}
// TestRouterConfigOverride tests that the ~/.ddev/.router-compose.yaml can be overridden
// with ~/.ddev/router-compose.*.yaml
func TestRouterConfigOverride(t *testing.T) {
assert := asrt.New(t)
origDir, _ := os.Getwd()
testDir := testcommon.CreateTmpDir(t.Name())
_ = os.Chdir(testDir)
overrideYaml := filepath.Join(globalconfig.GetGlobalDdevDir(), "router-compose.override.yaml")
testcommon.ClearDockerEnv()
app, err := ddevapp.NewApp(testDir, true)
assert.NoError(err)
err = app.WriteConfig()
assert.NoError(err)
err = fileutil.CopyFile(filepath.Join(origDir, "testdata", t.Name(), "router-compose.override.yaml"), overrideYaml)
assert.NoError(err)
answer := fileutil.RandomFilenameBase()
t.Setenv("ANSWER", answer)
assert.NoError(err)
t.Cleanup(func() {
err = app.Stop(true, false)
assert.NoError(err)
err = os.Chdir(origDir)
assert.NoError(err)
_ = os.RemoveAll(testDir)
_ = os.Remove(overrideYaml)
})
err = app.Start()
assert.NoError(err)
stdout, _, err := dockerutil.Exec("ddev-router", "bash -c 'echo $ANSWER'", "")
assert.Equal(answer+"\n", stdout)
}
// TestDisableHTTP2 tests we can enable or disable http2
func TestDisableHTTP2(t *testing.T) {
if nodeps.IsAppleSilicon() {
t.Skip("Skipping on mac M1 to ignore problems with 'connection reset by peer'")
}
if globalconfig.GetCAROOT() == "" {
t.Skip("Skipping because mkcert/http not enabled")
}
if globalconfig.DdevGlobalConfig.IsTraefikRouter() {
t.Skip("Skipping because router=traefik doesn't have feature to turn off http/2")
}
assert := asrt.New(t)
pwd, _ := os.Getwd()
testDir := testcommon.CreateTmpDir(t.Name())
_ = os.Chdir(testDir)
err := os.WriteFile("index.html", []byte("hello from the test"), 0644)
assert.NoError(err)
testcommon.ClearDockerEnv()
_, err = exec.RunCommand(DdevBin, []string{"poweroff"})
require.NoError(t, err)
app, err := ddevapp.NewApp(testDir, true)
assert.NoError(err)
err = app.WriteConfig()
assert.NoError(err)
t.Cleanup(func() {
globalconfig.DdevGlobalConfig.DisableHTTP2 = false
err = app.Stop(true, false)
assert.NoError(err)
err = os.Chdir(pwd)
assert.NoError(err)
_ = os.RemoveAll(testDir)
assert.NoError(err)
})
err = app.Start()
assert.NoError(err)
// Verify that http2 is on by default
out, err := exec.RunCommand("bash", []string{"-c", "curl -k -s -L -I " + app.GetPrimaryURL() + "| head -1"})
assert.NoError(err, "failed to curl, err=%v out=%v", err, out)
assert.Equal("HTTP/2 200 \r\n", out)
// Now turn it off and verify
globalconfig.DdevGlobalConfig.DisableHTTP2 = true
err = app.Start()
assert.NoError(err)
out, err = exec.RunCommand("bash", []string{"-c", "curl -k -s -L -I " + app.GetPrimaryURL() + "| head -1"})
assert.NoError(err, "failed to curl, err=%v out=%v", err, out)
assert.Equal("HTTP/1.1 200 OK\r\n", out)
}