server: Fix multihost crash

As introduced in v0.99.0.

Fixes #9901
This commit is contained in:
Bjørn Erik Pedersen 2022-05-18 09:47:55 +02:00
parent 3a8189ee93
commit 2f9eac480f
2 changed files with 56 additions and 21 deletions

View file

@ -168,6 +168,14 @@ func (sc *serverCmd) server(cmd *cobra.Command, args []string) error {
c.Set("watch", true) c.Set("watch", true)
} }
// TODO(bep) see issue 9901
// cfgInit is called twice, before and after the languages have been initialized.
// The servers (below) can not be initialized before we
// know if we're configured in a multihost setup.
if len(c.languages) == 0 {
return nil
}
// We can only do this once. // We can only do this once.
serverCfgInit.Do(func() { serverCfgInit.Do(func() {
c.serverPorts = make([]serverPortListener, 1) c.serverPorts = make([]serverPortListener, 1)

View file

@ -41,7 +41,7 @@ func TestServerPanicOnConfigError(t *testing.T) {
linenos='table' linenos='table'
` `
r := runServerTest(c, false, config) r := runServerTest(c, 0, config)
c.Assert(r.err, qt.IsNotNil) c.Assert(r.err, qt.IsNotNil)
c.Assert(r.err.Error(), qt.Contains, "cannot parse 'Highlight.LineNos' as bool:") c.Assert(r.err.Error(), qt.Contains, "cannot parse 'Highlight.LineNos' as bool:")
@ -52,7 +52,7 @@ func TestServerFlags(t *testing.T) {
assertPublic := func(c *qt.C, r serverTestResult, renderStaticToDisk bool) { assertPublic := func(c *qt.C, r serverTestResult, renderStaticToDisk bool) {
c.Assert(r.err, qt.IsNil) c.Assert(r.err, qt.IsNil)
c.Assert(r.homeContent, qt.Contains, "Environment: development") c.Assert(r.homesContent[0], qt.Contains, "Environment: development")
c.Assert(r.publicDirnames["myfile.txt"], qt.Equals, renderStaticToDisk) c.Assert(r.publicDirnames["myfile.txt"], qt.Equals, renderStaticToDisk)
} }
@ -81,7 +81,7 @@ baseURL="https://example.org"
args = strings.Split(test.flag, "=") args = strings.Split(test.flag, "=")
} }
r := runServerTest(c, true, config, args...) r := runServerTest(c, 1, config, args...)
test.assert(c, r) test.assert(c, r)
@ -96,29 +96,51 @@ func TestServerBugs(t *testing.T) {
for _, test := range []struct { for _, test := range []struct {
name string name string
config string
flag string flag string
numservers int
assert func(c *qt.C, r serverTestResult) assert func(c *qt.C, r serverTestResult)
}{ }{
// Issue 9788 // Issue 9788
{"PostProcess, memory", "", func(c *qt.C, r serverTestResult) { {"PostProcess, memory", "", "", 1, func(c *qt.C, r serverTestResult) {
c.Assert(r.err, qt.IsNil) c.Assert(r.err, qt.IsNil)
c.Assert(r.homeContent, qt.Contains, "PostProcess: /foo.min.css") c.Assert(r.homesContent[0], qt.Contains, "PostProcess: /foo.min.css")
}}, }},
{"PostProcess, disk", "--renderToDisk", func(c *qt.C, r serverTestResult) { {"PostProcess, disk", "", "--renderToDisk", 1, func(c *qt.C, r serverTestResult) {
c.Assert(r.err, qt.IsNil) c.Assert(r.err, qt.IsNil)
c.Assert(r.homeContent, qt.Contains, "PostProcess: /foo.min.css") c.Assert(r.homesContent[0], qt.Contains, "PostProcess: /foo.min.css")
}},
// Isue 9901
{"Multihost", `
defaultContentLanguage = 'en'
[languages]
[languages.en]
baseURL = 'https://example.com'
title = 'My blog'
weight = 1
[languages.fr]
baseURL = 'https://example.fr'
title = 'Mon blogue'
weight = 2
`, "", 2, func(c *qt.C, r serverTestResult) {
c.Assert(r.err, qt.IsNil)
for i, s := range []string{"My blog", "Mon blogue"} {
c.Assert(r.homesContent[i], qt.Contains, s)
}
}}, }},
} { } {
c.Run(test.name, func(c *qt.C) { c.Run(test.name, func(c *qt.C) {
config := ` if test.config == "" {
test.config = `
baseURL="https://example.org" baseURL="https://example.org"
` `
}
var args []string var args []string
if test.flag != "" { if test.flag != "" {
args = strings.Split(test.flag, "=") args = strings.Split(test.flag, "=")
} }
r := runServerTest(c, true, config, args...) r := runServerTest(c, test.numservers, test.config, args...)
test.assert(c, r) test.assert(c, r)
}) })
@ -129,11 +151,11 @@ baseURL="https://example.org"
type serverTestResult struct { type serverTestResult struct {
err error err error
homeContent string homesContent []string
publicDirnames map[string]bool publicDirnames map[string]bool
} }
func runServerTest(c *qt.C, getHome bool, config string, args ...string) (result serverTestResult) { func runServerTest(c *qt.C, getNumHomes int, config string, args ...string) (result serverTestResult) {
dir := createSimpleTestSite(c, testSiteConfig{configTOML: config}) dir := createSimpleTestSite(c, testSiteConfig{configTOML: config})
sp, err := helpers.FindAvailablePort() sp, err := helpers.FindAvailablePort()
@ -162,16 +184,21 @@ func runServerTest(c *qt.C, getHome bool, config string, args ...string) (result
return err return err
}) })
if getHome { if getNumHomes > 0 {
// Esp. on slow CI machines, we need to wait a little before the web // Esp. on slow CI machines, we need to wait a little before the web
// server is ready. // server is ready.
time.Sleep(567 * time.Millisecond) time.Sleep(567 * time.Millisecond)
resp, err := http.Get(fmt.Sprintf("http://localhost:%d/", port)) result.homesContent = make([]string, getNumHomes)
for i := 0; i < getNumHomes; i++ {
func() {
resp, err := http.Get(fmt.Sprintf("http://localhost:%d/", port+i))
c.Check(err, qt.IsNil) c.Check(err, qt.IsNil)
c.Check(resp.StatusCode, qt.Equals, http.StatusOK) c.Check(resp.StatusCode, qt.Equals, http.StatusOK)
if err == nil { if err == nil {
defer resp.Body.Close() defer resp.Body.Close()
result.homeContent = helpers.ReaderToString(resp.Body) result.homesContent[i] = helpers.ReaderToString(resp.Body)
}
}()
} }
} }