Java: Improve flow test case generator to emit a data extensions YAML file and qlpack file if needed.

This commit is contained in:
Michael Nebel
2022-11-28 15:53:52 +01:00
parent 48290c95a7
commit 984124b3b5
2 changed files with 43 additions and 12 deletions

View File

@@ -42,11 +42,11 @@ predicate summaryModelRow(
}
/**
* Gets a CSV row for which a test has been requested, but `SummaryModelCsv.row` does not hold of it.
* Gets a CSV row for which a test has been requested, but where a summary has not already been defined.
*/
query string missingSummaryModelCsv() {
any(TargetSummaryModelCsv target).row(result) and
not any(SummaryModelCsv model).row(result)
not summaryModelRow(_, _, _, _, _, _, _, _, _, _, result)
}
/**

View File

@@ -24,7 +24,9 @@ contain the needed classes.
If --force is present, existing files may be overwritten.
Requirements: `mvn` and `codeql` should both appear on your path.
Requirements:
- `mvn` and `codeql` should both appear on your path.
- `--additional-packs /path/to/semmle-code/ql` should be added to your `.config/codeql/config` file.
After test generation completes, any lines in specsToTest.csv that didn't produce tests are output.
If this happens, check the spelling of class and method names, and the syntax of input and output specifications.
@@ -52,10 +54,12 @@ except Exception as e:
resultJava = os.path.join(sys.argv[3], "Test.java")
resultQl = os.path.join(sys.argv[3], "test.ql")
resultYml = os.path.join(sys.argv[3], "test.model.yml")
resultPack = os.path.join(sys.argv[3], "qlpack.yml")
if not force and (os.path.exists(resultJava) or os.path.exists(resultQl)):
print("Won't overwrite existing files '%s' or '%s'" %
(resultJava, resultQl), file=sys.stderr)
if not force and (os.path.exists(resultJava) or os.path.exists(resultQl) or os.path.exists(resultYml) or os.path.exists(resultPack)):
print("Won't overwrite existing files '%s', '%s', '%s' or '%s'." %
(resultJava, resultQl, resultYml, resultPack), file=sys.stderr)
sys.exit(1)
workDir = tempfile.mkdtemp()
@@ -127,7 +131,13 @@ queryDir = os.path.join(workDir, "query")
os.makedirs(queryDir)
qlFile = os.path.join(queryDir, "gen.ql")
with open(os.path.join(queryDir, "qlpack.yml"), "w") as f:
f.write("name: test-generation-query\nversion: 0.0.0\nlibraryPathDependencies: codeql/java-queries")
f.write(f"""name: test-generation-query
version: 0.0.0
dependencies:
codeql/java-all: '*'
codeql/java-queries: '*'
""")
with open(qlFile, "w") as f:
f.write(
"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):
with open(resultQl, "w") as f:
copyfile("testHeader.qlfrag", f)
if len(supportModelRows) != 0:
copyfile("testModelsHeader.qlfrag", f)
f.write(", ".join('"%s"' %
modelSpecRow[0].strip() for modelSpecRow in supportModelRows))
copyfile("testModelsFooter.qlfrag", f)
if len(supportModelRows) != 0:
# Make a test extension file
with open(resultYml, "w") as f:
models = "\n".join(' - [%s]' %
modelSpecRow[0].strip() for modelSpecRow in supportModelRows)
dataextensions = f"""extensions:
- addsTo:
pack: codeql/java-tests
extensible: extSummaryModel
data:
{models}
"""
f.write(dataextensions)
# Make a qlpack file such that the extension will be picked up
with open(resultPack, "w") as f:
f.write(f"""name: example-test-pack
version: 0.0.0
extractor: java
dependencies:
codeql/java-all: '*'
codeql/java-queries: '*'
codeql/java-tests: '*'
dataExtensions:
- test.model.yml
""")
# Make an empty .expected file, since this is an inline-exectations test
with open(os.path.join(sys.argv[3], "test.expected"), "w"):