You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

63 lines
1.9 KiB

[Infer][incremental] Preventing --changed-only incremental mode from corrupting the future Summary: When someone runs --changed-only mode, there is a risk of corrupting the results for future analyses. The problem is that changed-only mode does not analyze the callers of changed procedures. If a subsequent analysis relies on the specs of one of these callers, they will be stale and may give the wrong results. To be concrete, let's say we know `Parent.foo()` calls `Child.bar()` and we do the following rounds of analysis: Analysis round 1: Analyze all files, including `Parent` and `Child` Analysis round 2: Analyze `Child.bar()` only with `--changed-only flag`. `Parent.foo()` is now stale. Analysis round 3: Add procedure `Parent.baz()` that calls `Parent.foo()`, analyze in (any) incremental mode. The analysis will only analyze `Parent.baz()`. However, the specs for `Parent.foo()` are stale and may give us bad results for `Parent.baz()`. We want the analysis to re-analyze `Parent.baz()`, but before this diff it will not. This diff fixes this problem by adding a `STALE` status bit to procedure summaries. In `--changed-only` mode, the callers of a changed procedures are not re-analyzed, but their summaries are marked as stale. For both `--changed-only` and regular incremental mode, callees of changed procedures that are marked as stale are re-analyzed even if they have not changed. This is better than a more obvious solution like deleting stale procedure summaries, since that would force the next analysis to re-analyze all stale procedures even if it does not need the results for whatever analysis it is doing. This scheme implemented in this diff ensures that each analysis only does the work that it needs to compute reliable results for its changed procedures.
9 years ago
/*
* 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;
/**
* Make sure the incremental --changed-only mode doesn't corrupt the results for future analyses by
* refusing to analyze callers of changed procedures (and thereby creating stale specs for some poor
* future analysis).
*/
public class ChangedOnlyFuture {
public static final String SOURCE_DIR =
"/infer/tests/codetoanalyze/java/incremental/changed_only_future/";
private static InferStats inferStats;
@BeforeClass
public static void loadResults() throws InterruptedException, IOException {
inferStats = InferStats.loadInferStats(ChangedOnlyModeTest.class, SOURCE_DIR);
}
@Test
public void onlyChangedFileReanalyzedInChangedOnlyMode()
throws IOException, InterruptedException, InferException {
assertThat(
"Only the changed file should be re-analyzed",
inferStats,
numberOfFilesAnalyzed(1));
}
@Test
public void changedAndStaleProcsReanalyze()
throws IOException, InterruptedException, InferException {
assertThat(
"Both the new (changed) procedure and its stale (unchanged) callee should be re-analyzed",
inferStats,
numberOfProceduresAnalyzed(2));
}
}