This Gradle plug-in creates a task, runDaikon
, that runs Daikon on Java projects' unit tests.
To use this plug-in you must apply the Randoop plug-in to the root project’s build.gradle
:
plugins {
id 'java'
id 'maven-publish'
id 'com.sri.gradle.daikon' version '0.0.2-SNAPSHOT'
}
Then, you must specify you must specify a few configuration parameters in your runDaikon
configuration.
For example, the location where the plug-in can find the Daikon tool, the Daikon output directory,
the test driver package name, etc.
You can find a complete example of this configuration below:
plugins {
id 'java'
id 'maven-publish'
id 'com.sri.gradle.daikon' version '0.0.2-SNAPSHOT'
}
repositories {
mavenLocal()
mavenCentral()
maven {
url 'https://plugins.gradle.org/m2/'
}
}
dependencies {
implementation 'com.google.guava:guava:28.0-jre'
testImplementation 'org.hamcrest:hamcrest:2.2'
testImplementation 'junit:junit:4.13'
}
runDaikon {
outputDir = file("${projectDir}/build/daikon-output")
// the project directory where daikon.jar, ChicoryPremain.jar,
// and dcomp_*.jar files exist
requires = file("libs")
// *TestDriver package name
// The Daikon tool requires a test driver. If you use Randoop,
// then Randoop will generate one for you.
testDriverPackage = "com.foo"
// Otherwise, you need to tell this plugin to create one for you.
// The instructions for how to do this are described later in this
// README file.
}
You can build the plug-in locally rather than downloading it from Maven Central.
To build the plug-in from source, run the ./gradlew build
command.
If you want to use a locally-built version of the plug-in, you must add the following configuration to
the settings.gradle
file of your Gradle project:
pluginManagement {
repositories {
mavenLocal()
gradlePluginPortal()
}
}
Then, you can publish the plug-in to your local Maven repository simply by running the ./gradlew publishToMavenLocal
command.
Make sure you run both the clean
and the build
tasks before running this command:
› ./gradlew clean
› ./gradlew build
› ./gradlew publishToMavenLocal
After that, you can use any of the Gradle tasks offered by the Daikon plug-in.
The plugin support the following tasks. The main task of this plugin is the runDaikon
task, which
runs other supporting tasks, such as generateTestDriverCode
. The entire list of tasks is presented here:
daikonCheck
- Checks if Daikon is in your project's classpath.daikonEvidence
- Produces an evidence artifact containing the specific details of the Daikon execution.generateTestDriverCode
- Generates test driver code that Daikon can execute.runDaikon
- Detection of likely program invariants using Daikon.
Additional build properties:
-Pdriver
- Tells the plugin to generate its own test driver atbuild/driver
directory.
If the above property is not provided, then the plugin assumes there is already test driver it can use with Daikon.
A simple example of how to use this plugin on a basic Java project can be found at this project's
consumer
sub-directory. Here are the steps for using the plugin:
- Make sure you publish the plugin to Maven local first (See steps above)
If build
tasks throws an error, try running the used commands with the --stacktrace
or --debug
options. E.g.,
› ./gradlew clean
› ./gradlew build --stacktrace
› ./gradlew publishToMavenLocal
- Run either
daikonEvidence
orrunDaikon
tasks
If you want to see the plugin in action, you can just run the runDaikon
task. That should be enough.
This task will execute Daikon based on the configuration on build.gradle
file. However, if you want to generate
an evidence artifact that provides a summary of a Daikon execution (based on the files generated by runDaikon
),
then you can run the daikonEvidence
task.
› cd consumer
› ./gradlew daikonEvidence
The tasks runDaikon
and daikonEvidence
generates a few files. The main ones are
*TestDriver.inv.txt
, daikon-evidence.json
. It also produces three CSV files:
DaikonInvsAndMetrics.csv
, DaikonPluginConfig
, and DaikonPluginQualification.csv
.
The daikon-evidence.json
file aggregates all the information in the other CSV
files.
Here is a snippet of the first one:
===========================================================================
com.foo.Foo:::OBJECT
===========================================================================
com.foo.Foo.Foo():::EXIT
===========================================================================
com.foo.Foo.mutate():::ENTER
===========================================================================
com.foo.Foo.mutate():::EXIT
===========================================================================
com.foo.FooManager:::OBJECT
===========================================================================
com.foo.FooManager.FooManager(com.foo.Foo):::ENTER
===========================================================================
com.foo.FooManager.FooManager(com.foo.Foo):::EXIT
===========================================================================
com.foo.FooManager.initialize():::ENTER
this.foo != null
===========================================================================
com.foo.FooManager.initialize():::EXIT
this.foo == orig(this.foo)
this.foo != null
===========================================================================
And here is the second file:
{
"Evidence": {
"DaikonPluginConfig": {
"OUTPUT_DIR": "build/daikon-output",
"TEST_DRIVER_PACKAGE": "com.foo"
},
"DaikonPluginQualification": {
"DATE": "2021-3-30",
"SUMMARY": "Runs the Daikon Tool",
"QUALIFIEDBY": "SRI International",
"INSTALLATION": "https://github.com/SRI-CSL/daikon-gradle-plugin/blob/master/README.md",
"USERGUIDE": "https://github.com/SRI-CSL/daikon-gradle-plugin/blob/master/README.md",
"TITLE": "DaikonGradlePlugin",
"ACTIVITY": "Dynamic Analysis"
},
"DaikonInvsAndMetrics": {
"CORES": "16",
"JVM_MEMORY_LIMIT_IN_BYTES": "477626368",
"SUPPORT_FILES": [
"build/daikon-output/RegressionTestDriver.dtrace.gz",
"build/daikon-output/RegressionTestDriver.decls-DynComp",
"build/daikon-output/RegressionTestDriver.inv.gz"
],
"PP_COUNT": "5",
"INVARIANTS_FILE": "build/daikon-output/RegressionTestDriver.inv.txt",
"MEMORY_AVAILABLE_TO_JVM_IN_BYTES": "432013312",
"CLASSES_COUNT": "1",
"TEST_DRIVER": "src/test/java/com/foo/RegressionTestDriver.java",
"TESTS_COUNT": "4",
"INVARIANT_COUNT": "0"
}
}
}
Copyright (C) 2020 SRI International
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.