@Override
    public Mono<Void> cleanup(Backup backup) {
        return Mono.<Void>create(sink -> {
            var status = backup.getStatus();
            if (status == null || !StringUtils.hasText(status.getFilename())) {
                sink.success();
                return;
            }
            var filename = status.getFilename();
            var backupsRoot = getBackupsRoot();
            var backupFile = backupsRoot.resolve(filename);
            try {
                checkDirectoryTraversal(backupsRoot, backupFile);
                deleteIfExists(backupFile);
                sink.success();
            } catch (IOException e) {
                sink.error(e);
            }
        }).subscribeOn(scheduler);
    }
@Test
    void cleanupBackupTest() throws IOException {
        var backupFile = tempDir.resolve("workdir").resolve("backups").resolve("backup.zip");
        Files.createDirectories(backupFile.getParent());
        Files.createFile(backupFile);

        when(backupRoot.get()).thenReturn(tempDir.resolve("workdir").resolve("backups"));
        var backup = createSucceededBackup("fake-backup", "backup.zip");
        StepVerifier.create(migrationService.cleanup(backup))
            .verifyComplete();
        verify(haloProperties, never()).getWorkDir();
        verify(backupRoot).get();
        assertTrue(Files.notExists(backupFile));
    }