From a9dd90f58443d26ef150a5f6766405f5eb15f9e7 Mon Sep 17 00:00:00 2001
From: Konstantin Osipov <kostja.osipov@gmail.com>
Date: Sat, 27 Aug 2011 11:28:17 +0400
Subject: [PATCH] Lua: add an implementation of simple FIFO queue to the test
 suite.

Implement box.unpack() to be able to convert integers,
packed into a tuple, to Lua numbers
---
 core/tarantool_lua.m | 26 +++++++++++++++++++
 test/box/fifo.lua    | 31 +++++++++++++++++++++++
 test/box/lua.result  | 60 ++++++++++++++++++++++++++++++++++++++++++--
 test/box/lua.test    | 20 +++++++++++++++
 4 files changed, 135 insertions(+), 2 deletions(-)
 create mode 100644 test/box/fifo.lua

diff --git a/core/tarantool_lua.m b/core/tarantool_lua.m
index fd736cbf41..20ace99567 100644
--- a/core/tarantool_lua.m
+++ b/core/tarantool_lua.m
@@ -157,10 +157,36 @@ lbox_pack(struct lua_State *L)
 	return 1;
 }
 
+static int
+lbox_unpack(struct lua_State *L)
+{
+	const char *format = luaL_checkstring(L, 1);
+	int i = 2; /* first arg comes second */
+	int nargs = lua_gettop(L);
+	u32 u32buf;
+
+	while (*format) {
+		if (i > nargs)
+			luaL_error(L, "box.unpack: argument count does not match the format");
+		switch (*format) {
+		case 'i':
+			u32buf = * (u32 *) lua_tostring(L, i);
+			lua_pushnumber(L, u32buf);
+			break;
+		default:
+			luaL_error(L, "box.unpack: unsupported pack "
+				   "format specifier '%c'", *format);
+		} /* end switch */
+		i++;
+		format++;
+	}
+	return i-2;
+}
 /** A descriptor for box.tbuf object methods */
 
 static const struct luaL_reg boxlib[] = {
 	{"pack", lbox_pack},
+	{"unpack", lbox_unpack},
 	{NULL, NULL}
 };
 
diff --git a/test/box/fifo.lua b/test/box/fifo.lua
new file mode 100644
index 0000000000..e8915fad3e
--- /dev/null
+++ b/test/box/fifo.lua
@@ -0,0 +1,31 @@
+fifomax = 5
+function find_or_create_fifo(name)
+    fifo = box.select(0, 0, name)
+    if fifo == nil then
+        fifo = {}
+        for i = 1, fifomax do fifo[i] = 0 end
+        fifo = box.insert(0, name, 3, 3, unpack(fifo))
+    end
+    return fifo
+end
+function fifo_push(name, val)
+    fifo = find_or_create_fifo(name)
+    top = box.unpack('i', fifo[1])
+    bottom = box.unpack('i', fifo[2])
+    if top == fifomax+2 then -- % size
+        top = 3
+    elseif top ~= bottom then -- was not empty
+        top = top + 1
+    end
+    if bottom == fifomax + 2 then -- % size
+        bottom = 3
+    elseif bottom == top then
+        bottom = bottom + 1
+    end
+    return box.update(0, name, '=p=p=p', 1, top, 2, bottom, top, val)
+end
+function fifo_top(name)
+    fifo = find_or_create_fifo(name)
+    top = box.unpack('i', fifo[1])
+    return box.unpack('i', fifo[top])
+end
diff --git a/test/box/lua.result b/test/box/lua.result
index af850b0b2f..40ed053735 100644
--- a/test/box/lua.result
+++ b/test/box/lua.result
@@ -13,12 +13,13 @@ lua print('  lua says: hello')
 lua for n in pairs(box) do print('  - box.', n) end
 ---
   - box.delete
+  - box.pack
   - box.select
-  - box.process
   - box.insert
+  - box.unpack
   - box.replace
   - box.update
-  - box.pack
+  - box.process
 ...
 lua box.pack()
 ---
@@ -243,3 +244,58 @@ Found 1 tuple:
 call box.delete(0, 'pass')
 Found 1 tuple:
 [1936941424, 'new', 1684234851]
+lua dofile('/opt/local/work/tarantool-newlua/test/box/fifo.lua')
+---
+...
+lua fifo_max
+---
+ - nil
+...
+lua fifo_push('test', 1)
+---
+ - 1953719668: {3, 4, 1, 0, 0, 0, 0}
+...
+lua fifo_push('test', 2)
+---
+ - 1953719668: {4, 5, 1, 2, 0, 0, 0}
+...
+lua fifo_push('test', 3)
+---
+ - 1953719668: {5, 6, 1, 2, 3, 0, 0}
+...
+lua fifo_push('test', 4)
+---
+ - 1953719668: {6, 7, 1, 2, 3, 4, 0}
+...
+lua fifo_push('test', 5)
+---
+ - 1953719668: {7, 3, 1, 2, 3, 4, 5}
+...
+lua fifo_push('test', 6)
+---
+ - 1953719668: {3, 4, 6, 2, 3, 4, 5}
+...
+lua fifo_push('test', 7)
+---
+ - 1953719668: {4, 5, 6, 7, 3, 4, 5}
+...
+lua fifo_push('test', 8)
+---
+ - 1953719668: {5, 6, 6, 7, 8, 4, 5}
+...
+lua fifo_top('test')
+---
+ - 8
+...
+lua box.delete(0, 'test')
+---
+ - 1953719668: {5, 6, 6, 7, 8, 4, 5}
+...
+lua fifo_top('test')
+---
+ - 0
+...
+lua box.delete(0, 'test')
+---
+ - 1953719668: {3, 3, 0, 0, 0, 0, 0}
+...
diff --git a/test/box/lua.test b/test/box/lua.test
index 9858a874da..58487ef3a1 100644
--- a/test/box/lua.test
+++ b/test/box/lua.test
@@ -1,4 +1,6 @@
 # encoding: tarantool
+import os
+import sys
 # Test Lua from admin console. Whenever producing output,
 # make sure it's a valid YAML.
 exec admin "lua"
@@ -80,3 +82,21 @@ exec admin "lua function field_x(namespace, key, field_index) return (box.select
 exec sql "call field_x(0, 'pass', 0)"
 exec sql "call field_x(0, 'pass', 1)"
 exec sql "call box.delete(0, 'pass')"
+fifo_lua = os.path.abspath("box/fifo.lua")
+# don't log the path name
+sys.stdout.push_filter("exec admin .*", "exec admin ...")
+exec admin "lua dofile('{0}')".format(fifo_lua)
+sys.stdout.pop_filter()
+exec admin "lua fifo_max"
+exec admin "lua fifo_push('test', 1)"
+exec admin "lua fifo_push('test', 2)"
+exec admin "lua fifo_push('test', 3)"
+exec admin "lua fifo_push('test', 4)"
+exec admin "lua fifo_push('test', 5)"
+exec admin "lua fifo_push('test', 6)"
+exec admin "lua fifo_push('test', 7)"
+exec admin "lua fifo_push('test', 8)"
+exec admin "lua fifo_top('test')"
+exec admin "lua box.delete(0, 'test')"
+exec admin "lua fifo_top('test')"
+exec admin "lua box.delete(0, 'test')"
-- 
GitLab