def test_simpleIf(): b = ast.parse(simpleIf).body p = Path(b,source=simpleIf) # Step through the "if" statement p = p.step()[0] p = p.step()[0] p2 = p.step() ifSide = p2[0] elseSide = p2[1] # ifSide's path should now be inside, meaning only the print statement assert len(ifSide.path) == 1 # Else should be in the else statement assert len(elseSide.path) == 2 # Neither have anything to do after the if statement assert len(ifSide.callStack) == 0 assert len(elseSide.callStack) == 0 # If side should not be possible assert not ifSide.state.isSat() assert elseSide.state.isSat() # Track expected number of assertions assert len(ifSide.state.solver.assertions()) == 3 assert len(elseSide.state.solver.assertions()) == 3 # Make sure the answer makes sense assert ifSide.state.any_int('x') == None assert elseSide.state.any_int('x') == 1
def test_pathCopy(): b = ast.parse(test1).body p = Path(b,source=test1) p2 = p.copy() assert p2 != p p = p.step()[0] assert p.state.any_int('x') == 1 assert p2.state.any_int('x') == None
def test_basicPathStep(): b = ast.parse(test1).body p1 = Path(b,source=test1) p2 = p1.step()[0].step()[0] p1.printBacktrace() p2.printBacktrace() assert p2.state.any_int('x') == 1 assert p2.state.any_int('y') == 2 assert p1.state.any_int('x') == None assert p1.state.any_int('y') == None
def test_ifReturn(): b = ast.parse(testIfReturn).body p = Path(b,source=testIfReturn) p = p.step()[0].step()[0] ifSide,elseSide = p.step() ifSide = ifSide.step()[0].step()[0] elseSide = elseSide.step()[0].step()[0] assert ifSide.state.any_int('x') == 2 assert ifSide.state.any_real('y') == 2.2 assert elseSide.state.any_int('x') == None assert elseSide.state.any_real('y') == None # Else side is wonky because it's not a possible path
def test_pySym_AugAssign_MixedTypes(): ####### # Add # ####### b = ast.parse(test2).body p = Path(b,source=test2) # Step through program p = p.step()[0] p = p.step()[0] ifSide,elseSide = p.step() elseSide = elseSide.step()[0] assert elseSide.state.isSat() assert elseSide.state.any_real('x') == 9.0 assert elseSide.state.getZ3Var('x').is_real()
def test_funcion_abs(): b = ast_parse.parse(test1).body p = Path(b, source=test1) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 1 assert pg.completed[0].state.any_int('a') == 10 assert pg.completed[0].state.any_int('b') == 10 assert pg.completed[0].state.any_int('c') == 10 assert pg.completed[0].state.any_int('d') == 10
def test_pyObjectManager_Int_MultipleObj(): b = ast_parse.parse(test4).body p = Path(b, source=test4) pg = PathGroup(p) pg.explore(find=4) assert len(pg.found) == 1 pg = PathGroup(p) pg.explore(find=6) assert len(pg.found) == 1
def test_pyObjectManager_BitVec_isStatic(): b = ast_parse.parse(test1).body p = Path(b, source=test1) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 1 x = pg.completed[0].state.getVar('x') assert x.isStatic() assert x.getValue() == 5
def test_pySym_BinOp_StrConcat(): b = ast_parse.parse(test10).body p = Path(b,source=test10) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 1 assert pg.completed[0].state.any_str('s') == "test" + " blerg" assert len(pg.completed[0].state.any_str('s2')) == 8 + len(" blerg") assert pg.completed[0].state.any_str('s2').endswith(" blerg") assert pg.completed[0].state.any_str('s3') == "This " + "is " + "a " + "test"
def test_pySym_BinOp_StatePropagation(): b = ast_parse.parse(test15).body p = Path(b,source=test15) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 9 # Check that the x value (output) is correct assert set([len(p.state.any_str('x')) for p in pg.completed]) == set([x*2 for x in range(9)]) # Check that the back-propogation of the s values are also accurate assert set([len(p.state.any_str('s')) - len(p.state.any_str('s').rstrip("x")) for p in pg.completed]) == set(range(9))
def test_function_pyState_String(): b = ast_parse.parse(test1).body p = Path(b, source=test1) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 1 s = pg.completed[0].state.getVar('s') s2 = pg.completed[0].state.getVar('s2') assert s.length() == 32 assert s2.length() == Z3_MAX_STRING_LENGTH
def test_pyState_ListComp_MultipleFor(): b = ast_parse.parse(test4).body p = Path(b, source=test4) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 1 assert pg.completed[0].state.any_list('l') == [ x for x in [1, 2, 3, 4, 5] for y in [1, 2, 3] ] with pytest.raises(Exception): pg.completed[0].state.any_int('x')
def test_assignInt(): b = ast_parse.parse(test1).body p = Path(b, source=test1) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 1 s = pg.completed[0].state # Basic dict checks assert type(s.getVar("x")) == Int assert s.getVar("x").getZ3Object().is_int() #assert len(s.solver.assertions()) == 1 # Try solving it to ensure that works correctly assert s.isSat() # Ensure we're getting expected output assert s.any_int('x') == 1 # Try assigning again b = ast_parse.parse(test2).body p = Path(b, source=test2) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 1 s = pg.completed[0].state # Basic dict checks assert type(s.getVar("x")) == Int assert s.getVar("x").getZ3Object().is_int() #assert len(s.solver.assertions()) == 2 # Try solving it to ensure that works correctly assert s.isSat() # Ensure we're getting expected output assert s.any_int('x') == 2
def test_pyPath_stepThroughProgram(): b = ast_parse.parse(test1).body p = Path(b, source=test1) pg = PathGroup(p) pg.explore() assert len(pg.active) == 0 assert len(pg.completed) == 1 assert len(pg.errored) == 0 assert len(pg.deadended) == 0 assert len(pg.found) == 0 assert pg.completed[0].state.any_int('x') == 10 assert pg.completed[0].state.any_int('z') == 1
def test_pyObjectManager_Int_PostSet(): b = ast_parse.parse(test5).body p = Path(b, source=test5) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 1 for q in range(6): s = pg.completed[0].state.copy() x = s.getVar('x') i = s.getVar('i') i.setTo(q) assert x.getValue() == q
def test_pySym_simpleWhile(): b = ast_parse.parse(test1).body p = Path(b, source=test1) pg = PathGroup(p) assert pg.explore(find=6) assert len(pg.active) == 0 assert len(pg.completed) == 0 assert len(pg.errored) == 0 assert len(pg.deadended) == 11 assert len(pg.found) == 1 assert pg.found[0].state.isSat() assert pg.found[0].state.any_int('x') == 10
def test_function_String_zfill_static(): b = ast_parse.parse(test1).body p = Path(b, source=test1) pg = PathGroup(p) pg.explore() # Every index should be a possibility assert len(pg.completed) == 1 assert pg.completed[0].state.any_str('x') == "test" assert pg.completed[0].state.any_str('y') == "0test" assert pg.completed[0].state.any_str('z') == "test" assert pg.completed[0].state.any_str('d') == "000000test"
def test_pyPathGroup_exploreWithIf(): b = ast_parse.parse(test2).body p = Path(b, source=test2) pg = PathGroup(p) # Explore to the end assert pg.explore(find=15) assert len(pg.active) == 0 assert len(pg.completed) == 0 assert len(pg.errored) == 0 assert len(pg.deadended) == 2 assert len(pg.found) == 1 assert pg.found[0].state.any_int('x') == 1337
def test_any_n_int(): b = ast_parse.parse(test1).body p = Path(b, source=test1) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 1 assert pg.completed[0].state.any_int('x') == 1 # Duplicate test to ensure we're not destroying state assert pg.completed[0].state.any_n_int('x', 10) == [1] assert pg.completed[0].state.any_n_int('x', 10) == [1] b = ast_parse.parse(test4).body p = Path(b, source=test4) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 1 assert pg.completed[0].state.any_int('x') != None # Duplicate test to ensure we're not destroying state assert len(pg.completed[0].state.any_n_int('x', 10)) == 10 assert len(pg.completed[0].state.any_n_int('x', 10)) == 10
def test_any_n_real(): b = ast_parse.parse(test3).body p = Path(b, source=test3) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 1 assert pg.completed[0].state.any_real('x') == 3.1415 # Duplicate test to ensure we're not destroying state assert pg.completed[0].state.any_n_real('x', 10) == [3.1415] assert pg.completed[0].state.any_n_real('x', 10) == [3.1415] b = ast_parse.parse(test5).body p = Path(b, source=test5) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 1 assert pg.completed[0].state.any_real('x') != None # Duplicate test to ensure we're not destroying state assert len(pg.completed[0].state.any_n_real('x', 10)) == 10 assert len(pg.completed[0].state.any_n_real('x', 10)) == 10
def test_pySym_AugAssign_MultipleStates(): b = ast_parse.parse(test13).body p = Path(b, source=test13) pg = PathGroup(p) pg.explore() # There should be 10 possible states here assert len(pg.completed) == 10 # Get the output states rets = [] for p in pg.completed: rets.append(p.state.any_int('x')) assert set(rets) == set([1 + x for x in range(10)])
def test_pyPathGroup_exploreFunctionCompare(): b = ast_parse.parse(test3).body p = Path(b, source=test3) pg = PathGroup(p) # Execute to the end assert pg.explore(find=10) assert len(pg.active) == 0 assert len(pg.completed) == 0 assert len(pg.errored) == 0 assert len(pg.deadended) == 1 assert len(pg.found) == 1 assert pg.found[0].state.any_int('x') == 1
def test_pyObjectManager_String_canBe(): b = ast_parse.parse(test1).body p = Path(b, source=test1) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 1 s = pg.completed[0].state.getVar('s') assert s.canBe("Test") assert not s.canBe("test") assert s[0:1].canBe("T") assert not s[0:2].canBe("T3") assert s[:3].canBe("Tes")
def test_pyObjectManager_String_isStatic(): b = ast_parse.parse(test4).body p = Path(b, source=test4) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 1 s = pg.completed[0].state.getVar('s') d = pg.completed[0].state.getVar('d') assert s.isStatic() assert s.getValue() == "abcd" assert not d.isStatic()
def test_function_String_zfill_statesplit(): b = ast_parse.parse(test2).body p = Path(b, source=test2) pg = PathGroup(p) pg.explore() # Every index should be a possibility assert len(pg.completed) == 8 o = [p.state.any_str('y') for p in pg.completed] o.sort() assert o == [ '000test', '00test', '0test', 'test', 'test', 'test', 'test', 'test' ]
def test_function_String_Index(): b = ast_parse.parse(test1.format("T")).body p = Path(b, source=test1.format("T")) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 1 assert pg.completed[0].state.any_int('x') == 0 b = ast_parse.parse(test1.format("t")).body p = Path(b, source=test1.format("t")) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 1 assert pg.completed[0].state.any_int('x') == 3 b = ast_parse.parse(test1.format("es")).body p = Path(b, source=test1.format("es")) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 1 assert pg.completed[0].state.any_int('x') == 1 b = ast_parse.parse(test1.format("st")).body p = Path(b, source=test1.format("st")) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 1 assert pg.completed[0].state.any_int('x') == 2
def test_pyObjectManager_List_canBe(): b = ast_parse.parse(test11).body p = Path(b, source=test11) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 1 l = pg.completed[0].state.getVar('l') k = pg.completed[0].state.getVar('k') j = pg.completed[0].state.getVar('j') assert l.canBe(k) assert not l.canBe(j) assert l.mustBe(k)
def test_function_String_Index_Symbolic(): b = ast_parse.parse(test2).body p = Path(b, source=test2) pg = PathGroup(p) pg.explore() # Every index should be a possibility assert len(pg.completed) == 10 indexes = [] # Make sure we got all of them for path in pg.completed: indexes.append(path.state.any_int('x')) assert set(indexes) == set(range(10))
def test_function_zip(): b = ast_parse.parse(test1).body p = Path(b, source=test1) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 1 assert pg.completed[0].state.any_list('l') == [[1, 4], [2, 5], [3, 6]] assert pg.completed[0].state.any_list('l3') == [[1, 4], [2, 5], [3, 6]] assert pg.completed[0].state.any_list('l6') == [["1", "4"], ["2", "5"], ["3", "6"]] assert pg.completed[0].state.any_list('l7') == [["1", "5"], ["2", "6"]] assert pg.completed[0].state.any_list('l8') == [["1", "3"], ["2", "4"]] assert pg.completed[0].state.any_list('l9') == [[1, "a"], [2, "b"], [3, "c"]]
def test_copy(): b = ast_parse.parse("a = 1").body p = Path(b, source="a = 1") s = p.state s2 = s.copy() # Ensure it's actually being copied assert s != s2 # Add something to one and make sure the other is empty #pyState.Assign.handle(s,assign) s = s.step()[0] assert s.any_int('a') == 1 with pytest.raises(Exception): s2.any_int('a')
def test_pyPath_exploreFindLine(): b = ast_parse.parse(test1).body p = Path(b, source=test1) pg = PathGroup(p) # Explore to line 9 (z = 1) # Current setup means that z=1 will not actually be executed assert pg.explore(find=9) assert len(pg.active) == 0 assert len(pg.completed) == 0 assert len(pg.errored) == 0 assert len(pg.deadended) == 0 assert len(pg.found) == 1 assert pg.found[0].state.any_int('x') == 10
def test_pyObjectManager_BitVec_setTo(): b = ast_parse.parse(test2).body p = Path(b, source=test2) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 1 x = pg.completed[0].state.getVar('x') y = pg.completed[0].state.getVar('y') x.setTo(1337) assert pg.completed[0].state.any_int('x') == 1337 x.increment() x.setTo(y) assert pg.completed[0].state.any_int('x') == 15
def test_pyObjectManager_String_canBe_mustBe_String(): b = ast_parse.parse(test3).body p = Path(b, source=test3) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 1 s = pg.completed[0].state.getVar('s') d = pg.completed[0].state.getVar('d') f = pg.completed[0].state.getVar('f') g = pg.completed[0].state.getVar('g') assert s.canBe(d) assert not s.canBe(f) assert g.canBe(s) assert not g.mustBe(s) assert g.canBe(f)
def test_pyObjectManager_getParent(): b = ast_parse.parse(test1).body p = Path(b, source=test1) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 1 l = pg.completed[0].state.getVar('l') i = l[2] # Make sure it returned the right object assert pg.completed[0].state.objectManager.getParent(i) == l q = pg.completed[0].state.getVar('q') i = q[2][0] # Check that it recurses fully assert pg.completed[0].state.objectManager.getParent(i) == q[2]
def test_recursiveCopy(): b = ast_parse.parse(test6).body p = Path(b, source=test6) pg = PathGroup(p) pg.explore() assert len(pg.completed) == 1 s = pg.completed[0].state l = s.getVar('l') l2 = s.recursiveCopy(s.getVar('l')) assert l != l2 l2[-1][2].value = 4 assert l[-1][2].value != l2[-1][2].value
def test_pySym_AugAssign(): ####### # Add # ####### b = ast.parse(test1.format("+=")).body p = Path(b,source=test1.format("+=")) # Step through program p = p.step()[0] p = p.step()[0] ifSide,elseSide = p.step() elseSide = elseSide.step()[0] assert elseSide.state.isSat() assert elseSide.state.any_int('x') == 14 ############ # Subtract # ############ b = ast.parse(test1.format("-=")).body p = Path(b,source=test1.format("-=")) # Step through program p = p.step()[0] p = p.step()[0] ifSide,elseSide = p.step() elseSide = elseSide.step()[0] assert elseSide.state.isSat() assert elseSide.state.any_int('x') == 0 ############ # Multiply # ############ b = ast.parse(test1.format("*=")).body p = Path(b,source=test1.format("*=")) # Step through program p = p.step()[0] p = p.step()[0] ifSide,elseSide = p.step() elseSide = elseSide.step()[0] assert elseSide.state.isSat() assert elseSide.state.any_int('x') == 49 ########## # Divide # ########## b = ast.parse(test1.format("/=")).body p = Path(b,source=test1.format("/=")) # Step through program p = p.step()[0] p = p.step()[0] ifSide,elseSide = p.step() elseSide = elseSide.step()[0] assert elseSide.state.isSat() assert elseSide.state.any_int('x') == 1 ########## # Modulo # ########## b = ast.parse(test1.format("%=")).body p = Path(b,source=test1.format("%=")) # Step through program p = p.step()[0] p = p.step()[0] ifSide,elseSide = p.step() elseSide = elseSide.step()[0] assert elseSide.state.isSat() assert elseSide.state.any_int('x') == 0
def test_pySym_Compare(): ################ # Greater Than # ################ b = ast.parse(compare1.format(1,5,">")).body p = Path(b,source=compare1.format(1,5,">")) # Step through the "if" statement p = p.step()[0] p = p.step()[0] p2 = p.step() ifSide = p2[0] elseSide = p2[1] # If side should not be possible assert not ifSide.state.isSat() assert elseSide.state.isSat() # Track expected number of assertions assert len(ifSide.state.solver.assertions()) == 3 assert len(elseSide.state.solver.assertions()) == 3 # Make sure the answer makes sense assert ifSide.state.any_int('x') == None assert elseSide.state.any_int('x') == 1 ######################### # Greater Than Or Equal # ######################### b = ast.parse(compare1.format(2,2,">=")).body p = Path(b,source=compare1.format(2,2,">=")) # Step through the "if" statement p = p.step()[0] p = p.step()[0] p2 = p.step() ifSide = p2[0] elseSide = p2[1] # If side should be correct assert ifSide.state.isSat() assert not elseSide.state.isSat() # Track expected number of assertions assert len(ifSide.state.solver.assertions()) == 3 assert len(elseSide.state.solver.assertions()) == 3 # Make sure the answer makes sense assert ifSide.state.any_int('x') == 2 assert elseSide.state.any_int('x') == None ############# # Less Than # ############# b = ast.parse(compare1.format(1,5,"<")).body p = Path(b,source=compare1.format(1,5,"<")) # Step through the "if" statement p = p.step()[0] p = p.step()[0] p2 = p.step() ifSide = p2[0] elseSide = p2[1] # If side should be correct assert ifSide.state.isSat() assert not elseSide.state.isSat() # Track expected number of assertions assert len(ifSide.state.solver.assertions()) == 3 assert len(elseSide.state.solver.assertions()) == 3 # Make sure the answer makes sense assert ifSide.state.any_int('x') == 1 assert elseSide.state.any_int('x') == None ###################### # Less Than Or Equal # ###################### b = ast.parse(compare1.format(3,5,"<=")).body p = Path(b,source=compare1.format(3,5,"<=")) # Step through the "if" statement p = p.step()[0] p = p.step()[0] p2 = p.step() ifSide = p2[0] elseSide = p2[1] # If side should be correct assert ifSide.state.isSat() assert not elseSide.state.isSat() # Track expected number of assertions assert len(ifSide.state.solver.assertions()) == 3 assert len(elseSide.state.solver.assertions()) == 3 # Make sure the answer makes sense assert ifSide.state.any_int('x') == 3 assert elseSide.state.any_int('x') == None ######### # Equal # ######### b = ast.parse(compare1.format(1,5,"==")).body p = Path(b,source=compare1.format(1,5,"==")) # Step through the "if" statement p = p.step()[0] p = p.step()[0] p2 = p.step() ifSide = p2[0] elseSide = p2[1] # If side should not be correct assert not ifSide.state.isSat() assert elseSide.state.isSat() # Track expected number of assertions assert len(ifSide.state.solver.assertions()) == 3 assert len(elseSide.state.solver.assertions()) == 3 # Make sure the answer makes sense assert ifSide.state.any_int('x') == None assert elseSide.state.any_int('x') == 1 ############# # Not Equal # ############# b = ast.parse(compare1.format(1,5,"!=")).body p = Path(b,source=compare1.format(1,5,"!=")) # Step through the "if" statement p = p.step()[0] p = p.step()[0] p2 = p.step() ifSide = p2[0] elseSide = p2[1] # If side should be correct assert ifSide.state.isSat() assert not elseSide.state.isSat() # Track expected number of assertions assert len(ifSide.state.solver.assertions()) == 3 assert len(elseSide.state.solver.assertions()) == 3 # Make sure the answer makes sense assert ifSide.state.any_int('x') == 1 assert elseSide.state.any_int('x') == None