Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
411 changes: 209 additions & 202 deletions lib/executor/constant_arrival_rate_test.go

Large diffs are not rendered by default.

46 changes: 25 additions & 21 deletions lib/executor/constant_vus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"sync"
"testing"
"testing/synctest"
"time"

"github.com/stretchr/testify/assert"
Expand All @@ -24,31 +25,34 @@ func getTestConstantVUsConfig() ConstantVUsConfig {

func TestConstantVUsRun(t *testing.T) {
t.Parallel()
var result sync.Map

runner := simpleRunner(func(ctx context.Context, state *lib.State) error {
select {
case <-ctx.Done():
synctest.Test(t, func(t *testing.T) {
var result sync.Map

runner := simpleRunner(func(ctx context.Context, state *lib.State) error {
select {
case <-ctx.Done():
return nil
default:
}
currIter, _ := result.LoadOrStore(state.VUID, uint64(0))
result.Store(state.VUID, currIter.(uint64)+1)
time.Sleep(210 * time.Millisecond)
return nil
default:
}
currIter, _ := result.LoadOrStore(state.VUID, uint64(0))
result.Store(state.VUID, currIter.(uint64)+1)
time.Sleep(210 * time.Millisecond)
return nil
})
})

test := setupExecutorTest(t, "", "", lib.Options{}, runner, getTestConstantVUsConfig())
defer test.cancel()
test := setupExecutorTest(t, "", "", lib.Options{}, runner, getTestConstantVUsConfig())
defer test.cancel()

require.NoError(t, test.executor.Run(test.ctx, nil))
require.NoError(t, test.executor.Run(test.ctx, nil))

var totalIters uint64
result.Range(func(_, value any) bool {
vuIters := value.(uint64)
assert.Equal(t, uint64(5), vuIters)
totalIters += vuIters
return true
var totalIters uint64
result.Range(func(_, value any) bool {
vuIters := value.(uint64)
assert.Equal(t, uint64(5), vuIters)
totalIters += vuIters
return true
})
assert.Equal(t, uint64(50), totalIters)
})
assert.Equal(t, uint64(50), totalIters)
}
184 changes: 95 additions & 89 deletions lib/executor/execution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import (
"fmt"
"io"
"math/rand"
"sync"
"testing"
"testing/synctest"
"time"

"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -61,111 +61,117 @@ func TestExecutionStateVUIDs(t *testing.T) {
r := rand.New(rand.NewSource(seed))
t.Logf("Random source seeded with %d\n", seed)
count := 100 + r.Intn(50)
wg := sync.WaitGroup{}
wg.Add(count)
for range count {
go func() {
es.GetUniqueVUIdentifiers()
wg.Done()
}()
}
wg.Wait()
idl, idg = es.GetUniqueVUIdentifiers()
assert.EqualValues(t, 4+count, idl)
assert.EqualValues(t, (3+count)*int(offsets[0])+int(start+1), idg)

synctest.Test(t, func(t *testing.T) {
for range count {
go func() {
es.GetUniqueVUIdentifiers()
}()
}
synctest.Wait()
idl, idg = es.GetUniqueVUIdentifiers()
assert.EqualValues(t, 4+count, idl)
assert.EqualValues(t, (3+count)*int(offsets[0])+int(start+1), idg)
})
})
}
}

func TestExecutionStateGettingVUsWhenNonAreAvailable(t *testing.T) {
t.Parallel()
et, err := lib.NewExecutionTuple(nil, nil)
require.NoError(t, err)
es := lib.NewExecutionState(nil, et, 0, 0)
logHook := testutils.NewLogHook(logrus.WarnLevel)
testLog := logrus.New()
testLog.AddHook(logHook)
testLog.SetOutput(io.Discard)
vu, err := es.GetPlannedVU(logrus.NewEntry(testLog), true)
require.Nil(t, vu)
require.Error(t, err)
require.Contains(t, err.Error(), "could not get a VU from the buffer in")
entries := logHook.Drain()
require.Equal(t, lib.MaxRetriesGetPlannedVU, len(entries))
for _, entry := range entries {
require.Contains(t, entry.Message, "Could not get a VU from the buffer for ")
}

synctest.Test(t, func(t *testing.T) {
et, err := lib.NewExecutionTuple(nil, nil)
require.NoError(t, err)
es := lib.NewExecutionState(nil, et, 0, 0)
logHook := testutils.NewLogHook(logrus.WarnLevel)
testLog := logrus.New()
testLog.AddHook(logHook)
testLog.SetOutput(io.Discard)
vu, err := es.GetPlannedVU(logrus.NewEntry(testLog), true)
require.Nil(t, vu)
require.Error(t, err)
require.Contains(t, err.Error(), "could not get a VU from the buffer in")
entries := logHook.Drain()
require.Equal(t, lib.MaxRetriesGetPlannedVU, len(entries))
for _, entry := range entries {
require.Contains(t, entry.Message, "Could not get a VU from the buffer for ")
}
})
}

