diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-12-14 13:49:02 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-12-14 13:49:02 -0200 |
commit | 2258f3133b27a6a3db703644311e0a59b6c7b0f6 (patch) | |
tree | 13b8e2d681e5a63ca87aa4a72c887e9bf0a6f26f | |
parent | 57f5b81da9f1f23380d20f164012e10c5f4fef94 (diff) | |
download | lua-2258f3133b27a6a3db703644311e0a59b6c7b0f6.tar.gz lua-2258f3133b27a6a3db703644311e0a59b6c7b0f6.tar.bz2 lua-2258f3133b27a6a3db703644311e0a59b6c7b0f6.zip |
Added file 'testes/heavy.lua'
This file is not part of the regular tests. It tests error conditions
that demand too much memory or too much time to create:
* string with too many characters
* control structure with body too large
* chunk with too many lines
* identifier with too many characters
* chunks with too many instructions
* function with too many constants
* too many strings internalized
* table with too many entries
In machines with limited memory (less than 150 GB), many tests run up
to a "not enough memory" error. We need some memory (~256 GB) to
run all tests up to their intrinsic limits.
-rw-r--r-- | testes/heavy.lua | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/testes/heavy.lua b/testes/heavy.lua new file mode 100644 index 00000000..4731c747 --- /dev/null +++ b/testes/heavy.lua | |||
@@ -0,0 +1,173 @@ | |||
1 | -- $Id: heavy.lua,v 1.7 2017/12/29 15:42:15 roberto Exp $ | ||
2 | -- See Copyright Notice in file all.lua | ||
3 | |||
4 | local function teststring () | ||
5 | print("creating a string too long") | ||
6 | do | ||
7 | local a = "x" | ||
8 | local st, msg = pcall(function () | ||
9 | while true do | ||
10 | a = a .. a.. a.. a.. a.. a.. a.. a.. a.. a | ||
11 | .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a | ||
12 | .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a | ||
13 | .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a | ||
14 | .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a | ||
15 | .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a | ||
16 | .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a | ||
17 | .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a | ||
18 | .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a | ||
19 | .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a | ||
20 | print(string.format("string with %d bytes", #a)) | ||
21 | end | ||
22 | end) | ||
23 | assert(not st and | ||
24 | (string.find(msg, "string length overflow") or | ||
25 | string.find(msg, "not enough memory"))) | ||
26 | print("string length overflow with " .. #a * 100) | ||
27 | end | ||
28 | print('+') | ||
29 | end | ||
30 | |||
31 | local function loadrep (x, what) | ||
32 | local p = 1<<20 | ||
33 | local s = string.rep(x, p) | ||
34 | local count = 0 | ||
35 | local function f() | ||
36 | count = count + p | ||
37 | if count % (0x80*p) == 0 then | ||
38 | io.stderr:write("(", count // 2^20, " M)") | ||
39 | end | ||
40 | return s | ||
41 | end | ||
42 | local st, msg = load(f, "=big") | ||
43 | print("\nmemory: ", collectgarbage'count' * 1024) | ||
44 | msg = string.match(msg, "^[^\n]+") -- get only first line | ||
45 | print(string.format("total: 0x%x %s ('%s')", count, what, msg)) | ||
46 | return st, msg | ||
47 | end | ||
48 | |||
49 | |||
50 | function controlstruct () | ||
51 | print("control structure too long") | ||
52 | local lim = ((1 << 24) - 2) // 3 | ||
53 | local s = string.rep("a = a + 1\n", lim) | ||
54 | s = "while true do " .. s .. "end" | ||
55 | assert(load(s)) | ||
56 | print("ok with " .. lim .. " lines") | ||
57 | lim = lim + 3 | ||
58 | s = string.rep("a = a + 1\n", lim) | ||
59 | s = "while true do " .. s .. "end" | ||
60 | local st, msg = load(s) | ||
61 | assert(not st and string.find(msg, "too long")) | ||
62 | print(msg) | ||
63 | end | ||
64 | |||
65 | |||
66 | function manylines () | ||
67 | print("loading chunk with too many lines") | ||
68 | local st, msg = loadrep("\n", "lines") | ||
69 | assert(not st and string.find(msg, "too many lines")) | ||
70 | print('+') | ||
71 | end | ||
72 | |||
73 | |||
74 | function hugeid () | ||
75 | print("loading chunk with huge identifier") | ||
76 | local st, msg = loadrep("a", "chars") | ||
77 | assert(not st and | ||
78 | (string.find(msg, "lexical element too long") or | ||
79 | string.find(msg, "not enough memory"))) | ||
80 | print('+') | ||
81 | end | ||
82 | |||
83 | function toomanyinst () | ||
84 | print("loading chunk with too many instructions") | ||
85 | local st, msg = loadrep("a = 10; ", "instructions") | ||
86 | print('+') | ||
87 | end | ||
88 | |||
89 | |||
90 | local function loadrepfunc (prefix, f) | ||
91 | local count = -1 | ||
92 | local function aux () | ||
93 | count = count + 1 | ||
94 | if count == 0 then | ||
95 | return prefix | ||
96 | else | ||
97 | if count % (0x100000) == 0 then | ||
98 | io.stderr:write("(", count // 2^20, " M)") | ||
99 | end | ||
100 | return f(count) | ||
101 | end | ||
102 | end | ||
103 | local st, msg = load(aux, "k") | ||
104 | print("\nmemory: ", collectgarbage'count' * 1024) | ||
105 | msg = string.match(msg, "^[^\n]+") -- get only first line | ||
106 | print("expected error: ", msg) | ||
107 | end | ||
108 | |||
109 | |||
110 | function toomanyconst () | ||
111 | print("loading function with too many constants") | ||
112 | loadrepfunc("function foo () return {0,", | ||
113 | function (n) | ||
114 | -- convert 'n' to a string in the format [["...",]], | ||
115 | -- where '...' is a kind of number in base 128 | ||
116 | -- (in a range that does not include either the double quote | ||
117 | -- and the escape.) | ||
118 | return string.char(34, | ||
119 | ((n // 128^0) & 127) + 128, | ||
120 | ((n // 128^1) & 127) + 128, | ||
121 | ((n // 128^2) & 127) + 128, | ||
122 | ((n // 128^3) & 127) + 128, | ||
123 | ((n // 128^4) & 127) + 128, | ||
124 | 34, 44) | ||
125 | end) | ||
126 | end | ||
127 | |||
128 | |||
129 | function toomanystr () | ||
130 | local a = {} | ||
131 | local st, msg = pcall(function () | ||
132 | for i = 1, math.huge do | ||
133 | if i % (0x100000) == 0 then | ||
134 | io.stderr:write("(", i // 2^20, " M)") | ||
135 | end | ||
136 | a[i] = string.pack("I", i) | ||
137 | end | ||
138 | end) | ||
139 | local size = #a | ||
140 | a = collectgarbage'count' | ||
141 | print("\nmemory:", a * 1024) | ||
142 | print("expected error:", msg) | ||
143 | print("size:", size) | ||
144 | end | ||
145 | |||
146 | |||
147 | function toomanyidx () | ||
148 | local a = {} | ||
149 | local st, msg = pcall(function () | ||
150 | for i = 1, math.huge do | ||
151 | if i % (0x100000) == 0 then | ||
152 | io.stderr:write("(", i // 2^20, " M)") | ||
153 | end | ||
154 | a[i] = i | ||
155 | end | ||
156 | end) | ||
157 | print("\nmemory: ", collectgarbage'count' * 1024) | ||
158 | print("expected error: ", msg) | ||
159 | print("size:", #a) | ||
160 | end | ||
161 | |||
162 | |||
163 | |||
164 | -- teststring() | ||
165 | -- controlstruct() | ||
166 | -- manylines() | ||
167 | -- hugeid() | ||
168 | -- toomanyinst() | ||
169 | -- toomanyconst() | ||
170 | -- toomanystr() | ||
171 | toomanyidx() | ||
172 | |||
173 | print "OK" | ||