github.com/jimmyx0x/go-ethereum@v1.10.28/common/mclock/alarm_test.go (about) 1 // Copyright 2022 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser 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 // The go-ethereum library 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 Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package mclock 18 19 import "testing" 20 21 // This test checks basic functionality of Alarm. 22 func TestAlarm(t *testing.T) { 23 clk := new(Simulated) 24 clk.Run(20) 25 a := NewAlarm(clk) 26 27 a.Schedule(clk.Now() + 10) 28 if recv(a.C()) { 29 t.Fatal("Alarm fired before scheduled deadline") 30 } 31 if ntimers := clk.ActiveTimers(); ntimers != 1 { 32 t.Fatal("clock has", ntimers, "active timers, want", 1) 33 } 34 clk.Run(5) 35 if recv(a.C()) { 36 t.Fatal("Alarm fired too early") 37 } 38 39 clk.Run(5) 40 if !recv(a.C()) { 41 t.Fatal("Alarm did not fire") 42 } 43 if recv(a.C()) { 44 t.Fatal("Alarm fired twice") 45 } 46 if ntimers := clk.ActiveTimers(); ntimers != 0 { 47 t.Fatal("clock has", ntimers, "active timers, want", 0) 48 } 49 50 a.Schedule(clk.Now() + 5) 51 if recv(a.C()) { 52 t.Fatal("Alarm fired before scheduled deadline when scheduling the second event") 53 } 54 55 clk.Run(5) 56 if !recv(a.C()) { 57 t.Fatal("Alarm did not fire when scheduling the second event") 58 } 59 if recv(a.C()) { 60 t.Fatal("Alarm fired twice when scheduling the second event") 61 } 62 } 63 64 // This test checks that scheduling an Alarm to an earlier time than the 65 // one already scheduled works properly. 66 func TestAlarmScheduleEarlier(t *testing.T) { 67 clk := new(Simulated) 68 clk.Run(20) 69 a := NewAlarm(clk) 70 71 a.Schedule(clk.Now() + 50) 72 clk.Run(5) 73 a.Schedule(clk.Now() + 1) 74 clk.Run(3) 75 if !recv(a.C()) { 76 t.Fatal("Alarm did not fire") 77 } 78 } 79 80 // This test checks that scheduling an Alarm to a later time than the 81 // one already scheduled works properly. 82 func TestAlarmScheduleLater(t *testing.T) { 83 clk := new(Simulated) 84 clk.Run(20) 85 a := NewAlarm(clk) 86 87 a.Schedule(clk.Now() + 50) 88 clk.Run(5) 89 a.Schedule(clk.Now() + 100) 90 clk.Run(50) 91 if !recv(a.C()) { 92 t.Fatal("Alarm did not fire") 93 } 94 } 95 96 // This test checks that scheduling an Alarm in the past makes it fire immediately. 97 func TestAlarmNegative(t *testing.T) { 98 clk := new(Simulated) 99 clk.Run(50) 100 a := NewAlarm(clk) 101 102 a.Schedule(-1) 103 clk.Run(1) // needed to process timers 104 if !recv(a.C()) { 105 t.Fatal("Alarm did not fire for negative time") 106 } 107 } 108 109 func recv(ch <-chan struct{}) bool { 110 select { 111 case <-ch: 112 return true 113 default: 114 return false 115 } 116 }