Skip to content

Latest commit

 

History

History
220 lines (175 loc) · 7.6 KB

README.md

File metadata and controls

220 lines (175 loc) · 7.6 KB

Daikon Gradle Plugin

License

This Gradle plug-in creates a task, runDaikon, that runs Daikon on Java projects' unit tests.

Configuration

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.
}

Using a locally-built plugin

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.

Daikon Tasks

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 at build/driver directory.

If the above property is not provided, then the plugin assumes there is already test driver it can use with Daikon.

An example: Applying the Daikon plug-in to a simple Java project

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:

  1. 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
  1. Run either daikonEvidence or runDaikon 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

Results

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"
    }
  }
}

License

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.