M .gitignore => .gitignore +7 -0
@@ 61,6 61,13 @@ update/*
# often created by the visual studio code
/null.d
+# macOS spotlight indexing files
+*.DS_Store
+
test/test_env
image/luts.bin
image/assets/fonts/*
+
+scripts/lua/test/assets*
+scripts/lua/test/update/user/temp/*
+scripts/lua/test/update/target/*
M scripts/lua/backup.lua => scripts/lua/backup.lua +34 -0
@@ 1,15 1,49 @@
local helpers = require('helpers')
local recovery = require('recovery')
+local paths = require('paths')
local tar = require('ltar')
local lfs = require('lfs')
local backup = {}
+-- Match only files with '.db' extensions and omit such files inside subdirectories
+local match_db_files = '^[^%/]*%.db$'
+
backup.script_name = "backup.lua"
backup.img_in_progress = "assets/gui_image_backup_in_progress.bin"
backup.img_success = "assets/gui_image_backup_success.bin"
backup.img_failure = "assets/gui_image_backup_failed.bin"
+local function check_available_space()
+ local db_size = helpers.dir_size_filtered(paths.db_dir, match_db_files)
+ local version_size = lfs.attributes(paths.version_file, 'size')
+ local available_space = recovery.sys.free_space(paths.user_dir)
+ -- Multiply the result by two due to the internal padding inside tar
+ local required_space = (db_size + version_size) * 2
+
+ print(string.format("Checking disk space:\nNeeded space: %d bytes, available space: %d bytes", required_space,
+ available_space))
+
+ assert(available_space > required_space, "Not enough free space on user disk")
+end
+
+local function create_temp_dir()
+ if not helpers.exists(paths.temp_dir) then
+ print(string.format("'%s' does not exist, creating", paths.temp_dir))
+ lfs.mkdir(paths.temp_dir)
+ end
+end
+
+local function create_backup_package()
+ print(string.format("Creating backup package from the contents of '%s' directory and saving it into '%s'",
+ paths.db_dir, paths.backup_file))
+ tar.create_from_path_regex(paths.db_dir, paths.backup_file, match_db_files)
+ tar.append_file(paths.version_file, paths.backup_file)
+end
+
function backup.execute()
+ check_available_space()
+ create_temp_dir()
+ create_backup_package()
end
return backup
M scripts/lua/entry.lua => scripts/lua/entry.lua +11 -9
@@ 2,6 2,7 @@ package.path = package.path .. ";share/?.lua"
local helpers = require('helpers')
+local paths = require('paths')
local rec = require('recovery')
local backup = require('backup')
local restore = require('restore')
@@ 32,11 33,11 @@ local function print_boot_reason()
print(string.format("Boot reason: %s", rec.sys.boot_reason_str()))
end
-local function generate_report_file(boot_reason, success, message)
- local file_path = rec.sys.source_slot() .. "/log/recovery_status.json"
+local function generate_report_file(boot_reason_str, success, message)
+ local file_path = paths.temp_dir .. "/recovery_status.json"
local body = string.format(
- "{\"version\": \"%s\",\"branch\": \"%s\",\"revision\": \"%s\",\"boot_reason\": %d,\"result\": %s,\"message\": \"%s\"}",
- rec.version(), rec.branch(), rec.revision(), boot_reason, tostring(success), message)
+ "{\"version\": \"%s\",\"branch\": \"%s\",\"revision\": \"%s\",\"operation\": \"%s\",\"successful\": %s,\"message\": \"%s\"}",
+ rec.version(), rec.branch(), rec.revision(), boot_reason_str, tostring(success), message)
local fd = io.open(file_path, 'w')
fd:write(body)
fd:close()
@@ 44,8 45,9 @@ end
local function handle_boot_reason()
local boot_reason = rec.sys.boot_reason()
+ local boot_reason_str = rec.sys.boot_reason_str()
rec.sys.set_boot_reason(rec.sys.boot_reason_codes.os)
- return boot_reason
+ return boot_reason, boot_reason_str
end
local function handle_script_success(boot_reason)
@@ 58,8 60,8 @@ local function handle_script_failure(boot_reason, message)
display_image(scripts[boot_reason].img_failure)
end
-local function handle_exit(boot_reason, status, message)
- generate_report_file(boot_reason, status, message)
+local function handle_exit(boot_reason_str, status, message)
+ generate_report_file(boot_reason_str, status, message)
rec.sys.sleep(1)
rec.gui.clear()
end
@@ 80,7 82,7 @@ end
print_recovery_info()
print_boot_reason()
-local boot_reason = handle_boot_reason()
+local boot_reason, boot_reason_str = handle_boot_reason()
local status, message = invoke_script(boot_reason)
-handle_exit(boot_reason, status, message)
+handle_exit(boot_reason_str, status, message)
M scripts/lua/factory.lua => scripts/lua/factory.lua +8 -13
@@ 1,12 1,7 @@
local helpers = require('helpers')
-local recovery = require('recovery')
+local paths = require('paths')
local factory = {}
-local user_dir = recovery.sys.user()
-local system_dir = recovery.sys.source_slot()
-local db_dir = system_dir .. "/db"
-local db_factory_dir = system_dir .. "/db/factory"
-local file_indexer_cache = system_dir .. "/data/.directory_is_indexed"
factory.script_name = "factory.lua"
factory.img_in_progress = "assets/gui_image_factory_reset_in_progress.bin"
@@ 14,19 9,19 @@ factory.img_success = "assets/gui_image_factory_reset_success.bin"
factory.img_failure = "assets/gui_image_factory_reset_failed.bin"
local function remove_old_databases()
- print(string.format("Removing old databases from '%s'", db_dir))
- helpers.rm_files_from_dir(db_dir)
+ print(string.format("Removing old databases from '%s'", paths.db_dir))
+ helpers.rm_files_from_dir(paths.db_dir)
end
local function copy_clean_databases()
- print(string.format("Copying clean databases from '%s' to '%s'", db_factory_dir, db_dir))
- helpers.copy_dir(db_factory_dir, db_dir)
+ print(string.format("Copying clean databases from '%s' to '%s'", paths.db_factory_dir, paths.db_dir))
+ helpers.copy_dir(paths.db_factory_dir, paths.db_dir)
end
local function remove_cache()
- if helpers.exists(file_indexer_cache) then
- print(string.format("Removing cache file '%s'", file_indexer_cache))
- assert(os.remove(file_indexer_cache))
+ if helpers.exists(paths.file_indexer_cache) then
+ print(string.format("Removing cache file '%s'", paths.file_indexer_cache))
+ assert(os.remove(paths.file_indexer_cache))
end
end
M scripts/lua/install.sh => scripts/lua/install.sh +2 -1
@@ 28,7 28,8 @@ if validate_product_selection; then
cd "$parent_path"
mkdir -p ${DESTINATION}
- cp -r assets/${PRODUCT} ${DESTINATION}/assets/
+ cp -r products/${PRODUCT}/assets ${DESTINATION}/assets/
+ cp products/${PRODUCT}/product_updater.lua ${DESTINATION}/product_updater.lua
cp -r share ${DESTINATION}/share
cp -r migration/migration.lua ${DESTINATION}/share
cp *.lua ${DESTINATION}
M scripts/lua/migration/migration.lua => scripts/lua/migration/migration.lua +1 -2
@@ 92,8 92,7 @@ end
local function print_db_set(db_set)
print("database set:")
for name, version in pairs(db_set) do
- print("\tname: " .. name)
- print("\ttarget version: " .. version)
+ print(string.format("'%s':%d",name,version))
end
end
R scripts/lua/assets/BellHybrid/gui_image_factory_reset_failed.bin => scripts/lua/products/BellHybrid/assets/gui_image_factory_reset_failed.bin +0 -0
R scripts/lua/assets/BellHybrid/gui_image_factory_reset_in_progress.bin => scripts/lua/products/BellHybrid/assets/gui_image_factory_reset_in_progress.bin +0 -0
R scripts/lua/assets/BellHybrid/gui_image_factory_reset_success.bin => scripts/lua/products/BellHybrid/assets/gui_image_factory_reset_success.bin +0 -0
R scripts/lua/assets/BellHybrid/gui_image_update_failed.bin => scripts/lua/products/BellHybrid/assets/gui_image_update_failed.bin +0 -0
R scripts/lua/assets/BellHybrid/gui_image_update_in_progress.bin => scripts/lua/products/BellHybrid/assets/gui_image_update_in_progress.bin +0 -0
R scripts/lua/assets/BellHybrid/gui_image_update_success.bin => scripts/lua/products/BellHybrid/assets/gui_image_update_success.bin +0 -0
R scripts/lua/assets/PurePhone/gui_image_backup_failed.bin => scripts/lua/products/PurePhone/assets/gui_image_backup_failed.bin +0 -0
R scripts/lua/assets/PurePhone/gui_image_backup_in_progress.bin => scripts/lua/products/PurePhone/assets/gui_image_backup_in_progress.bin +0 -0
R scripts/lua/assets/PurePhone/gui_image_backup_success.bin => scripts/lua/products/PurePhone/assets/gui_image_backup_success.bin +0 -0
R scripts/lua/assets/PurePhone/gui_image_factory_reset_failed.bin => scripts/lua/products/PurePhone/assets/gui_image_factory_reset_failed.bin +0 -0
R scripts/lua/assets/PurePhone/gui_image_factory_reset_in_progress.bin => scripts/lua/products/PurePhone/assets/gui_image_factory_reset_in_progress.bin +0 -0
R scripts/lua/assets/PurePhone/gui_image_factory_reset_success.bin => scripts/lua/products/PurePhone/assets/gui_image_factory_reset_success.bin +0 -0
R scripts/lua/assets/PurePhone/gui_image_keys_failed.bin => scripts/lua/products/PurePhone/assets/gui_image_keys_failed.bin +0 -0
R scripts/lua/assets/PurePhone/gui_image_keys_in_progress.bin => scripts/lua/products/PurePhone/assets/gui_image_keys_in_progress.bin +0 -0
R scripts/lua/assets/PurePhone/gui_image_keys_success.bin => scripts/lua/products/PurePhone/assets/gui_image_keys_success.bin +0 -0
R scripts/lua/assets/PurePhone/gui_image_recovery_failed.bin => scripts/lua/products/PurePhone/assets/gui_image_recovery_failed.bin +0 -0
R scripts/lua/assets/PurePhone/gui_image_recovery_in_progress.bin => scripts/lua/products/PurePhone/assets/gui_image_recovery_in_progress.bin +0 -0
R scripts/lua/assets/PurePhone/gui_image_recovery_success.bin => scripts/lua/products/PurePhone/assets/gui_image_recovery_success.bin +0 -0
R scripts/lua/assets/PurePhone/gui_image_restore_failed.bin => scripts/lua/products/PurePhone/assets/gui_image_restore_failed.bin +0 -0
R scripts/lua/assets/PurePhone/gui_image_restore_in_progress.bin => scripts/lua/products/PurePhone/assets/gui_image_restore_in_progress.bin +0 -0
R scripts/lua/assets/PurePhone/gui_image_restore_success.bin => scripts/lua/products/PurePhone/assets/gui_image_restore_success.bin +0 -0
R scripts/lua/assets/PurePhone/gui_image_update_failed.bin => scripts/lua/products/PurePhone/assets/gui_image_update_failed.bin +0 -0
R scripts/lua/assets/PurePhone/gui_image_update_in_progress.bin => scripts/lua/products/PurePhone/assets/gui_image_update_in_progress.bin +0 -0
R scripts/lua/assets/PurePhone/gui_image_update_success.bin => scripts/lua/products/PurePhone/assets/gui_image_update_success.bin +0 -0
A scripts/lua/products/PurePhone/product_updater.lua => scripts/lua/products/PurePhone/product_updater.lua +30 -0
@@ 0,0 1,30 @@
+local product_updater = {}
+
+local paths = require('paths')
+local helpers = require('helpers')
+local lfs = require('lfs')
+local paths = require('paths')
+
+function product_updater.is_migration_needed()
+ local current_version = helpers.get_os_version(paths.version_file)
+ local version = "1.5.0"
+ assert(current_version >= version, string.format("Updating from version '%s' not supported", current_version))
+ return current_version == version
+end
+
+function product_updater.execute()
+ local old_music_dir = "/user/music"
+ local new_music_dir = "/user/app/music_player"
+ local old_battery_config = "/user/batteryFuelGaugeConfig.cfg"
+ local new_battery_config = paths.data_dir .. "/batteryFuelGaugeConfig.cfg"
+
+ assert(helpers.mkdirp(new_music_dir))
+ helpers.copy_dir(old_music_dir, new_music_dir)
+ helpers.rmdir(old_music_dir)
+ helpers.copy_file(old_battery_config,new_battery_config)
+ os.remove(old_battery_config)
+
+end
+
+return product_updater
+
M scripts/lua/restore.lua => scripts/lua/restore.lua +70 -0
@@ 1,17 1,87 @@
local helpers = require('helpers')
local recovery = require('recovery')
+local paths = require('paths')
+local consts = require('consts')
local ltar = require('ltar')
local lfs = require('lfs')
local json = require('lunajson')
local migration = require('migration')
local restore = {}
+local unpacked_backup_dir = paths.temp_dir .. "/backup"
+local version_file = unpacked_backup_dir .. "/" .. consts.version_file
+
restore.script_name = "restore.lua"
restore.img_in_progress = "assets/gui_image_restore_in_progress.bin"
restore.img_success = "assets/gui_image_restore_success.bin"
restore.img_failure = "assets/gui_image_restore_failed.bin"
+local function check_available_space()
+ local backup_size = lfs.attributes(paths.backup_file, 'size')
+ local available_space = recovery.sys.free_space(paths.user_dir)
+
+ print(string.format("Checking disk space:\nNeeded space: %d bytes, available space: %d bytes", backup_size,
+ available_space))
+
+ assert(available_space > backup_size, "Not enough free space on user disk")
+end
+
+local function unpack_backup()
+ if helpers.exists(unpacked_backup_dir) then
+ print(string.format("Directory '%s' exists, removing", unpacked_backup_dir))
+ helpers.rmdir(unpacked_backup_dir)
+ end
+ lfs.mkdir(unpacked_backup_dir)
+ print(string.format("Unpacking backup file '%s' to '%s'", paths.backup_file, unpacked_backup_dir))
+ ltar.unpack(paths.backup_file, unpacked_backup_dir)
+end
+
+local function build_db_set(file)
+ local contents = helpers.read_whole_file(file)
+ local root = json.decode(contents)
+ local set = {}
+ for _, entry in pairs(root.databases) do
+ set[entry.name] = tonumber(entry.version)
+ end
+ return set
+end
+
+local function perform_db_migration()
+ print("Performing database migration")
+ local dbset = build_db_set(version_file)
+ local result = migration.migrate(unpacked_backup_dir, paths.migration_scripts_dir, dbset)
+ assert(result == migration.retcode.OK, string.format("Database migration process failed with %d", result))
+end
+
+local function sync_databases()
+ print("Syncing databases:")
+ print(string.format("Replacing old databases: '%s' with the ones from '%s'", paths.db_dir, unpacked_backup_dir))
+
+ helpers.rm_files_from_dir(paths.db_dir)
+ helpers.copy_dir(unpacked_backup_dir, paths.db_dir)
+ assert(os.remove(paths.db_dir .. "/" .. consts.version_file))
+end
+
+local function remove_cache()
+ if helpers.exists(paths.file_indexer_cache) then
+ print(string.format("Removing cache file '%s'", paths.file_indexer_cache))
+ assert(os.remove(paths.file_indexer_cache))
+ end
+end
+
+local function cleanup()
+ if helpers.exists(unpacked_backup_dir) then
+ helpers.rmdir(unpacked_backup_dir)
+ end
+end
+
function restore.execute()
+ check_available_space()
+ unpack_backup()
+ perform_db_migration()
+ sync_databases()
+ remove_cache()
+ cleanup()
end
return restore
A scripts/lua/share/consts.lua => scripts/lua/share/consts.lua +5 -0
@@ 0,0 1,5 @@
+local consts = {}
+
+consts.version_file = "version.json"
+
+return consts<
\ No newline at end of file
M scripts/lua/share/helpers.lua => scripts/lua/share/helpers.lua +30 -1
@@ 3,6 3,7 @@
--- helper scripts
-- @module helpers
local lfs = require('lfs')
+local json = require('lunajson')
local helpers = {}
@@ 78,7 79,7 @@ function helpers.copy_file(filename_in, filename_out)
fd_out:close()
end
---- Remove directory and its contents
+--- Remove directory and its content
-- @function rmdir
-- @param dir directory to remove
function helpers.rmdir(dir)
@@ 95,6 96,22 @@ function helpers.rmdir(dir)
lfs.rmdir(dir)
end
+--- Remove directory content
+-- @function rmdir_content
+-- @param dir directory path
+function helpers.rmdir_content(dir)
+ for file in lfs.dir(dir) do
+ local file_path = dir .. "/" .. file
+ if file ~= "." and file ~= ".." then
+ if lfs.attributes(file_path, "mode") == "file" then
+ assert(os.remove(file_path))
+ elseif lfs.attributes(file_path, "mode") == "directory" then
+ helpers.rmdir(file_path)
+ end
+ end
+ end
+end
+
--- Remove all files from directory without touching internal directories
-- @function rm_files_from_dir
-- @param dir directory to remove files from
@@ 184,6 201,9 @@ function helpers.get_file_extension(file)
return file:match("^.+(%..+)$")
end
+--- Create directory and all required subdirectories
+-- @function mkdirp
+-- @param file file path
function helpers.mkdirp(p)
if lfs.attributes(p, 'mode') == 'directory' then
return nil, 'already exists'
@@ 199,4 219,13 @@ function helpers.mkdirp(p)
return lfs.mkdir(p)
end
+--- Get OS version from the 'version.json'
+-- @function get_os_version
+-- @param file file path
+function helpers.get_os_version(file)
+ local contents = helpers.read_whole_file(file)
+ local root = json.decode(contents)
+ return root.os.version
+end
+
return helpers
A scripts/lua/share/paths.lua => scripts/lua/share/paths.lua +20 -0
@@ 0,0 1,20 @@
+local recovery = require('recovery')
+local consts = require('consts')
+
+local paths = {}
+
+local user_dir = recovery.sys.user()
+local system_dir = recovery.sys.source_slot()
+
+paths.data_dir = system_dir .. "/data"
+paths.db_dir = system_dir .. "/db"
+paths.db_factory_dir = paths.db_dir .. "/factory"
+paths.temp_dir = user_dir .. "/temp"
+paths.update_dir = user_dir .. "/temp/update"
+paths.migration_scripts_dir = paths.db_dir .. "/migration"
+
+paths.version_file = system_dir .. "/" .. consts.version_file
+paths.backup_file = paths.temp_dir .. "/backup.tar"
+paths.file_indexer_cache = system_dir .. "/data/.directory_is_indexed"
+
+return paths
A scripts/lua/test/device/system/db/alarms.db => scripts/lua/test/device/system/db/alarms.db +0 -0
A scripts/lua/test/device/system/db/calllog.db => scripts/lua/test/device/system/db/calllog.db +0 -0
A scripts/lua/test/device/system/db/callog.db => scripts/lua/test/device/system/db/callog.db +0 -0
A scripts/lua/test/device/system/db/contacts.db => scripts/lua/test/device/system/db/contacts.db +0 -0
A scripts/lua/test/device/system/db/custom_quotes.db => scripts/lua/test/device/system/db/custom_quotes.db +0 -0
A scripts/lua/test/device/system/db/events.db => scripts/lua/test/device/system/db/events.db +0 -0
A scripts/lua/test/device/system/db/factory/alarms.db => scripts/lua/test/device/system/db/factory/alarms.db +0 -0
A scripts/lua/test/device/system/db/factory/calllog.db => scripts/lua/test/device/system/db/factory/calllog.db +0 -0
A scripts/lua/test/device/system/db/factory/callog.db => scripts/lua/test/device/system/db/factory/callog.db +0 -0
A scripts/lua/test/device/system/db/factory/contacts.db => scripts/lua/test/device/system/db/factory/contacts.db +0 -0
A scripts/lua/test/device/system/db/factory/custom_quotes.db => scripts/lua/test/device/system/db/factory/custom_quotes.db +0 -0
A scripts/lua/test/device/system/db/factory/events.db => scripts/lua/test/device/system/db/factory/events.db +0 -0
A scripts/lua/test/device/system/db/factory/multimedia.db => scripts/lua/test/device/system/db/factory/multimedia.db +0 -0
A scripts/lua/test/device/system/db/factory/notes.db => scripts/lua/test/device/system/db/factory/notes.db +0 -0
A scripts/lua/test/device/system/db/factory/notifications.db => scripts/lua/test/device/system/db/factory/notifications.db +0 -0
A scripts/lua/test/device/system/db/factory/predefined_quotes.db => scripts/lua/test/device/system/db/factory/predefined_quotes.db +0 -0
A scripts/lua/test/device/system/db/factory/settings_v2.db => scripts/lua/test/device/system/db/factory/settings_v2.db +0 -0
A scripts/lua/test/device/system/db/factory/sms.db => scripts/lua/test/device/system/db/factory/sms.db +0 -0
A scripts/lua/test/device/system/db/migration/alarms/0/down.sql => scripts/lua/test/device/system/db/migration/alarms/0/down.sql +0 -0
A scripts/lua/test/device/system/db/migration/alarms/0/up.sql => scripts/lua/test/device/system/db/migration/alarms/0/up.sql +0 -0
A scripts/lua/test/device/system/db/migration/callog/0/down.sql => scripts/lua/test/device/system/db/migration/callog/0/down.sql +0 -0
A scripts/lua/test/device/system/db/migration/callog/0/up.sql => scripts/lua/test/device/system/db/migration/callog/0/up.sql +0 -0
A scripts/lua/test/device/system/db/migration/contacts/0/down.sql => scripts/lua/test/device/system/db/migration/contacts/0/down.sql +0 -0
A scripts/lua/test/device/system/db/migration/contacts/0/up.sql => scripts/lua/test/device/system/db/migration/contacts/0/up.sql +0 -0
A scripts/lua/test/device/system/db/migration/custom_quotes/0/down.sql => scripts/lua/test/device/system/db/migration/custom_quotes/0/down.sql +0 -0
A scripts/lua/test/device/system/db/migration/custom_quotes/0/up.sql => scripts/lua/test/device/system/db/migration/custom_quotes/0/up.sql +0 -0
A scripts/lua/test/device/system/db/migration/events/0/down.sql => scripts/lua/test/device/system/db/migration/events/0/down.sql +0 -0
A scripts/lua/test/device/system/db/migration/events/0/up.sql => scripts/lua/test/device/system/db/migration/events/0/up.sql +0 -0
A scripts/lua/test/device/system/db/migration/multimedia/0/down.sql => scripts/lua/test/device/system/db/migration/multimedia/0/down.sql +0 -0
A scripts/lua/test/device/system/db/migration/multimedia/0/up.sql => scripts/lua/test/device/system/db/migration/multimedia/0/up.sql +0 -0
A scripts/lua/test/device/system/db/migration/notes/0/down.sql => scripts/lua/test/device/system/db/migration/notes/0/down.sql +0 -0
A scripts/lua/test/device/system/db/migration/notes/0/up.sql => scripts/lua/test/device/system/db/migration/notes/0/up.sql +0 -0
A scripts/lua/test/device/system/db/migration/notifications/0/down.sql => scripts/lua/test/device/system/db/migration/notifications/0/down.sql +0 -0
A scripts/lua/test/device/system/db/migration/notifications/0/up.sql => scripts/lua/test/device/system/db/migration/notifications/0/up.sql +0 -0
A scripts/lua/test/device/system/db/migration/predefined_quotes/0/down.sql => scripts/lua/test/device/system/db/migration/predefined_quotes/0/down.sql +0 -0
A scripts/lua/test/device/system/db/migration/predefined_quotes/0/up.sql => scripts/lua/test/device/system/db/migration/predefined_quotes/0/up.sql +0 -0
A scripts/lua/test/device/system/db/migration/settings_v2/0/down.sql => scripts/lua/test/device/system/db/migration/settings_v2/0/down.sql +0 -0
A scripts/lua/test/device/system/db/migration/settings_v2/0/up.sql => scripts/lua/test/device/system/db/migration/settings_v2/0/up.sql +0 -0
A scripts/lua/test/device/system/db/migration/sms/0/down.sql => scripts/lua/test/device/system/db/migration/sms/0/down.sql +0 -0
A scripts/lua/test/device/system/db/migration/sms/0/up.sql => scripts/lua/test/device/system/db/migration/sms/0/up.sql +0 -0
A scripts/lua/test/device/system/db/multimedia.db => scripts/lua/test/device/system/db/multimedia.db +0 -0
A scripts/lua/test/device/system/db/notes.db => scripts/lua/test/device/system/db/notes.db +0 -0
A scripts/lua/test/device/system/db/notifications.db => scripts/lua/test/device/system/db/notifications.db +0 -0
A scripts/lua/test/device/system/db/predefined_quotes.db => scripts/lua/test/device/system/db/predefined_quotes.db +0 -0
A scripts/lua/test/device/system/db/settings_v2.db => scripts/lua/test/device/system/db/settings_v2.db +0 -0
A scripts/lua/test/device/system/db/sms.db => scripts/lua/test/device/system/db/sms.db +0 -0
A scripts/lua/test/device/system/version.json => scripts/lua/test/device/system/version.json +42 -0
@@ 0,0 1,42 @@
+{
+ "git":
+ {
+ "git_branch": "@GIT_BRANCH@",
+ "git_commit": "@GIT_REV@"
+ },
+ "version":
+ {
+ "version": "@PROJECT_VERSION@"
+ },
+ "bootloader":
+ {
+ "version": "@ECOBOOT_BIN_VERSION@",
+ "filename": "@BOOTLOADER_FILENAME@",
+ "md5sum": "@BOOTLOADER_MD5SUM@"
+ },
+ "os":
+ {
+ "version": "@OS_VERSION_MAJOR@.@OS_VERSION_MINOR@.@OS_VERSION_PATCH@",
+ "filename": "@OS_FILENAME@",
+ "md5sum": "@OS_MD5SUM@"
+ },
+ "recovery":
+ {
+ "version": "@RECOVERY_BIN_VERSION@",
+ "filename": "@RECOVERY_FILENAME@",
+ "md5sum": "@RECOVERY_MD5SUM@"
+ },
+ "databases":[
+ {"name": "alarms", "version": "0"},
+ {"name": "callog", "version": "0"},
+ {"name": "contacts", "version": "0"},
+ {"name": "custom_quotes", "version": "0"},
+ {"name": "events", "version": "0"},
+ {"name": "multimedia", "version": "0"},
+ {"name": "notes", "version": "0"},
+ {"name": "notifications", "version": "0"},
+ {"name": "predefined_quotes", "version": "0"},
+ {"name": "settings_v2", "version": "0"},
+ {"name": "sms", "version": "0"}
+ ]
+}
A scripts/lua/test/device/user/temp/recovery_status.json => scripts/lua/test/device/user/temp/recovery_status.json +1 -0
@@ 0,0 1,1 @@
+{"version": "0.0.0","branch": "test","revision": "BABEF00D","operation": "restore","successful": false,"message": "../restore.lua:26: Not enough free space on user disk"}<
\ No newline at end of file
A scripts/lua/test/install_dependencies.sh => scripts/lua/test/install_dependencies.sh +33 -0
@@ 0,0 1,33 @@
+#!/usr/bin/env bash
+# Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+# For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+function if_cmd_installed() {
+ if ! command -v "$1" &> /dev/null; then
+ echo "$1 command could not be found. Please install it using system package manager"
+ exit 1
+ fi
+}
+
+function install_ltar(){
+wget https://github.com/mudita/ltar/archive/master.zip -P temp
+cd temp
+tar -xvf master.zip && cd ltar-master
+luarocks make
+cd ../..
+rm -r temp
+}
+
+function copy_assets(){
+ mkdir -p assets
+ cp -r ../products/PurePhone/assets/ assets/
+}
+
+if_cmd_installed "luarocks"
+
+luarocks install lunajson
+luarocks install lfs
+luarocks install busted
+
+install_ltar
+copy_assets<
\ No newline at end of file
A scripts/lua/test/test.lua => scripts/lua/test/test.lua +177 -0
@@ 0,0 1,177 @@
+package.path = package.path .. ";../?.lua;../?/?.lua;../share/?.lua;../share/?/?.lua"
+
+local helpers = require('helpers')
+
+local recovery = {}
+
+function recovery.version()
+ return "0.0.0"
+end
+
+function recovery.branch()
+ return "test"
+end
+
+function recovery.revision()
+ return "BABEF00D"
+end
+
+local sys = {}
+local bootctrl = {}
+local gui = {}
+
+sys.boot_reason_codes = {
+ update = 0xF001,
+ recovery = 0xF002,
+ factory = 0xF003,
+ pgm_keys = 0xF004,
+ usb_mc_mode = 0xF005,
+ backup = 0xF006,
+ restore = 0xF007,
+ os = 0xF008,
+ unknown = 0xF009
+}
+
+bootctrl.slot = {
+ a = 0,
+ b = 1
+}
+
+function bootctrl.mark_as_active(slot)
+
+end
+
+function bootctrl.get_next_active()
+
+end
+
+function sys.source_slot()
+ return "device/system"
+end
+
+function sys.sleep(time)
+end
+
+function sys.set_os_boot_status()
+
+end
+
+function gui.clear()
+end
+
+function gui.display_raw_img(width, height, data)
+end
+
+sys.user = stub()
+sys.target_slot = stub()
+sys.boot_reason = stub()
+sys.boot_reason_str = stub()
+sys.set_boot_reason = stub()
+sys.flash_bootloader = stub()
+sys.repartition_fs = stub()
+sys.free_space = stub()
+
+recovery.sys = sys
+recovery.gui = gui
+recovery.bootctrl = bootctrl
+
+package.preload["recovery"] = function()
+ return recovery
+end
+
+-- Used to recreate the original package.path during switching between products
+local ppack = package.path
+
+describe("Factory/backup/restore scripts", function()
+ package.path = ppack .. ";../products/PurePhone/?.lua"
+ recovery.sys.target_slot.returns("device/target")
+ recovery.sys.user.returns("device/user")
+
+ -- Force reload of the 'entry' module after execution of each unit test case
+ after_each(function()
+ package.loaded['entry'] = false
+ end)
+
+ it("invoke factory reset script", function()
+ recovery.sys.free_space.returns(1024 * 1024 * 1024)
+ recovery.sys.boot_reason.returns(recovery.sys.boot_reason_codes.factory)
+ recovery.sys.boot_reason_str.returns("factory")
+ local entry = require('entry')
+ end)
+ it("invoke backup script", function()
+ recovery.sys.free_space.returns(1024 * 1024 * 1024)
+ recovery.sys.boot_reason.returns(recovery.sys.boot_reason_codes.backup)
+ recovery.sys.boot_reason_str.returns("backup")
+ local entry = require('entry')
+ end)
+ it("invoke backup script, no free space", function()
+ recovery.sys.free_space.returns(10)
+ recovery.sys.boot_reason.returns(recovery.sys.boot_reason_codes.backup)
+ recovery.sys.boot_reason_str.returns("backup")
+ local entry = require('entry')
+ end)
+ it("invoke restore script", function()
+ recovery.sys.free_space.returns(1024 * 1024 * 1024)
+ recovery.sys.boot_reason.returns(recovery.sys.boot_reason_codes.restore)
+ recovery.sys.boot_reason_str.returns("restore")
+ local entry = require('entry')
+ end)
+ it("invoke restore script, no free space", function()
+ recovery.sys.free_space.returns(10)
+ recovery.sys.boot_reason.returns(recovery.sys.boot_reason_codes.restore)
+ recovery.sys.boot_reason_str.returns("restore")
+ local entry = require('entry')
+ end)
+end)
+
+local function remove_test_package(path)
+ if helpers.exists(path) then
+ helpers.rmdir(path)
+ end
+end
+
+local function extract_test_package(path, where)
+ os.execute(string.format("tar xf %s -C %s", path, where))
+end
+
+describe("Update scripts for PurePhone", function()
+ recovery.sys.boot_reason.returns(recovery.sys.boot_reason_codes.update)
+ recovery.sys.boot_reason_str.returns("update")
+ recovery.sys.target_slot.returns("update/target")
+ recovery.sys.user.returns("update/user")
+
+ package.loaded['paths'] = false
+ package.loaded['update'] = false
+
+ it("Normal update", function()
+ -- Prepare test directory and its data
+ remove_test_package("update/target")
+ remove_test_package("update/user/temp/update")
+ extract_test_package("update/target.tar", "update")
+ extract_test_package("update/update.tar", "update/user/temp")
+
+ local entry = require('entry')
+ end)
+end)
+
+describe("Update scripts for BellHybrid", function()
+ package.path = ppack .. ";../products/BellHybrid/?.lua"
+ recovery.sys.boot_reason.returns(recovery.sys.boot_reason_codes.update)
+ recovery.sys.boot_reason_str.returns("update")
+ recovery.sys.target_slot.returns("update/target")
+ recovery.sys.user.returns("update/user")
+
+ package.loaded['paths'] = false
+ package.loaded['update'] = false
+
+ it("Normal update", function()
+ -- Prepare test directory and its data
+ remove_test_package("update/target")
+ remove_test_package("update/user/temp/update")
+ extract_test_package("update/target.tar", "update")
+ extract_test_package("update/update.tar", "update/user/temp")
+
+ local entry = require('entry')
+ end)
+end)
+
A scripts/lua/test/update/system/version.json => scripts/lua/test/update/system/version.json +42 -0
@@ 0,0 1,42 @@
+{
+ "git":
+ {
+ "git_branch": "@GIT_BRANCH@",
+ "git_commit": "@GIT_REV@"
+ },
+ "version":
+ {
+ "version": "@PROJECT_VERSION@"
+ },
+ "bootloader":
+ {
+ "version": "@ECOBOOT_BIN_VERSION@",
+ "filename": "@BOOTLOADER_FILENAME@",
+ "md5sum": "@BOOTLOADER_MD5SUM@"
+ },
+ "os":
+ {
+ "version": "@OS_VERSION_MAJOR@.@OS_VERSION_MINOR@.@OS_VERSION_PATCH@",
+ "filename": "@OS_FILENAME@",
+ "md5sum": "@OS_MD5SUM@"
+ },
+ "recovery":
+ {
+ "version": "@RECOVERY_BIN_VERSION@",
+ "filename": "@RECOVERY_FILENAME@",
+ "md5sum": "@RECOVERY_MD5SUM@"
+ },
+ "databases":[
+ {"name": "alarms", "version": "0"},
+ {"name": "callog", "version": "0"},
+ {"name": "contacts", "version": "0"},
+ {"name": "custom_quotes", "version": "0"},
+ {"name": "events", "version": "0"},
+ {"name": "multimedia", "version": "0"},
+ {"name": "notes", "version": "0"},
+ {"name": "notifications", "version": "0"},
+ {"name": "predefined_quotes", "version": "0"},
+ {"name": "settings_v2", "version": "0"},
+ {"name": "sms", "version": "0"}
+ ]
+}
A scripts/lua/test/update/target.tar => scripts/lua/test/update/target.tar +0 -0
A scripts/lua/test/update/update.tar => scripts/lua/test/update/update.tar +0 -0