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  }