Skip to content

Commit e9f3727

Browse files
author
Release Manager
committed
gh-40677: src/sage/libs/gap: move a few tests to pytest There are two files, `src/sage/libs/gap/test{,_long}.py` that contain only tests for `sage.libs.gap`. These are doctests for no other reason than because we had no other way to run them in the past. This commit moves them to a new file, `gap_test.py`, that will be run by pytest rather than the doctest runner. In the process I've tried to explain what I think the tests are doing. URL: #40677 Reported by: Michael Orlitzky Reviewer(s): Michael Orlitzky, user202729
2 parents 5e10ce7 + 1b56421 commit e9f3727

File tree

6 files changed

+104
-84
lines changed

6 files changed

+104
-84
lines changed

conftest.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,3 +341,21 @@ def add_imports(doctest_namespace: dict[str, Any]):
341341
sage_namespace["__name__"] = "__main__"
342342

343343
doctest_namespace.update(**sage_namespace)
344+
345+
346+
@pytest.fixture
347+
def tmpfile():
348+
r"""
349+
Temporary file fixture that can be reopened/closed and still
350+
clean itself up afterwards.
351+
352+
Similar to the built-in ``tmpdir`` fixture, but safer for now:
353+
354+
* https://github.com/pytest-dev/pytest/issues/13669
355+
356+
"""
357+
from tempfile import NamedTemporaryFile
358+
from os import unlink
359+
t = NamedTemporaryFile(delete=False)
360+
yield t
361+
unlink(t.name)

src/doc/en/reference/libs/index.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,8 @@ GAP
8989

9090
sage/libs/gap/context_managers
9191
sage/libs/gap/gap_functions
92-
sage/libs/gap/test_long
9392
sage/libs/gap/util
9493
sage/libs/gap/libgap
95-
sage/libs/gap/test
9694
sage/libs/gap/element
9795
sage/libs/gap/saved_workspace
9896

src/sage/libs/gap/gap_test.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import pytest
2+
from sage.libs.gap.libgap import libgap
3+
4+
5+
def test_libgap_can_read_and_write_files(tmpfile):
6+
"""
7+
Test that libgap can write to a temporary file and
8+
subsequently read it.
9+
10+
See :issue:`16502`, :issue:`15833`.
11+
"""
12+
message = "Ceci n'est pas une groupe"
13+
libgap.PrintTo(tmpfile.name, message)
14+
with open(tmpfile.name) as f:
15+
contents = f.read()
16+
assert contents == message
17+
SystemFile = libgap.function_factory('StringFile')
18+
assert SystemFile(tmpfile.name) == libgap(message)
19+
20+
21+
def test_gc_loop_1():
22+
r"""
23+
Stress test for garbage collection in libgap.
24+
25+
Manually runs the GAP garbage collector, and then creates 10,000
26+
instances of the cyclic group of order two in a loop. In each
27+
iteration, the python variable is overwritten, meaning that python
28+
is free to garbage collect the object.
29+
"""
30+
libgap.collect()
31+
for _ in range(10000):
32+
G = libgap.CyclicGroup(2)
33+
assert True
34+
35+
36+
def test_gc_loop_2():
37+
r"""
38+
Stress test for garbage collection in libgap.
39+
40+
Create the free group on two elements (``a`` and ``b``) and then
41+
construct a quotient group of order two in a loop by specifying
42+
some relations. The python variables are overwritten in each
43+
iteration, meaning that python is free to garbage-collect them.
44+
(We also ensure that the quotient group has the expected order.)
45+
46+
After that loop, we take one of the generators of the quotient
47+
group (from the final iteration), and compute its order in a
48+
loop. The python reference from the final iteration lives on,
49+
so this generator should not be collected.
50+
"""
51+
G = libgap.FreeGroup(2)
52+
a, b = G.GeneratorsOfGroup()
53+
two = libgap(2)
54+
55+
for _ in range(100):
56+
rel = libgap([a**2, b**2, a*b*a*b])
57+
H = G / rel
58+
H1 = H.GeneratorsOfGroup()[0]
59+
n = H1.Order()
60+
assert n == two
61+
62+
result = True
63+
for i in range(300000):
64+
n = libgap.Order(H1)
65+
result &= (n == two)
66+
assert result
67+
68+
69+
def test_gc_loop_3():
70+
r"""
71+
Stress test for garbage collection in libgap.
72+
73+
Create the free group on two elements (``a`` and ``b``) and then
74+
add some of its elements to a list in a loop. A new, empty list is
75+
created at each iteration, so this mainly serves to guarantee that
76+
the generators of the group are not garbage-collected.
77+
"""
78+
G = libgap.FreeGroup(2)
79+
a, b = G.GeneratorsOfGroup()
80+
for _ in range(300000):
81+
lis = libgap([])
82+
lis.Add(a ** 2)
83+
lis.Add(b ** 2)
84+
lis.Add(b * a)
85+
assert True

src/sage/libs/gap/meson.build

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@ py.install_sources(
88
'gap_functions.py',
99
'gap_globals.py',
1010
'gap_includes.pxd',
11+
'gap_test.py',
1112
'operations.py',
1213
'sage.gaprc',
1314
'saved_workspace.py',
14-
'test.py',
15-
'test_long.py',
1615
'util.pxd',
1716
subdir: 'sage/libs/gap',
1817
)

src/sage/libs/gap/test.py

Lines changed: 0 additions & 26 deletions
This file was deleted.

src/sage/libs/gap/test_long.py

Lines changed: 0 additions & 54 deletions
This file was deleted.

0 commit comments

Comments
 (0)