pages_cache_test.go (2134B)
1 // Copyright 2019 The Hugo Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13
14 package page
15
16 import (
17 "strconv"
18 "sync"
19 "sync/atomic"
20 "testing"
21
22 qt "github.com/frankban/quicktest"
23 )
24
25 func TestPageCache(t *testing.T) {
26 t.Parallel()
27 c := qt.New(t)
28 c1 := newPageCache()
29
30 changeFirst := func(p Pages) {
31 p[0].(*testPage).description = "changed"
32 }
33
34 var o1 uint64
35 var o2 uint64
36
37 var wg sync.WaitGroup
38
39 var l1 sync.Mutex
40 var l2 sync.Mutex
41
42 var testPageSets []Pages
43
44 for i := 0; i < 50; i++ {
45 testPageSets = append(testPageSets, createSortTestPages(i+1))
46 }
47
48 for j := 0; j < 100; j++ {
49 wg.Add(1)
50 go func() {
51 defer wg.Done()
52 for k, pages := range testPageSets {
53 l1.Lock()
54 p, ca := c1.get("k1", nil, pages)
55 c.Assert(ca, qt.Equals, !atomic.CompareAndSwapUint64(&o1, uint64(k), uint64(k+1)))
56 l1.Unlock()
57 p2, c2 := c1.get("k1", nil, p)
58 c.Assert(c2, qt.Equals, true)
59 c.Assert(pagesEqual(p, p2), qt.Equals, true)
60 c.Assert(pagesEqual(p, pages), qt.Equals, true)
61 c.Assert(p, qt.Not(qt.IsNil))
62
63 l2.Lock()
64 p3, c3 := c1.get("k2", changeFirst, pages)
65 c.Assert(c3, qt.Equals, !atomic.CompareAndSwapUint64(&o2, uint64(k), uint64(k+1)))
66 l2.Unlock()
67 c.Assert(p3, qt.Not(qt.IsNil))
68 c.Assert("changed", qt.Equals, p3[0].(*testPage).description)
69 }
70 }()
71 }
72 wg.Wait()
73 }
74
75 func BenchmarkPageCache(b *testing.B) {
76 cache := newPageCache()
77 pages := make(Pages, 30)
78 for i := 0; i < 30; i++ {
79 pages[i] = &testPage{title: "p" + strconv.Itoa(i)}
80 }
81 key := "key"
82
83 b.ResetTimer()
84 for i := 0; i < b.N; i++ {
85 cache.getP(key, nil, pages)
86 }
87 }