Skip to content

Commit fefdb57

Browse files
martinperezmaneirocarhc
authored andcommitted
854 Allow null event range
#854 [author: gonzaponte] This PR adds the option to run a city with `event_range = 0`, which can be useful for testing. Closes #573 [reviewer: martinperezmaneiro] Good PR. Adds protection to `slice` function for `event_range = 0`, and creates the corresponding test. Also changes a file structure test to run over no events. Everything works as expected :)
2 parents d25eb48 + b5442c3 commit fefdb57

File tree

3 files changed

+55
-10
lines changed

3 files changed

+55
-10
lines changed

invisible_cities/cities/cities_test.py

+30-5
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@
1010

1111
from .. core.configure import configure
1212

13-
online_cities = "irene dorothea sophronia esmeralda beersheba".split()
14-
all_cities = """beersheba berenice buffy detsim diomira dorothea esmeralda
15-
eutropia hypathia irene isaura isidora phyllis sophronia
16-
trude""".split()
13+
online_cities = "irene dorothea sophronia esmeralda beersheba isaura".split()
14+
mc_cities = "buffy detsim diomira hypathia".split()
15+
other_cities = "berenice isidora phyllis trude eutropia".split()
16+
all_cities = sorted(online_cities + mc_cities + other_cities)
17+
all_cities_with_event_range = sorted(set(all_cities).difference(set(["eutropia"])))
18+
1719

1820
@mark.filterwarnings("ignore::UserWarning")
1921
@mark.parametrize("city", online_cities)
@@ -35,6 +37,23 @@ def test_city_empty_input_file(config_tmpdir, ICDATADIR, city):
3537
city_function(**conf)
3638

3739

40+
@mark.filterwarnings("ignore::UserWarning")
41+
@mark.parametrize("city", all_cities_with_event_range)
42+
def test_city_null_event_range(config_tmpdir, ICDATADIR, city):
43+
# All cities must run with event_range = 0
44+
PATH_OUT = os.path.join(config_tmpdir, 'empty_output.h5')
45+
46+
config_file = 'dummy invisible_cities/config/{}.conf'.format(city)
47+
conf = configure(config_file.split())
48+
conf.update(dict( file_out = PATH_OUT
49+
, event_range = 0))
50+
51+
module_name = f'invisible_cities.cities.{city}'
52+
city_function = getattr(import_module(module_name), city)
53+
54+
city_function(**conf)
55+
56+
3857

3958
@mark.filterwarnings("ignore::UserWarning")
4059
@mark.parametrize("city", all_cities)
@@ -43,22 +62,28 @@ def test_city_output_file_is_compressed(config_tmpdir, ICDATADIR, city):
4362
config_file = 'dummy invisible_cities/config/{}.conf'.format(city)
4463

4564
conf = configure(config_file.split())
46-
conf.update(dict(file_out = file_out))
65+
conf.update(dict( file_out = file_out
66+
, event_range = 0))
4767

4868
module_name = f'invisible_cities.cities.{city}'
4969
city_function = getattr(import_module(module_name), city)
5070

5171
city_function(**conf)
5272

73+
checked_nodes = 0
5374
with tb.open_file(file_out) as file:
5475
for node in chain([file], file.walk_nodes()):
5576
try:
5677
assert (node.filters.complib is not None and
5778
node.filters.complevel > 0)
79+
checked_nodes += 1
5880

5981
except tb.NoSuchNodeError:
6082
continue
6183

84+
# ensure that we didn't pass the test because there were no nodes checked
85+
assert checked_nodes > 2
86+
6287

6388
@mark.filterwarnings("ignore::UserWarning")
6489
@mark.parametrize("city", all_cities)

invisible_cities/dataflow/dataflow.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ def string_to_pick(component):
324324
def slice(*args, close_all=False):
325325
spec = builtins.slice(*args)
326326
start, stop, step = spec.start, spec.stop, spec.step
327+
327328
if start is not None and start < 0: raise ValueError('slice requires start >= 0')
328329
if stop is not None and stop < 0: raise ValueError('slice requires stop >= 0')
329330
if step is not None and step <= 0: raise ValueError('slice requires step > 0')
@@ -332,13 +333,19 @@ def slice(*args, close_all=False):
332333
if step is None: step = 1
333334
if stop is None: stopper = it.count()
334335
else : stopper = range((stop - start + step - 1) // step)
336+
335337
@coroutine
336338
def slice_loop(target):
337339
with closing(target):
338-
for _ in range(start) : yield
340+
# ensures that we yield at least once in case of
341+
# stop<=start to avoid raising StopPipeline without
342+
# yielding first
343+
if stop is not None and start >= stop : yield
344+
345+
for _ in range(start) : yield
339346
for _ in stopper:
340347
target.send((yield))
341-
for _ in range(step - 1) : yield
348+
for _ in range(step - 1) : yield
342349
if close_all: raise StopPipeline
343350
while True:
344351
yield

invisible_cities/dataflow/dataflow_test.py

+16-3
Original file line numberDiff line numberDiff line change
@@ -465,20 +465,33 @@ def intercalate(a,b):
465465
tuples(small_ints, small_ints),
466466
tuples(slice_arg, slice_arg, slice_arg_nonzero)))
467467
def test_slice_downstream(spec):
468-
469468
the_source = list('abcdefghij')
470469
result = []
471470
the_sink = df.sink(result.append)
472471

473472
df.push(source = the_source,
474-
pipe = df.pipe(df.slice(*spec), the_sink))
473+
pipe = df.pipe(df.slice(*spec, close_all=False), the_sink))
474+
475475

476476
specslice = slice(*spec)
477477
assert result == the_source[specslice]
478478
assert result == the_source[specslice.start : specslice.stop : specslice.step]
479479

480480

481-
#TODO: Write test slice_close_all
481+
def test_slice_null_close_all():
482+
spec = (0,)
483+
484+
the_source = list('abcdefghij')
485+
result = []
486+
the_sink = df.sink(result.append)
487+
488+
df.push(source = the_source,
489+
pipe = df.pipe(df.slice(*spec, close_all=True), the_sink))
490+
491+
specslice = slice(*spec)
492+
assert result == the_source[specslice]
493+
assert result == the_source[specslice.start : specslice.stop : specslice.step]
494+
482495

483496
@parametrize('args',
484497
(( -1,),

0 commit comments

Comments
 (0)