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 }