github.com/marcomrtt/gopher-lua@v0.1.1/script_test.go (about)

     1  package lua
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/marcomrtt/gopher-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(Options{
    73  			RegistrySize:        1024 * 20,
    74  			CallStackSize:       1024,
    75  			IncludeGoStackTrace: true,
    76  		})
    77  		L.SetMx(maxMemory)
    78  		if err := L.DoFile(script); err != nil {
    79  			t.Error(err)
    80  		}
    81  		L.Close()
    82  	}
    83  }
    84  
    85  var numActiveUserDatas int32 = 0
    86  
    87  type finalizerStub struct{ x byte }
    88  
    89  func allocFinalizerUserData(L *LState) int {
    90  	ud := L.NewUserData()
    91  	atomic.AddInt32(&numActiveUserDatas, 1)
    92  	a := finalizerStub{}
    93  	ud.Value = &a
    94  	runtime.SetFinalizer(&a, func(aa *finalizerStub) {
    95  		atomic.AddInt32(&numActiveUserDatas, -1)
    96  	})
    97  	L.Push(ud)
    98  	return 1
    99  }
   100  
   101  func sleep(L *LState) int {
   102  	time.Sleep(time.Duration(L.CheckInt(1)) * time.Millisecond)
   103  	return 0
   104  }
   105  
   106  func countFinalizers(L *LState) int {
   107  	L.Push(LNumber(numActiveUserDatas))
   108  	return 1
   109  }
   110  
   111  // TestLocalVarFree verifies that tables and user user datas which are no longer referenced by the lua script are
   112  // correctly gc-ed. There was a bug in gopher lua where local vars were not being gc-ed in all circumstances.
   113  func TestLocalVarFree(t *testing.T) {
   114  	s := `
   115  		function Test(a, b, c)
   116  			local a = { v = allocFinalizer() }
   117  			local b = { v = allocFinalizer() }
   118  			return a
   119  		end
   120  		Test(1,2,3)
   121  		for i = 1, 100 do
   122  			collectgarbage()
   123  			if countFinalizers() == 0 then
   124  				return
   125  			end
   126  			sleep(100)
   127  		end
   128  		error("user datas not finalized after 100 gcs")
   129  `
   130  	L := NewState()
   131  	L.SetGlobal("allocFinalizer", L.NewFunction(allocFinalizerUserData))
   132  	L.SetGlobal("sleep", L.NewFunction(sleep))
   133  	L.SetGlobal("countFinalizers", L.NewFunction(countFinalizers))
   134  	defer L.Close()
   135  	if err := L.DoString(s); err != nil {
   136  		t.Error(err)
   137  	}
   138  }
   139  
   140  func TestGlua(t *testing.T) {
   141  	testScriptDir(t, gluaTests, "_glua-tests")
   142  }
   143  
   144  func TestLua(t *testing.T) {
   145  	testScriptDir(t, luaTests, "_lua5.1-tests")
   146  }