Skip to content

Commit db868c3

Browse files
paolopasgrafikrobot
authored andcommitted
Fixed test/core_multifile_actions.py, fix #164
Add test/semaphore.py for testing of JAM_SEMAPHORE. Closes #543 Add testing of exclusive tests. There are tests that need to run exclusive, i.e. serially, in order to guarantee correct operation. For example the semaphore test that run additional parallel tasks. Without the exclusive operation the OS resources can starve the launching of such parallel sub-tasks.
1 parent ab806fe commit db868c3

File tree

4 files changed

+197
-65
lines changed

4 files changed

+197
-65
lines changed

doc/src/history.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
* Fix crash when reflecting environment variables that happen to have an empty
2424
value.
2525
-- _zyk2507_
26+
* Fix testing of JAM_SEMAPHORE.
27+
-- _Paolo Pastori_
2628

2729
== Version 5.4.2
2830

test/core_multifile_actions.py

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -133,30 +133,6 @@
133133
...updated 3 targets...
134134
""")
135135

136-
# JAM_SEMAPHORE rules:
137-
#
138-
# - if two updating actions have targets that share a semaphore,
139-
# these actions cannot be run in parallel.
140-
#
141-
t.write("file.jam", """\
142-
actions update
143-
{
144-
echo updating $(<)
145-
}
146-
147-
targets = x1 x2 ;
148-
JAM_SEMAPHORE on $(targets) = <s>update_sem ;
149-
update x1 x2 ;
150-
""")
151-
t.run_build_system(["-ffile.jam", "x1"], stdout="""\
152-
...found 2 targets...
153-
...updating 2 targets...
154-
update x1
155-
updating x1 x2
156-
157-
...updated 2 targets...
158-
""")
159-
160136
# A target can appear multiple times in an action
161137
t.write("file.jam", """\
162138
actions update
@@ -206,6 +182,4 @@
206182
...updated 4 targets...
207183
""")
208184

209-
210-
211185
t.cleanup()

test/semaphore.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#!/usr/bin/env python3
2+
3+
# Copyright 2026 Paolo Pastori
4+
# Copyright 2026 Rene Ferdinand Rivera Morell
5+
# Distributed under the Boost Software License, Version 1.0.
6+
# (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt)
7+
8+
# Test for the JAM_SEMAPHORE variable:
9+
# verify that actions for targets sharing the same named semaphore
10+
# cannot be run in parallel.
11+
12+
import sys
13+
14+
15+
def touch(fname):
16+
with open(fname, "w"):
17+
pass
18+
19+
20+
def update(mode, sentry, secs, target):
21+
from os.path import isfile
22+
from time import sleep
23+
from os import unlink
24+
25+
secs = float(secs)
26+
other = {"x1": "x2", "x2": "x1"}
27+
# Indicate we started.
28+
touch(sentry + target)
29+
# Check for parallel action to start.
30+
while not isfile(sentry + other[target]) and secs > 0:
31+
sleep(0.05)
32+
secs -= 0.05
33+
if mode == "parallel":
34+
# Did not see the other action start in time.
35+
if secs <= 0:
36+
raise TimeoutError
37+
# Both actions are now running in parallel.
38+
print("PARALLEL UPDATE")
39+
sleep(secs)
40+
else:
41+
# For semaphore mode, having the sentry check not time out means the
42+
# parallel action ran, ignoring the semaphore.
43+
if secs > 0:
44+
raise RuntimeError
45+
# Indicate we completed, and create our result target.
46+
unlink(sentry + target)
47+
touch(target)
48+
49+
50+
if len(sys.argv) == 5:
51+
# called by jam update action
52+
# python semaphore.py <sentry_fname> <sleep_secs> <target_fname>
53+
update(*sys.argv[1:])
54+
sys.exit()
55+
56+
import os.path
57+
58+
# remember this script absolute pathname
59+
script = os.path.abspath(__file__)
60+
61+
import BoostBuild
62+
63+
t = BoostBuild.Tester(["-ffile.jam"], pass_toolset=False)
64+
65+
# 1. test parallel execution of update
66+
t.write(
67+
"file.jam",
68+
"""\
69+
actions update
70+
{{
71+
"{0}" "{1}" parallel sentry 1 $(<)
72+
}}
73+
update x1 ;
74+
update x2 ;
75+
DEPENDS all : x1 x2 ;
76+
""".format(
77+
sys.executable, script
78+
),
79+
)
80+
81+
t.run_build_system(extra_args=["-j2"])
82+
t.expect_addition("x1")
83+
t.expect_addition("x2")
84+
t.expect_output_lines("PARALLEL UPDATE")
85+
86+
t.rm("x1")
87+
t.rm("x2")
88+
89+
# 2. test parallel execution suppression by JAM_SEMAPHORE
90+
t.write(
91+
"file.jam",
92+
"""\
93+
actions update
94+
{{
95+
"{0}" "{1}" semaphore sentry 1 $(<)
96+
}}
97+
JAM_SEMAPHORE on x1 x2 = <s>update_sem ;
98+
update x1 ;
99+
update x2 ;
100+
DEPENDS all : x1 x2 ;
101+
""".format(
102+
sys.executable, script
103+
),
104+
)
105+
106+
expected_output = """\
107+
...found 3 targets...
108+
...updating 2 targets...
109+
update x1
110+
update x2
111+
112+
...updated 2 targets...
113+
"""
114+
115+
t.run_build_system(stdout=expected_output, extra_args=["-j2"])
116+
t.expect_addition("x1")
117+
t.expect_addition("x2")
118+
119+
t.cleanup()

0 commit comments

Comments
 (0)