diff --git a/tests/integration/test_glibcxx_3_4_25/setup.py b/tests/integration/test_glibcxx_3_4_25/setup.py new file mode 100644 index 00000000..ae6d279b --- /dev/null +++ b/tests/integration/test_glibcxx_3_4_25/setup.py @@ -0,0 +1,14 @@ +from setuptools import Extension, setup + +setup( + name="testentropy", + version="0.0.1", + ext_modules=[ + Extension( + "testentropy", + language="c++", + sources=["testentropy.cpp"], + extra_compile_args=["-std=c++11"], + ), + ], +) diff --git a/tests/integration/test_glibcxx_3_4_25/testentropy.cpp b/tests/integration/test_glibcxx_3_4_25/testentropy.cpp new file mode 100644 index 00000000..0799f439 --- /dev/null +++ b/tests/integration/test_glibcxx_3_4_25/testentropy.cpp @@ -0,0 +1,28 @@ +#include +#include + +static PyObject * +run(PyObject *self, PyObject *args) +{ + (void)self; + (void)args; + std::random_device rd; + return PyLong_FromLong(rd.entropy() >= 0.0 ? 0 : -1); +} + +/* Module initialization */ +PyMODINIT_FUNC PyInit_testentropy(void) +{ + static PyMethodDef module_methods[] = { + {"run", (PyCFunction)run, METH_NOARGS, "run."}, + {NULL} /* Sentinel */ + }; + static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "testentropy", + "testentropy module", + -1, + module_methods, + }; + return PyModule_Create(&moduledef); +} diff --git a/tests/integration/test_manylinux.py b/tests/integration/test_manylinux.py index c2d11232..2eb372d6 100644 --- a/tests/integration/test_manylinux.py +++ b/tests/integration/test_manylinux.py @@ -25,12 +25,14 @@ MANYLINUX2010_IMAGE_ID = f"quay.io/pypa/manylinux2010_{PLATFORM}:latest" MANYLINUX2014_IMAGE_ID = f"quay.io/pypa/manylinux2014_{PLATFORM}:latest" MANYLINUX_2_24_IMAGE_ID = f"quay.io/pypa/manylinux_2_24_{PLATFORM}:latest" +MANYLINUX_2_28_IMAGE_ID = f"quay.io/pypa/manylinux_2_28_{PLATFORM}:latest" if PLATFORM in {"i686", "x86_64"}: MANYLINUX_IMAGES = { "manylinux_2_5": MANYLINUX1_IMAGE_ID, "manylinux_2_12": MANYLINUX2010_IMAGE_ID, "manylinux_2_17": MANYLINUX2014_IMAGE_ID, "manylinux_2_24": MANYLINUX_2_24_IMAGE_ID, + "manylinux_2_28": MANYLINUX_2_28_IMAGE_ID, } POLICY_ALIASES = { "manylinux_2_5": ["manylinux1"], @@ -42,6 +44,8 @@ "manylinux_2_17": MANYLINUX2014_IMAGE_ID, "manylinux_2_24": MANYLINUX_2_24_IMAGE_ID, } + if PLATFORM in {"aarch64", "ppc64le"}: + MANYLINUX_IMAGES["manylinux_2_28"] = MANYLINUX_2_28_IMAGE_ID POLICY_ALIASES = { "manylinux_2_17": ["manylinux2014"], } @@ -60,6 +64,7 @@ "manylinux_2_12": "devtoolset-8", "manylinux_2_17": "devtoolset-10", "manylinux_2_24": "devtoolset-not-present", + "manylinux_2_28": "gcc-toolset-11", "musllinux_1_1": "devtoolset-not-present", } PATH_DIRS = [ @@ -688,6 +693,46 @@ def test_nonpy_rpath(self, any_manylinux_container, docker_python, io_folder): ], ) + def test_glibcxx_3_4_25(self, any_manylinux_container, docker_python, io_folder): + policy, tag, manylinux_ctr = any_manylinux_container + docker_exec( + manylinux_ctr, + [ + "bash", + "-c", + "cd /auditwheel_src/tests/integration/test_glibcxx_3_4_25 && " + "if [ -d ./build ]; then rm -rf ./build ./*.egg-info; fi && " + "python -m pip wheel --no-deps -w /io .", + ], + ) + + orig_wheel, *_ = os.listdir(io_folder) + assert orig_wheel.startswith("testentropy-0.0.1") + + # Repair the wheel using the appropriate manylinux container + repair_command = f"auditwheel repair --plat {policy} -w /io /io/{orig_wheel}" + if policy.startswith("manylinux_2_28_"): + with pytest.raises(CalledProcessError): + docker_exec(manylinux_ctr, repair_command) + # TODO if a "permissive" mode is implemented, add the relevant flag to the + # repair_command here and drop the return statement below + return + + docker_exec(manylinux_ctr, repair_command) + + repaired_wheel, *_ = glob.glob(f"{io_folder}/*{policy}*.whl") + repaired_wheel = os.path.basename(repaired_wheel) + + docker_exec(docker_python, "pip install /io/" + repaired_wheel) + docker_exec( + docker_python, + [ + "python", + "-c", + "from testentropy import run; exit(run())", + ], + ) + class TestManylinux(Anylinux): @pytest.fixture(scope="session") diff --git a/tests/integration/testdependencies/dependency.c b/tests/integration/testdependencies/dependency.c index 30cbb89f..19695ba0 100644 --- a/tests/integration/testdependencies/dependency.c +++ b/tests/integration/testdependencies/dependency.c @@ -3,10 +3,15 @@ #include #include #include +#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 28) +#include +#endif int dep_run() { -#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 24) +#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 28) + return thrd_equal(thrd_current(), thrd_current()) ? 0 : 1; +#elif defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 24) return (int)nextupf(0.0F); #elif defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 17) return (int)(intptr_t)secure_getenv("NON_EXISTING_ENV_VARIABLE"); diff --git a/tests/integration/testdependencies/testdependencies.c b/tests/integration/testdependencies/testdependencies.c index 9379ec6e..10045b0f 100644 --- a/tests/integration/testdependencies/testdependencies.c +++ b/tests/integration/testdependencies/testdependencies.c @@ -5,6 +5,9 @@ #include #include #include +#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 28) +#include +#endif #endif #include @@ -20,6 +23,8 @@ run(PyObject *self, PyObject *args) #ifdef WITH_DEPENDENCY res = dep_run(); +#elif defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 28) + res = thrd_equal(thrd_current(), thrd_current()) ? 0 : 1; #elif defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 24) res = (int)nextupf(0.0F); #elif defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 17)