3c30109cd0
* fix bytecode encoding/decoding of builtin modules * Bytecode.Decode() to take map[string]objects.Importable * add objects.ModuleMap * update docs * stdlib.GetModuleMap()
99 lines
1.8 KiB
Go
99 lines
1.8 KiB
Go
package script_test
|
|
|
|
import (
|
|
"math/rand"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/d5/tengo/assert"
|
|
"github.com/d5/tengo/objects"
|
|
"github.com/d5/tengo/script"
|
|
)
|
|
|
|
func TestScriptConcurrency(t *testing.T) {
|
|
solve := func(a, b, c int) (d, e int) {
|
|
a += 2
|
|
b += c
|
|
a += b * 2
|
|
d = a + b + c
|
|
e = 0
|
|
for i := 1; i <= d; i++ {
|
|
e += i
|
|
}
|
|
e *= 2
|
|
return
|
|
}
|
|
|
|
code := []byte(`
|
|
mod1 := import("mod1")
|
|
|
|
a += 2
|
|
b += c
|
|
a += b * 2
|
|
|
|
arr := [a, b, c]
|
|
arrstr := string(arr)
|
|
map := {a: a, b: b, c: c}
|
|
|
|
d := a + b + c
|
|
s := 0
|
|
|
|
for i:=1; i<=d; i++ {
|
|
s += i
|
|
}
|
|
|
|
e := mod1.double(s)
|
|
`)
|
|
mod1 := map[string]objects.Object{
|
|
"double": &objects.UserFunction{
|
|
Value: func(args ...objects.Object) (ret objects.Object, err error) {
|
|
arg0, _ := objects.ToInt64(args[0])
|
|
ret = &objects.Int{Value: arg0 * 2}
|
|
return
|
|
},
|
|
},
|
|
}
|
|
|
|
scr := script.New(code)
|
|
_ = scr.Add("a", 0)
|
|
_ = scr.Add("b", 0)
|
|
_ = scr.Add("c", 0)
|
|
mods := objects.NewModuleMap()
|
|
mods.AddBuiltinModule("mod1", mod1)
|
|
scr.SetImports(mods)
|
|
compiled, err := scr.Compile()
|
|
assert.NoError(t, err)
|
|
|
|
executeFn := func(compiled *script.Compiled, a, b, c int) (d, e int) {
|
|
_ = compiled.Set("a", a)
|
|
_ = compiled.Set("b", b)
|
|
_ = compiled.Set("c", c)
|
|
err := compiled.Run()
|
|
assert.NoError(t, err)
|
|
d = compiled.Get("d").Int()
|
|
e = compiled.Get("e").Int()
|
|
return
|
|
}
|
|
|
|
concurrency := 500
|
|
var wg sync.WaitGroup
|
|
wg.Add(concurrency)
|
|
for i := 0; i < concurrency; i++ {
|
|
go func(compiled *script.Compiled) {
|
|
time.Sleep(time.Duration(rand.Int63n(50)) * time.Millisecond)
|
|
defer wg.Done()
|
|
|
|
a := rand.Intn(10)
|
|
b := rand.Intn(10)
|
|
c := rand.Intn(10)
|
|
|
|
d, e := executeFn(compiled, a, b, c)
|
|
expectedD, expectedE := solve(a, b, c)
|
|
|
|
assert.Equal(t, expectedD, d, "input: %d, %d, %d", a, b, c)
|
|
assert.Equal(t, expectedE, e, "input: %d, %d, %d", a, b, c)
|
|
}(compiled.Clone())
|
|
}
|
|
wg.Wait()
|
|
}
|