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  }