[Infer][tests] Adding tests for incremental functionality

Summary:
using the json stats parsing + some BUCK magic
to write tests for the incremental mode.
master
Sam Blackshear 10 years ago
parent f192b02f01
commit 7987d1a2a6

@ -0,0 +1,11 @@
java_test(
name='incremental',
deps=[
'//infer/tests/codetoanalyze/java/incremental/file_unchanged:file_unchanged',
'//infer/tests/codetoanalyze/java/incremental/parent_changed:parent_changed',
'//infer/tests/codetoanalyze/java/incremental/child_changed:child_changed',
],
visibility = [
'PUBLIC'
]
)

@ -0,0 +1,46 @@
v1_files = glob([ '**/*.java.v1'])
v2_files = glob(['**/*.java.v2'])
normal_files = glob(['**/*.java'])
sources = v1_files + v2_files + normal_files
java_library(
name = 'child_changed',
srcs = sources,
deps = [],
visibility = [
'PUBLIC'
]
)
def copy_files_strip_suffix_cmd(sfx, files):
return ' && '.join([' '.join(['cp', f, f.replace(sfx, '')]) for f in files])
out = 'out'
clean_cmd = ' '.join(['rm', '-rf', out])
stripped_suffix_files = map(lambda f: f.replace('.v1', ''), v1_files)
to_compile = ' '.join(normal_files + stripped_suffix_files)
infer_cmd = ' '.join([
'infer',
'-i',
'--absolute-paths',
'-o', out,
'-a', 'infer',
'--',
'javac',
to_compile
])
v1_copy_cmd = copy_files_strip_suffix_cmd('.v1', v1_files)
v2_copy_cmd = copy_files_strip_suffix_cmd('.v2', v2_files)
stats_copy_cmd = ' '.join(['cp', out + '/stats.json', '$OUT'])
command = ' && '.join([clean_cmd, v1_copy_cmd, infer_cmd, v2_copy_cmd, infer_cmd, stats_copy_cmd])
genrule(
name = 'analyze',
srcs = sources,
out = 'stats.json',
cmd = command,
deps = [':child_changed'],
visibility = [
'PUBLIC',
]
)

@ -0,0 +1,22 @@
/*
* Copyright (c) 2015 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package codetoanalyze.java.incremental.child_changed;
class Child {
Object bar() {
return null;
}
Object dontReanalyze(Object o) {
return o;
}
}

@ -0,0 +1,22 @@
/*
* Copyright (c) 2015 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package codetoanalyze.java.incremental.child_changed;
class Child {
Object bar() {
return new Object();
}
Object dontReanalyze(Object o) {
return o;
}
}

@ -0,0 +1,22 @@
/*
* Copyright (c) 2015 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package codetoanalyze.java.incremental.child_changed;
class Child {
Object bar() {
return null;
}
Object dontReanalyze(Object o) {
return o;
}
}

@ -0,0 +1,20 @@
/*
* Copyright (c) 2015 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package codetoanalyze.java.incremental.child_changed;
class Grandparent {
void baz() {
Parent p = new Parent();
Object o = p.foo();
o.toString();
}
}

@ -0,0 +1,24 @@
/*
* Copyright (c) 2015 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package codetoanalyze.java.incremental.child_changed;
class Parent {
Object foo() {
Child c = new Child();
Object o = c.bar();
return o;
}
void dontReanalyze() {
Object o1 = new Object();
}
}

@ -0,0 +1,35 @@
sources = glob([ '**/*.java'])
java_library(
name = 'file_unchanged',
srcs = sources,
visibility = [
'PUBLIC'
]
)
out = 'out'
clean_cmd = ' '.join(['rm', '-rf', out])
infer_cmd = ' '.join([
'infer',
'-i',
'--absolute-paths',
'-o', out,
'-a', 'infer',
'--',
'javac',
'$SRCS',
])
stats_copy_cmd = ' '.join(['cp', out + '/stats.json', '$OUT'])
command = ' && '.join([clean_cmd, infer_cmd, infer_cmd, stats_copy_cmd])
genrule(
name = 'analyze',
srcs = sources,
out = 'stats.json',
cmd = command,
deps = [':file_unchanged'],
visibility = [
'PUBLIC',
]
)

