Skip to content

Commit 984124b

Browse files
committed
Java: Improve flow test case generator to emit a data extensions YAML file and qlpack file if needed.
1 parent 48290c9 commit 984124b

File tree

2 files changed

+43
-12
lines changed

2 files changed

+43
-12
lines changed

java/ql/src/utils/flowtestcasegenerator/FlowTestCase.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ predicate summaryModelRow(
4242
}
4343

4444
/**
45-
* Gets a CSV row for which a test has been requested, but `SummaryModelCsv.row` does not hold of it.
45+
* Gets a CSV row for which a test has been requested, but where a summary has not already been defined.
4646
*/
4747
query string missingSummaryModelCsv() {
4848
any(TargetSummaryModelCsv target).row(result) and
49-
not any(SummaryModelCsv model).row(result)
49+
not summaryModelRow(_, _, _, _, _, _, _, _, _, _, result)
5050
}
5151

5252
/**

java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
2525
If --force is present, existing files may be overwritten.
2626
27-
Requirements: `mvn` and `codeql` should both appear on your path.
27+
Requirements:
28+
- `mvn` and `codeql` should both appear on your path.
29+
- `--additional-packs /path/to/semmle-code/ql` should be added to your `.config/codeql/config` file.
2830
2931
After test generation completes, any lines in specsToTest.csv that didn't produce tests are output.
3032
If this happens, check the spelling of class and method names, and the syntax of input and output specifications.
@@ -52,10 +54,12 @@
5254

5355
resultJava = os.path.join(sys.argv[3], "Test.java")
5456
resultQl = os.path.join(sys.argv[3], "test.ql")
57+
resultYml = os.path.join(sys.argv[3], "test.model.yml")
58+
resultPack = os.path.join(sys.argv[3], "qlpack.yml")
5559

56-
if not force and (os.path.exists(resultJava) or os.path.exists(resultQl)):
57-
print("Won't overwrite existing files '%s' or '%s'" %
58-
(resultJava, resultQl), file=sys.stderr)
60+
if not force and (os.path.exists(resultJava) or os.path.exists(resultQl) or os.path.exists(resultYml) or os.path.exists(resultPack)):
61+
print("Won't overwrite existing files '%s', '%s', '%s' or '%s'." %
62+
(resultJava, resultQl, resultYml, resultPack), file=sys.stderr)
5963
sys.exit(1)
6064

6165
workDir = tempfile.mkdtemp()
@@ -127,7 +131,13 @@ def qualifiedOuterNameFromCsvRow(row):
127131
os.makedirs(queryDir)
128132
qlFile = os.path.join(queryDir, "gen.ql")
129133
with open(os.path.join(queryDir, "qlpack.yml"), "w") as f:
130-
f.write("name: test-generation-query\nversion: 0.0.0\nlibraryPathDependencies: codeql/java-queries")
134+
f.write(f"""name: test-generation-query
135+
version: 0.0.0
136+
dependencies:
137+
codeql/java-all: '*'
138+
codeql/java-queries: '*'
139+
""")
140+
131141
with open(qlFile, "w") as f:
132142
f.write(
133143
"import java\nimport utils.flowtestcasegenerator.GenerateFlowTestCase\n\nclass GenRow extends TargetSummaryModelCsv {\n\n\toverride predicate row(string r) {\n\t\tr = [\n")
@@ -207,11 +217,32 @@ def copyfile(fromName, toFileHandle):
207217

208218
with open(resultQl, "w") as f:
209219
copyfile("testHeader.qlfrag", f)
210-
if len(supportModelRows) != 0:
211-
copyfile("testModelsHeader.qlfrag", f)
212-
f.write(", ".join('"%s"' %
213-
modelSpecRow[0].strip() for modelSpecRow in supportModelRows))
214-
copyfile("testModelsFooter.qlfrag", f)
220+
221+
if len(supportModelRows) != 0:
222+
# Make a test extension file
223+
with open(resultYml, "w") as f:
224+
models = "\n".join(' - [%s]' %
225+
modelSpecRow[0].strip() for modelSpecRow in supportModelRows)
226+
dataextensions = f"""extensions:
227+
- addsTo:
228+
pack: codeql/java-tests
229+
extensible: extSummaryModel
230+
data:
231+
{models}
232+
"""
233+
f.write(dataextensions)
234+
# Make a qlpack file such that the extension will be picked up
235+
with open(resultPack, "w") as f:
236+
f.write(f"""name: example-test-pack
237+
version: 0.0.0
238+
extractor: java
239+
dependencies:
240+
codeql/java-all: '*'
241+
codeql/java-queries: '*'
242+
codeql/java-tests: '*'
243+
dataExtensions:
244+
- test.model.yml
245+
""")
215246

216247
# Make an empty .expected file, since this is an inline-exectations test
217248
with open(os.path.join(sys.argv[3], "test.expected"), "w"):

0 commit comments

Comments
 (0)