Verified Commit 1c3769dc authored by Karel Koci's avatar Karel Koci 🤘

Add options --model and --board

This also moves some configuration variables from backend to separate
syscnf module.
Original design where hard coded in values were used as defaults is not
replaced with design where set function is required to be called before
anything is done. Commonly that is suppose to be done in C before we
start using other Lua modules.
Thanks to new options --model and --board we can now set target even
outside of the router environment without requiring /tmp tainting. It's
now also not possible to run updater's executables on non-openwrt
platform without specifying those two options.
parent 8876cbcb
......@@ -655,13 +655,14 @@ Allowed package architectures (in a table).
model
~~~~~
Content of `/tmp/sysinfo/model`. Might be nil on non-OpenWRT systems.
Content of `/tmp/sysinfo/model`. On non-OpenWRT systems it has to be supplied by
`--model` argument.
board_name
~~~~~~~~~~
Content of `/tmp/sysinfo/board_name`. Might be nil on non-OpenWRT
systems.
Content of `/tmp/sysinfo/board_name`. On non-OpenWRT systems it has to be supplied
by `--board` argument.
turris_version
~~~~~~~~~~~~~~
......
......@@ -76,6 +76,10 @@ static const char *opt_help[COT_LAST] = {
"--exclude=<name> Exclude this from output.\n",
[COT_USIGN] =
"--usign=<path> Path to usign tool used to verify packages signature. In default /usr/bin/usign.\n",
[COT_MODEL] =
"--model=<model> Set/override target system model (e.g. Turris Omnia)\n",
[COT_BOARD] =
"--board=<board> Set/override target system board (e.g. rtrom01)\n",
[COT_NO_REPLAN] =
"--no-replan Don't replan. Install everyting at once. Use this if updater you are running isn't from packages it installs.\n",
[COT_NO_IMMEDIATE_REBOOT] =
......@@ -97,6 +101,8 @@ enum option_val {
OPT_TASK_LOG_VAL,
OPT_EXCLUDE,
OPT_USIGN,
OPT_MODEL,
OPT_BOARD,
OPT_NO_REPLAN,
OPT_NO_IMMEDIATE_REBOOT,
OPT_OUT_OF_ROOT,
......@@ -120,6 +126,8 @@ static const struct option opt_long[] = {
{ .name = "task-log", .has_arg = required_argument, .val = OPT_TASK_LOG_VAL },
{ .name = "exclude", .has_arg = required_argument, .val = OPT_EXCLUDE },
{ .name = "usign", .has_arg = required_argument, .val = OPT_USIGN },
{ .name = "model", .has_arg = required_argument, .val = OPT_MODEL },
{ .name = "board", .has_arg = required_argument, .val = OPT_BOARD },
{ .name = "no-replan", .has_arg = no_argument, .val = OPT_NO_REPLAN },
{ .name = "no-immediate-reboot", .has_arg = no_argument, .val = OPT_NO_IMMEDIATE_REBOOT },
{ .name = "out-of-root", .has_arg = no_argument, .val = OPT_OUT_OF_ROOT },
......@@ -145,6 +153,8 @@ static const struct simple_opt {
[OPT_TASK_LOG_VAL] = { COT_TASK_LOG, true, true },
[OPT_EXCLUDE] = { COT_EXCLUDE, true, true },
[OPT_USIGN] = { COT_USIGN, true, true },
[OPT_MODEL] = { COT_MODEL, true, true },
[OPT_BOARD] = { COT_BOARD, true, true },
[OPT_NO_REPLAN] = { COT_NO_REPLAN, false, true },
[OPT_NO_IMMEDIATE_REBOOT] = { COT_NO_IMMEDIATE_REBOOT, false, true },
[OPT_OUT_OF_ROOT] = { COT_OUT_OF_ROOT, false, false },
......@@ -265,6 +275,8 @@ struct cmd_op *cmd_args_parse(int argc, char *argv[], const enum cmd_op_type acc
case COT_APPROVE:
case COT_EXCLUDE:
case COT_USIGN:
case COT_MODEL:
case COT_BOARD:
case COT_NO_REPLAN:
case COT_TASK_LOG: {
struct cmd_op tmp = result[i];
......
......@@ -68,6 +68,10 @@ enum cmd_op_type {
COT_EXCLUDE,
// Path to usign tool
COT_USIGN,
// Target model specification
COT_MODEL,
// Target board specification
COT_BOARD,
// Don't replan (do whole install at once)
COT_NO_REPLAN,
// Don't immediatelly reboot system
......
......@@ -17,6 +17,8 @@ You should have received a copy of the GNU General Public License
along with Updater. If not, see <http://www.gnu.org/licenses/>.
]]--
local utils = require "utils"
-- Just for testing purposes
local testing = {}
......
......@@ -17,6 +17,9 @@ You should have received a copy of the GNU General Public License
along with Updater. If not, see <http://www.gnu.org/licenses/>.
]]--
local utils = require "utils"
local stacktraceplus = require "stacktraceplus"
-- Generate appropriate logging functions
for _, name in ipairs({ 'ERROR', 'WARN', 'INFO', 'DBG', 'TRACE' }) do
_G[name] = function(...)
......
--[[
Copyright 2018, CZ.NIC z.s.p.o. (http://www.nic.cz/)
This file is part of the turris updater.
Updater is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Updater is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Updater. If not, see <http://www.gnu.org/licenses/>.
]]--
local utils = require "utils"
local DIE = DIE
module "syscnf"
-- Variables accessed from outside of this module
-- luacheck: globals root_dir status_file info_dir pkg_temp_dir dir_opkg_collided target_model target_board
-- Functions that we want to access from outside of this module
-- luacheck: globals set_root_dir set_target
local status_file_suffix = "/usr/lib/opkg/status"
local info_dir_suffix = "/usr/lib/opkg/info/"
local pkg_temp_dir_suffix = "/usr/share/updater/unpacked"
local dir_opkg_collided_suffix = "/usr/share/updater/collided"
--[[
Set all the configurable directories to be inside the provided dir
Effectively sets that the whole system is mounted under some
prefix.
]]
function set_root_dir(dir)
-- A root directory
root_dir = dir or "/"
dir = dir or ""
-- The file with status of installed packages
status_file = dir .. status_file_suffix
-- The directory where unpacked control files of the packages live
info_dir = dir .. info_dir_suffix
-- A directory where unpacked packages live
pkg_temp_dir = dir .. pkg_temp_dir_suffix
-- Directory where we move files and directories that weren't part of any package.
dir_opkg_collided = dir .. dir_opkg_collided_suffix
end
--[[
Set variables taget_model and target_board.
You can explicitly specify model or board or both. If not specified then detection
is performed. That is files from /tmp/sysinfo directory are used.
If no model or board is specified (passed as nil) and detection failed than this
function causes error and execution termination.
]]
function set_target(model, board)
-- Name of the target model (ex: Turris Omnia)
target_model = model or utils.strip(utils.read_file('/tmp/sysinfo/model'))
-- Name of the target board (ex: rtrom01)
target_board = board or utils.strip(utils.read_file('/tmp/sysinfo/board_name'))
if not target_model or not target_board then
DIE("Auto detection of target model or board failed.You can specify them " ..
"explicitly using --model and --board arguments.")
end
end
......@@ -36,6 +36,7 @@ local io = io
local table = table
local backend = require "backend"
local utils = require "utils"
local syscnf = require "syscnf"
local journal = require "journal"
local DBG = DBG
local WARN = WARN
......@@ -87,7 +88,7 @@ local function pkg_unpack(operations, status)
WARN("Package " .. op.name .. " is not installed. Can't remove")
end
elseif op.op == "install" then
local pkg_dir = backend.pkg_unpack(op.data, backend.pkg_temp_dir)
local pkg_dir = backend.pkg_unpack(op.data, syscnf.pkg_temp_dir)
table.insert(dir_cleanups, pkg_dir)
local files, dirs, configs, control = backend.pkg_examine(pkg_dir)
to_remove[control.Package] = true
......@@ -286,7 +287,7 @@ local function perform_internal(operations, journal_status, run_state)
local ok, err = pcall(function ()
-- Make sure the temporary directory for unpacked packages exist
local created = ""
for segment in (backend.pkg_temp_dir .. "/"):gmatch("([^/]*)/") do
for segment in (syscnf.pkg_temp_dir .. "/"):gmatch("([^/]*)/") do
created = created .. segment .. "/"
backend.dir_ensure(created)
end
......
......@@ -43,6 +43,7 @@ local get_updater_version = get_updater_version
local utils = require "utils"
local backend = require "backend"
local requests = require "requests"
local syscnf = require "syscnf"
local uri = require "uri"
local uci_ok, uci = pcall(require, "uci")
......@@ -238,9 +239,9 @@ function load_state_vars()
might not have them legally and we mark that by providing nil.
]]
state_vars = {
root_dir = backend.root_dir,
model = utils.strip(utils.read_file('/tmp/sysinfo/model')),
board_name = utils.strip(utils.read_file('/tmp/sysinfo/board_name')),
root_dir = syscnf.root_dir,
model = syscnf.target_model,
board_name = syscnf.target_board,
turris_version = utils.strip(utils.read_file('/etc/turris-version')),
self_version = get_updater_version(),
language_version = 1,
......
......@@ -1087,7 +1087,14 @@ const char *interpreter_call(struct interpreter *interpreter, const char *functi
lua_pushnil(L);
break;
CASE(int, 'i', integer);
CASE(const char *, 's', string);
case 's': { // string that can be NULL
const char *s = va_arg(args, const char *);
if (s)
lua_pushstring(L, s);
else
lua_pushnil(L);
break;
}
case 'S': { // binary string, it has 2 parameters
const char *s = va_arg(args, const char *);
size_t len = va_arg(args, size_t);
......@@ -1156,6 +1163,9 @@ int interpreter_collect_results(struct interpreter *interpreter, const char *spe
if (lua_isstring(L, pos + 1)) {
const char **s = va_arg(args, const char **);
*s = lua_tostring(L, pos + 1);
} else if (lua_isnil(L, pos + 1)) {
const char **s = va_arg(args, const char **);
*s = NULL;
} else
return pos;
break;
......
......@@ -126,7 +126,7 @@ static bool journal_open(lua_State *L, int flags) {
luaL_error(L, "Journal already open");
// Get current root directory
// TODO this should probably be argument instead
lua_getglobal(L, "backend");
lua_getglobal(L, "syscnf");
lua_getfield(L, -1, "root_dir");
const char *root_dir = lua_tostring(L, -1);
journal_path = malloc(strlen(root_dir) + strlen(DEFAULT_JOURNAL_PATH) + 1);
......
......@@ -39,7 +39,7 @@ static bool results_interpret(struct interpreter *interpreter, size_t result_cou
}
static const enum cmd_op_type cmd_op_allows[] = {
COT_JOURNAL_ABORT, COT_JOURNAL_RESUME, COT_INSTALL, COT_REMOVE, COT_ROOT_DIR, COT_SYSLOG_LEVEL, COT_STDERR_LEVEL, COT_SYSLOG_NAME, COT_REEXEC, COT_USIGN, COT_LAST };
COT_JOURNAL_ABORT, COT_JOURNAL_RESUME, COT_INSTALL, COT_REMOVE, COT_ROOT_DIR, COT_SYSLOG_LEVEL, COT_STDERR_LEVEL, COT_SYSLOG_NAME, COT_REEXEC, COT_USIGN, COT_MODEL, COT_BOARD, COT_LAST };
static void print_help() {
fputs("Usage: opkg-trans [OPTION]...\n", stderr);
......@@ -69,9 +69,13 @@ int main(int argc, char *argv[]) {
return 1;
}
bool transaction_run = false;
bool journal_resume = false;
bool trans_ok = true;
bool early_exit = false;
const char *usign_exec = NULL;
const char *root_dir = NULL;
const char *target_model = NULL;
const char *target_board = NULL;
for (; op->type != COT_EXIT && op->type != COT_CRASH; op ++)
switch (op->type) {
case COT_HELP:
......@@ -85,6 +89,9 @@ int main(int argc, char *argv[]) {
case COT_ERR_MSG:
fputs(op->parameter, stderr);
break;
case COT_JOURNAL_RESUME:
journal_resume = true;
break;
case COT_INSTALL: {
const char *err = interpreter_call(interpreter, "transaction.queue_install", NULL, "s", op->parameter);
ASSERT_MSG(!err, "%s", err);
......@@ -97,19 +104,10 @@ int main(int argc, char *argv[]) {
transaction_run = true;
break;
}
case COT_JOURNAL_RESUME: {
size_t result_count;
const char *err = interpreter_call(interpreter, "transaction.recover_pretty", &result_count, "");
ASSERT_MSG(!err, "%s", err);
trans_ok = results_interpret(interpreter, result_count);
early_exit = true;
break;
}
#define NIP(TYPE) case COT_##TYPE: fputs("Operation " #TYPE " not implemented yet\n", stderr); return 1
NIP(JOURNAL_ABORT);
case COT_ROOT_DIR: {
const char *err = interpreter_call(interpreter, "backend.root_dir_set", NULL, "s", op->parameter);
ASSERT_MSG(!err, "%s", err);
root_dir = op->parameter;
break;
}
case COT_USIGN: {
......@@ -117,6 +115,14 @@ int main(int argc, char *argv[]) {
ASSERT_MSG(!err, "%s", err);
break;
}
case COT_MODEL: {
target_model = op->parameter;
break;
}
case COT_BOARD: {
target_board = op->parameter;
break;
}
case COT_SYSLOG_LEVEL: {
enum log_level level = log_level_get(op->parameter);
ASSERT_MSG(level != LL_UNKNOWN, "Unknown log level %s", op->parameter);
......@@ -140,10 +146,22 @@ int main(int argc, char *argv[]) {
assert(0);
}
enum cmd_op_type exit_type = op->type;
free(ops);
if (transaction_run && exit_type == COT_EXIT) {
size_t result_count;
const char *err = interpreter_call(interpreter, "transaction.perform_queue", &result_count, "");
if (exit_type != COT_EXIT || early_exit)
goto CLEANUP;
// Some configurations
const char *err = interpreter_call(interpreter, "syscnf.set_root_dir", NULL, "s", root_dir);
ASSERT_MSG(!err, "%s", err);
err = interpreter_call(interpreter, "syscnf.set_target", NULL, "ss", target_model, target_board);
ASSERT_MSG(!err, "%s", err);
size_t result_count;
if (journal_resume) {
err = interpreter_call(interpreter, "transaction.recover_pretty", &result_count, "");
ASSERT_MSG(!err, "%s", err);
trans_ok = results_interpret(interpreter, result_count);
} else if (transaction_run) {
err = interpreter_call(interpreter, "transaction.perform_queue", &result_count, "");
ASSERT_MSG(!err, "%s", err);
trans_ok = results_interpret(interpreter, result_count);
} else if (!early_exit && exit_type != COT_CRASH) {
......@@ -152,6 +170,8 @@ int main(int argc, char *argv[]) {
exit_type = COT_CRASH;
}
CLEANUP:
free(ops);
interpreter_destroy(interpreter);
events_destroy(events);
arg_backup_clear();
......
......@@ -47,7 +47,7 @@ static bool results_interpret(struct interpreter *interpreter, size_t result_cou
}
static const enum cmd_op_type cmd_op_allows[] = {
COT_BATCH, COT_NO_OP, COT_REEXEC, COT_REBOOT, COT_STATE_LOG, COT_ROOT_DIR, COT_SYSLOG_LEVEL, COT_STDERR_LEVEL, COT_SYSLOG_NAME, COT_ASK_APPROVAL, COT_APPROVE, COT_TASK_LOG, COT_USIGN, COT_NO_REPLAN, COT_NO_IMMEDIATE_REBOOT, COT_LAST
COT_BATCH, COT_NO_OP, COT_REEXEC, COT_REBOOT, COT_STATE_LOG, COT_ROOT_DIR, COT_SYSLOG_LEVEL, COT_STDERR_LEVEL, COT_SYSLOG_NAME, COT_ASK_APPROVAL, COT_APPROVE, COT_TASK_LOG, COT_USIGN, COT_MODEL, COT_BOARD, COT_NO_REPLAN, COT_NO_IMMEDIATE_REBOOT, COT_LAST
};
static void print_help() {
......@@ -127,6 +127,8 @@ int main(int argc, char *argv[]) {
struct cmd_op *op = ops;
const char *top_level_config = "internal:entry_lua";
const char *root_dir = NULL;
const char *target_model = NULL;
const char *target_board = NULL;
bool batch = false, early_exit = false, replan = false, reboot_finished = false;
const char *approval_file = NULL;
const char **approvals = NULL;
......@@ -162,6 +164,12 @@ int main(int argc, char *argv[]) {
case COT_ROOT_DIR:
root_dir = op->parameter;
break;
case COT_MODEL:
target_model = op->parameter;
break;
case COT_BOARD:
target_board = op->parameter;
break;
case COT_STATE_LOG:
set_state_log(true);
break;
......@@ -215,35 +223,33 @@ int main(int argc, char *argv[]) {
const char *error = interpreter_autoload(interpreter);
ASSERT_MSG(!error, "%s", error);
if (root_dir) {
const char *err = interpreter_call(interpreter, "backend.root_dir_set", NULL, "s", root_dir);
ASSERT_MSG(!err, "%s", err);
} else
root_dir = "";
bool trans_ok = true;
if (exit_type != COT_EXIT || early_exit)
goto CLEANUP;
size_t result_count;
// Set some configuration
const char *err = interpreter_call(interpreter, "syscnf.set_root_dir", NULL, "s", root_dir);
ASSERT_MSG(!err, "%s", err);
err = interpreter_call(interpreter, "syscnf.set_target", NULL, "ss", target_model, target_board);
ASSERT_MSG(!err, "%s", err);
if (usign_exec) {
const char *err = interpreter_call(interpreter, "uri.usign_exec_set", NULL, "s", usign_exec);
err = interpreter_call(interpreter, "uri.usign_exec_set", NULL, "s", usign_exec);
ASSERT_MSG(!err, "%s", err);
}
if (no_replan) {
const char *err = interpreter_call(interpreter, "updater.disable_replan", NULL, "");
err = interpreter_call(interpreter, "updater.disable_replan", NULL, "");
ASSERT_MSG(!err, "%s", err);
}
bool trans_ok = true;
if (exit_type != COT_EXIT)
goto CLEANUP;
if (early_exit)
goto CLEANUP;
size_t result_count;
// Check if we should recover previous execution first if so do
if (journal_exists(root_dir)) {
INFO("Detected existing journal. Trying to recover it.");
const char *err = interpreter_call(interpreter, "transaction.recover_pretty", &result_count, "");
err = interpreter_call(interpreter, "transaction.recover_pretty", &result_count, "");
ASSERT_MSG(!err, "%s", err);
if (!results_interpret(interpreter, result_count))
goto CLEANUP;
}
// Decide what packages need to be downloaded and handled
const char *err = interpreter_call(interpreter, "updater.prepare", NULL, "s", top_level_config);
err = interpreter_call(interpreter, "updater.prepare", NULL, "s", top_level_config);
if (err) {
exit_type = COT_CRASH;
ERROR("%s", err);
......
......@@ -21,6 +21,7 @@ LUA_TESTS := \
sandbox \
transaction \
utils \
syscnf \
uri \
picosat
......@@ -45,7 +46,7 @@ clean-coverage:
rm -rf $(O)/coverage
# Ignore stacktraceplus and dumper, not our creation.
LUA_AUTOLOAD := $(filter-out 01_stacktraceplus 05_dumper,$(patsubst a_%.lua,%,$(notdir $(wildcard $(S)/src/lib/autoload/a_*.lua))))
LUA_AUTOLOAD := $(filter-out 01_stacktraceplus 06_dumper,$(patsubst a_%.lua,%,$(notdir $(wildcard $(S)/src/lib/autoload/a_*.lua))))
TEST_URIINTERNAL := $(abspath $(wildcard $(S)/tests/internal/*))
$(O)/.gen/tests/uriinternal.embedlist: $(S)/src/lib/gen_embed.sh $(S)/src/lib/embed_types.h $(TEST_URIINTERNAL)
......
--[[
Copyright 2016-2017, CZ.NIC z.s.p.o. (http://www.nic.cz/)
Copyright 2016-2018, CZ.NIC z.s.p.o. (http://www.nic.cz/)
This file is part of the turris updater.
......@@ -20,6 +20,7 @@ along with Updater. If not, see <http://www.gnu.org/licenses/>.
require 'lunit'
local print = print
local B = require 'backend'
require "syscnf"
require 'utils'
local lines2set = utils.lines2set
......@@ -246,13 +247,10 @@ function test_status_parse()
files = {}
})
-- More broken case - the whole status file missing
B.status_file = "/does/not/exist"
syscnf.status_file = "/does/not/exist"
assert_error(B.status_parse)
end
local orig_status_file = B.status_file
local orig_info_dir = B.info_dir
local orig_root_dir = B.root_dir
local tmp_dirs = {}
--[[
......@@ -348,7 +346,7 @@ function test_pkg_unpack()
}, control)
local test_root = mkdtemp()
table.insert(tmp_dirs, test_root)
B.root_dir = test_root
syscnf.set_root_dir(test_root)
-- Try merging it to a „root“ directory. We need to find all the files and directories.
--[[
Omit the empty directories. They wouldn't get cleared currently, and
......@@ -408,7 +406,7 @@ function test_cleanup_files_config()
-- Create an empty testing file
local fname = test_root .. "/config"
io.open(fname, "w"):close()
B.root_dir = test_root
syscnf.set_root_dir(test_root)
-- First try with a non-matching hash ‒ the file has been modified
B.pkg_cleanup_files({["/config"] = true}, {["/config"] = "12345678901234567890123456789012"})
-- It is left there
......@@ -771,7 +769,7 @@ function test_status_parse_dump()
-- Make a copy of the status file, we'are going to write into it
local test_dir = mkdtemp()
table.insert(tmp_dirs, test_dir)
B.status_file = test_dir .. "/status"
syscnf.status_file = test_dir .. "/status"
B.status_dump(status)
-- Now read it again. It must be the same
local status2 = B.status_parse()
......@@ -800,7 +798,7 @@ function test_control_cleanup()
]]
local test_dir = mkdtemp() .. "/"
table.insert(tmp_dirs, test_dir)
B.info_dir = test_dir
syscnf.info_dir = test_dir
local all_files = {
["pkg1.control"] = "r",
["pkg1.list"] = "r",
......@@ -850,7 +848,7 @@ function test_merge_control()
f:close()
local dst_dir = mkdtemp()
table.insert(tmp_dirs, dst_dir)
B.info_dir = dst_dir
syscnf.info_dir = dst_dir
-- Place an "outdated" file in the destination, which should disappear by the merge
local f, err = io.open(dst_dir .. "/pkg1.outdated", "w")
assert_not_nil(f, err)
......@@ -866,7 +864,7 @@ function test_merge_control()
end
function test_script_run()
B.info_dir = (os.getenv("S") or ".") .. "/tests/data/scripts"
syscnf.info_dir = (os.getenv("S") or ".") .. "/tests/data/scripts"
-- This one doesn't exist. So the call succeeds.
local result, stderr = B.script_run("xyz", "preinst", "install")
assert(result)
......@@ -895,13 +893,6 @@ PKG_ROOT=
B.cmd_timeout = old_cmd_timeout
end
function test_root_dir_set()
B.root_dir_set("/dir")
assert_equal("/dir/usr/lib/opkg/status", B.status_file)
assert_equal("/dir/usr/lib/opkg/info/", B.info_dir)
assert_equal("/dir/usr/share/updater/unpacked", B.pkg_temp_dir)
end
function test_config_modified()
-- Bad length of the hash, no matter what file:
assert_error(function() B.config_modified("/file/does/not/exist", "1234") end)
......@@ -970,15 +961,13 @@ end
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"
B.info_dir = sdir .. "/tests/data/opkg/info/"
syscnf.status_file = sdir .. "/tests/data/opkg/status"
syscnf.info_dir = sdir .. "/tests/data/opkg/info/"
end
function teardown()
-- Clean up, return the original file name
B.status_file = orig_status_file
B.info_dir = orig_info_dir
B.root_dir= orig_root_dir
syscnf.set_root_dir()
utils.cleanup_dirs(tmp_dirs)
tmp_dirs = {}
end
......@@ -203,20 +203,21 @@ START_INTERPRETER_TEST(call_echo)
* Test we can pass some types of parameters and get the results back.
*/
size_t results;
const char *error = interpreter_call(interpreter, "testing.subtable.echo", &results, "ibsnf", 42, true, "hello", 3.1415);
const char *error = interpreter_call(interpreter, "testing.subtable.echo", &results, "ibssnf", 42, true, "hello", NULL, 3.1415);
ck_assert_msg(!error, "Failed to run the function: %s", error);
ck_assert_uint_eq(5, results);
ck_assert_uint_eq(6, results);
int i;
bool b;
const char *s;
const char *s, *sn;
size_t l;
double f;
// Mix the binary and null-terminated string ‒ that is allowed
ck_assert_int_eq(-1, interpreter_collect_results(interpreter, "ibSnf", &i, &b, &s, &l, &f));
ck_assert_int_eq(-1, interpreter_collect_results(interpreter, "ibSsnf", &i, &b, &s, &l, &sn, &f));
ck_assert_int_eq(42, i);
ck_assert(b);
ck_assert_str_eq(s, "hello");
ck_assert_uint_eq(5, l);
ck_assert(sn == NULL);
ck_assert_msg(3.1414 < f && f < 3.1416, "Wrong double got through: %lf", f);
// Check we can skip parameters when reading
ck_assert_int_eq(-1, interpreter_collect_results(interpreter, "--s", &s));
......
......@@ -22,6 +22,9 @@ require 'lunit'
require 'utils'
local J = require 'journal'
local backend = require 'backend'
require "syscnf"
syscnf.set_root_dir()
module("journal-tests", package.seeall, lunit.testcase)
......@@ -52,7 +55,7 @@ end
function dir_init()
local dir = mkdtemp()
table.insert(tmp_dirs, dir)
backend.root_dir = dir
syscnf.root_dir = dir
mkpath = dir
for dr in journal_path:gmatch('[^/]+') do
mkpath = mkpath .. '/' .. dr
......
......@@ -23,7 +23,9 @@ local requests = require "requests"
local postprocess = require "postprocess"
local utils = require "utils"
local uri = require "uri"
require "syscnf"
syscnf.set_root_dir()
local dir = (os.getenv("S") .. "/") or ''
module("postprocess-tests", package.seeall, lunit.testcase)
......
--[[
Copyright 2018, CZ.NIC z.s.p.o. (http://www.nic.cz/)
This file is part of the turris updater.
Updater is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Updater is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Updater. If not, see <http://www.gnu.org/licenses/>.
]]--
require 'lunit'
local SC = require "syscnf"
module("syscnf-tests", package.seeall, lunit.testcase)
function test_set_root_dir()
SC.set_root_dir("/dir")
assert_equal("/dir/usr/lib/opkg/status", SC.status_file)
assert_equal("/dir/usr/lib/opkg/info/", SC.info_dir)
assert_equal("/dir/usr/share/updater/unpacked", SC.pkg_temp_dir)
end
function test_set_target()
SC.set_target("Turris", "unknown")
assert_equal("Turris", SC.target_model)
assert_equal("unknown", SC.target_board)
end
......@@ -5,7 +5,7 @@ export PATH=$ROOT_DIR/bin:$PATH
## This section is edited copy of part of ../run script
cp -ar "$DEFINITION"/after-reboot "$TMP_DIR"/after-reboot
# Launch pkgupdate. Should exit only with kill, so exit code should be 137
eval $LAUNCHER "$O"/bin/pkgupdate file://$ROOT_DIR/config --batch -R "$ROOT_DIR" --task-log="$ROOT_DIR/task-log" || [ $? -eq 137 ]
eval $LAUNCHER "$O"/bin/pkgupdate --model Turris --board unknown file://$ROOT_DIR/config --batch -R "$ROOT_DIR" --task-log="$ROOT_DIR/task-log" || [ $? -eq 137 ]
# Do we need to de-randomize the output somehow?
sed -i -e 's/^[^\t]*/0/' "$ROOT_DIR"/task-log
# Check it did what it should have. For sanity sake we can't check journal content. Just check that it's there.
......
......@@ -5,7 +5,7 @@ export PATH=$ROOT_DIR/bin:$PATH
## This section is edited copy of part of ../run script
cp -ar "$DEFINITION"/after-reboot "$TMP_DIR"/after-reboot
# Launch pkgupdate. Should exit only with kill, so exit code should be 137
eval $LAUNCHER "$O"/bin/pkgupdate file://$ROOT_DIR/config --batch -R "$ROOT_DIR" --task-log="$ROOT_DIR/task-log" || [ $? -eq 137 ]
eval $LAUNCHER "$O"/bin/pkgupdate --model Turris --board unknown file://$ROOT_DIR/config --batch -R "$ROOT_DIR" --task-log="$ROOT_DIR/task-log" || [ $? -eq 137 ]
# Do we need to de-randomize the output somehow?
rm "$ROOT_DIR"/config
rm -r "$ROOT_DIR"/repo
......
......@@ -48,7 +48,7 @@ fi
find "$TMP_DIR" -type f -name .keep -exec rm {} \;
# Launch it
export COVERAGEDIR="$O/.lua_coverage"
eval $LAUNCHER "$O"/bin/"$1" $(cat "$DEFINITION"/params)
eval $LAUNCHER "$O"/bin/"$1" --model Turris --board unknown $(cat "$DEFINITION"/params)
# Do we need to de-randomize the output somehow?
if [ -f "$DEFINITION"/cleanup ] ; then
. "$DEFINITION"/cleanup
......
......@@ -22,6 +22,9 @@ local B = require 'backend'
local T = require 'transaction'
local utils = require 'utils'
local journal = require 'journal'
require "syscnf"
syscnf.set_root_dir()
module("transaction-tests", package.seeall, lunit.testcase)
......@@ -220,7 +223,7 @@ function test_perform_ok()
local expected = tables_join(intro, {
{
f = "backend.pkg_unpack",
p = {"<package data>", B.pkg_temp_dir}
p = {"<package data>", syscnf.pkg_temp_dir}
},
{
f = "backend.pkg_examine",
......@@ -367,7 +370,7 @@ function test_perform_collision()
local expected = tables_join(intro, {
{
f = "backend.pkg_unpack",