@ -0,0 +1,17 @@
/*
* Copyright (c) 2015 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package codetoanalyze.java.incremental.file_unchanged;
public class File {
Object o() {
return new Object();
}
}

@ -0,0 +1,46 @@
v1_files = glob([ '**/*.java.v1'])
v2_files = glob(['**/*.java.v2'])
normal_files = glob(['**/*.java'])
sources = v1_files + v2_files + normal_files
java_library(
name = 'parent_changed',
srcs = sources,
deps = [],
visibility = [
'PUBLIC'
]
)
def copy_files_strip_suffix_cmd(sfx, files):
return ' && '.join([' '.join(['cp', f, f.replace(sfx, '')]) for f in files])
out = 'out'
clean_cmd = ' '.join(['rm', '-rf', out])
stripped_suffix_files = map(lambda f: f.replace('.v1', ''), v1_files)
to_compile = ' '.join(normal_files + stripped_suffix_files)
infer_cmd = ' '.join([
'infer',
'-i',
'--absolute-paths',
'-o', out,
'-a', 'infer',
'--',
'javac',
to_compile
])
v1_copy_cmd = copy_files_strip_suffix_cmd('.v1', v1_files)
v2_copy_cmd = copy_files_strip_suffix_cmd('.v2', v2_files)
stats_copy_cmd = ' '.join(['cp', out + '/stats.json', '$OUT'])
command = ' && '.join([clean_cmd, v1_copy_cmd, infer_cmd, v2_copy_cmd, infer_cmd, stats_copy_cmd])
genrule(
name = 'analyze',
srcs = sources,
out = 'stats.json',
cmd = command,
deps = [':parent_changed'],
visibility = [
'PUBLIC',
]
)

