Skip to content

Commit c5c1c4c

Browse files
committed
Python: started adding some coverage tests
1 parent 415e0c4 commit c5c1c4c

5 files changed

Lines changed: 105 additions & 6 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
| test.py:20:9:20:14 | ControlFlowNode for SOURCE | test.py:21:10:21:10 | ControlFlowNode for x |
2+
| test.py:25:9:25:16 | ControlFlowNode for Str | test.py:26:10:26:10 | ControlFlowNode for x |
3+
| test.py:29:9:29:17 | ControlFlowNode for Str | test.py:30:10:30:10 | ControlFlowNode for x |
4+
| test.py:33:9:33:10 | ControlFlowNode for IntegerLiteral | test.py:34:10:34:10 | ControlFlowNode for x |
5+
| test.py:37:9:37:12 | ControlFlowNode for FloatLiteral | test.py:38:10:38:10 | ControlFlowNode for x |
6+
| test.py:46:10:46:15 | ControlFlowNode for SOURCE | test.py:47:10:47:10 | ControlFlowNode for x |

python/ql/test/experimental/dataflow/coverage/localFlow.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
| test.py:12:1:12:33 | GSSA Variable SINK | test.py:15:5:15:8 | ControlFlowNode for SINK |
2+
| test.py:12:1:12:33 | GSSA Variable SOURCE | test.py:13:13:13:18 | ControlFlowNode for SOURCE |
13
| test.py:13:5:13:5 | SSA variable x | test.py:12:1:12:33 | Exit node for Function test_tuple_with_local_flow |
24
| test.py:13:5:13:5 | SSA variable x | test.py:14:9:14:9 | ControlFlowNode for x |
35
| test.py:13:10:13:18 | ControlFlowNode for Tuple | test.py:13:5:13:5 | SSA variable x |

python/ql/test/experimental/dataflow/coverage/test.py

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,91 @@
44
#
55
# Functions whose name ends with "_with_local_flow" will also be tested for local flow.
66

7-
# Uncomment these to test the test code
8-
# SOURCE = 42
9-
# def SINK(x):
10-
# return 42
7+
# These are included so that we can easily evaluate the test code
8+
SOURCE = "source"
9+
def SINK(x):
10+
print(x)
1111

1212
def test_tuple_with_local_flow():
1313
x = (3, SOURCE)
1414
y = x[1]
1515
SINK(y)
1616

17+
# List taken from https://docs.python.org/3/reference/expressions.html
18+
# 6.2.1. Identifiers (Names)
19+
def test_names():
20+
x = SOURCE
21+
SINK(x)
22+
23+
# 6.2.2. Literals
24+
def test_string_literal():
25+
x = "source"
26+
SINK(x)
27+
28+
def test_bytes_literal():
29+
x = b"source"
30+
SINK(x)
31+
32+
def test_integer_literal():
33+
x = 42
34+
SINK(x)
35+
36+
def test_floatnumber_literal():
37+
x = 42.0
38+
SINK(x)
39+
40+
def test_imagnumber_literal():
41+
x = 42j
42+
SINK(x)
43+
44+
# 6.2.3. Parenthesized forms
45+
def test_parenthesized_form():
46+
x = (SOURCE)
47+
SINK(x)
48+
49+
# 6.2.5. List displays
50+
def test_list_display():
51+
x = [SOURCE]
52+
SINK(x[0])
53+
54+
def test_list_comprehension():
55+
x = [SOURCE for y in [3]]
56+
SINK(x[0])
57+
58+
def test_nested_list_display():
59+
x = [* [SOURCE]]
60+
SINK(x[0])
61+
62+
# 6.2.6. Set displays
63+
def test_set_display():
64+
x = {SOURCE}
65+
SINK(x.pop())
66+
67+
def test_set_comprehension():
68+
x = {SOURCE for y in [3]}
69+
SINK(x.pop())
70+
71+
def test_nested_set_display():
72+
x = {* {SOURCE}}
73+
SINK(x.pop())
74+
75+
# 6.2.7. Dictionary displays
76+
def test_dict_display():
77+
x = {"s": SOURCE}
78+
SINK(x["s"])
79+
80+
def test_dict_comprehension():
81+
x = {y: SOURCE for y in ["s"]}
82+
SINK(x["s"])
83+
84+
def test_nested_dict_display():
85+
x = {** {"s": SOURCE}}
86+
SINK(x["s"])
87+
88+
# 6.2.8. Generator expressions
89+
def test_generator():
90+
x = (SOURCE for y in [3])
91+
SINK([*x][0])
1792

1893
# List taken from https://docs.python.org/3/reference/expressions.html
1994
# 6. Expressions

python/ql/test/experimental/dataflow/regression/test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,9 @@ def test_truth():
159159
if t:
160160
SINK(t)
161161
else:
162-
SINK(t)
162+
SINK(t) # Regression: FP here
163163
if not t:
164-
SINK(t)
164+
SINK(t) # Regression: FP here
165165
else:
166166
SINK(t)
167167

python/ql/test/experimental/dataflow/testConfig.qll

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@
99
* SINK(s)
1010
* ```
1111
* `SOURCE` will be a source and the second occurance of `s` will be a sink.
12+
*
13+
* In order to test literals, alternative sources are defined for each type:
14+
*
15+
* for | use
16+
* ----------
17+
* string | `"source"`
18+
* integer | `42`
19+
* float | `42.0`
20+
* complex | `42j` (not supported yet)
1221
*/
1322

1423
import experimental.dataflow.DataFlow
@@ -18,6 +27,13 @@ class TestConfiguration extends DataFlow::Configuration {
1827

1928
override predicate isSource(DataFlow::Node node) {
2029
node.asCfgNode().(NameNode).getId() = "SOURCE"
30+
or
31+
node.asCfgNode().getNode().(StrConst).getS() = "source"
32+
or
33+
node.asCfgNode().getNode().(IntegerLiteral).getN() = "42"
34+
or
35+
node.asCfgNode().getNode().(FloatLiteral).getN() = "42.0"
36+
// No support for complex numbers
2137
}
2238

2339
override predicate isSink(DataFlow::Node node) {

0 commit comments

Comments
 (0)