Skip to content

Commit bbc13cf

Browse files
committed
Add test to find random length list issue
1 parent 6cb0171 commit bbc13cf

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

tests/features/user.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import unittest
1515

1616
from constrainedrandom import RandObj
17+
from .. import testutils
1718

1819

1920
class NonPureFunction(unittest.TestCase):
@@ -48,3 +49,48 @@ def non_pure_constraint(a):
4849
# after c.var is assigned.
4950
c.var = 5
5051
r.randomize()
52+
53+
54+
class RandSizeListOrder(testutils.RandObjTestBase):
55+
'''
56+
Minimal test that hits a specific corner case involving
57+
random list length.
58+
The case requires:
59+
- more than one list depending on the same random length
60+
- a small total state space
61+
- the lists are constrained based on one another and the random length
62+
- a constraint that uses the random length to index the lists
63+
- fails with naive solver, or skips it
64+
- fails with sparsities == 1, or manually run with sparsities > 1
65+
The symptom seen was IndexError: list index out of range
66+
when applying the constraint.
67+
'''
68+
69+
ITERATIONS = 100
70+
71+
def get_randobj(self, *args):
72+
r = RandObj(*args)
73+
r.add_rand_var('length', domain=range(1,3), order=0)
74+
r.add_rand_var('list1', domain=range(-10,11), rand_length='length', order=1)
75+
r.add_rand_var('list2', domain=range(-10,11), rand_length='length', order=2)
76+
77+
def var_not_in_list(length, list1, list2):
78+
# Use length as an index, as this is how the bug
79+
# was found in the wild.
80+
for i in range(length):
81+
if list1[i] == list2[i]:
82+
return False
83+
return True
84+
r.add_constraint(var_not_in_list, ('length', 'list1', 'list2'))
85+
r.set_solver_mode(naive=False, sparsities=[10])
86+
return r
87+
88+
def check(self, results):
89+
for result in results:
90+
length = result['length']
91+
list1 = result['list1']
92+
list2 = result['list2']
93+
self.assertEqual(len(list1), length, "list1 length was wrong")
94+
self.assertEqual(len(list2), length, "list2 length was wrong")
95+
for x1, x2 in zip(list1, list2):
96+
self.assertFalse(x1 == x2)

0 commit comments

Comments
 (0)