@Test
  public void testCompileUsingHeaderModulesTransitivelyWithTranstiveModuleMaps() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCrosstool(
            mockToolsConfig,
            MockCcSupport.HEADER_MODULES_FEATURE_CONFIGURATION
                + "feature { name: 'transitive_module_maps' }");
    useConfiguration("--features=transitive_module_maps");
    setupPackagesForModuleTests(/*useHeaderModules=*/ true);

    getConfiguredTarget("//nomodule:f");
    Artifact fObjectArtifact = getBinArtifact("_objs/f/nomodule/f.pic.o", "//nomodule:f");
    CppCompileAction fObjectAction = (CppCompileAction) getGeneratingAction(fObjectArtifact);
    // Only the module map of f itself itself and the direct dependencies are needed.
    assertThat(getNonSystemModuleMaps(fObjectAction.getInputs()))
        .containsExactly(
            getGenfilesArtifact("y.cppmap", "//nomodule:y"),
            getGenfilesArtifact("z.cppmap", "//nomodule:z"),
            getGenfilesArtifact("a.cppmap", "//nomodule:a"),
            getGenfilesArtifact("f.cppmap", "//nomodule:f"),
            getGenfilesArtifact("e.cppmap", "//nomodule:e"));

    getConfiguredTarget("//nomodule:c");
    Artifact cObjectArtifact = getBinArtifact("_objs/c/nomodule/c.pic.o", "//nomodule:c");
    CppCompileAction cObjectAction = (CppCompileAction) getGeneratingAction(cObjectArtifact);
    assertThat(getNonSystemModuleMaps(cObjectAction.getInputs()))
        .containsExactly(
            getGenfilesArtifact("y.cppmap", "//nomodule:y"),
            getGenfilesArtifact("z.cppmap", "//nomodule:z"),
            getGenfilesArtifact("a.cppmap", "//nomodule:a"),
            getGenfilesArtifact("b.cppmap", "//module:b"),
            getGenfilesArtifact("c.cppmap", "//nomodule:e"));
    assertThat(getHeaderModuleFlags(cObjectAction.getCompilerOptions()))
        .containsExactly("b.pic.pcm");

    getConfiguredTarget("//nomodule:d");
    Artifact dObjectArtifact = getBinArtifact("_objs/d/nomodule/d.pic.o", "//nomodule:d");
    CppCompileAction dObjectAction = (CppCompileAction) getGeneratingAction(dObjectArtifact);
    assertThat(getNonSystemModuleMaps(dObjectAction.getInputs()))
        .containsExactly(
            getGenfilesArtifact("y.cppmap", "//nomodule:y"),
            getGenfilesArtifact("z.cppmap", "//nomodule:z"),
            getGenfilesArtifact("a.cppmap", "//nomodule:a"),
            getGenfilesArtifact("b.cppmap", "//module:b"),
            getGenfilesArtifact("c.cppmap", "//nomodule:c"),
            getGenfilesArtifact("d.cppmap", "//nomodule:d"));
    assertThat(getHeaderModuleFlags(dObjectAction.getCompilerOptions()))
        .containsExactly("b.pic.pcm");
  }
  @Test
  public void testCompileHeaderModules() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCrosstool(
            mockToolsConfig,
            "" + "feature { name: 'header_modules' }" + "feature { name: 'module_maps' }");
    useConfiguration();
    scratch.file(
        "module/BUILD",
        "package(features = ['header_modules'])",
        "cc_library(",
        "    name = 'a',",
        "    srcs = ['a.h', 'a.cc'],",
        "    deps = ['b']",
        ")",
        "cc_library(",
        "    name = 'b',",
        "    srcs = ['b.h'],",
        "    textual_hdrs = ['t.h'],",
        ")");
    getConfiguredTarget("//module:b");
    Artifact bModuleArtifact = getBinArtifact("_objs/b/module/b.pic.pcm", "//module:b");
    CppCompileAction bModuleAction = (CppCompileAction) getGeneratingAction(bModuleArtifact);
    assertThat(bModuleAction.getIncludeScannerSources())
        .containsExactly(getSourceArtifact("module/b.h"), getSourceArtifact("module/t.h"));
    assertThat(bModuleAction.getInputs())
        .contains(getGenfilesArtifactWithNoOwner("module/b.cppmap"));

    getConfiguredTarget("//module:a");
    Artifact aObjectArtifact = getBinArtifact("_objs/a/module/a.pic.o", "//module:a");
    CppCompileAction aObjectAction = (CppCompileAction) getGeneratingAction(aObjectArtifact);
    assertThat(aObjectAction.getIncludeScannerSources())
        .containsExactly(
            getSourceArtifact("module/a.cc"),
            getSourceArtifact("module/b.h"),
            getSourceArtifact("module/t.h"));
    assertThat(aObjectAction.getInputs())
        .contains(getBinArtifact("_objs/b/module/b.pic.pcm", "//module:b"));
    assertThat(aObjectAction.getInputs())
        .contains(getGenfilesArtifactWithNoOwner("module/b.cppmap"));
    assertNoEvents();
  }
  @Test
  public void testCompileHeaderModulesTransitively() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCrosstool(mockToolsConfig, MockCcSupport.HEADER_MODULES_FEATURE_CONFIGURATION);
    useConfiguration();
    setupPackagesForModuleTests(/*useHeaderModules=*/ false);

    // The //nomodule:f target only depends on non-module targets, thus it should be module-free.
    getConfiguredTarget("//nomodule:f");
    assertThat(getGeneratingAction(getBinArtifact("_objs/f/nomodule/f.pic.pcm", "//nomodule:f")))
        .isNull();
    Artifact fObjectArtifact = getBinArtifact("_objs/f/nomodule/f.pic.o", "//nomodule:f");
    CppCompileAction fObjectAction = (CppCompileAction) getGeneratingAction(fObjectArtifact);
    // Only the module map of f itself itself and the direct dependencies are needed.
    assertThat(getNonSystemModuleMaps(fObjectAction.getInputs()))
        .containsExactly(
            getGenfilesArtifact("f.cppmap", "//nomodule:f"),
            getGenfilesArtifact("e.cppmap", "//nomodule:e"));
    assertThat(getHeaderModules(fObjectAction.getInputs())).isEmpty();
    assertThat(fObjectAction.getIncludeScannerSources())
        .containsExactly(getSourceArtifact("nomodule/f.cc"));
    assertThat(getHeaderModuleFlags(fObjectAction.getCompilerOptions())).isEmpty();

    // The //nomodule:c target will get the header module for //module:b, which is a direct
    // dependency.
    getConfiguredTarget("//nomodule:c");
    assertThat(getGeneratingAction(getBinArtifact("_objs/c/nomodule/c.pic.pcm", "//nomodule:c")))
        .isNull();
    Artifact cObjectArtifact = getBinArtifact("_objs/c/nomodule/c.pic.o", "//nomodule:c");
    CppCompileAction cObjectAction = (CppCompileAction) getGeneratingAction(cObjectArtifact);
    assertThat(getNonSystemModuleMaps(cObjectAction.getInputs()))
        .containsExactly(
            getGenfilesArtifact("b.cppmap", "//module:b"),
            getGenfilesArtifact("c.cppmap", "//nomodule:e"));
    assertThat(getHeaderModules(cObjectAction.getInputs()))
        .containsExactly(getBinArtifact("_objs/b/module/b.pic.pcm", "//module:b"));
    // All headers of transitive dependencies that are built as modules are needed as entry points
    // for include scanning.
    assertThat(cObjectAction.getIncludeScannerSources())
        .containsExactly(getSourceArtifact("nomodule/c.cc"), getSourceArtifact("module/b.h"));
    assertThat(cObjectAction.getMainIncludeScannerSource())
        .isEqualTo(getSourceArtifact("nomodule/c.cc"));
    assertThat(getHeaderModuleFlags(cObjectAction.getCompilerOptions())).isEmpty();

    // The //nomodule:d target depends on //module:b via one indirection (//nomodule:c).
    getConfiguredTarget("//nomodule:d");
    assertThat(getGeneratingAction(getBinArtifact("_objs/d/nomodule/d.pic.pcm", "//nomodule:d")))
        .isNull();
    Artifact dObjectArtifact = getBinArtifact("_objs/d/nomodule/d.pic.o", "//nomodule:d");
    CppCompileAction dObjectAction = (CppCompileAction) getGeneratingAction(dObjectArtifact);
    // Module map 'c.cppmap' is needed because it is a direct dependency.
    assertThat(getNonSystemModuleMaps(dObjectAction.getInputs()))
        .containsExactly(
            getGenfilesArtifact("c.cppmap", "//nomodule:c"),
            getGenfilesArtifact("d.cppmap", "//nomodule:d"));
    assertThat(getHeaderModules(dObjectAction.getInputs()))
        .containsExactly(getBinArtifact("_objs/b/module/b.pic.pcm", "//module:b"));
    // All headers of transitive dependencies that are built as modules are needed as entry points
    // for include scanning.
    assertThat(dObjectAction.getIncludeScannerSources())
        .containsExactly(getSourceArtifact("module/b.h"), getSourceArtifact("nomodule/d.cc"));
    assertThat(getHeaderModuleFlags(dObjectAction.getCompilerOptions())).isEmpty();

    // The //module:j target depends on //module:g via //nomodule:h and on //module:b via
    // both //module:g and //nomodule:c.
    getConfiguredTarget("//module:j");
    Artifact jObjectArtifact = getBinArtifact("_objs/j/module/j.pic.o", "//module:j");
    CppCompileAction jObjectAction = (CppCompileAction) getGeneratingAction(jObjectArtifact);
    assertThat(getHeaderModules(jObjectAction.getInputs()))
        .containsExactly(
            getBinArtifact("_objs/b/module/b.pic.pcm", "//module:b"),
            getBinArtifact("_objs/g/module/g.pic.pcm", "//module:g"));
    assertThat(jObjectAction.getIncludeScannerSources())
        .containsExactly(
            getSourceArtifact("module/j.cc"),
            getSourceArtifact("module/b.h"),
            getSourceArtifact("module/g.h"));
    assertThat(jObjectAction.getMainIncludeScannerSource())
        .isEqualTo(getSourceArtifact("module/j.cc"));
    assertThat(getHeaderModuleFlags(jObjectAction.getCompilerOptions()))
        .containsExactly("b.pic.pcm", "g.pic.pcm");
  }