def test_set_unknown(client: Client, package_ahriman: Package, mocker: MockerFixture) -> None: """ must add new package with unknown status """ add_mock = mocker.patch("ahriman.core.status.client.Client.add") client.set_unknown(package_ahriman) add_mock.assert_called_with(package_ahriman, BuildStatusEnum.Unknown)
def test_set_success(client: Client, package_ahriman: Package, mocker: MockerFixture) -> None: """ must set success status to the package """ add_mock = mocker.patch("ahriman.core.status.client.Client.add") client.set_success(package_ahriman) add_mock.assert_called_with(package_ahriman, BuildStatusEnum.Success)
def test_set_failed(client: Client, package_ahriman: Package, mocker: MockerFixture) -> None: """ must set failed status to the package """ update_mock = mocker.patch("ahriman.core.status.client.Client.update") client.set_failed(package_ahriman.base) update_mock.assert_called_with(package_ahriman.base, BuildStatusEnum.Failed)
def test_load_full_client(configuration: Configuration) -> None: """ must load full client if no settings set """ configuration.set("web", "host", "localhost") configuration.set("web", "port", "8080") assert isinstance(Client.load(configuration), WebClient)
def __init__(self, args: argparse.Namespace, architecture: str, configuration: Configuration) -> None: """ default constructor :param args: command line args :param architecture: repository architecture :param configuration: configuration instance """ self.path = Path( f"{args.lock}_{architecture}") if args.lock is not None else None self.force = args.force self.unsafe = args.unsafe self.root = Path(configuration.get("repository", "root")) self.reporter = Client() if args.no_report else Client.load( configuration)
def __init__(self, architecture: str, configuration: Configuration) -> None: self.logger = logging.getLogger("builder") self.architecture = architecture self.configuration = configuration self.aur_url = configuration.get("alpm", "aur_url") self.name = configuration.get("repository", "name") self.paths = RepositoryPaths( configuration.getpath("repository", "root"), architecture) self.paths.create_tree() self.ignore_list = configuration.getlist("build", "ignore_packages") self.pacman = Pacman(configuration) self.sign = GPG(architecture, configuration) self.repo = Repo(self.name, self.paths, self.sign.repository_sign_args) self.reporter = Client.load(configuration)
def client() -> Client: return Client()
def test_update_self(client: Client) -> None: """ must update self status without errors """ client.update_self(BuildStatusEnum.Unknown)
def test_update(client: Client, package_ahriman: Package) -> None: """ must update package status without errors """ client.update(package_ahriman.base, BuildStatusEnum.Unknown)
def test_remove(client: Client, package_ahriman: Package) -> None: """ must process remove without errors """ client.remove(package_ahriman.base)
def test_get_self(client: Client) -> None: """ must return unknown status for service """ assert client.get_self().status == BuildStatusEnum.Unknown
def test_get_internal(client: Client) -> None: """ must return dummy status for web service """ assert client.get_internal() == InternalStatus()
def test_get(client: Client, package_ahriman: Package) -> None: """ must return empty package list """ assert client.get(package_ahriman.base) == [] assert client.get(None) == []
def test_add(client: Client, package_ahriman: Package) -> None: """ must process package addition without errors """ client.add(package_ahriman, BuildStatusEnum.Unknown)
def test_load_dummy_client(configuration: Configuration) -> None: """ must load dummy client if no settings set """ assert isinstance(Client.load(configuration), Client)
class Lock: """ wrapper for application lock file :ivar force: remove lock file on start if any :ivar path: path to lock file if any :ivar reporter: build status reporter instance :ivar root: repository root (i.e. ahriman home) :ivar unsafe: skip user check """ def __init__(self, args: argparse.Namespace, architecture: str, configuration: Configuration) -> None: """ default constructor :param args: command line args :param architecture: repository architecture :param configuration: configuration instance """ self.path = Path( f"{args.lock}_{architecture}") if args.lock is not None else None self.force = args.force self.unsafe = args.unsafe self.root = Path(configuration.get("repository", "root")) self.reporter = Client() if args.no_report else Client.load( configuration) def __enter__(self) -> Lock: """ default workflow is the following: check user UID check if there is lock file check web status watcher status create lock file report to web if enabled """ self.check_user() self.check_version() self.create() self.reporter.update_self(BuildStatusEnum.Building) return self def __exit__(self, exc_type: Optional[Type[Exception]], exc_val: Optional[Exception], exc_tb: TracebackType) -> Literal[False]: """ remove lock file when done :param exc_type: exception type name if any :param exc_val: exception raised if any :param exc_tb: exception traceback if any :return: always False (do not suppress any exception) """ self.clear() status = BuildStatusEnum.Success if exc_val is None else BuildStatusEnum.Failed self.reporter.update_self(status) return False def check_version(self) -> None: """ check web server version """ status = self.reporter.get_internal() if status.version is not None and status.version != version.__version__: logging.getLogger("root").warning( f"status watcher version mismatch, " f"our {version.__version__}, their {status.version}") def check_user(self) -> None: """ check if current user is actually owner of ahriman root """ if self.unsafe: return current_uid = os.getuid() root_uid = self.root.stat().st_uid if current_uid != root_uid: raise UnsafeRun(current_uid, root_uid) def clear(self) -> None: """ remove lock file """ if self.path is None: return self.path.unlink(missing_ok=True) def create(self) -> None: """ create lock file """ if self.path is None: return try: self.path.touch(exist_ok=self.force) except FileExistsError: raise DuplicateRun()