aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/test_remote.py159
1 files changed, 155 insertions, 4 deletions
diff --git a/tests/test_remote.py b/tests/test_remote.py
index 31d0597..c2b9857 100644
--- a/tests/test_remote.py
+++ b/tests/test_remote.py
@@ -45,7 +45,9 @@ class Base(unittest.TestCase):
with open(conf, "w") as f:
f.write(f'state_dir = "{self.tmp}"\n'
f'repo_dir = "{self.tmp}/repo"\n'
- f'slackrepo_db = "{self.tmp}/slackrepo.sqlite3"\n')
+ f'slackrepo_db = "{self.tmp}/slackrepo.sqlite3"\n'
+ f'hintdir = "{self.tmp}/hints"\n'
+ f'genreprc = "{self.tmp}/genreprc"\n')
patcher = mock.patch.dict(os.environ, {"SBB_CONFIG": conf})
patcher.start()
self.addCleanup(patcher.stop)
@@ -61,6 +63,34 @@ class Base(unittest.TestCase):
open(os.path.join(d, "log"), "wb").close()
return jid, d
+ def make_pkg(self, path, info="", hint=None, desc=None):
+ d = os.path.join(self.cfg["repo_dir"], path)
+ pkg = os.path.basename(path)
+ os.makedirs(d, exist_ok=True)
+ open(os.path.join(d, pkg + ".SlackBuild"), "w").close()
+ with open(os.path.join(d, pkg + ".info"), "w") as f:
+ f.write(info)
+ if desc:
+ with open(os.path.join(d, "slack-desc"), "w") as f:
+ f.write(f"{pkg}: {pkg} ({desc})\n{pkg}:\n")
+ if hint is not None:
+ os.makedirs(self.cfg["hintdir"], exist_ok=True)
+ with open(os.path.join(self.cfg["hintdir"], pkg + ".hint"), "w") as f:
+ f.write(hint)
+
+ def fake_bin(self, name, script):
+ bindir = os.path.join(self.tmp, "bin")
+ os.makedirs(bindir, exist_ok=True)
+ path = os.path.join(bindir, name)
+ with open(path, "w") as f:
+ f.write("#!/bin/sh\n" + script)
+ os.chmod(path, 0o755)
+ if bindir not in os.environ["PATH"]:
+ patcher = mock.patch.dict(os.environ, {"PATH": bindir + os.pathsep + os.environ["PATH"]})
+ patcher.start()
+ self.addCleanup(patcher.stop)
+ return path
+
def hold_lock(self):
f = open(os.path.join(self.tmp, "lock"), "a")
fcntl.flock(f, fcntl.LOCK_EX)
@@ -109,11 +139,33 @@ class ConfigTest(Base):
class KindsTest(Base):
def test_sbpull_argv(self):
self.assertEqual(sbb.KINDS["sbpull"](self.cfg, ["personal", "--no"]),
- ["bash", "-c", '. "$1" && sbpull "$2" "$3"', "_",
- self.cfg["sbpull_script"], "personal", "--no"])
+ (["bash", "-c", '. "$1" && sbpull "$2" "$3"', "_",
+ self.cfg["sbpull_script"], "personal", "--no"], {}))
def test_sbshadow_argv(self):
- self.assertEqual(sbb.KINDS["sbshadow"](self.cfg, ["--yes"]), ["sbshadow", "--yes"])
+ self.assertEqual(sbb.KINDS["sbshadow"](self.cfg, ["--yes"]), (["sbshadow", "--yes"], {}))
+
+ def test_slackrepo_argv(self):
+ self.make_pkg("misc/nuclei")
+ self.make_pkg("personal/foo")
+ kind = sbb.KINDS["slackrepo"]
+ self.assertEqual(kind(self.cfg, ["update", "--preview", "nuclei", "foo", "nuclei"]),
+ (["slackrepo", "--repo=SBo-danix", "update", "--preview", "nuclei", "foo"], {}))
+ self.assertEqual(kind(self.cfg, ["build", "--no-publish", "foo"]),
+ (["slackrepo", "--repo=SBo-danix", "build", "foo"], {"SBB_PUBLISH": "n"}))
+ self.assertEqual(kind(self.cfg, ["update"]), (["slackrepo", "--repo=SBo-danix", "update"], {}))
+
+ def test_slackrepo_rejects(self):
+ self.make_pkg("misc/nuclei")
+ for args in (["install", "nuclei"], ["build"], ["remove"], ["build", "nope"],
+ ["build", "../etc"], ["build", "--force", "nuclei"]):
+ with self.subTest(args=args), self.assertRaises(sbb.Error):
+ sbb.KINDS["slackrepo"](self.cfg, args)
+
+ def test_publish(self):
+ self.assertEqual(sbb.KINDS["publish"](self.cfg, []), (["sb-publish"], {}))
+ with self.assertRaises(sbb.Error):
+ sbb.KINDS["publish"](self.cfg, ["x"])
def test_rejects_bad_args(self):
for kind, args in (("sbpull", ["evil", "--no"]), ("sbpull", ["personal"]),
@@ -138,6 +190,100 @@ class MainTest(Base):
(0, {"version": sbb.VERSION, "overlays": ["personal", "pentesting"]}))
+class InventoryTest(Base):
+ def test_rows(self):
+ self.make_pkg("misc/nuclei", 'VERSION="3.11.0"\nMAINTAINER="Some One"\n'
+ 'REQUIRES="go \\\n git"\n', desc="Fast scanner")
+ self.make_pkg("personal/foo", 'VERSION="1.0"\n',
+ hint='VERSION="1.1" # bumped\nDELREQUIRES="a b"\nOPTIONS="X=$(uname -m)"\n')
+ os.makedirs(os.path.join(self.cfg["repo_dir"], "misc", "notapkg"))
+ db = sqlite3.connect(self.cfg["slackrepo_db"])
+ db.executescript("""
+ create table buildresults (itemid text primary key, time text, result text);
+ create table revisions (itemid text, dep text, deplist text, version text,
+ built text, rev text, os text, hintcksum text, primary key (itemid, dep));
+ insert into buildresults values ('misc/nuclei', '5', 'ok'), ('nuclei', '1', 'bad');
+ insert into revisions values ('misc/nuclei', '/', '/', '3.11.0', '1788978222', 'r', 'o', '/');
+ """)
+ db.close()
+ inv = sbb.cmd_inventory(self.cfg)
+ rows = [dict(zip(inv["columns"], r)) for r in inv["rows"]]
+ self.assertEqual([r["path"] for r in rows], ["misc/nuclei", "personal/foo"])
+ nuclei, foo = rows
+ self.assertEqual((nuclei["version"], nuclei["built_version"], nuclei["built_time"],
+ nuclei["result"], nuclei["maintainer"], nuclei["requires"],
+ nuclei["summary"], nuclei["hint_path"]),
+ ("3.11.0", "3.11.0", 1788978222, "ok", "Some One", ["go", "git"],
+ "Fast scanner", None))
+ self.assertEqual((foo["version"], foo["info_version"], foo["hint_version"], foo["result"]),
+ ("1.1", "1.0", "1.1", None))
+ self.assertEqual(foo["hints"]["DELREQUIRES"], "a b")
+ self.assertEqual(foo["hints"]["OPTIONS"], {"value": '"X=$(uname -m)"', "shell": True})
+ json.dumps(inv)
+
+ def test_hint_search_order(self):
+ self.make_pkg("misc/foo")
+ sub = os.path.join(self.cfg["hintdir"], "misc", "foo")
+ os.makedirs(sub)
+ with open(os.path.join(sub, "foo.hint"), "w") as f:
+ f.write('VERSION="2"\n')
+ self.assertEqual(sbb.find_hint(self.cfg, "misc/foo"), os.path.join(sub, "foo.hint"))
+ with open(os.path.join(self.cfg["hintdir"], "foo.hint"), "w") as f:
+ f.write('VERSION="3"\n')
+ self.assertEqual(sbb.find_hint(self.cfg, "misc/foo"),
+ os.path.join(self.cfg["hintdir"], "foo.hint"))
+ in_repo = os.path.join(self.cfg["repo_dir"], "misc", "foo", "foo.hint")
+ open(in_repo, "w").close()
+ self.assertEqual(sbb.find_hint(self.cfg, "misc/foo"), in_repo)
+
+ def test_missing_db(self):
+ self.make_pkg("misc/foo", 'VERSION="1"\n')
+ row = sbb.cmd_inventory(self.cfg)["rows"][0]
+ self.assertEqual(row[4:7], [None, None, None])
+
+
+class GpgTest(Base):
+ def setup_key(self, cached):
+ with open(self.cfg["genreprc"], "w") as f:
+ f.write('REPOSOWNERGPG="ABCD1234"\nUSE_GPGAGENT=1\n')
+ self.fake_bin("gpg", 'case "$*" in\n'
+ ' *--list-secret-keys*) printf "sec:u:255:22:K:1::::::scESC:\\n'
+ 'grp:::::::::GRIPSIGN:\\nssb:u:255:18:S:1::::::e:\\ngrp:::::::::GRIPENC:\\n" ;;\n'
+ f' *-bas*) [ -f "{self.tmp}/good" ] ;;\n'
+ 'esac\n')
+ flag = "1" if cached else "-"
+ self.fake_bin("gpg-connect-agent", f'echo "S KEYINFO GRIPSIGN D - - {flag} P - - -"; echo OK\n')
+
+ def test_status(self):
+ self.assertEqual(sbb.cmd_gpg_status(self.cfg), {"unlocked": None, "key": None})
+ self.setup_key(cached=False)
+ self.assertEqual(sbb.cmd_gpg_status(self.cfg), {"unlocked": False, "key": "ABCD1234"})
+ self.setup_key(cached=True)
+ self.assertEqual(sbb.cmd_gpg_status(self.cfg)["unlocked"], True)
+
+ def test_locked_refuses_real_run_only(self):
+ self.setup_key(cached=False)
+ self.make_pkg("misc/foo")
+ with self.assertRaisesRegex(sbb.Error, "signing key locked"):
+ sbb.cmd_job_start(self.cfg, "slackrepo", "build", "foo")
+ self.fake_bin("slackrepo", "exit 0\n")
+ self.assertIn("id", sbb.cmd_job_start(self.cfg, "slackrepo", "build", "--preview", "foo"))
+
+ def test_unlock(self):
+ self.setup_key(cached=False)
+ log = os.path.join(self.tmp, "preset.log")
+ preset = self.fake_bin("preset", f'echo "$* $(cat)" >> {log}\n')
+ with mock.patch.object(sbb, "PRESET", preset):
+ with self.assertRaisesRegex(sbb.Error, "bad passphrase"):
+ sbb.cmd_gpg_unlock(self.cfg, stdin=io.BytesIO(b"wrong\n"))
+ open(os.path.join(self.tmp, "good"), "w").close()
+ self.assertEqual(sbb.cmd_gpg_unlock(self.cfg, stdin=io.BytesIO(b"right\n")),
+ {"unlocked": True})
+ with open(log) as f:
+ self.assertEqual(f.read().splitlines(),
+ ["--preset GRIPSIGN wrong", "--forget GRIPSIGN ", "--preset GRIPSIGN right"])
+
+
class JobsTest(Base):
def log(self, d):
with open(os.path.join(d, "log"), "rb") as f:
@@ -220,6 +366,11 @@ class JobsTest(Base):
patcher.start()
self.addCleanup(patcher.stop)
+ def test_env_reaches_child(self):
+ jid, d = self.make_job(["sh", "-c", 'echo "publish=$SBB_PUBLISH"'], env={"SBB_PUBLISH": "n"})
+ sbb.cmd_run(self.cfg, jid)
+ self.assertEqual(self.log(d), b"publish=n\n")
+
def test_start_end_to_end(self):
self.fake_sbshadow()
rc, data = self.run_main("job-start", "sbshadow", "--no")