@ -0,0 +1,17 @@
/*
* Copyright (c) 2015 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package codetoanalyze.java.incremental.parent_changed;
class Child {
Object bar() {
return new Object();
}
}

@ -0,0 +1,20 @@
/*
* Copyright (c) 2015 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package codetoanalyze.java.incremental.parent_changed;
class Parent {
void foo() {
Child c = new Child();
Object o = c.bar();
o.toString();
}
}

@ -0,0 +1,24 @@
/*
* Copyright (c) 2015 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package codetoanalyze.java.incremental.parent_changed;
class Parent {
void foo() {
Child c = new Child();
Object o = c.bar();
o.toString();
}
void bar() {
Object o1 = new Object();
}
}

@ -10,6 +10,7 @@ tests_dependencies = [
'//infer/tests/codetoanalyze/java/checkers:checkers', '//infer/tests/codetoanalyze/java/checkers:checkers',
'//infer/tests/codetoanalyze/java/eradicate:eradicate', '//infer/tests/codetoanalyze/java/eradicate:eradicate',
'//infer/tests/codetoanalyze/java/infer:infer', '//infer/tests/codetoanalyze/java/infer:infer',
'//infer/tests/codetoanalyze/java/incremental:incremental',
'//infer/tests/codetoanalyze/java/tracing:tracing', '//infer/tests/codetoanalyze/java/tracing:tracing',
] ]
@ -97,6 +98,7 @@ java_test(
'//infer/tests/endtoend/java/harness:harness', '//infer/tests/endtoend/java/harness:harness',
'//infer/tests/endtoend/java/tracing:tracing', '//infer/tests/endtoend/java/tracing:tracing',
'//infer/tests/endtoend/java/comparison:comparison', '//infer/tests/endtoend/java/comparison:comparison',
'//infer/tests/endtoend/java/incremental:incremental',
], ],
visibility=integration_tests, visibility=integration_tests,
) )

@ -0,0 +1,18 @@
java_test(
name='incremental',
srcs=glob(['*.java']),
deps=[
'//dependencies/java/guava:guava',
'//dependencies/java/junit:hamcrest',
'//dependencies/java/junit:junit',
'//infer/tests/utils:utils',
],
resources=[
'//infer/tests/codetoanalyze/java/incremental/file_unchanged:analyze',
'//infer/tests/codetoanalyze/java/incremental/parent_changed:analyze',
'//infer/tests/codetoanalyze/java/incremental/child_changed:analyze',
],
visibility=[
'PUBLIC',
],
)

@ -0,0 +1,48 @@
/*
* Copyright (c) 2015 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package endtoend.java.incremental;
import static org.hamcrest.MatcherAssert.assertThat;
import static utils.matchers.NumberOfFilesAnalyzed.numberOfFilesAnalyzed;
import static utils.matchers.NumberOfProceduresAnalyzed.numberOfProceduresAnalyzed;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.IOException;
import java.nio.file.Paths;
import java.nio.file.Path;
import java.io.*;
import utils.InferException;
import utils.InferStats;
public class ChildChangedTest {
public static final String SOURCE_DIR =
"/infer/tests/codetoanalyze/java/incremental/child_changed/";
private static InferStats inferStats;
@BeforeClass
public static void loadResults() throws InterruptedException, IOException {
inferStats = InferStats.loadInferStats(ChildChangedTest.class, SOURCE_DIR);
}
@Test
public void unchangedFileNotReanalyzedInIncrementalMode()
throws IOException, InterruptedException, InferException {
assertThat(
"After changing the child file, parent and grandparent should be re-analyzed",
inferStats,
numberOfFilesAnalyzed(3));
}
}

@ -0,0 +1,57 @@
/*
* Copyright (c) 2015 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package endtoend.java.incremental;
import static org.hamcrest.MatcherAssert.assertThat;
import static utils.matchers.NumberOfFilesAnalyzed.numberOfFilesAnalyzed;
import static utils.matchers.NumberOfProceduresAnalyzed.numberOfProceduresAnalyzed;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.IOException;
import java.nio.file.Paths;
import java.nio.file.Path;
import java.io.*;
import utils.InferException;
import utils.InferStats;
public class FileUnchangedTest {
public static final String SOURCE_DIR =
"/infer/tests/codetoanalyze/java/incremental/file_unchanged/";
private static InferStats inferStats;
@BeforeClass
public static void loadResults() throws InterruptedException, IOException {
inferStats = InferStats.loadInferStats(FileUnchangedTest.class, SOURCE_DIR);
}
@Test
public void unchangedFileNotReanalyzedInIncrementalMode()
throws IOException, InterruptedException, InferException {
assertThat(
"Unchanged file should not be re-analyzed in incremental mode",
inferStats,
numberOfFilesAnalyzed(0));
}
@Test
public void unchangedProcdureNotReanalyzedInIncrementalMode()
throws IOException, InterruptedException, InferException {
assertThat(
"Unchanged procedure should not be re-analyzed in incremental mode",
inferStats,
numberOfProceduresAnalyzed(0));
}
}

@ -0,0 +1,61 @@
/*
* Copyright (c) 2015 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package endtoend.java.incremental;
import static org.hamcrest.MatcherAssert.assertThat;
import static utils.matchers.NumberOfFilesAnalyzed.numberOfFilesAnalyzed;
import static utils.matchers.NumberOfProceduresAnalyzed.numberOfProceduresAnalyzed;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.IOException;
import java.nio.file.Paths;
import java.nio.file.Path;
import java.io.*;
import utils.InferException;
import utils.InferStats;
public class ParentChangedTest {
public static final String SOURCE_DIR =
"/infer/tests/codetoanalyze/java/incremental/parent_changed/";
private static InferStats inferStats;
@BeforeClass
public static void loadResults() throws InterruptedException, IOException {
inferStats = InferStats.loadInferStats(ParentChangedTest.class, SOURCE_DIR);
}
@Test
public void unchangedFileNotReanalyzedInIncrementalMode()
throws IOException, InterruptedException, InferException {
assertThat(
"After changing only the parent file, the child file should not be re-analyzed",
inferStats,
numberOfFilesAnalyzed(1));
assertThat(
"When adding a new procedure, the old ones should not be re-analyzed",
inferStats,
numberOfProceduresAnalyzed(1));
}
@Test
public void unchangedProcedureNotReanalyzedInIncrementalMode()
throws IOException, InterruptedException, InferException {
assertThat(
"When adding a new procedure, the old ones should not be re-analyzed",
inferStats,
numberOfProceduresAnalyzed(1));
}
}

@ -22,6 +22,7 @@ import java.io.Reader;
@JsonIgnoreProperties(ignoreUnknown=true) @JsonIgnoreProperties(ignoreUnknown=true)
public class InferStats { public class InferStats {
@JsonIgnoreProperties(ignoreUnknown=true)
private static class IntFields { private static class IntFields {
@JsonProperty(value = "files") @JsonProperty(value = "files")
int numFiles; int numFiles;

Loading…
Cancel
Save