github.com/graemephi/kahugo@v0.62.3-0.20211121071557-d78c0423784d/common/para/para_test.go (about)

     1  // Copyright 2019 The Hugo Authors. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package para
    15  
    16  import (
    17  	"context"
    18  	"runtime"
    19  	"sort"
    20  	"sync"
    21  	"sync/atomic"
    22  	"testing"
    23  	"time"
    24  
    25  	"github.com/gohugoio/hugo/htesting"
    26  
    27  	qt "github.com/frankban/quicktest"
    28  )
    29  
    30  func TestPara(t *testing.T) {
    31  	if runtime.NumCPU() < 4 {
    32  		t.Skipf("skip para test, CPU count is %d", runtime.NumCPU())
    33  	}
    34  
    35  	if !htesting.IsCI() {
    36  		t.Skip("skip para test when not running on CI")
    37  	}
    38  
    39  	c := qt.New(t)
    40  
    41  	c.Run("Order", func(c *qt.C) {
    42  		n := 500
    43  		ints := make([]int, n)
    44  		for i := 0; i < n; i++ {
    45  			ints[i] = i
    46  		}
    47  
    48  		p := New(4)
    49  		r, _ := p.Start(context.Background())
    50  
    51  		var result []int
    52  		var mu sync.Mutex
    53  		for i := 0; i < n; i++ {
    54  			i := i
    55  			r.Run(func() error {
    56  				mu.Lock()
    57  				defer mu.Unlock()
    58  				result = append(result, i)
    59  				return nil
    60  			})
    61  		}
    62  
    63  		c.Assert(r.Wait(), qt.IsNil)
    64  		c.Assert(result, qt.HasLen, len(ints))
    65  		c.Assert(sort.IntsAreSorted(result), qt.Equals, false, qt.Commentf("Para does not seem to be parallel"))
    66  		sort.Ints(result)
    67  		c.Assert(result, qt.DeepEquals, ints)
    68  	})
    69  
    70  	c.Run("Time", func(c *qt.C) {
    71  		const n = 100
    72  
    73  		p := New(5)
    74  		r, _ := p.Start(context.Background())
    75  
    76  		start := time.Now()
    77  
    78  		var counter int64
    79  
    80  		for i := 0; i < n; i++ {
    81  			r.Run(func() error {
    82  				atomic.AddInt64(&counter, 1)
    83  				time.Sleep(1 * time.Millisecond)
    84  				return nil
    85  			})
    86  		}
    87  
    88  		c.Assert(r.Wait(), qt.IsNil)
    89  		c.Assert(counter, qt.Equals, int64(n))
    90  
    91  		since := time.Since(start)
    92  		limit := n / 2 * time.Millisecond
    93  		c.Assert(since < limit, qt.Equals, true, qt.Commentf("%s >= %s", since, limit))
    94  	})
    95  }