mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-01-16 03:52:12 +02:00
f0b4db184e
this bug comes and goes every couple of versions it seems. this will change the snapcraft implementation to run the first item without concurrency, so all needed shared directories can be created without issues, and then grows the limit of the wait group so the other ones can run in parallel. I haven't tested this yet, but I think it'll work. - [x] test - [x] godoc refs https://github.com/goreleaser/goreleaser/issues/1715 refs https://bugs.launchpad.net/snapcraft/+bug/1889741
170 lines
3.5 KiB
Go
170 lines
3.5 KiB
Go
package semerrgroup
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/goreleaser/goreleaser/v2/internal/pipe"
|
|
"github.com/hashicorp/go-multierror"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestBlockingFirst(t *testing.T) {
|
|
g := NewBlockingFirst(New(5))
|
|
var lock sync.Mutex
|
|
var counter int
|
|
for i := 0; i < 10; i++ {
|
|
g.Go(func() error {
|
|
time.Sleep(10 * time.Millisecond)
|
|
lock.Lock()
|
|
defer lock.Unlock()
|
|
counter++
|
|
return nil
|
|
})
|
|
}
|
|
require.NoError(t, g.Wait())
|
|
require.Equal(t, 10, counter)
|
|
}
|
|
|
|
func TestBlockingFirstError(t *testing.T) {
|
|
g := NewBlockingFirst(New(5))
|
|
var lock sync.Mutex
|
|
var counter int
|
|
for i := 0; i < 10; i++ {
|
|
g.Go(func() error {
|
|
time.Sleep(10 * time.Millisecond)
|
|
lock.Lock()
|
|
defer lock.Unlock()
|
|
if counter == 0 {
|
|
return fmt.Errorf("my error")
|
|
}
|
|
counter++
|
|
return nil
|
|
})
|
|
}
|
|
require.EqualError(t, g.Wait(), "my error")
|
|
require.Equal(t, 0, counter)
|
|
}
|
|
|
|
func TestSemaphore(t *testing.T) {
|
|
for _, i := range []int{1, 4} {
|
|
t.Run(fmt.Sprintf("limit-%d", i), func(t *testing.T) {
|
|
g := New(i)
|
|
var lock sync.Mutex
|
|
var counter int
|
|
for i := 0; i < 10; i++ {
|
|
g.Go(func() error {
|
|
time.Sleep(10 * time.Millisecond)
|
|
lock.Lock()
|
|
counter++
|
|
lock.Unlock()
|
|
return nil
|
|
})
|
|
}
|
|
require.NoError(t, g.Wait())
|
|
require.Equal(t, 10, counter)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSemaphoreOrder(t *testing.T) {
|
|
num := 10
|
|
g := New(1)
|
|
output := []int{}
|
|
for i := 0; i < num; i++ {
|
|
g.Go(func() error {
|
|
output = append(output, i)
|
|
return nil
|
|
})
|
|
}
|
|
require.NoError(t, g.Wait())
|
|
require.Equal(t, []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, output)
|
|
}
|
|
|
|
func TestSemaphoreError(t *testing.T) {
|
|
for _, i := range []int{1, 4} {
|
|
t.Run(fmt.Sprintf("limit-%d", i), func(t *testing.T) {
|
|
g := New(i)
|
|
var lock sync.Mutex
|
|
output := []int{}
|
|
for i := 0; i < 10; i++ {
|
|
g.Go(func() error {
|
|
lock.Lock()
|
|
defer lock.Unlock()
|
|
output = append(output, i)
|
|
return fmt.Errorf("fake err")
|
|
})
|
|
}
|
|
require.EqualError(t, g.Wait(), "fake err")
|
|
require.Len(t, output, 10)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSemaphoreSkipAware(t *testing.T) {
|
|
for _, i := range []int{1, 4} {
|
|
t.Run(fmt.Sprintf("limit-%d", i), func(t *testing.T) {
|
|
g := NewSkipAware(New(i))
|
|
for i := 0; i < 10; i++ {
|
|
g.Go(func() error {
|
|
time.Sleep(10 * time.Millisecond)
|
|
return pipe.Skip("fake skip")
|
|
})
|
|
}
|
|
merr := &multierror.Error{}
|
|
require.ErrorAs(t, g.Wait(), &merr, "must be a multierror")
|
|
require.Len(t, merr.Errors, 10)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSemaphoreSkipAwareSingleError(t *testing.T) {
|
|
for _, i := range []int{1, 4} {
|
|
t.Run(fmt.Sprintf("limit-%d", i), func(t *testing.T) {
|
|
g := NewSkipAware(New(i))
|
|
for i := 0; i < 10; i++ {
|
|
g.Go(func() error {
|
|
time.Sleep(10 * time.Millisecond)
|
|
if i == 5 {
|
|
return pipe.Skip("fake skip")
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
require.EqualError(t, g.Wait(), "fake skip")
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSemaphoreSkipAwareNoSkips(t *testing.T) {
|
|
for _, i := range []int{1, 4} {
|
|
t.Run(fmt.Sprintf("limit-%d", i), func(t *testing.T) {
|
|
g := NewSkipAware(New(i))
|
|
for i := 0; i < 10; i++ {
|
|
g.Go(func() error {
|
|
time.Sleep(10 * time.Millisecond)
|
|
return nil
|
|
})
|
|
}
|
|
require.NoError(t, g.Wait())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSemaphoreSkipAndRealError(t *testing.T) {
|
|
g := NewSkipAware(New(10))
|
|
for i := 0; i < 100; i++ {
|
|
g.Go(func() error {
|
|
time.Sleep(10 * time.Millisecond)
|
|
return pipe.Skip("fake skip")
|
|
})
|
|
}
|
|
g.Go(func() error {
|
|
time.Sleep(10 * time.Millisecond)
|
|
return fmt.Errorf("errrrrr")
|
|
})
|
|
require.EqualError(t, g.Wait(), "errrrrr")
|
|
}
|