github.com/haraldrudell/parl@v0.4.176/moderator_test.go (about)

     1  /*
     2  © 2022–present Harald Rudell <harald.rudell@gmail.com> https://haraldrudell.github.io/haraldrudell/)
     3  ISC License
     4  */
     5  
     6  package parl
     7  
     8  const (
     9  //mttShortTime = 10 * time.Millisecond
    10  )
    11  
    12  // func TestModerator(t *testing.T) {
    13  // 	taskALaunched := "a"
    14  // 	taskAExited := "A"
    15  // 	goB := "d"
    16  // 	doB := "b"
    17  // 	doC := "c"
    18  // 	goC := "¢"
    19  // 	taskBExited := "B"
    20  // 	taskCExited := "C"
    21  // 	expectedSequence := "a¢dAcCbB"
    22  // 	exitAIndex := strings.Index(expectedSequence, taskAExited)
    23  
    24  // 	Append := func() func(string) string {
    25  // 		sequence := ""
    26  // 		seqLock := sync.Mutex{}
    27  // 		return func(sIn string) (sOut string) {
    28  // 			seqLock.Lock()
    29  // 			defer seqLock.Unlock()
    30  // 			sequence += sIn
    31  // 			return sequence
    32  // 		}
    33  // 	}()
    34  
    35  // 	// instantiate
    36  // 	count := 1
    37  // 	ctx, cancel := context.WithCancel(context.Background())
    38  // 	mo := NewModerator(1, ctx)
    39  
    40  // 	// initial Status
    41  // 	parallelism, active, waiting, shutdown := mo.Status()
    42  // 	if parallelism != uint64(count) {
    43  // 		t.Errorf("Parallelism %d expected %d", parallelism, count)
    44  // 	}
    45  // 	if active != 0 {
    46  // 		t.Errorf("Parallelism %d expected %d", active, 0)
    47  // 	}
    48  // 	if waiting != 0 {
    49  // 		t.Errorf("Waiting %d expected %d", waiting, 0)
    50  // 	}
    51  // 	if shutdown {
    52  // 		t.Errorf("shutdown %t expected %t", shutdown, false)
    53  // 	}
    54  
    55  // 	// StateOne: status: one thread running, ni available tickets, no threads waiting
    56  // 	extecpedA := 1
    57  // 	extecpedW := 0
    58  // 	wgADo := sync.WaitGroup{}
    59  // 	wgADo.Add(1)
    60  // 	wgAWait := sync.WaitGroup{}
    61  // 	wgAWait.Add(1)
    62  // 	wgAExit := sync.WaitGroup{}
    63  // 	wgAExit.Add(1)
    64  // 	// thread A goes into its Do function
    65  // 	go func() {
    66  // 		if err := mo.DoErr(func() (err error) {
    67  // 			Append(taskALaunched)
    68  // 			wgADo.Done()
    69  // 			wgAWait.Wait()
    70  // 			return
    71  // 		}); err != nil {
    72  // 			t.Logf("A err: %v", err)
    73  // 			t.Fail()
    74  // 		}
    75  // 		Append(taskAExited)
    76  // 		wgAExit.Done()
    77  // 	}()
    78  // 	wgADo.Wait()
    79  // 	_, active, waiting, _ = mo.Status()
    80  // 	if active != uint64(extecpedA) {
    81  // 		t.Errorf("State One: active expected: %d actual: %d", active, extecpedA)
    82  // 	}
    83  // 	if waiting != uint64(extecpedW) {
    84  // 		t.Errorf("State One: waiting expected: %d actual: %d", waiting, extecpedW)
    85  // 	}
    86  
    87  // 	// state two: 2 threads in queue
    88  // 	extecpedW = 2
    89  // 	wgBCWait := sync.WaitGroup{}
    90  // 	wgBCWait.Add(1)
    91  // 	wgBCExit := sync.WaitGroup{}
    92  // 	wgBCExit.Add(2)
    93  // 	BC := func(goo, do, exit string) {
    94  // 		Append(goo)
    95  // 		if err := mo.DoErr(func() (err error) {
    96  // 			Append(do)
    97  // 			wgBCWait.Wait()
    98  // 			return
    99  // 		}); err != nil {
   100  // 			t.Logf("%s err: %v", do, err)
   101  // 		}
   102  // 		Append(exit)
   103  // 		wgBCExit.Done()
   104  // 	}
   105  // 	// thread B waiting
   106  // 	go BC(goB, doB, taskBExited)
   107  // 	// thread C waiting
   108  // 	go BC(goC, doC, taskCExited)
   109  // 	// wait for threads to enter cond.Wait()
   110  // 	time.Sleep(mttShortTime)
   111  // 	_, active, waiting, _ = mo.Status()
   112  // 	if active != uint64(extecpedA) {
   113  // 		t.Errorf("State One: active expected: %d actual: %d", active, extecpedA)
   114  // 	}
   115  // 	if waiting != uint64(extecpedW) {
   116  // 		t.Errorf("State One: waiting expected: %d actual: %d", waiting, extecpedW)
   117  // 	}
   118  
   119  // 	// state three: 1 thread in queue
   120  // 	extecpedW = 1
   121  // 	wgAWait.Done()
   122  // 	wgAExit.Wait()
   123  // 	// wait for a thread to exit cond.Wait()
   124  // 	time.Sleep(mttShortTime)
   125  // 	_, active, waiting, _ = mo.Status()
   126  // 	if active != uint64(extecpedA) {
   127  // 		t.Errorf("State One: active expected: %d actual: %d", active, extecpedA)
   128  // 	}
   129  // 	if waiting != uint64(extecpedW) {
   130  // 		t.Errorf("State One: waiting expected: %d actual: %d", waiting, extecpedW)
   131  // 	}
   132  
   133  // 	// state 4: 1 ticket available
   134  // 	extecpedA = 0
   135  // 	extecpedW = 0
   136  // 	wgBCWait.Done()
   137  // 	wgBCExit.Wait()
   138  // 	_, active, waiting, _ = mo.Status()
   139  // 	if active != uint64(extecpedA) {
   140  // 		t.Errorf("State One: active expected: %d actual: %d", active, extecpedA)
   141  // 	}
   142  // 	if waiting != uint64(extecpedW) {
   143  // 		t.Errorf("State One: waiting expected: %d actual: %d", waiting, extecpedW)
   144  // 	}
   145  
   146  // 	seq := Append("") // get result
   147  // 	// expected sequence: a¢dAcCbB
   148  // 	// ¢d and cCbB may flip
   149  // 	if len(seq) != len(expectedSequence) ||
   150  // 		seq[0:1] != expectedSequence[0:1] ||
   151  // 		seq[exitAIndex:exitAIndex+1] != expectedSequence[exitAIndex:exitAIndex+1] {
   152  // 		t.Logf("Bad sequence: expected: %s actual: %s", expectedSequence, seq)
   153  // 		t.Fail()
   154  // 	}
   155  
   156  // 	cancel()
   157  // 	_, _, _, shutdown = mo.Status()
   158  // 	if !shutdown {
   159  // 		t.Errorf("shutdown %t expected %t", shutdown, true)
   160  // 	}
   161  
   162  // }