libfaketime na Windows
Krótka odpowiedź: libfaketime nie działa na Windows i działać nie
może - opiera się na LD_PRELOAD, którego Windows nie ma. Chrono Mock to ta
sama idea zbudowana tak, jak pozwala Windows.
Dlaczego nie da się tego po prostu przenieść
libfaketime działa tak, że
dynamiczny loader ustawia małą bibliotekę przed biblioteką C, więc wywołania
time() trafiają najpierw do podmiany. Tym zaczepem jest
LD_PRELOAD na Linuksie i DYLD_INSERT_LIBRARIES na macOS-ie.
Własny README projektu wymienia dokładnie te dwie platformy.
Windows nie ma odpowiednika, a jego zegar i tak nie mieszka za jedną funkcją. Aplikacje czytają czas przez API Win32, przez natywne API pod spodem i przez to, co owija jedno albo drugie ich środowisko uruchomieniowe - więc windowsowa wersja tego pomysłu to biblioteka wstrzykiwana do procesu celu, przekierowująca zestaw eksportowanych funkcji, a nie jeden symbol.
Flagi, przełożone jedna po drugiej
| libfaketime | Chrono Mock |
|---|---|
FAKETIME="2020-12-24 20:30:00" |
--at 2020-12-24T20:30:00 |
FAKETIME="+14d" |
--at +14d |
FAKETIME="-10m" |
--at -10m |
FAKETIME="+0 x2" |
--mode x2 |
FAKETIME_DONT_FAKE_MONOTONIC=1 |
tutaj domyślne - patrz niżej |
LD_PRELOAD=libfaketime.so.1 |
nic do ustawiania - narzędzie wstrzykuje samo |
Więc dwie strony tego samego testu wyglądają tak:
# Linux FAKETIME="2020-12-24 20:30:00" LD_PRELOAD=/usr/local/lib/libfaketime.so.1 ./test # Windows chrono run "C:\apps\test.exe" --at 2020-12-24T20:30:00
Czym te dwa naprawdę się różnią
Zegary monotoniczne są odwrócone. libfaketime fałszuje je domyślnie i
daje FAKETIME_DONT_FAKE_MONOTONIC, żeby to wyłączyć. Tutaj licznik
wysokiej rozdzielczości domyślnie zostaje prawdziwy, bo jego skalowanie
destabilizowało renderowanie w testach, a włącza się je flagą
--scale-qpc. To ten przełącznik sprawia, że monotonic w
Pythonie 3.13+, Stopwatch w .NET i nanoTime w Javie idą za
zegarem sesji.
Windows ma więcej miejsc do przechwycenia. Poza zegarem ściennym jest strefa czasowa, oś czasu trwania, cztery rodziny timerów, funkcje uśpienia i czekania oraz tworzenie procesów - razem 41 kanałów.
To narzędzie raportuje własne pokrycie. Każda sesja kończy się werdyktem, listą kanałów, które aplikacja naprawdę czytała, z liczbą wywołań każdego, oraz listą kanałów pominiętych. To część, która nie ma odpowiednika na żadnej z tych platform.
libfaketime jest starsze i na swoim gruncie szersze. Ma za sobą lata użycia, obejmuje szeroki zakres punktów wejścia biblioteki C, a na Linuksie jest właściwym narzędziem. Nic tutaj go tam nie zastępuje.
Jeśli naprawdę chcesz samego libfaketime
Dwie uczciwe drogi, obie przenoszą testowany program na Linuksa:
- WSL - zbuduj i uruchom libfaketime w podsystemie Linux. Dobre, kiedy testowany program jest linuksowy, a ty po prostu pracujesz na Windows.
- Kontener - ten sam pomysł, bardziej powtarzalny.
Żadna z nich nie pomoże przy aplikacji windowsowej, a to jest przypadek, dla którego to narzędzie istnieje.