local createLibTest = require('/apis/libtest'); local createInstallerDisk = require('/apis/libinstallerdisk'); local testlib = createLibTest({ ... }); local counter = 0; local function freshDir() counter = counter + 1; local path = '/create-disk-test/case-' .. counter; fs.delete(path); fs.makeDir(path); return path; end local function readAll(path) local file = fs.open(path, 'r'); local body = file.readAll(); file.close(); return body; end local function writeFile(path, body) local file = fs.open(path, 'w'); file.write(body); file.close(); end local function fakePeripheral(drives) local names = {}; local byName = {}; for i, drive in ipairs(drives) do drive.name = drive.name or ('drive_' .. i); drive.present = drive.present ~= false; drive.data = drive.data ~= false; names[#names + 1] = drive.name; byName[drive.name] = drive; end return { getNames = function() return names; end, getType = function(name) if byName[name] then return 'drive'; end return nil; end, wrap = function(name) local drive = byName[name]; return { isDiskPresent = function() return drive.present; end, hasData = function() return drive.data; end, getMountPath = function() return drive.mountPath; end, setDiskLabel = function(label) drive.label = label; end, getDiskLabel = function() return drive.label; end, }; end, }; end local function fakeSettings() local api = { saveCount = 0 }; function api.save() api.saveCount = api.saveCount + 1; end return api; end local function assertCompiles(body) local chunk, err = load(body, 'generated-startup'); testlib.assertTrue(chunk, tostring(err)); end testlib.test('install autorun copies settings before wget and no reboot', function() local installer = createInstallerDisk(); local body = installer.buildAutorun('install'); assertCompiles(body); local sentinel = string.find(body, "fs.exists('/trapos')", 1, true); local label = string.find(body, 'TrapOS Disk', 1, true); local url = string.find(body, 'https://os.trapcloud.fr/install', 1, true); local copy = string.find(body, "fs.copy(src, '/.settings')", 1, true); local wget = string.find(body, "shell.run('wget', 'run', INSTALL_URL)", 1, true); testlib.assertTrue(sentinel); testlib.assertTrue(label); testlib.assertTrue(url); testlib.assertTrue(copy); testlib.assertTrue(wget); testlib.assertTrue(copy < wget); testlib.assertTrue(not string.find(body, 'os.reboot', 1, true)); end); testlib.test('uninstall autorun removes trapos and waits for eject', function() local installer = createInstallerDisk(); local body = installer.buildAutorun('uninstall'); assertCompiles(body); testlib.assertTrue(string.find(body, "shell.run('ccpm', 'uninstall', 'trapos', '--yes')", 1, true)); testlib.assertTrue(string.find(body, "os.pullEvent('disk_eject')", 1, true)); testlib.assertTrue(string.find(body, 'os.reboot', 1, true)); testlib.assertTrue(not string.find(body, "shell.run('wget'", 1, true)); testlib.assertTrue(not string.find(body, "fs.copy(src, '/.settings')", 1, true)); end); testlib.test('reinstall autorun uses marker, uninstall and wget', function() local installer = createInstallerDisk(); local body = installer.buildAutorun('reinstall'); assertCompiles(body); testlib.assertTrue(string.find(body, '.trapos-reinstalled', 1, true)); testlib.assertTrue(string.find(body, 'writeMarker(MARKER)', 1, true)); testlib.assertTrue(string.find(body, "shell.run('ccpm', 'uninstall', 'trapos', '--yes')", 1, true)); testlib.assertTrue(string.find(body, "shell.run('wget', 'run', INSTALL_URL)", 1, true)); testlib.assertTrue(string.find(body, "os.pullEvent('disk_eject')", 1, true)); end); testlib.test('findTargetDrive asks for blank disk with zero drives', function() local installer = createInstallerDisk({ peripheral = fakePeripheral({}) }); local ok, err = installer.findTargetDrive(); testlib.assertTrue(not ok); testlib.assertTrue(string.find(err, 'insert a blank', 1, true)); end); testlib.test('findTargetDrive rejects a non-empty floppy', function() local disk = freshDir(); writeFile(fs.combine(disk, 'existing'), 'x'); local installer = createInstallerDisk({ peripheral = fakePeripheral({ { mountPath = disk } }), }); local ok, err = installer.findTargetDrive(); testlib.assertTrue(not ok); testlib.assertTrue(string.find(err, 'not empty', 1, true)); end); testlib.test('findTargetDrive picks one empty over one non-empty', function() local nonEmpty = freshDir(); local empty = freshDir(); writeFile(fs.combine(nonEmpty, 'existing'), 'x'); local installer = createInstallerDisk({ peripheral = fakePeripheral({ { name = 'left', mountPath = nonEmpty }, { name = 'right', mountPath = empty }, }), }); local ok, result = installer.findTargetDrive(); testlib.assertTrue(ok, tostring(result)); testlib.assertEquals(result.name, 'right'); testlib.assertEquals(result.mountPath, empty); end); testlib.test('findTargetDrive rejects multiple empty disks', function() local installer = createInstallerDisk({ peripheral = fakePeripheral({ { mountPath = freshDir() }, { mountPath = freshDir() }, }), }); local ok, err = installer.findTargetDrive(); testlib.assertTrue(not ok); testlib.assertTrue(string.find(err, 'remove all but one', 1, true)); end); testlib.test('create install disk labels, copies settings, writes startup', function() local disk = freshDir(); local settingsPath = fs.combine(freshDir(), '.settings'); local drive = { name = 'top', mountPath = disk }; local settingsApi = fakeSettings(); writeFile(settingsPath, 'cloud.url=https://example.test'); local installer = createInstallerDisk({ peripheral = fakePeripheral({ drive }), settings = settingsApi, settingsSourcePath = settingsPath, }); local ok, result = installer.create({ mode = 'install' }); testlib.assertTrue(ok, tostring(result)); testlib.assertEquals(drive.label, 'TrapOS Disk'); testlib.assertEquals(result.mode, 'install'); testlib.assertEquals(settingsApi.saveCount, 1); testlib.assertEquals(readAll(fs.combine(disk, 'startup.lua')), installer.buildAutorun('install')); testlib.assertEquals(readAll(fs.combine(disk, '.settings')), 'cloud.url=https://example.test'); testlib.assertTrue(result.settingsCopied); testlib.assertTrue(not result.settingsWarning); end); testlib.test('create install disk warns when settings source is missing', function() local disk = freshDir(); local settingsApi = fakeSettings(); local installer = createInstallerDisk({ peripheral = fakePeripheral({ { mountPath = disk } }), settings = settingsApi, settingsSourcePath = fs.combine(freshDir(), '.settings'), }); local ok, result = installer.create({ mode = 'install' }); testlib.assertTrue(ok, tostring(result)); testlib.assertEquals(settingsApi.saveCount, 0); testlib.assertTrue(not fs.exists(fs.combine(disk, '.settings'))); testlib.assertTrue(not result.settingsCopied); testlib.assertTrue(result.settingsWarning); testlib.assertEquals(readAll(fs.combine(disk, 'startup.lua')), installer.buildAutorun('install')); end); testlib.test('create reinstall disk skips settings clone', function() local disk = freshDir(); local settingsPath = fs.combine(freshDir(), '.settings'); local drive = { name = 'top', mountPath = disk }; local settingsApi = fakeSettings(); writeFile(settingsPath, 'cloud.url=https://example.test'); local installer = createInstallerDisk({ peripheral = fakePeripheral({ drive }), settings = settingsApi, settingsSourcePath = settingsPath, }); local ok, result = installer.create({ mode = 'reinstall' }); testlib.assertTrue(ok, tostring(result)); testlib.assertEquals(drive.label, 'TrapOS Disk'); testlib.assertEquals(result.mode, 'reinstall'); testlib.assertEquals(settingsApi.saveCount, 0); testlib.assertTrue(not fs.exists(fs.combine(disk, '.settings'))); testlib.assertTrue(not result.settingsCopied); testlib.assertTrue(not result.settingsWarning); testlib.assertEquals(readAll(fs.combine(disk, 'startup.lua')), installer.buildAutorun('reinstall')); end); testlib.run();