Selfie
Loading...
Searching...
No Matches
WithinTestGC.py
Go to the documentation of this file.
1from collections.abc import Iterable
2from threading import Lock
3
4from .ArrayMap import ArrayMap, ArraySet
5from .Snapshot import Snapshot
6
7
9 def __init__(self):
10 self.suffixes_to_keep = ArraySet.empty()
11 self.lock = Lock()
12
13 def keep_suffix(self, suffix: str):
14 with self.lock:
15 if self.suffixes_to_keep:
16 self.suffixes_to_keep = self.suffixes_to_keep.plusOrThis(suffix)
17
18 def keep_all(self) -> "WithinTestGC":
19 with self.lock:
20 self.suffixes_to_keep = None
21 return self
22
23 def __str__(self) -> str:
24 with self.lock:
25 return (
26 str(self.suffixes_to_keep)
27 if self.suffixes_to_keep is not None
28 else "(null)"
29 )
30
32 with self.lock:
33 return self.suffixes_to_keep == ArraySet.empty()
34
35 def keeps(self, s: str) -> bool:
36 with self.lock:
37 return True if self.suffixes_to_keep is None else s in self.suffixes_to_keep
38
39 @staticmethod
41 snapshots: ArrayMap[str, Snapshot],
42 tests_that_ran: ArrayMap[str, "WithinTestGC"],
43 tests_that_didnt_run: Iterable[str],
44 ) -> list[int]:
45 stale_indices = []
46
47 # combine what we know about methods that did run with what we know about the tests that didn't
48 total_gc = tests_that_ran
49 for method in tests_that_didnt_run:
50 total_gc = total_gc.plus(method, WithinTestGC().keep_all())
51
52 gc_roots = total_gc.items()
53 keys = snapshots.keys()
54 # we'll start with the lowest gc, and the lowest key
55 gc_idx = 0
56 key_idx = 0
57 while key_idx < len(keys) and gc_idx < len(gc_roots):
58 key: str = keys[key_idx] # type: ignore
59 gc: tuple[str, WithinTestGC] = gc_roots[gc_idx] # type: ignore
60 if key.startswith(gc[0]):
61 if len(key) == len(gc[0]):
62 # startWith + same length = exact match, no suffix
63 if not gc[1].keeps(""):
64 stale_indices.append(key_idx)
65 key_idx += 1
66 continue
67 elif key[len(gc[0])] == "/":
68 # startWith + not same length = can safely query the `/`
69 suffix = key[len(gc[0]) :]
70 if not gc[1].keeps(suffix):
71 stale_indices.append(key_idx)
72 key_idx += 1
73 continue
74 else:
75 # key is longer than gc.key, but doesn't start with gc.key, so we must increment gc
76 gc_idx += 1
77 continue
78 else:
79 # we don't start with the key, so we must increment
80 if gc[0] < key:
81 gc_idx += 1
82 else:
83 # we never found a gc that started with this key, so it's stale
84 stale_indices.append(key_idx)
85 key_idx += 1
86
87 while key_idx < len(keys):
88 stale_indices.append(key_idx)
89 key_idx += 1
90
91 return stale_indices
list[int] find_stale_snapshots_within(ArrayMap[str, Snapshot] snapshots, ArrayMap[str, "WithinTestGC"] tests_that_ran, Iterable[str] tests_that_didnt_run)