xref: /freebsd/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_table.lua (revision 61145dc2b94f12f6a47344fb9aac702321880e43)
1--SPDX-License-Identifier: MIT
2--[[
3--*****************************************************************************
4--* Copyright (C) 1994-2016 Lua.org, PUC-Rio.
5--*
6--* Permission is hereby granted, free of charge, to any person obtaining
7--* a copy of this software and associated documentation files (the
8--* "Software"), to deal in the Software without restriction, including
9--* without limitation the rights to use, copy, modify, merge, publish,
10--* distribute, sublicense, and/or sell copies of the Software, and to
11--* permit persons to whom the Software is furnished to do so, subject to
12--* the following conditions:
13--*
14--* The above copyright notice and this permission notice shall be
15--* included in all copies or substantial portions of the Software.
16--*
17--* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18--* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19--* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20--* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21--* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22--* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23--* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24--*****************************************************************************
25--]]
26
27-- testing table library
28
29-- workaround missing pcall in zfs lua implementation
30local function tuple(...)
31  return {n=select('#', ...), ...}
32end
33
34function pcall(f, ...)
35  local co = coroutine.create(f)
36  local res = tuple(coroutine.resume(co, ...))
37  if res[1] and coroutine.status(co) == "suspended" then
38    res[1] = false
39  end
40  return table.unpack(res, 1, res.n)
41end
42
43
44-- workaround missing math lib in zfs lua implementation
45local A1, A2 = 727595, 798405  -- 5^17=D20*A1+A2
46local D20, D40 = 1048576, 1099511627776  -- 2^20, 2^40
47local X1, X2 = 0, 1
48function rand()
49    local U = X2*A2
50    local V = (X1*A2 + X2*A1) % D20
51    V = (V*D20 + U) % D40
52    X1 = V/D20
53    X2 = V - X1*D20
54    return V*100/D40
55end
56
57
58-- testing unpack
59
60local unpack = table.unpack
61
62local x,y,z,a,n
63a = {}; lim = 2000
64for i=1, lim do a[i]=i end
65assert(select(lim, unpack(a)) == lim and select('#', unpack(a)) == lim)
66x = unpack(a)
67assert(x == 1)
68x = {unpack(a)}
69assert(#x == lim and x[1] == 1 and x[lim] == lim)
70x = {unpack(a, lim-2)}
71assert(#x == 3 and x[1] == lim-2 and x[3] == lim)
72x = {unpack(a, 10, 6)}
73assert(next(x) == nil)   -- no elements
74x = {unpack(a, 11, 10)}
75assert(next(x) == nil)   -- no elements
76x,y = unpack(a, 10, 10)
77assert(x == 10 and y == nil)
78x,y,z = unpack(a, 10, 11)
79assert(x == 10 and y == 11 and z == nil)
80a,x = unpack{1}
81assert(a==1 and x==nil)
82a,x = unpack({1,2}, 1, 1)
83assert(a==1 and x==nil)
84
85if not _no32 then
86  assert(not pcall(unpack, {}, 0, 2^31-1))
87  assert(not pcall(unpack, {}, 1, 2^31-1))
88  assert(not pcall(unpack, {}, -(2^31), 2^31-1))
89  assert(not pcall(unpack, {}, -(2^31 - 1), 2^31-1))
90  assert(pcall(unpack, {}, 2^31-1, 0))
91  assert(pcall(unpack, {}, 2^31-1, 1))
92  pcall(unpack, {}, 1, 2^31)
93  a, b = unpack({[2^31-1] = 20}, 2^31-1, 2^31-1)
94  assert(a == 20 and b == nil)
95  a, b = unpack({[2^31-1] = 20}, 2^31-2, 2^31-1)
96  assert(a == nil and b == 20)
97end
98
99-- testing pack
100
101a = table.pack()
102assert(a[1] == nil and a.n == 0)
103
104a = table.pack(table)
105assert(a[1] == table and a.n == 1)
106
107a = table.pack(nil, nil, nil, nil)
108assert(a[1] == nil and a.n == 4)
109
110
111-- testing sort
112
113
114-- test checks for invalid order functions
115local function check (t)
116  local function f(a, b) assert(a and b); return true end
117  local s, e = pcall(table.sort, t, f)
118  assert(not s and e:find("invalid order function"))
119end
120
121check{1,2,3,4}
122check{1,2,3,4,5}
123check{1,2,3,4,5,6}
124
125
126function check (a, f)
127  f = f or function (x,y) return x<y end;
128  for n = #a, 2, -1 do
129    assert(not f(a[n], a[n-1]))
130  end
131end
132
133a = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
134     "Oct", "Nov", "Dec"}
135
136table.sort(a)
137check(a)
138
139function perm (s, n)
140  n = n or #s
141  if n == 1 then
142    local t = {unpack(s)}
143    table.sort(t)
144    check(t)
145  else
146    for i = 1, n do
147      s[i], s[n] = s[n], s[i]
148      perm(s, n - 1)
149      s[i], s[n] = s[n], s[i]
150    end
151  end
152end
153
154perm{}
155perm{1}
156perm{1,2}
157perm{1,2,3}
158perm{1,2,3,4}
159perm{2,2,3,4}
160perm{1,2,3,4,5}
161perm{1,2,3,3,5}
162perm{1,2,3,4,5,6}
163perm{2,2,3,3,5,6}
164
165limit = 5000
166
167a = {}
168for i=1,limit do
169  a[i] = rand()
170end
171
172table.sort(a)
173check(a)
174
175table.sort(a)
176check(a)
177
178a = {}
179for i=1,limit do
180  a[i] = rand()
181end
182
183i=0
184table.sort(a, function(x,y) i=i+1; return y<x end)
185check(a, function(x,y) return y<x end)
186
187
188table.sort{}  -- empty array
189
190for i=1,limit do a[i] = false end
191table.sort(a, function(x,y) return nil end)
192check(a, function(x,y) return nil end)
193for i,v in pairs(a) do assert(not v or i=='n' and v==limit) end
194
195A = {"�lo", "\0first :-)", "alo", "then this one", "45", "and a new"}
196table.sort(A)
197check(A)
198
199tt = {__lt = function (a,b) return a.val < b.val end}
200a = {}
201for i=1,10 do  a[i] = {val=rand(100)}; setmetatable(a[i], tt); end
202table.sort(a)
203check(a, tt.__lt)
204check(a)
205
206
207-- test remove
208local function test (a)
209  table.insert(a, 10); table.insert(a, 2, 20);
210  table.insert(a, 1, -1); table.insert(a, 40);
211  table.insert(a, #a+1, 50)
212  table.insert(a, 2, -2)
213  assert(table.remove(a,1) == -1)
214  assert(table.remove(a,1) == -2)
215  assert(table.remove(a,1) == 10)
216  assert(table.remove(a,1) == 20)
217  assert(table.remove(a,1) == 40)
218  assert(table.remove(a,1) == 50)
219  assert(table.remove(a,1) == nil)
220end
221
222a = {n=0, [-7] = "ban"}
223test(a)
224assert(a.n == 0 and a[-7] == "ban")
225
226a = {[-7] = "ban"};
227test(a)
228assert(a.n == nil and #a == 0 and a[-7] == "ban")
229
230
231table.insert(a, 1, 10); table.insert(a, 1, 20); table.insert(a, 1, -1)
232assert(table.remove(a) == 10)
233assert(table.remove(a) == 20)
234assert(table.remove(a) == -1)
235
236a = {'c', 'd'}
237table.insert(a, 3, 'a')
238table.insert(a, 'b')
239assert(table.remove(a, 1) == 'c')
240assert(table.remove(a, 1) == 'd')
241assert(table.remove(a, 1) == 'a')
242assert(table.remove(a, 1) == 'b')
243assert(#a == 0 and a.n == nil)
244
245a = {10,20,30,40}
246assert(a[#a] == 40)
247assert(table.remove(a, #a) == 40)
248assert(a[#a] == 30)
249assert(table.remove(a, 2) == 20)
250assert(a[#a] == 30 and #a == 2)
251
252
253return "OK"
254