testing: pass N, P into Run of hammer (#2146)
Signed-off-by: Takeshi Yoneda <t.y.mathetake@gmail.com>
This commit is contained in:
@@ -97,7 +97,7 @@ func closeModuleWhileInUse(t *testing.T, r wazero.Runtime, closeFn func(imported
|
|||||||
|
|
||||||
// As this is a blocking function call, only run 1 per goroutine.
|
// As this is a blocking function call, only run 1 per goroutine.
|
||||||
i := importing // pin the module used inside goroutines
|
i := importing // pin the module used inside goroutines
|
||||||
hammer.NewHammer(t, P, 1).Run(func(name string) {
|
hammer.NewHammer(t, P, 1).Run(func(p, n int) {
|
||||||
// In all cases, the importing module is closed, so the error should have that as its module name.
|
// In all cases, the importing module is closed, so the error should have that as its module name.
|
||||||
requireFunctionCallExits(t, i.ExportedFunction("call_return_input"))
|
requireFunctionCallExits(t, i.ExportedFunction("call_return_input"))
|
||||||
}, func() { // When all functions are in-flight, re-assign the modules.
|
}, func() { // When all functions are in-flight, re-assign the modules.
|
||||||
|
|||||||
@@ -100,8 +100,9 @@ func incrementGuardedByMutex(t *testing.T, r wazero.Runtime) {
|
|||||||
mod, err := r.Instantiate(testCtx, mutexWasm)
|
mod, err := r.Instantiate(testCtx, mutexWasm)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
hammer.NewHammer(t, P, 30000).Run(func(name string) {
|
fns := make([]api.Function, P)
|
||||||
_, err := mod.ExportedFunction(tt.fn).Call(testCtx)
|
hammer.NewHammer(t, P, 30000).Run(func(p, n int) {
|
||||||
|
_, err := mustGetFn(mod, tt.fn, fns, p).Call(testCtx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}, func() {})
|
}, func() {})
|
||||||
|
|
||||||
@@ -161,8 +162,9 @@ func atomicAdd(t *testing.T, r wazero.Runtime) {
|
|||||||
mod, err := r.Instantiate(testCtx, addWasm)
|
mod, err := r.Instantiate(testCtx, addWasm)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
hammer.NewHammer(t, P, 30000).Run(func(name string) {
|
fns := make([]api.Function, P)
|
||||||
_, err := mod.ExportedFunction(tt.fn).Call(testCtx)
|
hammer.NewHammer(t, P, 30000).Run(func(p, n int) {
|
||||||
|
_, err := mustGetFn(mod, tt.fn, fns, p).Call(testCtx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}, func() {})
|
}, func() {})
|
||||||
|
|
||||||
@@ -222,8 +224,9 @@ func atomicSub(t *testing.T, r wazero.Runtime) {
|
|||||||
mod, err := r.Instantiate(testCtx, subWasm)
|
mod, err := r.Instantiate(testCtx, subWasm)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
hammer.NewHammer(t, P, 30000).Run(func(name string) {
|
fns := make([]api.Function, P)
|
||||||
_, err := mod.ExportedFunction(tt.fn).Call(testCtx)
|
hammer.NewHammer(t, P, 30000).Run(func(p, n int) {
|
||||||
|
_, err := mustGetFn(mod, tt.fn, fns, p).Call(testCtx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}, func() {})
|
}, func() {})
|
||||||
|
|
||||||
@@ -273,8 +276,9 @@ func atomicXor(t *testing.T, r wazero.Runtime) {
|
|||||||
|
|
||||||
mod.Memory().WriteUint32Le(0, 12345)
|
mod.Memory().WriteUint32Le(0, 12345)
|
||||||
|
|
||||||
hammer.NewHammer(t, P, 30000).Run(func(name string) {
|
fns := make([]api.Function, P)
|
||||||
_, err := mod.ExportedFunction(tt.fn).Call(testCtx)
|
hammer.NewHammer(t, P, 30000).Run(func(p, n int) {
|
||||||
|
_, err := mustGetFn(mod, tt.fn, fns, p).Call(testCtx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}, func() {})
|
}, func() {})
|
||||||
|
|
||||||
@@ -286,3 +290,14 @@ func atomicXor(t *testing.T, r wazero.Runtime) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mustGetFn is a helper to get a function from a module, caching the result to avoid repeated allocations.
|
||||||
|
//
|
||||||
|
// Creating ExportedFunction per invocation costs a lot here since each time the runtime allocates the execution stack,
|
||||||
|
// so only do it once per goroutine of the hammer.
|
||||||
|
func mustGetFn(m api.Module, name string, fns []api.Function, p int) api.Function {
|
||||||
|
if fns[p] == nil {
|
||||||
|
fns[p] = m.ExportedFunction(name)
|
||||||
|
}
|
||||||
|
return fns[p]
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package hammer
|
package hammer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -38,7 +37,7 @@ type Hammer interface {
|
|||||||
// if t.Failed() {
|
// if t.Failed() {
|
||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
Run(test func(name string), onRunning func())
|
Run(test func(p, n int), onRunning func())
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewHammer returns a Hammer initialized to indicated count of goroutines (P) and iterations per goroutine (N).
|
// NewHammer returns a Hammer initialized to indicated count of goroutines (P) and iterations per goroutine (N).
|
||||||
@@ -58,7 +57,7 @@ type hammer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run implements Hammer.Run
|
// Run implements Hammer.Run
|
||||||
func (h *hammer) Run(test func(name string), onRunning func()) {
|
func (h *hammer) Run(test func(p, n int), onRunning func()) {
|
||||||
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(h.P / 2)) // Ensure goroutines have to switch cores.
|
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(h.P / 2)) // Ensure goroutines have to switch cores.
|
||||||
|
|
||||||
// running track
|
// running track
|
||||||
@@ -84,7 +83,7 @@ func (h *hammer) Run(test func(name string), onRunning func()) {
|
|||||||
|
|
||||||
unblocked.Wait() // Wait to be unblocked
|
unblocked.Wait() // Wait to be unblocked
|
||||||
for n := 0; n < h.N; n++ { // Invoke one test
|
for n := 0; n < h.N; n++ { // Invoke one test
|
||||||
test(fmt.Sprintf("%s:%d-%d", h.t.Name(), p, n))
|
test(p, n)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -269,7 +269,7 @@ func TestModule_BuildFunctionDefinitions(t *testing.T) {
|
|||||||
testName := tc.name + " (concurrent)"
|
testName := tc.name + " (concurrent)"
|
||||||
t.Run(testName, func(t *testing.T) {
|
t.Run(testName, func(t *testing.T) {
|
||||||
hammer.NewHammer(t, nGoroutines, nIterations).
|
hammer.NewHammer(t, nGoroutines, nIterations).
|
||||||
Run(func(name string) {
|
Run(func(p, n int) {
|
||||||
tc.m.buildFunctionDefinitions()
|
tc.m.buildFunctionDefinitions()
|
||||||
}, nil)
|
}, nil)
|
||||||
|
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ func TestModuleInstance_Close(t *testing.T) {
|
|||||||
require.True(t, ok, "sysCtx.openedFiles was empty")
|
require.True(t, ok, "sysCtx.openedFiles was empty")
|
||||||
|
|
||||||
// Closing should not err even when concurrently closed.
|
// Closing should not err even when concurrently closed.
|
||||||
hammer.NewHammer(t, 100, 10).Run(func(name string) {
|
hammer.NewHammer(t, 100, 10).Run(func(p, n int) {
|
||||||
require.NoError(t, m.Close(testCtx))
|
require.NoError(t, m.Close(testCtx))
|
||||||
// closeWithExitCode is the one called during Store.CloseWithExitCode.
|
// closeWithExitCode is the one called during Store.CloseWithExitCode.
|
||||||
require.NoError(t, m.closeWithExitCode(testCtx, 0))
|
require.NoError(t, m.closeWithExitCode(testCtx, 0))
|
||||||
|
|||||||
@@ -220,8 +220,8 @@ func TestStore_hammer(t *testing.T) {
|
|||||||
P = 4
|
P = 4
|
||||||
N = 100
|
N = 100
|
||||||
}
|
}
|
||||||
hammer.NewHammer(t, P, N).Run(func(name string) {
|
hammer.NewHammer(t, P, N).Run(func(p, n int) {
|
||||||
mod, instantiateErr := s.Instantiate(testCtx, importingModule, name, sys.DefaultContext(nil), []FunctionTypeID{0})
|
mod, instantiateErr := s.Instantiate(testCtx, importingModule, fmt.Sprintf("%d:%d", p, n), sys.DefaultContext(nil), []FunctionTypeID{0})
|
||||||
require.NoError(t, instantiateErr)
|
require.NoError(t, instantiateErr)
|
||||||
require.NoError(t, mod.Close(testCtx))
|
require.NoError(t, mod.Close(testCtx))
|
||||||
}, nil)
|
}, nil)
|
||||||
@@ -279,7 +279,7 @@ func TestStore_hammer_close(t *testing.T) {
|
|||||||
instances[i] = mod
|
instances[i] = mod
|
||||||
}
|
}
|
||||||
|
|
||||||
hammer.NewHammer(t, 100, 2).Run(func(name string) {
|
hammer.NewHammer(t, 100, 2).Run(func(p, n int) {
|
||||||
for i := 0; i < instCount; i++ {
|
for i := 0; i < instCount; i++ {
|
||||||
if i == instCount/2 {
|
if i == instCount/2 {
|
||||||
// Close store concurrently as well.
|
// Close store concurrently as well.
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ func TestDWARFLines_Line_Zig(t *testing.T) {
|
|||||||
tc := tc
|
tc := tc
|
||||||
t.Run(fmt.Sprintf("%#x/%s", tc.offset, tc.exp), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%#x/%s", tc.offset, tc.exp), func(t *testing.T) {
|
||||||
// Ensures that DWARFLines.Line is goroutine-safe.
|
// Ensures that DWARFLines.Line is goroutine-safe.
|
||||||
hammer.NewHammer(t, 100, 5).Run(func(name string) {
|
hammer.NewHammer(t, 100, 5).Run(func(p, n int) {
|
||||||
actual := mod.DWARFLines.Line(tc.offset)
|
actual := mod.DWARFLines.Line(tc.offset)
|
||||||
require.Equal(t, len(tc.exp), len(actual))
|
require.Equal(t, len(tc.exp), len(actual))
|
||||||
for i := range tc.exp {
|
for i := range tc.exp {
|
||||||
|
|||||||
Reference in New Issue
Block a user