github.com/richardwilkes/toolbox@v1.121.0/softref/softref_test.go (about) 1 // Copyright (c) 2016-2024 by Richard A. Wilkes. All rights reserved. 2 // 3 // This Source Code Form is subject to the terms of the Mozilla Public 4 // License, version 2.0. If a copy of the MPL was not distributed with 5 // this file, You can obtain one at http://mozilla.org/MPL/2.0/. 6 // 7 // This Source Code Form is "Incompatible With Secondary Licenses", as 8 // defined by the Mozilla Public License, version 2.0. 9 10 package softref_test 11 12 import ( 13 "runtime" 14 "testing" 15 "time" 16 17 "github.com/richardwilkes/toolbox/check" 18 "github.com/richardwilkes/toolbox/softref" 19 ) 20 21 type res struct { 22 released chan<- string 23 key string 24 } 25 26 func newRes(key string, released chan<- string) *res { 27 return &res{ 28 key: key, 29 released: released, 30 } 31 } 32 33 func (r *res) Key() string { 34 return r.key 35 } 36 37 func (r *res) Release() { 38 r.released <- r.key 39 } 40 41 func TestSoftRef(t *testing.T) { 42 p := softref.NewPool() 43 ch := make(chan string, 128) 44 sr1, existed := p.NewSoftRef(newRes("1", ch)) 45 check.False(t, existed) 46 _, existed = p.NewSoftRef(newRes("2", ch)) 47 check.False(t, existed) 48 sr3, existed := p.NewSoftRef(newRes("3", ch)) 49 check.False(t, existed) 50 r4 := newRes("4", ch) 51 sr4a, existed := p.NewSoftRef(r4) 52 check.False(t, existed) 53 sr4b, existed := p.NewSoftRef(r4) 54 check.True(t, existed) 55 lookFor(t, "2", ch) 56 key := sr3.Resource.(*res).key 57 lookFor(t, key, ch) 58 key = sr1.Resource.(*res).key 59 lookFor(t, key, ch) 60 key = sr4a.Resource.(*res).key 61 check.Equal(t, key, sr4b.Resource.(*res).key) 62 lookForExpectingTimeout(t, ch) 63 check.Equal(t, "4", sr4b.Key) // Keeps refs to r4 alive for the above call 64 lookFor(t, key, ch) 65 } 66 67 func lookFor(t *testing.T, key string, ch <-chan string) { 68 t.Helper() 69 runtime.GC() 70 select { 71 case <-time.After(time.Second): 72 t.Errorf("timed out waiting for %s", key) 73 case k := <-ch: 74 check.Equal(t, key, k) 75 } 76 } 77 78 func lookForExpectingTimeout(t *testing.T, ch <-chan string) { 79 t.Helper() 80 runtime.GC() 81 select { 82 case <-time.After(time.Second): 83 case k := <-ch: 84 t.Errorf("received key '%s' when none expected", k) 85 } 86 }