74 lines
		
	
	
		
			1.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			74 lines
		
	
	
		
			1.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package eventloop
 | |
| 
 | |
| import (
 | |
| 	"sync"
 | |
| 	"testing"
 | |
| 	"time"
 | |
| )
 | |
| 
 | |
| type racyEvent struct {
 | |
| 	m  map[int]struct{}
 | |
| 	wg *sync.WaitGroup
 | |
| }
 | |
| 
 | |
| func (e *racyEvent) Handle() {
 | |
| 	e.m[0] = struct{}{}
 | |
| 	e.wg.Done()
 | |
| }
 | |
| 
 | |
| func simulateRacyEvents(el EventLoop) {
 | |
| 	wg := &sync.WaitGroup{}
 | |
| 	raceMap := make(map[int]struct{})
 | |
| 	var evs []*racyEvent
 | |
| 	for i := 0; i < 1024; i++ {
 | |
| 		wg.Add(1)
 | |
| 		evs = append(evs, &racyEvent{m: raceMap, wg: wg})
 | |
| 	}
 | |
| 	for _, ev := range evs {
 | |
| 		el.Send(ev)
 | |
| 	}
 | |
| 	wg.Wait()
 | |
| }
 | |
| 
 | |
| // run with -race
 | |
| func TestChanRace(t *testing.T) {
 | |
| 	e := NewChanLoop(1024)
 | |
| 	e.Start()
 | |
| 	simulateRacyEvents(e)
 | |
| }
 | |
| 
 | |
| // run with -race
 | |
| func TestChanStartTwiceRace(t *testing.T) {
 | |
| 	e := NewChanLoop(1024)
 | |
| 	e.Start()
 | |
| 	e.Start()
 | |
| 	simulateRacyEvents(e)
 | |
| }
 | |
| 
 | |
| type testEvent struct {
 | |
| 	wg *sync.WaitGroup
 | |
| }
 | |
| 
 | |
| func (e *testEvent) Handle() {
 | |
| 	e.wg.Done()
 | |
| }
 | |
| 
 | |
| func TestChanEventSpawn(t *testing.T) {
 | |
| 	e := NewChanLoop(1024)
 | |
| 	e.Start()
 | |
| 	wg := &sync.WaitGroup{}
 | |
| 	wg.Add(2)
 | |
| 	e.Send(&testEvent{wg: wg})
 | |
| 	e.Send(&testEvent{wg: wg})
 | |
| 	waitCh := make(chan struct{})
 | |
| 	go func() {
 | |
| 		wg.Wait()
 | |
| 		close(waitCh)
 | |
| 	}()
 | |
| 	select {
 | |
| 	case <-waitCh:
 | |
| 	case <-time.After(1 * time.Second):
 | |
| 		t.Fatal("Events was not handled in loop")
 | |
| 	}
 | |
| }
 | 
