github.com/vivi-app/lua@v1.5.0/script_test.go (about) 1 package lua 2 3 import ( 4 "fmt" 5 "github.com/vivi-app/lua/parse" 6 "os" 7 "runtime" 8 "sync/atomic" 9 "testing" 10 "time" 11 ) 12 13 const maxMemory = 40 14 15 var gluaTests []string = []string{ 16 "base.lua", 17 "coroutine.lua", 18 "db.lua", 19 "issues.lua", 20 "os.lua", 21 "table.lua", 22 "vm.lua", 23 "math.lua", 24 "strings.lua", 25 } 26 27 var luaTests []string = []string{ 28 "attrib.lua", 29 "calls.lua", 30 "closure.lua", 31 "constructs.lua", 32 "events.lua", 33 "literals.lua", 34 "locals.lua", 35 "math.lua", 36 "sort.lua", 37 "strings.lua", 38 "vararg.lua", 39 "pm.lua", 40 "files.lua", 41 } 42 43 func testScriptCompile(t *testing.T, script string) { 44 file, err := os.Open(script) 45 if err != nil { 46 t.Fatal(err) 47 return 48 } 49 chunk, err2 := parse.Parse(file, script) 50 if err2 != nil { 51 t.Fatal(err2) 52 return 53 } 54 parse.Dump(chunk) 55 proto, err3 := Compile(chunk, script) 56 if err3 != nil { 57 t.Fatal(err3) 58 return 59 } 60 nop := func(s string) {} 61 nop(proto.String()) 62 } 63 64 func testScriptDir(t *testing.T, tests []string, directory string) { 65 if err := os.Chdir(directory); err != nil { 66 t.Error(err) 67 } 68 defer os.Chdir("..") 69 for _, script := range tests { 70 fmt.Printf("testing %s/%s\n", directory, script) 71 testScriptCompile(t, script) 72 L := NewState(nil) 73 L.SetMx(maxMemory) 74 if err := L.DoFile(script); err != nil { 75 t.Error(err) 76 } 77 L.Close() 78 } 79 } 80 81 var numActiveUserDatas int32 = 0 82 83 type finalizerStub struct{ x byte } 84 85 func allocFinalizerUserData(L *LState) int { 86 ud := L.NewUserData() 87 atomic.AddInt32(&numActiveUserDatas, 1) 88 a := finalizerStub{} 89 ud.Value = &a 90 runtime.SetFinalizer(&a, func(aa *finalizerStub) { 91 atomic.AddInt32(&numActiveUserDatas, -1) 92 }) 93 L.Push(ud) 94 return 1 95 } 96 97 func sleep(L *LState) int { 98 time.Sleep(time.Duration(L.CheckInt(1)) * time.Millisecond) 99 return 0 100 } 101 102 func countFinalizers(L *LState) int { 103 L.Push(LNumber(numActiveUserDatas)) 104 return 1 105 } 106 107 // TestLocalVarFree verifies that tables and user user datas which are no longer referenced by the lua script are 108 // correctly gc-ed. There was a bug in gopher lua where local vars were not being gc-ed in all circumstances. 109 func TestLocalVarFree(t *testing.T) { 110 s := ` 111 function Test(a, b, c) 112 local a = { v = allocFinalizer() } 113 local b = { v = allocFinalizer() } 114 return a 115 end 116 Test(1,2,3) 117 for i = 1, 100 do 118 collectgarbage() 119 if countFinalizers() == 0 then 120 return 121 end 122 sleep(100) 123 end 124 error("user datas not finalized after 100 gcs") 125 ` 126 L := NewState(nil) 127 L.SetGlobal("allocFinalizer", L.NewFunction(allocFinalizerUserData)) 128 L.SetGlobal("sleep", L.NewFunction(sleep)) 129 L.SetGlobal("countFinalizers", L.NewFunction(countFinalizers)) 130 defer L.Close() 131 if err := L.DoString(s); err != nil { 132 t.Error(err) 133 } 134 } 135 136 func TestGlua(t *testing.T) { 137 testScriptDir(t, gluaTests, "_glua-tests") 138 } 139 140 func TestLua(t *testing.T) { 141 testScriptDir(t, luaTests, "_lua5.1-tests") 142 }