mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-07 20:30:36 -05:00
3c29c5af8e
Fixes #5439
217 lines
5.1 KiB
Go
217 lines
5.1 KiB
Go
// Copyright 2018 The Hugo Authors. All rights reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package filecache
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"path/filepath"
|
|
"regexp"
|
|
"strings"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gohugoio/hugo/common/hugio"
|
|
|
|
"github.com/gohugoio/hugo/config"
|
|
"github.com/gohugoio/hugo/hugofs"
|
|
"github.com/gohugoio/hugo/hugolib/paths"
|
|
"github.com/spf13/afero"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestFileCache(t *testing.T) {
|
|
t.Parallel()
|
|
assert := require.New(t)
|
|
|
|
for _, cacheDir := range []string{"mycache", ""} {
|
|
|
|
configStr := `
|
|
workingDir = "/my/work"
|
|
resourceDir = "resources"
|
|
cacheDir = "CACHEDIR"
|
|
[caches]
|
|
[caches.getJSON]
|
|
maxAge = "10h"
|
|
dir = ":cacheDir/c"
|
|
|
|
`
|
|
configStr = strings.Replace(configStr, "CACHEDIR", cacheDir, 1)
|
|
|
|
cfg, err := config.FromConfigString(configStr, "toml")
|
|
assert.NoError(err)
|
|
|
|
fs := hugofs.NewMem(cfg)
|
|
p, err := paths.New(fs, cfg)
|
|
assert.NoError(err)
|
|
|
|
caches, err := NewCachesFromPaths(p)
|
|
assert.NoError(err)
|
|
|
|
c := caches.Get("GetJSON")
|
|
assert.NotNil(c)
|
|
assert.Equal("10h0m0s", c.maxAge.String())
|
|
|
|
bfs, ok := c.Fs.(*afero.BasePathFs)
|
|
assert.True(ok)
|
|
filename, err := bfs.RealPath("key")
|
|
assert.NoError(err)
|
|
if cacheDir != "" {
|
|
assert.Equal(filepath.FromSlash(cacheDir+"/c/"+filecacheRootDirname+"/getjson/key"), filename)
|
|
} else {
|
|
// Temp dir.
|
|
assert.Regexp(regexp.MustCompile(".*hugo_cache.*"+filecacheRootDirname+".*key"), filename)
|
|
}
|
|
|
|
c = caches.Get("images")
|
|
assert.NotNil(c)
|
|
assert.Equal(time.Duration(-1), c.maxAge)
|
|
bfs, ok = c.Fs.(*afero.BasePathFs)
|
|
assert.True(ok)
|
|
filename, _ = bfs.RealPath("key")
|
|
assert.Equal(filepath.FromSlash("/my/work/resources/_gen/images/key"), filename)
|
|
|
|
rf := func(s string) func() (io.ReadCloser, error) {
|
|
return func() (io.ReadCloser, error) {
|
|
return struct {
|
|
io.ReadSeeker
|
|
io.Closer
|
|
}{
|
|
strings.NewReader(s),
|
|
ioutil.NopCloser(nil),
|
|
}, nil
|
|
}
|
|
}
|
|
|
|
bf := func() ([]byte, error) {
|
|
return []byte("bcd"), nil
|
|
}
|
|
|
|
for i := 0; i < 2; i++ {
|
|
info, r, err := c.GetOrCreate("a", rf("abc"))
|
|
assert.NoError(err)
|
|
assert.NotNil(r)
|
|
assert.Equal("a", info.Name)
|
|
b, _ := ioutil.ReadAll(r)
|
|
r.Close()
|
|
assert.Equal("abc", string(b))
|
|
|
|
info, b, err = c.GetOrCreateBytes("b", bf)
|
|
assert.NoError(err)
|
|
assert.NotNil(r)
|
|
assert.Equal("b", info.Name)
|
|
assert.Equal("bcd", string(b))
|
|
|
|
_, b, err = c.GetOrCreateBytes("a", bf)
|
|
assert.NoError(err)
|
|
assert.Equal("abc", string(b))
|
|
|
|
_, r, err = c.GetOrCreate("a", rf("bcd"))
|
|
assert.NoError(err)
|
|
b, _ = ioutil.ReadAll(r)
|
|
r.Close()
|
|
assert.Equal("abc", string(b))
|
|
}
|
|
|
|
assert.NotNil(caches.Get("getJSON"))
|
|
|
|
info, w, err := caches.ImageCache().WriteCloser("mykey")
|
|
assert.NoError(err)
|
|
assert.Equal("mykey", info.Name)
|
|
io.WriteString(w, "Hugo is great!")
|
|
w.Close()
|
|
assert.Equal("Hugo is great!", caches.ImageCache().getString("mykey"))
|
|
|
|
info, r, err := caches.ImageCache().Get("mykey")
|
|
assert.NoError(err)
|
|
assert.NotNil(r)
|
|
assert.Equal("mykey", info.Name)
|
|
b, _ := ioutil.ReadAll(r)
|
|
r.Close()
|
|
assert.Equal("Hugo is great!", string(b))
|
|
|
|
info, b, err = caches.ImageCache().GetBytes("mykey")
|
|
assert.NoError(err)
|
|
assert.Equal("mykey", info.Name)
|
|
assert.Equal("Hugo is great!", string(b))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
func TestFileCacheConcurrent(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
assert := require.New(t)
|
|
|
|
configStr := `
|
|
resourceDir = "myresources"
|
|
[caches]
|
|
[caches.getjson]
|
|
maxAge = "1s"
|
|
dir = "/cache/c"
|
|
|
|
`
|
|
|
|
cfg, err := config.FromConfigString(configStr, "toml")
|
|
assert.NoError(err)
|
|
fs := hugofs.NewMem(cfg)
|
|
p, err := paths.New(fs, cfg)
|
|
assert.NoError(err)
|
|
|
|
caches, err := NewCachesFromPaths(p)
|
|
assert.NoError(err)
|
|
|
|
const cacheName = "getjson"
|
|
|
|
filenameData := func(i int) (string, string) {
|
|
data := fmt.Sprintf("data: %d", i)
|
|
filename := fmt.Sprintf("file%d", i)
|
|
return filename, data
|
|
}
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
for i := 0; i < 50; i++ {
|
|
wg.Add(1)
|
|
go func(i int) {
|
|
defer wg.Done()
|
|
for j := 0; j < 20; j++ {
|
|
c := caches.Get(cacheName)
|
|
assert.NotNil(c)
|
|
filename, data := filenameData(i)
|
|
_, r, err := c.GetOrCreate(filename, func() (io.ReadCloser, error) {
|
|
return hugio.ToReadCloser(strings.NewReader(data)), nil
|
|
})
|
|
assert.NoError(err)
|
|
b, _ := ioutil.ReadAll(r)
|
|
r.Close()
|
|
assert.Equal(data, string(b))
|
|
// Trigger some expiration.
|
|
time.Sleep(50 * time.Millisecond)
|
|
}
|
|
}(i)
|
|
|
|
}
|
|
wg.Wait()
|
|
}
|
|
|
|
func TestCleanID(t *testing.T) {
|
|
assert := require.New(t)
|
|
assert.Equal(filepath.FromSlash("a/b/c.txt"), cleanID(filepath.FromSlash("/a/b//c.txt")))
|
|
assert.Equal(filepath.FromSlash("a/b/c.txt"), cleanID(filepath.FromSlash("a/b//c.txt")))
|
|
}
|