github.com/apcera/util@v0.0.0-20180322191801-7a50bc84ee48/timeoutwg/timeoutwg_test.go (about)

     1  // Copyright 2017 Apcera Inc. All rights reserved.
     2  
     3  package timeoutwg
     4  
     5  import (
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/apcera/util/testtool"
    10  )
    11  
    12  func TestTimeoutWaitGroup(t *testing.T) {
    13  	testcases := []struct {
    14  		desc              string
    15  		addDeltas         []int
    16  		removes           int
    17  		expectTestTimeout bool
    18  		expectWaitReturn  int
    19  		retry             bool
    20  		expectPanic       bool
    21  		postWaitAdd       bool
    22  	}{
    23  		{
    24  			desc:              "Success",
    25  			addDeltas:         []int{1, 1, 1},
    26  			removes:           3,
    27  			expectTestTimeout: false,
    28  			expectWaitReturn:  0,
    29  		},
    30  		{
    31  			desc:              "ZeroWait",
    32  			addDeltas:         []int{},
    33  			removes:           0,
    34  			expectTestTimeout: false,
    35  			expectWaitReturn:  0,
    36  		},
    37  		{
    38  			desc:              "Fail",
    39  			addDeltas:         []int{1, 1, 1},
    40  			removes:           2,
    41  			expectTestTimeout: true,
    42  			expectWaitReturn:  1,
    43  		},
    44  		{
    45  			desc:              "MultiAdd",
    46  			addDeltas:         []int{1, 3, 1},
    47  			removes:           5,
    48  			expectTestTimeout: false,
    49  			expectWaitReturn:  0,
    50  		},
    51  		{
    52  			desc:              "SuccessWithRetry",
    53  			addDeltas:         []int{1, 1, 1},
    54  			removes:           3,
    55  			expectTestTimeout: false,
    56  			expectWaitReturn:  0,
    57  			retry:             true,
    58  		},
    59  		{
    60  			desc:              "FailWithRetry",
    61  			addDeltas:         []int{1, 1, 1},
    62  			removes:           2,
    63  			expectTestTimeout: true,
    64  			expectWaitReturn:  1,
    65  			retry:             true,
    66  		},
    67  		{
    68  			desc:              "TooManyDone",
    69  			addDeltas:         []int{1},
    70  			removes:           2,
    71  			expectTestTimeout: false,
    72  			retry:             true,
    73  			expectPanic:       true,
    74  		},
    75  		{
    76  			desc:              "AddAfterWait",
    77  			addDeltas:         []int{1},
    78  			removes:           2,
    79  			postWaitAdd:       true,
    80  			expectTestTimeout: false,
    81  			retry:             true,
    82  			expectPanic:       true,
    83  		},
    84  	}
    85  
    86  	for _, tc := range testcases {
    87  		t.Run(tc.desc, func(t *testing.T) {
    88  			var twg TimeoutWaitGroup
    89  
    90  			if tc.expectPanic {
    91  				defer func() {
    92  					if r := recover(); r == nil {
    93  						t.Fatalf("Expected panic, but did not get one.")
    94  					}
    95  				}()
    96  			}
    97  
    98  			totalAdds := 0
    99  			for _, delta := range tc.addDeltas {
   100  				totalAdds += delta
   101  				twg.Add(delta)
   102  			}
   103  			done := make(chan int, 1)
   104  			defer func() { close(done) }()
   105  
   106  			if tc.postWaitAdd {
   107  				twg.Wait(0)
   108  				twg.Add(1) // should panic here, can verify that in panic handler
   109  			}
   110  
   111  			if tc.retry {
   112  				// We expect this to always timeout.
   113  				testtool.TestEqual(t, twg.Wait(0), totalAdds)
   114  			}
   115  			for i := 0; i < tc.removes; i++ {
   116  				twg.Done()
   117  			}
   118  			go func() {
   119  				done <- twg.Wait(300 * time.Millisecond)
   120  			}()
   121  			select {
   122  			case <-time.After(100 * time.Millisecond):
   123  				if !tc.expectTestTimeout {
   124  					t.Fatal("Wait did not return within the expected time.")
   125  				}
   126  				// Get the RV when the Wait finally times out.
   127  				rv := <-done
   128  				testtool.TestEqual(t, rv, tc.expectWaitReturn)
   129  			case rv := <-done:
   130  				if tc.expectTestTimeout {
   131  					t.Fatal("Wait unexpectedly returned.")
   132  				}
   133  				testtool.TestEqual(t, rv, tc.expectWaitReturn)
   134  			}
   135  		})
   136  	}
   137  }