github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/utils/reftracker/reftracker_test.go (about) 1 /* 2 * Copyright (C) 2021 The "MysteriumNetwork/node" Authors. 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 package reftracker 19 20 import ( 21 "testing" 22 "time" 23 ) 24 25 const testPatrolPeriod = 10 * time.Millisecond 26 27 func TestCollect(t *testing.T) { 28 tr := NewRefTracker(testPatrolPeriod) 29 defer tr.Close() 30 31 called := make(chan struct{}) 32 33 tr.Put("1", 100*time.Millisecond, func() { 34 close(called) 35 }) 36 37 time.Sleep(200 * time.Millisecond) 38 select { 39 case <-called: 40 default: 41 t.Error("release callback was not invoked") 42 } 43 } 44 45 func TestUseAndCollect(t *testing.T) { 46 tr := NewRefTracker(testPatrolPeriod) 47 defer tr.Close() 48 49 called := make(chan struct{}) 50 51 tr.Put("1", 100*time.Millisecond, func() { 52 close(called) 53 }) 54 55 time.Sleep(50 * time.Millisecond) 56 57 select { 58 case <-called: 59 t.Error("release callback was invoked too early") 60 return 61 default: 62 } 63 64 err := tr.Incr("1") 65 if err != nil { 66 t.Errorf("error: %v", err) 67 return 68 } 69 70 time.Sleep(200 * time.Millisecond) 71 72 select { 73 case <-called: 74 t.Error("release callback was invoked too early") 75 return 76 default: 77 } 78 79 tr.Decr("1") 80 81 time.Sleep(200 * time.Millisecond) 82 select { 83 case <-called: 84 default: 85 t.Error("release callback was not invoked") 86 return 87 } 88 } 89 90 func TestNegativeRefcountPanic(t *testing.T) { 91 var failedSuccessfully bool 92 tr := NewRefTracker(testPatrolPeriod) 93 defer tr.Close() 94 95 tr.Put("1", 2*time.Second, func() {}) 96 97 func() { 98 defer func() { 99 if r := recover(); r != nil { 100 failedSuccessfully = true 101 } 102 }() 103 tr.Decr("1") 104 }() 105 106 if !failedSuccessfully { 107 t.Fail() 108 } 109 } 110 111 func TestPutIdempotent(t *testing.T) { 112 tr := NewRefTracker(testPatrolPeriod) 113 defer tr.Close() 114 115 called := make(chan struct{}) 116 117 tr.Put("1", 100*time.Millisecond, func() { 118 close(called) 119 }) 120 tr.Put("1", 1*time.Millisecond, func() { 121 t.Fail() 122 }) 123 124 time.Sleep(200 * time.Millisecond) 125 select { 126 case <-called: 127 default: 128 t.Error("release callback was not invoked") 129 } 130 }