github.com/hata/goseq@v0.0.0-20150316021154-a5ca66a92399/handlergroup_test.go (about)

     1  package goseq
     2  
     3  import (
     4  	"sync"
     5  	"testing"
     6  	"time"
     7  )
     8  
     9  func sampleToIndexFunc(id SequenceID) (index int) {
    10  	index = 0xff & int(id)
    11  	return
    12  }
    13  
    14  func TestNewHandlerGroupStruct(t *testing.T) {
    15  	group := newHandlerGroup(sampleToIndexFunc)
    16  	if group.handlers == nil {
    17  		t.Error("handlers should be initialized.")
    18  	}
    19  	if group.nextGroups == nil {
    20  		t.Error("nextGroups should be initialized.")
    21  	}
    22  	if group.lastProcessedID == nil {
    23  		t.Error("lastProcessedID should be initialized.")
    24  	}
    25  	if group.seqToIndexFunc == nil {
    26  		t.Error("seqToIndexFunc should not be nil.")
    27  	}
    28  }
    29  
    30  func TestAddHandlerHandlerGroup(t *testing.T) {
    31  	group := newHandlerGroup(sampleToIndexFunc)
    32  	f := func(id SequenceID, index int) {}
    33  	group.AddHandler(f)
    34  	if len(group.handlers) != 1 {
    35  		t.Error("AddHandler should add a new handler.")
    36  	}
    37  	group.AddHandler(f, f)
    38  	if len(group.handlers) != 3 {
    39  		t.Error("AddHandler can add some tasks.")
    40  	}
    41  }
    42  
    43  func TestAddhandlersHandlerGroups(t *testing.T) {
    44  	group := newHandlerGroup(sampleToIndexFunc)
    45  	f := func(id SequenceID, index int) {}
    46  	handlers := make([]TaskHandler, 4, 4)
    47  	for i := range handlers {
    48  		handlers[i] = f
    49  	}
    50  	group.AddHandlers(handlers)
    51  	if len(group.handlers) != 4 {
    52  		t.Error("AddHandlers should have added handlers.")
    53  	}
    54  }
    55  
    56  func TestAddNextGroup(t *testing.T) {
    57  	group := newHandlerGroup(sampleToIndexFunc)
    58  	group2 := newHandlerGroup(sampleToIndexFunc)
    59  
    60  	group.addNextGroup(group2)
    61  	if len(group.nextGroups) != 1 {
    62  		t.Error("addNextGroup should add a new group.")
    63  	}
    64  }
    65  
    66  func TestAddNextGroups(t *testing.T) {
    67  	group := newHandlerGroup(sampleToIndexFunc)
    68  	group2 := newHandlerGroup(sampleToIndexFunc)
    69  	group3 := newHandlerGroup(sampleToIndexFunc)
    70  	group4 := newHandlerGroup(sampleToIndexFunc)
    71  
    72  	group.addNextGroups(group2)
    73  	group.addNextGroups(group3, group4)
    74  	if len(group.nextGroups) != 3 {
    75  		t.Error("addNextGroup should add a new group.")
    76  	}
    77  }
    78  
    79  func TestStartAndStop(t *testing.T) {
    80  	group := newHandlerGroup(sampleToIndexFunc)
    81  	handler := func(id SequenceID, index int) {}
    82  	group.AddHandler(handler)
    83  	group.start()
    84  	group.process(1)
    85  	group.stop()
    86  	if group.LastProcessedID() != 1 {
    87  		t.Error("start/stop didn't process a request.")
    88  	}
    89  	if group.inChannels != nil {
    90  		t.Error("stop should close and clean inChannels.")
    91  	}
    92  	if group.outChannels != nil {
    93  		t.Error("stop should close and clean outChannels.")
    94  	}
    95  }
    96  
    97  func TestStartAllAndStopAll(t *testing.T) {
    98  	group := newHandlerGroup(sampleToIndexFunc)
    99  	group2 := newHandlerGroup(sampleToIndexFunc)
   100  	handler := func(id SequenceID, index int) {}
   101  	group.AddHandler(handler)
   102  	group2.AddHandler(handler)
   103  	group.addNextGroup(group2)
   104  	group.startAll()
   105  	group.process(1)
   106  	group.stopAll()
   107  
   108  	if group.LastProcessedID() != 1 {
   109  		t.Error("startAll/stopAll didn't process a request")
   110  	}
   111  	if group2.LastProcessedID() != 1 {
   112  		t.Error("StartAll/StopAll didn't propagate to a next group.")
   113  	}
   114  	if group.inChannels != nil {
   115  		t.Error("stop should close and clean inChannels.")
   116  	}
   117  	if group.outChannels != nil {
   118  		t.Error("stop should close and clean outChannels.")
   119  	}
   120  	if group2.inChannels != nil {
   121  		t.Error("stop should close and clean inChannels.")
   122  	}
   123  	if group2.outChannels != nil {
   124  		t.Error("stop should close and clean outChannels.")
   125  	}
   126  }
   127  
   128  func TestProcess(t *testing.T) {
   129  	var m sync.Mutex
   130  	count := 0
   131  	group := newHandlerGroup(sampleToIndexFunc)
   132  	handler := func(id SequenceID, index int) {
   133  		m.Lock()
   134  		defer m.Unlock()
   135  		count++
   136  	}
   137  	group.AddHandler(handler)
   138  	group.start()
   139  	group.process(1)
   140  	group.process(2)
   141  	group.stop()
   142  
   143  	if count != 2 {
   144  		t.Error("process call doesn't handle requests.")
   145  	}
   146  
   147  	if group.LastProcessedID() != 2 {
   148  		t.Error("LastProcessedID is not updated well.")
   149  	}
   150  }
   151  
   152  func TestLastHandlerGroups(t *testing.T) {
   153  	group := newHandlerGroup(sampleToIndexFunc)
   154  	lastGroups := group.lastHandlerGroups()
   155  	if len(lastGroups) != 1 || lastGroups[0] != group {
   156  		t.Error("lastHandlerGroups() returns self when there is no nextGroups.")
   157  	}
   158  }
   159  
   160  func TestLastHandlerGroupsReturnNextGroup(t *testing.T) {
   161  	group := newHandlerGroup(sampleToIndexFunc)
   162  	group2 := newHandlerGroup(sampleToIndexFunc)
   163  	group.addNextGroup(group2)
   164  	lastGroups := group.lastHandlerGroups()
   165  	if len(lastGroups) != 1 || lastGroups[0] != group2 {
   166  		t.Error("lastHandlerGroups() returns a next group. len:", len(lastGroups))
   167  	}
   168  }
   169  
   170  func TestLastHandlerGroupsReturnSomeGroups(t *testing.T) {
   171  	group := newHandlerGroup(sampleToIndexFunc)
   172  	group2 := newHandlerGroup(sampleToIndexFunc)
   173  	group3 := newHandlerGroup(sampleToIndexFunc)
   174  	group4 := newHandlerGroup(sampleToIndexFunc)
   175  	group5 := newHandlerGroup(sampleToIndexFunc)
   176  	group.addNextGroups(group2, group3)
   177  	group2.addNextGroups(group4, group5)
   178  	lastGroups := group.lastHandlerGroups()
   179  	if len(lastGroups) != 3 ||
   180  		lastGroups[0] != group4 ||
   181  		lastGroups[1] != group5 ||
   182  		lastGroups[2] != group3 {
   183  		t.Error("lastHandlerGroups() returns next groups. len:", len(lastGroups))
   184  	}
   185  }
   186  
   187  func TestSomeHandlers(t *testing.T) {
   188  	var m sync.Mutex
   189  	count := 0
   190  	group := newHandlerGroup(sampleToIndexFunc)
   191  	handler := func(id SequenceID, index int) {
   192  		m.Lock()
   193  		defer m.Unlock()
   194  		count++
   195  	}
   196  	group.AddHandler(handler, handler, handler, handler, handler)
   197  	group.start()
   198  	group.process(0)
   199  	group.process(1)
   200  	group.process(2)
   201  	group.stop()
   202  	if count != 15 { // 5 handlers and processing 3 times
   203  		t.Error("handlers are not processed.")
   204  	}
   205  }
   206  
   207  func TestSomeHandlersAndSomeNextGroups(t *testing.T) {
   208  	var m sync.Mutex
   209  	count := 0
   210  
   211  	handler := func(id SequenceID, index int) {
   212  		m.Lock()
   213  		defer m.Unlock()
   214  		count++
   215  	}
   216  
   217  	group1 := newHandlerGroup(sampleToIndexFunc)
   218  	group1.name = "group1"
   219  	group1.AddHandler(handler)
   220  	group2 := newHandlerGroup(sampleToIndexFunc)
   221  	group2.name = "group2"
   222  	group2.AddHandler(handler, handler)
   223  	group3 := newHandlerGroup(sampleToIndexFunc)
   224  	group3.name = "group3"
   225  	group3.AddHandler(handler, handler, handler)
   226  	group4 := newHandlerGroup(sampleToIndexFunc)
   227  	group4.name = "group4"
   228  	group4.AddHandler(handler, handler, handler, handler)
   229  	group5 := newHandlerGroup(sampleToIndexFunc)
   230  	group5.name = "group5"
   231  	group5.AddHandler(handler, handler, handler, handler, handler)
   232  
   233  	group1.addNextGroup(group2)
   234  	group1.addNextGroup(group3)
   235  	group2.addNextGroup(group4)
   236  	group4.addNextGroup(group5)
   237  
   238  	group1.startAll()
   239  	group1.process(0)
   240  	group1.process(1)
   241  	group1.process(2)
   242  	group1.stopAll()
   243  
   244  	time.Sleep(10000)
   245  
   246  	if group1.LastProcessedID() != 2 {
   247  		t.Error("LastProcessedID didn't return 2. id:", group3.LastProcessedID())
   248  	}
   249  
   250  	if group2.LastProcessedID() != 2 {
   251  		t.Error("LastProcessedID didn't return 2. id:", group4.LastProcessedID())
   252  	}
   253  
   254  	if group3.LastProcessedID() != 2 {
   255  		t.Error("LastProcessedID didn't return 2. id:", group3.LastProcessedID())
   256  	}
   257  
   258  	if group4.LastProcessedID() != 2 {
   259  		t.Error("LastProcessedID didn't return 2. id:", group4.LastProcessedID())
   260  	}
   261  
   262  	if group5.LastProcessedID() != 2 {
   263  		t.Error("LastProcessedID didn't return 2. id:", group5.LastProcessedID())
   264  	}
   265  
   266  	if count != (15 * 3) { // 15 handlers and 3 requests
   267  		t.Error("Some handlers and some groups are not processing requests. count:", count)
   268  	}
   269  }
   270  
   271  func BenchmarkProcess(b *testing.B) {
   272  	group := newHandlerGroup(sampleToIndexFunc)
   273  	seq := NewSequence()
   274  	handler := func(id SequenceID, index int) {
   275  		index++
   276  	}
   277  	group.AddHandler(handler)
   278  	group.start()
   279  	b.ResetTimer()
   280  	for i := 0; i < 100000; i++ {
   281  		group.process(seq.Next())
   282  	}
   283  	group.stop()
   284  }
   285  
   286  func BenchmarkSomeGroups(b *testing.B) {
   287  	groups := make([]HandlerGroup, 10, 10)
   288  	seq := NewSequence()
   289  	handler := func(id SequenceID, index int) {
   290  		index++
   291  	}
   292  	var previousGroup HandlerGroup
   293  	for i, _ := range groups {
   294  		groups[i] = newHandlerGroup(sampleToIndexFunc)
   295  		groups[i].AddHandler(handler, handler)
   296  		if previousGroup != nil {
   297  			previousGroup.addNextGroup(groups[i])
   298  		}
   299  		previousGroup = groups[i]
   300  	}
   301  
   302  	groups[0].startAll()
   303  	b.ResetTimer()
   304  	for i := 0; i < 10000; i++ {
   305  		groups[0].process(seq.Next())
   306  	}
   307  	groups[0].stopAll()
   308  }