parser: status_parse

Function to parse the whole DB of packages (still some more needs to be
added, obviously ‒ we parse just /usr/lib/opkg/status now).

Also, rename the previous functions to the proper noun_verb form.
parent 21e82a22
......@@ -19,6 +19,8 @@ along with Updater. If not, see <http://www.gnu.org/licenses/>.
local error = error
local type = type
local io = io
local DBG = DBG
module "backend"
......@@ -26,7 +28,7 @@ module "backend"
Parse a single block of mail-header-like records.
Return as a table.
]]--
function parse_block(block)
function block_parse(block)
local result = {}
local name
local value
......@@ -62,7 +64,7 @@ end
Split text into blocks separated by at least one empty line.
Returns an iterator.
]]
function split_blocks(string)
function block_split(string)
local pos = 0 -- 0 is the last one we /don't/ want.
-- Get the next block (an iterator)
local function next_block()
......@@ -137,4 +139,26 @@ function package_postprocess(status)
return status
end
status_file = "/usr/lib/opkg/status"
function status_parse()
DBG("Parsing status file ", status_file)
local result = {}
local f, err = io.open(status_file)
if f then
local content = f:read("*a")
f:close()
if not content then error("Failed to read content of the status file") end
for block in block_split(content) do
local pkg = block_parse(block)
-- TODO: merge other sources of information
pkg = package_postprocess(pkg)
result[pkg.Package] = pkg
end
else
error("Couldn't read status file " .. status_file .. ": " .. err)
end
return result
end
return _M
......@@ -48,10 +48,10 @@ test: test-lua-$(1)
valgrind: valgrind-lua-$(1)
test-lua-$(1): $(O)/bin/lulaunch $(S)/tests/$(1).lua
SUPPRESS_LOG=1 $(O)/bin/lulaunch $(S)/tests/$(1).lua
SUPPRESS_LOG=1 S=$(S) $(O)/bin/lulaunch $(S)/tests/$(1).lua
valgrind-lua-$(1): $(O)/bin/lulaunch $(S)/tests/$(1).lua
SUPPRESS_LOG=1 $(VALGRIND) $(O)/bin/lulaunch $(S)/tests/$(1).lua
SUPPRESS_LOG=1 S=$(S) $(VALGRIND) $(O)/bin/lulaunch $(S)/tests/$(1).lua
endef
......
......@@ -22,14 +22,14 @@ local B = require 'backend'
module("backend-tests", package.seeall, lunit.testcase)
-- Tests for the parse_block function
function test_parse_block()
-- Tests for the block_parse function
function test_block_parse()
-- Simple case
assert_table_equal({
val1 = "value 1",
val2 = "value 2",
val3 = "value 3"
}, B.parse_block([[val1: value 1
}, B.block_parse([[val1: value 1
val2: value 2
val3: value 3]]))
-- Continuations of fields
......@@ -38,25 +38,25 @@ val3: value 3]]))
line 2
line 3]],
val2 = "value 2"
}, B.parse_block([[val1: value 1
}, B.block_parse([[val1: value 1
line 2
line 3
val2: value 2]]))
-- Continuation on the first line, several ways
assert_error(function() B.parse_block(" x") end)
assert_error(function() B.parse_block(" x: y") end)
assert_error(function() B.block_parse(" x") end)
assert_error(function() B.block_parse(" x: y") end)
-- Some other strange lines
assert_error(function() B.parse_block("xyz") end)
assert_error(function() B.parse_block(" ") end)
assert_error(function() B.block_parse("xyz") end)
assert_error(function() B.block_parse(" ") end)
end
--[[
Call the B.split_blocks on inputs. Then go in through the iterator
Call the B.block_split on inputs. Then go in through the iterator
returned and in the outputs table in tandem, checking the things match.
]]
local function blocks_check(input, outputs)
local exp_i, exp_v = next(outputs)
for b in B.split_blocks(input) do
for b in B.block_split(input) do
assert_equal(exp_v, b)
exp_i, exp_v = next(outputs, exp_i)
end
......@@ -64,8 +64,8 @@ local function blocks_check(input, outputs)
assert_nil(exp_i)
end
-- Tests for the split_blocks function.
function test_split_blocks()
-- Tests for the block_split function.
function test_block_split()
-- Just splitting into blocks
blocks_check([[block 1
next line
......@@ -130,3 +130,57 @@ function test_package_postprocces()
assert_equal(pack_nomod, output)
assert_table_equal(pack_nomod_cp, output)
end
-- Tests for status_parse ‒ which parses the whole thing
function test_status_parse()
local result = B.status_parse()
local function status_check(name, desc, depends, status, conffiles)
local pkg = result[name]
assert_not_nil(pkg)
if depends then
assert_not_nil(pkg.Depends)
assert_table_equal(depends, pkg.Depends)
desc.Depends = pkg.Depends
end
if status then
assert_not_nil(pkg.Status)
assert_table_equal(status, pkg.Status)
desc.Status = pkg.Status
end
if conffiles then
assert_not_nil(pkg.Conffiles)
assert_table_equal(conffiles, pkg.Conffiles)
desc.Conffiles = pkg.Conffiles
end
assert_table_equal(desc, pkg)
end
local std_status = {install = true, user = true, installed = true}
status_check("kmod-usb-storage", {
Package = "kmod-usb-storage",
Version = "3.18.21+10-1-70ea6b9a4b789c558ac9d579b5c1022f-10",
Architecture = "mpc85xx",
["Installed-Time"] = "1453896142"}, {"kernel (=3.18.21-1-70ea6b9a4b789c558ac9d579b5c1022f-10)", "kmod-scsi-core", "kmod-usb-core"}, std_status)
status_check("terminfo", {
Package = "terminfo",
Version = "5.9-2",
Architecture = "mpc85xx",
["Installed-Time"] = "1453896265"}, {"libc"}, std_status)
status_check("dnsmasq-dhcpv6", {
Package = "dnsmasq-dhcpv6",
Version = "2.73-1",
Architecture = "mpc85xx",
["Installed-Time"] = "1453896240"}, {"libc"}, std_status, {["/etc/config/dhcp"] = "f81fe9bd228dede2165be71e5c9dcf76cc", ["/etc/dnsmasq.conf"] = "1e6ab19c1ae5e70d609ac7b6246541d520"})
end
local orig_status_file = B.status_file
function setup()
local sdir = os.getenv("S") or "."
-- Use a shortened version of a real status file for tests
B.status_file = sdir .. "/tests/data/opkg/status"
end
function teardown()
-- Clean up, return the original file name
B.status_file = orig_status_file
end
Package: kmod-usb-storage
Version: 3.18.21+10-1-70ea6b9a4b789c558ac9d579b5c1022f-10
Depends: kernel (= 3.18.21-1-70ea6b9a4b789c558ac9d579b5c1022f-10), kmod-scsi-core, kmod-usb-core
Status: install user installed
Architecture: mpc85xx
Installed-Time: 1453896142
Package: terminfo
Version: 5.9-2
Depends: libc
Status: install user installed
Architecture: mpc85xx
Installed-Time: 1453896265
Package: dnsmasq-dhcpv6
Version: 2.73-1
Depends: libc
Status: install user installed
Architecture: mpc85xx
Conffiles:
/etc/config/dhcp f81fe9bd228dede2165be71e5c9dcf76cc
/etc/dnsmasq.conf 1e6ab19c1ae5e70d609ac7b6246541d520
Installed-Time: 1453896240
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment