mirror of
https://github.com/abraunegg/onedrive
synced 2026-03-14 14:35:46 +01:00
115 lines
7.5 KiB
Python
115 lines
7.5 KiB
Python
from __future__ import annotations
|
|
|
|
import os
|
|
from pathlib import Path
|
|
|
|
from framework.base import E2ETestCase
|
|
from framework.context import E2EContext
|
|
from framework.manifest import build_manifest, write_manifest
|
|
from framework.result import TestResult
|
|
from framework.utils import command_to_string, reset_directory, run_command, write_text_file
|
|
|
|
|
|
class TestCase0022LocalFirstValidation(E2ETestCase):
|
|
case_id = "0022"
|
|
name = "local_first validation"
|
|
description = "Validate that local_first treats local content as the source of truth during a conflict"
|
|
|
|
def _write_default_config(self, config_path: Path) -> None:
|
|
write_text_file(config_path, "# tc0022 config\n" 'bypass_data_preservation = "true"\n')
|
|
|
|
def _write_local_first_config(self, config_path: Path) -> None:
|
|
write_text_file(config_path, "# tc0022 local first config\n" 'bypass_data_preservation = "true"\n' 'local_first = "true"\n')
|
|
|
|
def run(self, context: E2EContext) -> TestResult:
|
|
case_work_dir = context.work_root / "tc0022"
|
|
case_log_dir = context.logs_dir / "tc0022"
|
|
state_dir = context.state_dir / "tc0022"
|
|
reset_directory(case_work_dir)
|
|
reset_directory(case_log_dir)
|
|
reset_directory(state_dir)
|
|
context.ensure_refresh_token_available()
|
|
|
|
seed_root = case_work_dir / "seedroot"
|
|
local_root = case_work_dir / "localroot"
|
|
remote_update_root = case_work_dir / "remoteupdateroot"
|
|
verify_root = case_work_dir / "verifyroot"
|
|
conf_seed = case_work_dir / "conf-seed"
|
|
conf_local = case_work_dir / "conf-local"
|
|
conf_remote = case_work_dir / "conf-remote"
|
|
conf_verify = case_work_dir / "conf-verify"
|
|
root_name = f"ZZ_E2E_TC0022_{context.run_id}_{os.getpid()}"
|
|
relative_file = f"{root_name}/conflict.txt"
|
|
|
|
write_text_file(seed_root / relative_file, "base\n")
|
|
write_text_file(remote_update_root / relative_file, "remote wins unless local_first applies\n")
|
|
|
|
context.bootstrap_config_dir(conf_seed)
|
|
self._write_default_config(conf_seed / "config")
|
|
context.bootstrap_config_dir(conf_local)
|
|
self._write_local_first_config(conf_local / "config")
|
|
context.bootstrap_config_dir(conf_remote)
|
|
self._write_default_config(conf_remote / "config")
|
|
context.bootstrap_config_dir(conf_verify)
|
|
self._write_default_config(conf_verify / "config")
|
|
|
|
seed_stdout = case_log_dir / "seed_stdout.log"
|
|
seed_stderr = case_log_dir / "seed_stderr.log"
|
|
download_stdout = case_log_dir / "download_stdout.log"
|
|
download_stderr = case_log_dir / "download_stderr.log"
|
|
remote_stdout = case_log_dir / "remote_update_stdout.log"
|
|
remote_stderr = case_log_dir / "remote_update_stderr.log"
|
|
final_stdout = case_log_dir / "final_sync_stdout.log"
|
|
final_stderr = case_log_dir / "final_sync_stderr.log"
|
|
verify_stdout = case_log_dir / "verify_stdout.log"
|
|
verify_stderr = case_log_dir / "verify_stderr.log"
|
|
remote_manifest_file = state_dir / "remote_verify_manifest.txt"
|
|
metadata_file = state_dir / "metadata.txt"
|
|
|
|
seed_command = [context.onedrive_bin, "--display-running-config", "--upload-only", "--verbose", "--resync", "--resync-auth", "--single-directory", root_name, "--syncdir", str(seed_root), "--confdir", str(conf_seed)]
|
|
seed_result = run_command(seed_command, cwd=context.repo_root)
|
|
write_text_file(seed_stdout, seed_result.stdout)
|
|
write_text_file(seed_stderr, seed_result.stderr)
|
|
|
|
download_command = [context.onedrive_bin, "--display-running-config", "--sync", "--verbose", "--download-only", "--resync", "--resync-auth", "--single-directory", root_name, "--syncdir", str(local_root), "--confdir", str(conf_local)]
|
|
download_result = run_command(download_command, cwd=context.repo_root)
|
|
write_text_file(download_stdout, download_result.stdout)
|
|
write_text_file(download_stderr, download_result.stderr)
|
|
|
|
write_text_file(local_root / relative_file, "local wins because local_first is enabled\n")
|
|
|
|
remote_command = [context.onedrive_bin, "--display-running-config", "--upload-only", "--verbose", "--single-directory", root_name, "--syncdir", str(remote_update_root), "--confdir", str(conf_remote)]
|
|
remote_result = run_command(remote_command, cwd=context.repo_root)
|
|
write_text_file(remote_stdout, remote_result.stdout)
|
|
write_text_file(remote_stderr, remote_result.stderr)
|
|
|
|
final_command = [context.onedrive_bin, "--display-running-config", "--sync", "--verbose", "--single-directory", root_name, "--syncdir", str(local_root), "--confdir", str(conf_local)]
|
|
final_result = run_command(final_command, cwd=context.repo_root)
|
|
write_text_file(final_stdout, final_result.stdout)
|
|
write_text_file(final_stderr, final_result.stderr)
|
|
|
|
verify_command = [context.onedrive_bin, "--display-running-config", "--sync", "--verbose", "--download-only", "--resync", "--resync-auth", "--single-directory", root_name, "--syncdir", str(verify_root), "--confdir", str(conf_verify)]
|
|
verify_result = run_command(verify_command, cwd=context.repo_root)
|
|
write_text_file(verify_stdout, verify_result.stdout)
|
|
write_text_file(verify_stderr, verify_result.stderr)
|
|
remote_manifest = build_manifest(verify_root)
|
|
write_manifest(remote_manifest_file, remote_manifest)
|
|
|
|
local_content = (local_root / relative_file).read_text(encoding="utf-8") if (local_root / relative_file).is_file() else ""
|
|
remote_content = (verify_root / relative_file).read_text(encoding="utf-8") if (verify_root / relative_file).is_file() else ""
|
|
write_text_file(metadata_file, f"case_id={self.case_id}\nroot_name={root_name}\nseed_returncode={seed_result.returncode}\ndownload_returncode={download_result.returncode}\nremote_returncode={remote_result.returncode}\nfinal_returncode={final_result.returncode}\nverify_returncode={verify_result.returncode}\nlocal_content={local_content!r}\nremote_content={remote_content!r}\n")
|
|
|
|
artifacts = [str(seed_stdout), str(seed_stderr), str(download_stdout), str(download_stderr), str(remote_stdout), str(remote_stderr), str(final_stdout), str(final_stderr), str(verify_stdout), str(verify_stderr), str(remote_manifest_file), str(metadata_file)]
|
|
details = {"seed_returncode": seed_result.returncode, "download_returncode": download_result.returncode, "remote_returncode": remote_result.returncode, "final_returncode": final_result.returncode, "verify_returncode": verify_result.returncode, "root_name": root_name}
|
|
|
|
for label, rc in [("seed", seed_result.returncode), ("download", download_result.returncode), ("remote update", remote_result.returncode), ("final sync", final_result.returncode), ("verify", verify_result.returncode)]:
|
|
if rc != 0:
|
|
return TestResult.fail_result(self.case_id, self.name, f"{label} phase failed with status {rc}", artifacts, details)
|
|
|
|
expected = "local wins because local_first is enabled\n"
|
|
if local_content != expected:
|
|
return TestResult.fail_result(self.case_id, self.name, "Local content was not retained after conflict resolution with local_first enabled", artifacts, details)
|
|
if remote_content != expected:
|
|
return TestResult.fail_result(self.case_id, self.name, "Remote content did not converge to the local source-of-truth content when local_first was enabled", artifacts, details)
|
|
|
|
return TestResult.pass_result(self.case_id, self.name, artifacts, details)
|