test(safety): allow public GitHub attachments

This commit is contained in:
Jason Morcos
2026-08-02 16:31:15 -07:00
parent 2c93cb3097
commit fc6240b72e
4 changed files with 217 additions and 43 deletions
+64 -35
View File
@@ -9,23 +9,37 @@ from smartthings_local.ocf.state_cache import StateCache
from smartthings_local.protocol.dtls_session import DtlsCoapSession
def _parameter_names(callable_object) -> list[str]:
return list(inspect.signature(callable_object).parameters)
def _assert_compatible_signature(callable_object, expected: list[str]) -> None:
"""Require the existing call surface while allowing safe extensions."""
parameters = list(inspect.signature(callable_object).parameters.values())
assert [parameter.name for parameter in parameters[: len(expected)]] == expected
for parameter in parameters[len(expected) :]:
assert (
parameter.kind
in (
inspect.Parameter.VAR_POSITIONAL,
inspect.Parameter.VAR_KEYWORD,
)
or parameter.default is not inspect.Parameter.empty
)
def test_dtls_session_constructor_keeps_file_memory_and_local_port_inputs():
assert _parameter_names(DtlsCoapSession) == [
"host",
"port",
"cert_path",
"key_path",
"cert_pem",
"key_pem",
"on_notification",
"mtu",
"rate_limit_rps",
"local_port",
]
_assert_compatible_signature(
DtlsCoapSession,
[
"host",
"port",
"cert_path",
"key_path",
"cert_pem",
"key_pem",
"on_notification",
"mtu",
"rate_limit_rps",
"local_port",
],
)
def test_dtls_session_keeps_current_consumer_methods():
@@ -42,23 +56,32 @@ def test_dtls_session_keeps_current_consumer_methods():
"subscribe",
}
assert expected <= set(dir(DtlsCoapSession))
assert _parameter_names(DtlsCoapSession.get) == [
"self",
"path_segs",
"query",
"timeout",
]
assert _parameter_names(DtlsCoapSession.post) == [
"self",
"path_segs",
"body_cbor",
"timeout",
]
assert _parameter_names(DtlsCoapSession.subscribe) == ["self", "path_segs"]
_assert_compatible_signature(
DtlsCoapSession.get,
[
"self",
"path_segs",
"query",
"timeout",
],
)
_assert_compatible_signature(
DtlsCoapSession.post,
[
"self",
"path_segs",
"body_cbor",
"timeout",
],
)
_assert_compatible_signature(
DtlsCoapSession.subscribe,
["self", "path_segs"],
)
def test_state_cache_keeps_current_consumer_surface():
assert _parameter_names(StateCache) == ["descriptor"]
_assert_compatible_signature(StateCache, ["descriptor"])
expected = {
"apply_optimistic",
"apply_rep",
@@ -73,10 +96,16 @@ def test_state_cache_keeps_current_consumer_surface():
def test_observe_refresh_task_keeps_current_consumer_surface():
assert _parameter_names(ObserveRefreshTask) == [
"session",
"paths",
"interval_s",
"logger",
]
assert _parameter_names(ObserveRefreshTask.run_forever) == ["self", "stop"]
_assert_compatible_signature(
ObserveRefreshTask,
[
"session",
"paths",
"interval_s",
"logger",
],
)
_assert_compatible_signature(
ObserveRefreshTask.run_forever,
["self", "stop"],
)
+62
View File
@@ -13,6 +13,22 @@ def test_documentation_addresses_and_synthetic_uuid_are_safe():
assert check_share_safety.scan_text("fixture.txt", text) == []
def test_dotted_object_identifiers_are_not_ipv4_addresses():
text = "extendedKeyUsage = 1.3.6.1.4.1.51414.0.1.2"
assert check_share_safety.scan_text("fixture.txt", text) == []
def test_public_github_attachment_uuid_is_safe_but_bare_uuid_is_not():
value = "cc1dca15-f272-4625-" + "a13c-2dc82283ff95"
public_url = f"https://github.com/user-attachments/assets/{value}"
assert check_share_safety.scan_text("README.md", public_url) == []
assert check_share_safety.scan_text("fixture.txt", value) == [
check_share_safety.Finding("fixture.txt", 1, "UUID")
]
def test_findings_never_echo_matched_content():
cases = {
"PEM_PRIVATE_KEY": "-----BEGIN " + "PRIVATE KEY-----",
@@ -94,3 +110,49 @@ def test_changed_paths_include_staged_unstaged_and_untracked_files(
"staged.txt",
"untracked.txt",
]
def test_committed_scan_ignores_unchanged_findings_but_checks_added_lines(
tmp_path, monkeypatch
):
def git(*args):
return subprocess.run(
[
"git",
"-c",
"commit.gpgsign=false",
"-c",
"user.name=Test",
"-c",
"user.email=" + "test" + chr(64) + "example.invalid",
*args,
],
cwd=tmp_path,
capture_output=True,
check=True,
text=True,
)
candidate = tmp_path / "candidate.txt"
private_one = "10." + "24.8.9"
private_two = "10." + "24.8.10"
git("init", "--quiet")
candidate.write_text(f"existing {private_one}\n")
git("add", "candidate.txt")
git("commit", "--quiet", "-m", "baseline")
base = git("rev-parse", "HEAD").stdout.strip()
candidate.write_text(f"existing {private_one}\nsafe addition\n")
git("add", "candidate.txt")
git("commit", "--quiet", "-m", "safe change")
monkeypatch.chdir(tmp_path)
assert check_share_safety.check_changed(base) == []
candidate.write_text(
f"existing {private_one}\nsafe addition\nintroduced {private_two}\n"
)
git("add", "candidate.txt")
git("commit", "--quiet", "-m", "unsafe change")
assert check_share_safety.check_changed(base) == [
check_share_safety.Finding("candidate.txt", 3, "NON_DOCUMENTATION_IPV4")
]
+6 -2
View File
@@ -9,6 +9,8 @@ from smartthings_local.ocf.observe_refresh import ObserveRefreshTask
from smartthings_local.ocf.poll_scheduler import PollScheduler, PollTier
from smartthings_local.ocf.state_cache import StateCache
_THREAD_DEADLINE_S = 2.0
class _Session:
def ping(self):
@@ -45,9 +47,11 @@ def _assert_worker_stops(target, name: str):
worker = threading.Thread(target=run, name=name, daemon=True)
worker.start()
assert stop.waiting.wait(0.5), f"{name} did not enter an interruptible wait"
assert stop.waiting.wait(_THREAD_DEADLINE_S), (
f"{name} did not enter an interruptible wait"
)
stop.set()
worker.join(0.5)
worker.join(_THREAD_DEADLINE_S)
assert not worker.is_alive(), f"{name} did not stop"
assert errors == [], f"{name} raised {errors[0]}"