diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 544b516..d114212 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -6,11 +6,16 @@ on: jobs: tests: - name: ${{ matrix.python }} - runs-on: ubuntu-latest + name: ${{ matrix.os }} - python${{ matrix.python }} - ${{ matrix.tz }} + runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: + os: + - ubuntu-22.04 + - macos-14 + - macos-13 + - macos-12 python: - '3.12' - '3.11' @@ -21,15 +26,17 @@ jobs: - 'utc' - 'cest' steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} - - uses: actions/cache@v1 + - uses: actions/cache@v4 with: path: ~/.cache/pip key: pip|${{ hashFiles('setup.py') }}|${{ hashFiles('setup.cfg') }} - run: pip install tox - - run: git submodule update --init - - run: make -C libfaketime/vendor/libfaketime + - run: git submodule update --init --force + - run: | + git apply --directory libfaketime/vendor/libfaketime libfaketime/vendor/libfaketime.patch + make -C libfaketime/vendor/libfaketime - run: tox -e ${{ matrix.python }}-${{ matrix.tz }} diff --git a/.gitmodules b/.gitmodules index 51214e3..f0ed0ea 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,8 +1,4 @@ [submodule "vendor/libfaketime"] path = libfaketime/vendor/libfaketime - url = https://github.com/simon-weber/libfaketime.git + url = https://github.com/wolfcw/libfaketime.git branch = python-libfaketime -[submodule "vendor/libfaketime-pre_sierra"] - path = libfaketime/vendor/libfaketime-pre_sierra - url = https://github.com/simon-weber/libfaketime.git - branch = python-libfaketime-pre_sierra diff --git a/MANIFEST.in b/MANIFEST.in index e8e8bb2..c7dbb74 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -5,8 +5,3 @@ include libfaketime/vendor/libfaketime/src/Makefile include libfaketime/vendor/libfaketime/src/Makefile.OSX include libfaketime/vendor/libfaketime/COPYING recursive-include libfaketime/vendor/libfaketime/src *.c *.h *.map -include libfaketime/vendor/libfaketime-pre_sierra/Makefile -include libfaketime/vendor/libfaketime-pre_sierra/src/Makefile -include libfaketime/vendor/libfaketime-pre_sierra/src/Makefile.OSX -include libfaketime/vendor/libfaketime-pre_sierra/COPYING -recursive-include libfaketime/vendor/libfaketime-pre_sierra/src *.c *.h *.map diff --git a/README.md b/README.md index 2bbc636..6b08c38 100644 --- a/README.md +++ b/README.md @@ -147,6 +147,7 @@ In some cases - especially when your tests start other processes - re-execing ca $ python-libfaketime export LD_PRELOAD="/home/foo//vendor/libfaketime/src/libfaketime.so.1" export DONT_FAKE_MONOTONIC="1" +export FAKETIME_NO_CACHE="1" export FAKETIME_DID_REEXEC=true ``` @@ -163,6 +164,8 @@ Contributing and testing Contributions are welcome! You should compile libfaketime before running tests: ```bash +git submodule init --update +git apply --directory libfaketime/vendor/libfaketime libfaketime/vendor/libfaketime.patch make -C libfaketime/vendor/libfaketime ``` diff --git a/libfaketime/__init__.py b/libfaketime/__init__.py index b82bb72..182ecc0 100644 --- a/libfaketime/__init__.py +++ b/libfaketime/__init__.py @@ -6,7 +6,6 @@ import functools import inspect import os -import platform import sys import threading import time @@ -21,7 +20,6 @@ basestring = (str, bytes) -SIERRA_VERSION_TUPLE = (10, 12) # When using reexec_if_needed, remove_vars=True and a test loader that purges sys.modules # (like nose), it can be tough to run reexec_if_needed only once. @@ -33,12 +31,6 @@ def _get_lib_path(): vendor_dir = 'libfaketime' - if sys.platform == "darwin": - version_tuple = tuple(int(x) for x in platform.mac_ver()[0].split('.')) - pre_sierra = version_tuple < SIERRA_VERSION_TUPLE - if pre_sierra: - vendor_dir = 'libfaketime-pre_sierra' - return os.path.join( os.path.dirname(__file__), os.path.join('vendor', vendor_dir, 'src')) @@ -71,10 +63,12 @@ def _setup_ld_preload(soname): _other_additions = { 'linux': { 'DONT_FAKE_MONOTONIC': '1', + 'FAKETIME_NO_CACHE': '1', }, 'darwi': { 'DONT_FAKE_MONOTONIC': '1', 'DYLD_FORCE_FLAT_NAMESPACE': '1', + 'FAKETIME_NO_CACHE': '1', }, } diff --git a/libfaketime/vendor/libfaketime b/libfaketime/vendor/libfaketime index d9d2bd7..d475b92 160000 --- a/libfaketime/vendor/libfaketime +++ b/libfaketime/vendor/libfaketime @@ -1 +1 @@ -Subproject commit d9d2bd76f00f95e9409e4a53d0469aef0e988a0b +Subproject commit d475b925943ad404c6c728ac868dc73949e7281c diff --git a/libfaketime/vendor/libfaketime-pre_sierra b/libfaketime/vendor/libfaketime-pre_sierra deleted file mode 160000 index 83c997b..0000000 --- a/libfaketime/vendor/libfaketime-pre_sierra +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 83c997b9c11b437ec5791387045c0364626649df diff --git a/libfaketime/vendor/libfaketime.patch b/libfaketime/vendor/libfaketime.patch new file mode 100644 index 0000000..e5b44d7 --- /dev/null +++ b/libfaketime/vendor/libfaketime.patch @@ -0,0 +1,38 @@ +diff --git a/src/Makefile b/src/Makefile +index 62e924c..6f03e26 100644 +--- a/src/Makefile ++++ b/src/Makefile +@@ -110,7 +110,7 @@ PREFIX ?= /usr/local + LIBDIRNAME ?= /lib/faketime + PLATFORM ?=$(shell uname) + +-CFLAGS += -std=gnu99 -Wall -Wextra -Werror -Wno-nonnull-compare -DFAKE_PTHREAD -DFAKE_STAT -DFAKE_UTIME -DFAKE_SLEEP -DFAKE_TIMERS -DFAKE_INTERNAL_CALLS -fPIC -DPREFIX='"'$(PREFIX)'"' -DLIBDIRNAME='"'$(LIBDIRNAME)'"' $(FAKETIME_COMPILE_CFLAGS) ++CFLAGS += -std=gnu99 -Wall -Wextra -Werror -Wno-nonnull-compare -DFAKE_PTHREAD -fPIC -DPREFIX='"'$(PREFIX)'"' -DLIBDIRNAME='"'$(LIBDIRNAME)'"' $(FAKETIME_COMPILE_CFLAGS) + ifeq ($(PLATFORM),SunOS) + CFLAGS += -D__EXTENSIONS__ -D_XOPEN_SOURCE=600 + endif +diff --git a/src/libfaketime.c b/src/libfaketime.c +index e632395..09d9019 100644 +--- a/src/libfaketime.c ++++ b/src/libfaketime.c +@@ -2384,10 +2384,16 @@ static void parse_ft_string(const char *user_faked_time) + user_faked_time_tm.tm_isdst = -1; + nstime_str = strptime(user_faked_time, user_faked_time_fmt, &user_faked_time_tm); + ++ /* the actual format has a " %f" appended. Parse out the microseconds. */ ++ char nanosecond_str[7]; ++ memcpy(&nanosecond_str, user_faked_time + 20, 6); ++ nanosecond_str[6] = '\0'; ++ int nanoseconds = atoi(nanosecond_str) * 1000; ++ + if (NULL != nstime_str) + { + user_faked_time_timespec.tv_sec = mktime(&user_faked_time_tm); +- user_faked_time_timespec.tv_nsec = 0; ++ user_faked_time_timespec.tv_nsec = nanoseconds; + + if (nstime_str[0] == '.') + { +-- +2.45.0 + diff --git a/setup.py b/setup.py index 4f28d7a..b479ab8 100644 --- a/setup.py +++ b/setup.py @@ -1,8 +1,6 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- import os -import platform import re from setuptools import setup, find_packages from setuptools.command.install import install @@ -10,10 +8,6 @@ import sys -# libfaketime broke compatibility with osx before sierra. -# We keep a separate submodule for each and choose between them dynamically. -SIERRA_VERSION_TUPLE = (10, 12) - # This hack is from http://stackoverflow.com/a/7071358/1231454; # the version is kept in a seperate file and gets parsed - this # way, setup.py doesn't have to import the package. @@ -35,13 +29,6 @@ elif sys.platform == "darwin": libname = 'libfaketime.1.dylib' - version_tuple = tuple(int(x) for x in platform.mac_ver()[0].split('.')) - pre_sierra = version_tuple < SIERRA_VERSION_TUPLE - if pre_sierra: - _vendor_path = 'libfaketime/vendor/libfaketime-pre_sierra' - - print("OSX version is %s-sierra: %r" % ('pre' if pre_sierra else 'post', version_tuple)) - else: raise RuntimeError("libfaketime does not support platform %s" % sys.platform) @@ -51,6 +38,7 @@ class CustomInstall(install): def run(self): self.my_outputs = [] + subprocess.check_call(['patch', '-p1', '<', '../libfaketime.patch'], cwd=_vendor_path, shell=True) subprocess.check_call(['make', '-C', _vendor_path]) dest = os.path.join(self.install_purelib, os.path.dirname(faketime_lib))