github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/f/goroutine_test.go (about)

     1  package f_test
     2  
     3  import (
     4  	"github.com/angenalZZZ/gofunc/f"
     5  	"sync"
     6  	"sync/atomic"
     7  	"testing"
     8  	"time"
     9  )
    10  
    11  func BenchmarkPoolFuncJob(b *testing.B) {
    12  	pool := f.NewPoolsFunc(func(in interface{}) interface{} {
    13  		intVal := in.(int)
    14  		return intVal * 2
    15  	})
    16  	defer pool.Close()
    17  
    18  	b.ResetTimer()
    19  
    20  	for i := 0; i < b.N; i++ {
    21  		ret := pool.Process(10)
    22  		if exp, act := 20, ret.(int); exp != act {
    23  			b.Errorf("Wrong result: %v != %v", act, exp)
    24  		}
    25  	}
    26  }
    27  
    28  func BenchmarkPoolFuncTimedJob(b *testing.B) {
    29  	pool := f.NewPoolsFunc(func(in interface{}) interface{} {
    30  		intVal := in.(int)
    31  		return intVal * 2
    32  	})
    33  	defer pool.Close()
    34  
    35  	b.ResetTimer()
    36  
    37  	for i := 0; i < b.N; i++ {
    38  		ret, err := pool.ProcessTimed(10, 2*time.Millisecond)
    39  		if err != nil {
    40  			b.Error(err)
    41  		}
    42  		if exp, act := 20, ret.(int); exp != act {
    43  			b.Errorf("Wrong result: %v != %v", act, exp)
    44  		}
    45  	}
    46  }
    47  
    48  func TestPoolFuncJob(t *testing.T) {
    49  	pool := f.NewPoolsFunc(func(in interface{}) interface{} {
    50  		intVal := in.(int)
    51  		return intVal * 2
    52  	})
    53  	defer pool.Close()
    54  
    55  	for i := 0; i < 1000000; i++ {
    56  		ret := pool.Process(10)
    57  		if exp, act := 20, ret.(int); exp != act {
    58  			t.Errorf("Wrong result: %v != %v", act, exp)
    59  		}
    60  	}
    61  }
    62  
    63  func TestPoolFuncJobTimed(t *testing.T) {
    64  	pool := f.NewPoolsFunc(func(in interface{}) interface{} {
    65  		intVal := in.(int)
    66  		return intVal * 2
    67  	})
    68  	defer pool.Close()
    69  
    70  	for i := 0; i < 1000000; i++ {
    71  		ret, err := pool.ProcessTimed(10, 2*time.Millisecond)
    72  		if err != nil {
    73  			t.Fatalf("Failed to process: %v", err)
    74  		}
    75  		if exp, act := 20, ret.(int); exp != act {
    76  			t.Errorf("Wrong result: %v != %v", act, exp)
    77  		}
    78  	}
    79  }
    80  
    81  func TestPoolCallbackJob(t *testing.T) {
    82  	pool := f.NewPoolsCallback()
    83  	defer pool.Close()
    84  
    85  	var counter int32
    86  	for i := 0; i < 1000000; i++ {
    87  		ret := pool.Process(func() {
    88  			atomic.AddInt32(&counter, 1)
    89  		})
    90  		if ret != nil {
    91  			t.Errorf("Non-nil callback response: %v", ret)
    92  		}
    93  	}
    94  
    95  	ret := pool.Process("foo")
    96  	if exp, act := f.ErrJobNotFunc, ret; exp != act {
    97  		t.Errorf("Wrong result from non-func: %v != %v", act, exp)
    98  	}
    99  
   100  	if exp, act := int32(1000000), counter; exp != act {
   101  		t.Errorf("Wrong result: %v != %v", act, exp)
   102  	}
   103  }
   104  
   105  func TestPoolTimeout(t *testing.T) {
   106  	f1 := f.NewFunc(func(in interface{}) interface{} {
   107  		intVal := in.(int)
   108  		<-time.After(time.Second)
   109  		return intVal * 2
   110  	})
   111  	defer f1.Close()
   112  
   113  	_, act := f1.ProcessTimed(1, time.Microsecond)
   114  	if exp := f.ErrJobTimedOut; exp != act {
   115  		t.Errorf("Wrong error returned: %v != %v", act, exp)
   116  	}
   117  }
   118  
   119  func TestPoolTimedJobsAfterClose(t *testing.T) {
   120  	f1 := f.NewFunc(func(in interface{}) interface{} {
   121  		return in
   122  	})
   123  	f1.Close()
   124  
   125  	_, act := f1.ProcessTimed(1, time.Duration(1))
   126  	if exp := f.ErrPoolNotRunning; exp != act {
   127  		t.Errorf("Wrong error returned: %v != %v", act, exp)
   128  	}
   129  }
   130  
   131  func TestPoolJobsAfterClose(t *testing.T) {
   132  	f1 := f.NewFunc(func(in interface{}) interface{} {
   133  		return in
   134  	})
   135  	f1.Close()
   136  
   137  	defer func() {
   138  		if r := recover(); r != f.ErrPoolNotRunning {
   139  			t.Errorf("Process after Stop() did not panic")
   140  		}
   141  	}()
   142  
   143  	f1.Process(1)
   144  }
   145  
   146  func TestPoolParallelJobs(t *testing.T) {
   147  	nWorkers := 100000
   148  
   149  	testGroup := new(sync.WaitGroup)
   150  
   151  	pool := f.NewPoolFunc(nWorkers, func(in interface{}) interface{} {
   152  		intVal := in.(int)
   153  		return intVal * 2
   154  	})
   155  	defer pool.Close()
   156  
   157  	for j := 0; j < 1; j++ {
   158  		testGroup.Add(nWorkers)
   159  
   160  		for i := 0; i < nWorkers; i++ {
   161  			go func() {
   162  				ret := pool.Process(10)
   163  				if exp, act := 20, ret.(int); exp != act {
   164  					t.Errorf("Wrong result: %v != %v", act, exp)
   165  				}
   166  				testGroup.Done()
   167  			}()
   168  		}
   169  
   170  		testGroup.Wait()
   171  	}
   172  }