Add the gifn-apply test tool
Add a tool that checks out the repositories mentioned in
a git-if-needed patch series, runs gif-it-needed, and performs
some checks on its operation. This tool will eventually be used in
a Zuul test job for this repository.
Change-Id: Id02fb7c21f5ab34d9639bf845fcc3961d929b13b
diff --git a/tools/git-if-needed/python/unit_tests/__init__.py b/tools/git-if-needed/python/unit_tests/__init__.py
new file mode 100644
index 0000000..621bbac
--- /dev/null
+++ b/tools/git-if-needed/python/unit_tests/__init__.py
@@ -0,0 +1,3 @@
+# SPDX-FileCopyrightText: StorPool <support@storpool.com>
+# SPDX-License-Identifier: BSD-2-Clause
+"""Unit tests for the gifn-apply tool."""
diff --git a/tools/git-if-needed/python/unit_tests/test_repo_urls.py b/tools/git-if-needed/python/unit_tests/test_repo_urls.py
new file mode 100644
index 0000000..54c6bf9
--- /dev/null
+++ b/tools/git-if-needed/python/unit_tests/test_repo_urls.py
@@ -0,0 +1,50 @@
+# SPDX-FileCopyrightText: StorPool <support@storpool.com>
+# SPDX-License-Identifier: BSD-2-Clause
+"""Test the parsing of base/URL pairs."""
+
+from __future__ import annotations
+
+from typing import NamedTuple
+
+import pytest
+
+from gifn_apply import repo_url
+
+
+class TrivURL(NamedTuple):
+ """The basic elements of a parsed URL."""
+
+ scheme: str
+ netloc: str
+ path: str
+
+
+PARSE_URLS: list[tuple[str, str, TrivURL | None]] = [
+ ("", "https://github.com/openstack", None),
+ ("ostack", "https://github.com/openstack", None),
+ ("OSTACK!", "https://github.com/openstack", None),
+ ("OSTACK", "https://github.com/openstack", TrivURL("https", "github.com", "/openstack/")),
+ ("OSTACK", "https://github.com/openstack/", TrivURL("https", "github.com", "/openstack/")),
+ ("local", "file:///absolute/path", None),
+ ("LOCAL_3!", "file:///absolute/path", None),
+ ("LOCAL_3", "file://host", None),
+ ("LOCAL_3", "file:relative/path", None),
+ ("LOCAL_3", "file:///absolute/path", TrivURL("file", "", "/absolute/path/")),
+ ("OSTACK", "file:///absolute/path", TrivURL("file", "", "/absolute/path/")),
+ ("OSTACK", "httpx://github.com/openstack", None),
+ ("OSTACK", "loc", None),
+ ("OSTACK", "/path", None),
+ ("OSTACK", ":path", None),
+]
+
+
+@pytest.mark.parametrize(("base", "value", "expected"), PARSE_URLS)
+def test_parse_url(base: str, value: str, expected: TrivURL | None) -> None:
+ """Test the base parse_url() function."""
+ res = repo_url.parse_url(f"R_{base}", base, value)
+ if expected is None:
+ assert isinstance(res, repo_url.RepoURLError)
+ else:
+ assert isinstance(res, repo_url.RepoURLOK)
+ url = res.url.url
+ assert (url.scheme, url.netloc, url.path) == expected
diff --git a/tools/git-if-needed/python/unit_tests/test_util.py b/tools/git-if-needed/python/unit_tests/test_util.py
new file mode 100644
index 0000000..bdcb5ad
--- /dev/null
+++ b/tools/git-if-needed/python/unit_tests/test_util.py
@@ -0,0 +1,21 @@
+# SPDX-FileCopyrightText: StorPool <support@storpool.com>
+# SPDX-License-Identifier: BSD-2-Clause
+"""Test the gifn_apply.util functions."""
+
+import pytest
+
+from gifn_apply import util
+
+
+@pytest.mark.parametrize(
+ ("value", "prefix", "expected"),
+ [
+ ("hello", "goodbye", "hello"),
+ ("hello", "hel", "lo"),
+ ("hel", "hello", "hel"),
+ ("hello", "hello", ""),
+ ],
+)
+def test_remove_prefix(value: str, prefix: str, expected: str) -> None:
+ """Test our hand-rolled str.removeprefix() implementation."""
+ assert util.str_removeprefix(value, prefix) == expected