~aleteoryx/muditaos

ea5492fa429a7852a70b3fd8cb794a9796632633 — Mateusz Piesta 3 years ago 6f05c75
[MOS-803] Add backup/restore scripts

* Added test directory layout
* Added test assets
* Added backup/restore scripts
88 files changed, 513 insertions(+), 26 deletions(-)

M .gitignore
M scripts/lua/backup.lua
M scripts/lua/entry.lua
M scripts/lua/factory.lua
M scripts/lua/install.sh
M scripts/lua/migration/migration.lua
R scripts/lua/{assets/BellHybrid => products/BellHybrid/assets}/gui_image_factory_reset_failed.bin
R scripts/lua/{assets/BellHybrid => products/BellHybrid/assets}/gui_image_factory_reset_in_progress.bin
R scripts/lua/{assets/BellHybrid => products/BellHybrid/assets}/gui_image_factory_reset_success.bin
R scripts/lua/{assets/BellHybrid => products/BellHybrid/assets}/gui_image_update_failed.bin
R scripts/lua/{assets/BellHybrid => products/BellHybrid/assets}/gui_image_update_in_progress.bin
R scripts/lua/{assets/BellHybrid => products/BellHybrid/assets}/gui_image_update_success.bin
R scripts/lua/{assets/PurePhone => products/PurePhone/assets}/gui_image_backup_failed.bin
R scripts/lua/{assets/PurePhone => products/PurePhone/assets}/gui_image_backup_in_progress.bin
R scripts/lua/{assets/PurePhone => products/PurePhone/assets}/gui_image_backup_success.bin
R scripts/lua/{assets/PurePhone => products/PurePhone/assets}/gui_image_factory_reset_failed.bin
R scripts/lua/{assets/PurePhone => products/PurePhone/assets}/gui_image_factory_reset_in_progress.bin
R scripts/lua/{assets/PurePhone => products/PurePhone/assets}/gui_image_factory_reset_success.bin
R scripts/lua/{assets/PurePhone => products/PurePhone/assets}/gui_image_keys_failed.bin
R scripts/lua/{assets/PurePhone => products/PurePhone/assets}/gui_image_keys_in_progress.bin
R scripts/lua/{assets/PurePhone => products/PurePhone/assets}/gui_image_keys_success.bin
R scripts/lua/{assets/PurePhone => products/PurePhone/assets}/gui_image_recovery_failed.bin
R scripts/lua/{assets/PurePhone => products/PurePhone/assets}/gui_image_recovery_in_progress.bin
R scripts/lua/{assets/PurePhone => products/PurePhone/assets}/gui_image_recovery_success.bin
R scripts/lua/{assets/PurePhone => products/PurePhone/assets}/gui_image_restore_failed.bin
R scripts/lua/{assets/PurePhone => products/PurePhone/assets}/gui_image_restore_in_progress.bin
R scripts/lua/{assets/PurePhone => products/PurePhone/assets}/gui_image_restore_success.bin
R scripts/lua/{assets/PurePhone => products/PurePhone/assets}/gui_image_update_failed.bin
R scripts/lua/{assets/PurePhone => products/PurePhone/assets}/gui_image_update_in_progress.bin
R scripts/lua/{assets/PurePhone => products/PurePhone/assets}/gui_image_update_success.bin
A scripts/lua/products/PurePhone/product_updater.lua
M scripts/lua/restore.lua
A scripts/lua/share/consts.lua
M scripts/lua/share/helpers.lua
A scripts/lua/share/paths.lua
A scripts/lua/test/device/system/db/alarms.db
A scripts/lua/test/device/system/db/calllog.db
A scripts/lua/test/device/system/db/callog.db
A scripts/lua/test/device/system/db/contacts.db
A scripts/lua/test/device/system/db/custom_quotes.db
A scripts/lua/test/device/system/db/events.db
A scripts/lua/test/device/system/db/factory/alarms.db
A scripts/lua/test/device/system/db/factory/calllog.db
A scripts/lua/test/device/system/db/factory/callog.db
A scripts/lua/test/device/system/db/factory/contacts.db
A scripts/lua/test/device/system/db/factory/custom_quotes.db
A scripts/lua/test/device/system/db/factory/events.db
A scripts/lua/test/device/system/db/factory/multimedia.db
A scripts/lua/test/device/system/db/factory/notes.db
A scripts/lua/test/device/system/db/factory/notifications.db
A scripts/lua/test/device/system/db/factory/predefined_quotes.db
A scripts/lua/test/device/system/db/factory/settings_v2.db
A scripts/lua/test/device/system/db/factory/sms.db
A scripts/lua/test/device/system/db/migration/alarms/0/down.sql
A scripts/lua/test/device/system/db/migration/alarms/0/up.sql
A scripts/lua/test/device/system/db/migration/callog/0/down.sql
A scripts/lua/test/device/system/db/migration/callog/0/up.sql
A scripts/lua/test/device/system/db/migration/contacts/0/down.sql
A scripts/lua/test/device/system/db/migration/contacts/0/up.sql
A scripts/lua/test/device/system/db/migration/custom_quotes/0/down.sql
A scripts/lua/test/device/system/db/migration/custom_quotes/0/up.sql
A scripts/lua/test/device/system/db/migration/events/0/down.sql
A scripts/lua/test/device/system/db/migration/events/0/up.sql
A scripts/lua/test/device/system/db/migration/multimedia/0/down.sql
A scripts/lua/test/device/system/db/migration/multimedia/0/up.sql
A scripts/lua/test/device/system/db/migration/notes/0/down.sql
A scripts/lua/test/device/system/db/migration/notes/0/up.sql
A scripts/lua/test/device/system/db/migration/notifications/0/down.sql
A scripts/lua/test/device/system/db/migration/notifications/0/up.sql
A scripts/lua/test/device/system/db/migration/predefined_quotes/0/down.sql
A scripts/lua/test/device/system/db/migration/predefined_quotes/0/up.sql
A scripts/lua/test/device/system/db/migration/settings_v2/0/down.sql
A scripts/lua/test/device/system/db/migration/settings_v2/0/up.sql
A scripts/lua/test/device/system/db/migration/sms/0/down.sql
A scripts/lua/test/device/system/db/migration/sms/0/up.sql
A scripts/lua/test/device/system/db/multimedia.db
A scripts/lua/test/device/system/db/notes.db
A scripts/lua/test/device/system/db/notifications.db
A scripts/lua/test/device/system/db/predefined_quotes.db
A scripts/lua/test/device/system/db/settings_v2.db
A scripts/lua/test/device/system/db/sms.db
A scripts/lua/test/device/system/version.json
A scripts/lua/test/device/user/temp/recovery_status.json
A scripts/lua/test/install_dependencies.sh
A scripts/lua/test/test.lua
A scripts/lua/test/update/system/version.json
A scripts/lua/test/update/target.tar
A scripts/lua/test/update/update.tar
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