Shuffle test files before insertion
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 10 Feb 2020 11:03:41 +0000 (12:03 +0100)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 10 Feb 2020 11:03:41 +0000 (12:03 +0100)
hugolib/testhelpers_test.go

index 7a87245a6bf760ecccb43c930861d6e49e48b8d3..f43ac69074cffdaab9cbda1719f6280bb619e82e 100644 (file)
@@ -3,10 +3,12 @@ package hugolib
 import (
        "image/jpeg"
        "io"
+       "math/rand"
        "path/filepath"
        "runtime"
        "strconv"
        "testing"
+       "time"
        "unicode/utf8"
 
        "github.com/gohugoio/hugo/output"
@@ -63,7 +65,7 @@ type sitesBuilder struct {
        *qt.C
 
        logger *loggers.Logger
-
+       rnd    *rand.Rand
        dumper litter.Options
 
        // Used to test partial rebuilds.
@@ -89,17 +91,22 @@ type sitesBuilder struct {
 
        addNothing bool
        // Base data/content
-       contentFilePairs  []string
-       templateFilePairs []string
-       i18nFilePairs     []string
-       dataFilePairs     []string
+       contentFilePairs  []filenameContent
+       templateFilePairs []filenameContent
+       i18nFilePairs     []filenameContent
+       dataFilePairs     []filenameContent
 
        // Additional data/content.
        // As in "use the base, but add these on top".
-       contentFilePairsAdded  []string
-       templateFilePairsAdded []string
-       i18nFilePairsAdded     []string
-       dataFilePairsAdded     []string
+       contentFilePairsAdded  []filenameContent
+       templateFilePairsAdded []filenameContent
+       i18nFilePairsAdded     []filenameContent
+       dataFilePairsAdded     []filenameContent
+}
+
+type filenameContent struct {
+       filename string
+       content  string
 }
 
 func newTestSitesBuilder(t testing.TB) *sitesBuilder {
@@ -112,7 +119,8 @@ func newTestSitesBuilder(t testing.TB) *sitesBuilder {
                Separator:         " ",
        }
 
-       return &sitesBuilder{T: t, C: qt.New(t), Fs: fs, configFormat: "toml", dumper: litterOptions}
+       return &sitesBuilder{T: t, C: qt.New(t), Fs: fs, configFormat: "toml",
+               dumper: litterOptions, rnd: rand.New(rand.NewSource(time.Now().Unix()))}
 }
 
 func newTestSitesBuilderFromDepsCfg(t testing.TB, d deps.DepsCfg) *sitesBuilder {
@@ -124,7 +132,7 @@ func newTestSitesBuilderFromDepsCfg(t testing.TB, d deps.DepsCfg) *sitesBuilder
                Separator:         " ",
        }
 
-       b := &sitesBuilder{T: t, C: c, depsCfg: d, Fs: d.Fs, dumper: litterOptions}
+       b := &sitesBuilder{T: t, C: c, depsCfg: d, Fs: d.Fs, dumper: litterOptions, rnd: rand.New(rand.NewSource(time.Now().Unix()))}
        workingDir := d.Cfg.GetString("workingDir")
 
        b.WithWorkingDir(workingDir)
@@ -349,43 +357,62 @@ func (s *sitesBuilder) WithSunset(in string) {
        src.Close()
 }
 
+func (s *sitesBuilder) createFilenameContent(pairs []string) []filenameContent {
+       var slice []filenameContent
+       s.appendFilenameContent(&slice, pairs...)
+       return slice
+}
+
+func (s *sitesBuilder) appendFilenameContent(slice *[]filenameContent, pairs ...string) {
+       if len(pairs)%2 != 0 {
+               panic("file content mismatch")
+       }
+       for i := 0; i < len(pairs); i += 2 {
+               c := filenameContent{
+                       filename: pairs[i],
+                       content:  pairs[i+1],
+               }
+               *slice = append(*slice, c)
+       }
+}
+
 func (s *sitesBuilder) WithContent(filenameContent ...string) *sitesBuilder {
-       s.contentFilePairs = append(s.contentFilePairs, filenameContent...)
+       s.appendFilenameContent(&s.contentFilePairs, filenameContent...)
        return s
 }
 
 func (s *sitesBuilder) WithContentAdded(filenameContent ...string) *sitesBuilder {
-       s.contentFilePairsAdded = append(s.contentFilePairsAdded, filenameContent...)
+       s.appendFilenameContent(&s.contentFilePairsAdded, filenameContent...)
        return s
 }
 
 func (s *sitesBuilder) WithTemplates(filenameContent ...string) *sitesBuilder {
-       s.templateFilePairs = append(s.templateFilePairs, filenameContent...)
+       s.appendFilenameContent(&s.templateFilePairs, filenameContent...)
        return s
 }
 
 func (s *sitesBuilder) WithTemplatesAdded(filenameContent ...string) *sitesBuilder {
-       s.templateFilePairsAdded = append(s.templateFilePairsAdded, filenameContent...)
+       s.appendFilenameContent(&s.templateFilePairsAdded, filenameContent...)
        return s
 }
 
 func (s *sitesBuilder) WithData(filenameContent ...string) *sitesBuilder {
-       s.dataFilePairs = append(s.dataFilePairs, filenameContent...)
+       s.appendFilenameContent(&s.dataFilePairs, filenameContent...)
        return s
 }
 
 func (s *sitesBuilder) WithDataAdded(filenameContent ...string) *sitesBuilder {
-       s.dataFilePairsAdded = append(s.dataFilePairsAdded, filenameContent...)
+       s.appendFilenameContent(&s.dataFilePairsAdded, filenameContent...)
        return s
 }
 
 func (s *sitesBuilder) WithI18n(filenameContent ...string) *sitesBuilder {
-       s.i18nFilePairs = append(s.i18nFilePairs, filenameContent...)
+       s.appendFilenameContent(&s.i18nFilePairs, filenameContent...)
        return s
 }
 
 func (s *sitesBuilder) WithI18nAdded(filenameContent ...string) *sitesBuilder {
-       s.i18nFilePairsAdded = append(s.i18nFilePairsAdded, filenameContent...)
+       s.appendFilenameContent(&s.i18nFilePairsAdded, filenameContent...)
        return s
 }
 
@@ -409,15 +436,17 @@ func (s *sitesBuilder) RemoveFiles(filenames ...string) *sitesBuilder {
        return s
 }
 
-func (s *sitesBuilder) writeFilePairs(folder string, filenameContent []string) *sitesBuilder {
-       if len(filenameContent)%2 != 0 {
-               s.Fatalf("expect filenameContent for %q in pairs (%d)", folder, len(filenameContent))
-       }
-       for i := 0; i < len(filenameContent); i += 2 {
-               filename, content := filenameContent[i], filenameContent[i+1]
+func (s *sitesBuilder) writeFilePairs(folder string, files []filenameContent) *sitesBuilder {
+       // We have had some "filesystem ordering" bugs that we have not discovered in
+       // our tests running with the in memory filesystem.
+       // That file system is backed by a map so not sure how this helps, but some
+       // randomness in tests doesn't hurt.
+       s.rnd.Shuffle(len(files), func(i, j int) { files[i], files[j] = files[j], files[i] })
+
+       for _, fc := range files {
                target := folder
                // TODO(bep) clean  up this magic.
-               if strings.HasPrefix(filename, folder) {
+               if strings.HasPrefix(fc.filename, folder) {
                        target = ""
                }
 
@@ -425,7 +454,7 @@ func (s *sitesBuilder) writeFilePairs(folder string, filenameContent []string) *
                        target = filepath.Join(s.workingDir, target)
                }
 
-               writeSource(s.T, s.Fs, filepath.Join(target, filename), content)
+               writeSource(s.T, s.Fs, filepath.Join(target, fc.filename), fc.content)
        }
        return s
 }
@@ -640,16 +669,17 @@ hello:
        )
 
        if len(s.contentFilePairs) == 0 {
-               s.writeFilePairs("content", defaultContent)
+               s.writeFilePairs("content", s.createFilenameContent(defaultContent))
        }
+
        if len(s.templateFilePairs) == 0 {
-               s.writeFilePairs("layouts", defaultTemplates)
+               s.writeFilePairs("layouts", s.createFilenameContent(defaultTemplates))
        }
        if len(s.dataFilePairs) == 0 {
-               s.writeFilePairs("data", defaultData)
+               s.writeFilePairs("data", s.createFilenameContent(defaultData))
        }
        if len(s.i18nFilePairs) == 0 {
-               s.writeFilePairs("i18n", defaultI18n)
+               s.writeFilePairs("i18n", s.createFilenameContent(defaultI18n))
        }
 }