func TestExecutionStateGettingVUs(t *testing.T) {
t.Parallel()
logHook := testutils.NewLogHook(logrus.WarnLevel, logrus.DebugLevel)
testLog := logrus.New()
testLog.AddHook(logHook)
testLog.SetOutput(io.Discard)
logEntry := logrus.NewEntry(testLog)

et, err := lib.NewExecutionTuple(nil, nil)
require.NoError(t, err)
es := lib.NewExecutionState(nil, et, 10, 20)
es.SetInitVUFunc(func(_ context.Context, _ *logrus.Entry) (lib.InitializedVU, error) {
return &minirunner.VU{}, nil
})
synctest.Test(t, func(t *testing.T) {
logHook := testutils.NewLogHook(logrus.WarnLevel, logrus.DebugLevel)
testLog := logrus.New()
testLog.AddHook(logHook)
testLog.SetOutput(io.Discard)
logEntry := logrus.NewEntry(testLog)

var vu lib.InitializedVU
for i := range 10 {
require.EqualValues(t, i, es.GetInitializedVUsCount())
vu, err = es.InitializeNewVU(context.Background(), logEntry)
et, err := lib.NewExecutionTuple(nil, nil)
require.NoError(t, err)
require.EqualValues(t, i+1, es.GetInitializedVUsCount())
es.ReturnVU(vu, false)
require.EqualValues(t, 0, es.GetCurrentlyActiveVUsCount())
require.EqualValues(t, i+1, es.GetInitializedVUsCount())
}
es := lib.NewExecutionState(nil, et, 10, 20)
es.SetInitVUFunc(func(_ context.Context, _ *logrus.Entry) (lib.InitializedVU, error) {
return &minirunner.VU{}, nil
})

// Test getting initialized VUs is okay :)
for i := range 10 {
require.EqualValues(t, i, es.GetCurrentlyActiveVUsCount())
vu, err = es.GetPlannedVU(logEntry, true)
require.NoError(t, err)
require.Empty(t, logHook.Drain())
require.NotNil(t, vu)
require.EqualValues(t, i+1, es.GetCurrentlyActiveVUsCount())
require.EqualValues(t, 10, es.GetInitializedVUsCount())
}
var vu lib.InitializedVU
for i := range 10 {
require.EqualValues(t, i, es.GetInitializedVUsCount())
vu, err = es.InitializeNewVU(context.Background(), logEntry)
require.NoError(t, err)
require.EqualValues(t, i+1, es.GetInitializedVUsCount())
es.ReturnVU(vu, false)
require.EqualValues(t, 0, es.GetCurrentlyActiveVUsCount())
require.EqualValues(t, i+1, es.GetInitializedVUsCount())
}

// Test getting initialized VUs is okay :)
for i := range 10 {
require.EqualValues(t, i, es.GetCurrentlyActiveVUsCount())
vu, err = es.GetPlannedVU(logEntry, true)
require.NoError(t, err)
require.Empty(t, logHook.Drain())
require.NotNil(t, vu)
require.EqualValues(t, i+1, es.GetCurrentlyActiveVUsCount())
require.EqualValues(t, 10, es.GetInitializedVUsCount())
}

// Check that getting 1 more planned VU will error out
vu, err = es.GetPlannedVU(logEntry, true)
require.Nil(t, vu)
require.Error(t, err)
require.Contains(t, err.Error(), "could not get a VU from the buffer in")
entries := logHook.Drain()
require.Equal(t, lib.MaxRetriesGetPlannedVU, len(entries))
for _, entry := range entries {
require.Contains(t, entry.Message, "Could not get a VU from the buffer for ")
}
// Check that getting 1 more planned VU will error out
vu, err = es.GetPlannedVU(logEntry, true)
require.Nil(t, vu)
require.Error(t, err)
require.Contains(t, err.Error(), "could not get a VU from the buffer in")
entries := logHook.Drain()
require.Equal(t, lib.MaxRetriesGetPlannedVU, len(entries))
for _, entry := range entries {
require.Contains(t, entry.Message, "Could not get a VU from the buffer for ")
}

// Test getting uninitialized vus will work
for i := range 10 {
require.EqualValues(t, 10+i, es.GetInitializedVUsCount())
vu, err = es.GetUnplannedVU(context.Background(), logEntry)
require.NoError(t, err)
require.Empty(t, logHook.Drain())
require.NotNil(t, vu)
require.EqualValues(t, 10+i+1, es.GetInitializedVUsCount())
require.EqualValues(t, 10, es.GetCurrentlyActiveVUsCount())
}

// Test getting uninitialized vus will work
for i := range 10 {
require.EqualValues(t, 10+i, es.GetInitializedVUsCount())
// Check that getting 1 more unplanned VU will error out
vu, err = es.GetUnplannedVU(context.Background(), logEntry)
require.NoError(t, err)
require.Empty(t, logHook.Drain())
require.NotNil(t, vu)
require.EqualValues(t, 10+i+1, es.GetInitializedVUsCount())
require.EqualValues(t, 10, es.GetCurrentlyActiveVUsCount())
}

// Check that getting 1 more unplanned VU will error out
vu, err = es.GetUnplannedVU(context.Background(), logEntry)
require.Nil(t, vu)
require.Error(t, err)
require.Contains(t, err.Error(), "could not get a VU from the buffer in")
entries = logHook.Drain()
require.Equal(t, lib.MaxRetriesGetPlannedVU, len(entries))
for _, entry := range entries {
require.Contains(t, entry.Message, "Could not get a VU from the buffer for ")
}
require.Nil(t, vu)
require.Error(t, err)
require.Contains(t, err.Error(), "could not get a VU from the buffer in")
entries = logHook.Drain()
require.Equal(t, lib.MaxRetriesGetPlannedVU, len(entries))
for _, entry := range entries {
require.Contains(t, entry.Message, "Could not get a VU from the buffer for ")
}
})
}

func TestMarkStartedPanicsOnSecondRun(t *testing.T) {
Expand Down
Loading
Loading