github.com/jeffjen/go-libkv@v0.0.0-20151212051932-5df59a45a168/timer/timer_test.go (about)

     1  package timer
     2  
     3  import (
     4  	"fmt"
     5  	"sync"
     6  	"testing"
     7  	"time"
     8  )
     9  
    10  type Expire struct {
    11  	iden int
    12  	wg   *sync.WaitGroup
    13  }
    14  
    15  func (e Expire) Done(jobId int64) {
    16  	fmt.Printf("triggered expired [%d] - [%d] - [%s]\n", e.iden, jobId, time.Now())
    17  	e.wg.Done()
    18  }
    19  
    20  func TestSchedTimer(t *testing.T) {
    21  	exp := NewTimer()
    22  
    23  	exp.Tic()
    24  	defer exp.Toc() // schedule expire worker
    25  
    26  	var (
    27  		wg sync.WaitGroup
    28  
    29  		cases = []time.Duration{
    30  			300 * time.Millisecond,
    31  			5 * time.Second,
    32  			1 * time.Second,
    33  		}
    34  
    35  		end = make(chan struct{})
    36  	)
    37  
    38  	wg.Add(len(cases))
    39  	go func() {
    40  		wg.Wait()
    41  		close(end)
    42  	}()
    43  
    44  	now := time.Now()
    45  	fmt.Printf("begin TestSchedTimer %v\n", now)
    46  
    47  	for idx, c := range cases {
    48  		exp.Sched(now.Add(c), Expire{idx, &wg})
    49  	}
    50  
    51  	select {
    52  	case <-end:
    53  		return
    54  	case <-time.After(1 * time.Minute):
    55  		t.Errorf("Unable to complete test")
    56  	}
    57  }
    58  
    59  func TestBurstSched(t *testing.T) {
    60  	exp := NewTimer()
    61  
    62  	exp.Tic()
    63  	defer exp.Toc() // schedule expire worker
    64  
    65  	var (
    66  		wg sync.WaitGroup
    67  
    68  		schedNumHandler = 10000
    69  
    70  		end = make(chan struct{})
    71  	)
    72  
    73  	wg.Add(schedNumHandler)
    74  	go func() {
    75  		wg.Wait()
    76  		close(end)
    77  	}()
    78  
    79  	now := time.Now()
    80  	fmt.Printf("begin TestBurstSched %v\n", now)
    81  
    82  	for idx := 0; idx < schedNumHandler; idx += 1 {
    83  		exp.SchedFunc(now.Add(1*time.Millisecond), func(jobId int64) {
    84  			wg.Done()
    85  		})
    86  	}
    87  
    88  	select {
    89  	case <-end:
    90  		return
    91  	case <-time.After(time.Duration(schedNumHandler) * time.Millisecond):
    92  		t.Errorf("Unable to complete test")
    93  	}
    94  }
    95  
    96  func TestCancel(t *testing.T) {
    97  	exp := NewTimer()
    98  
    99  	exp.Tic()
   100  	defer exp.Toc() // schedule expire worker
   101  
   102  	now := time.Now()
   103  	fmt.Printf("begin TestCancel %v\n", now)
   104  
   105  	resp := make(chan int, 1)
   106  
   107  	iden := exp.SchedFunc(now.Add(10*time.Second), func(id int64) {
   108  		fmt.Printf("work order [%d;%d] triggered at %v\n", 1, id, time.Now())
   109  		resp <- 1
   110  	})
   111  
   112  	exp.SchedFunc(now.Add(2*time.Second), func(id int64) {
   113  		fmt.Printf("work order [%d;%d] triggered at %v\n", 2, id, time.Now())
   114  		resp <- 2
   115  	})
   116  
   117  	woe := time.After(10 * time.Second)
   118  	for {
   119  		select {
   120  		case v := <-resp:
   121  			if v != 2 {
   122  				t.Errorf("Failed to cancel work %d", v)
   123  			} else {
   124  				exp.Cancel(iden) // cancel the first one
   125  			}
   126  		case <-woe:
   127  			return
   128  		}
   129  	}
   130  }
   131  
   132  func TestUpdate(t *testing.T) {
   133  	exp := NewTimer()
   134  
   135  	exp.Tic()
   136  	defer exp.Toc() // schedule expire worker
   137  
   138  	now := time.Now()
   139  	fmt.Printf("begin TestUpdate %v\n", now)
   140  
   141  	resp := make(chan int, 1)
   142  
   143  	iden := exp.SchedFunc(now.Add(10*time.Second), func(jobId int64) {
   144  		resp <- 1
   145  	})
   146  
   147  	trigger := time.After(2 * time.Second)
   148  	woe := time.After(5 * time.Second)
   149  	for {
   150  		select {
   151  		case <-resp:
   152  			return
   153  		case <-trigger:
   154  			exp.Update(iden, time.Now().Add(1*time.Second))
   155  		case <-woe:
   156  			t.Errorf("Failed to update scheduled work")
   157  		}
   158  	}
   159  }
   160  
   161  func TestRepeat(t *testing.T) {
   162  	exp := NewTimer()
   163  
   164  	exp.Tic()
   165  	defer exp.Toc() // schedule expire worker
   166  
   167  	now := time.Now()
   168  	fmt.Printf("begin TestRepeat %v\n", now)
   169  
   170  	resp := make(chan int, 1)
   171  
   172  	iden := exp.RepeatFunc(1*time.Second, 1, func(jobId int64) {
   173  		resp <- 1
   174  	})
   175  
   176  	history, counter := 0, 0
   177  
   178  	pre := time.After(5 * time.Second)
   179  	end := time.After(10 * time.Second)
   180  	for {
   181  		select {
   182  		case <-resp:
   183  			counter += 1
   184  		case <-pre:
   185  			exp.Cancel(iden)
   186  			if counter == 0 {
   187  				t.Errorf("Failed to repeat scheduled work")
   188  			} else {
   189  				fmt.Printf("work order repated %d times\n", counter)
   190  			}
   191  			history = counter
   192  		case <-end:
   193  			if history != counter {
   194  				t.Errorf("Failed to cancel repeat work")
   195  			}
   196  			return
   197  		}
   198  	}
   199  }
   200  
   201  func TestRepeatRateLimit(t *testing.T) {
   202  	exp := NewTimer()
   203  
   204  	exp.Tic()
   205  	defer exp.Toc() // schedule expire worker
   206  
   207  	now := time.Now()
   208  	fmt.Printf("begin TestRepeatRateLimit %v\n", now)
   209  
   210  	resp := make(chan int, 1)
   211  
   212  	iden := exp.RepeatFunc(1*time.Millisecond, 5, func(jobId int64) {
   213  		<-time.After(1 * time.Second)
   214  		resp <- 1
   215  	})
   216  
   217  	counter := 0
   218  
   219  	end := time.After(5 * time.Second)
   220  	for {
   221  		select {
   222  		case <-resp:
   223  			counter += 1
   224  		case <-end:
   225  			exp.Cancel(iden)
   226  			fmt.Printf("Handler invoked: %d times\n", counter)
   227  			return
   228  		}
   229  	}
   230  }
   231  
   232  func BenchmarkSchedFunc(b *testing.B) {
   233  	exp := NewTimer()
   234  
   235  	exp.Tic()
   236  	defer exp.Toc() // schedule expire worker
   237  
   238  	const N = 10000
   239  
   240  	handle := func(jobId int64) {}
   241  
   242  	future := time.Now().Add(1 * time.Hour)
   243  
   244  	for idx := 0; idx < N; idx++ {
   245  		exp.SchedFunc(future, handle)
   246  	}
   247  }