1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-01-16 03:52:12 +02:00
goreleaser/internal/semerrgroup/sem_test.go
Carlos Alexandro Becker f0b4db184e
fix: snapcraft temporary directory + concurrency (#4963)
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
2024-06-29 19:00:52 -03:00

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")
}