// Copyright 2020 The Bazel Authors. All rights reserved.
//
// 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.
package com.google.devtools.build.lib.analysis;

import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.lib.packages.Attribute.attr;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;

import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.CoreOptions.IncludeConfigFragmentsEnum;
import com.google.devtools.build.lib.analysis.config.Fragment;
import com.google.devtools.build.lib.analysis.config.FragmentOptions;
import com.google.devtools.build.lib.analysis.config.RequiresOptions;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.analysis.util.MockRule;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.packages.AspectDefinition;
import com.google.devtools.build.lib.packages.AspectParameters;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.NativeAspectClass;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.rules.cpp.CppOptions;
import com.google.devtools.build.lib.rules.java.JavaConfiguration;
import com.google.devtools.build.lib.rules.java.JavaOptions;
import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
import com.google.devtools.build.lib.util.FileTypeSet;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionDocumentationCategory;
import com.google.devtools.common.options.OptionEffectTag;
import com.google.testing.junit.testparameterinjector.TestParameter;
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import javax.annotation.Nullable;
import org.junit.Test;
import org.junit.runner.RunWith;

/** Tests for {@link RequiredConfigFragmentsProvider}. */
@RunWith(TestParameterInjector.class)
public final class RequiredConfigFragmentsTest extends BuildViewTestCase {

  public static final class AOptions extends FragmentOptions {
    @Option(
        name = "a_option",
        defaultValue = "",
        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
        effectTags = {OptionEffectTag.UNKNOWN})
    public String aOption;
  }

  /**
   * Public for {@link com.google.devtools.build.lib.analysis.config.FragmentFactory}'s
   * reflection-based construction.
   */
  @RequiresOptions(options = {AOptions.class})
  public static final class TestFragmentA extends Fragment {
    public TestFragmentA(BuildOptions options) {}
  }

  /**
   * Public for {@link com.google.devtools.build.lib.analysis.config.FragmentFactory}'s
   * reflection-based construction.
   */
  public static final class TestFragmentB extends Fragment {
    public TestFragmentB(BuildOptions options) {}
  }

  @Override
  protected ConfiguredRuleClassProvider createRuleClassProvider() {
    ConfiguredRuleClassProvider.Builder builder =
        new ConfiguredRuleClassProvider.Builder()
            .addRuleDefinition(new RuleThatAttachesAspect())
            .addRuleDefinition(REQUIRES_FRAGMENT_A)
            .addRuleDefinition(REQUIRES_FRAGMENT_B)
            .addNativeAspectClass(ASPECT_WITH_CONFIG_FRAGMENT_REQUIREMENTS)
            .addConfigurationFragment(TestFragmentA.class)
            .addConfigurationFragment(TestFragmentB.class);
    TestRuleClassProvider.addStandardRules(builder);
    return builder.build();
  }

  private static final MockRule REQUIRES_FRAGMENT_A =
      () ->
          MockRule.define(
              "requires_fragment_a",
              (builder, env) ->
                  builder
                      .add(
                          attr("deps", BuildType.LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE))
                      .requiresConfigurationFragments(TestFragmentA.class));

  private static final MockRule REQUIRES_FRAGMENT_B =
      () ->
          MockRule.define(
              "requires_fragment_b",
              (builder, env) -> builder.requiresConfigurationFragments(TestFragmentB.class));

  @Test
  public void provideTransitiveRequiredFragmentsMode() throws Exception {
    useConfiguration("--include_config_fragments_provider=transitive");
    scratch.file(
        "a/BUILD",
        "requires_fragment_b(name = 'b')",
        "requires_fragment_a(name = 'a', deps = [':b'])");

    RequiredConfigFragmentsProvider aTransitiveFragments =
        getConfiguredTarget("//a:a").getProvider(RequiredConfigFragmentsProvider.class);
    assertThat(aTransitiveFragments.getFragmentClasses())
        .containsAtLeast(TestFragmentA.class, TestFragmentB.class);
  }

  @Test
  public void configSettingProvideTransitiveRequiresFragment() throws Exception {
    useConfiguration("--include_config_fragments_provider=transitive");
    scratch.file(
        "a/BUILD",
        "config_setting(name = 'config_on_native', values = {'cpu': 'foo'})",
        "config_setting(name = 'config_on_a', values = {'a_option': 'foo'})");

    assertThat(
            getConfiguredTarget("//a:config_on_a")
                .getProvider(RequiredConfigFragmentsProvider.class)
                .getOptionsClasses())
        .contains(AOptions.class);
    assertThat(
            getConfiguredTarget("//a:config_on_native")
                .getProvider(RequiredConfigFragmentsProvider.class)
                .getOptionsClasses())
        .doesNotContain(AOptions.class);
  }

  @Test
  public void provideDirectRequiredFragmentsMode() throws Exception {
    useConfiguration("--include_config_fragments_provider=direct");
    scratch.file(
        "a/BUILD",
        "requires_fragment_b(name = 'b')",
        "requires_fragment_a(name = 'a', deps = [':b'])");

    RequiredConfigFragmentsProvider aDirectFragments =
        getConfiguredTarget("//a:a").getProvider(RequiredConfigFragmentsProvider.class);
    assertThat(aDirectFragments.getFragmentClasses()).contains(TestFragmentA.class);
    assertThat(aDirectFragments.getFragmentClasses()).doesNotContain(TestFragmentB.class);
  }

  @Test
  public void configSettingProvideDirectRequiresFragment() throws Exception {
    useConfiguration("--include_config_fragments_provider=direct");
    scratch.file(
        "a/BUILD",
        "config_setting(name = 'config_on_native', values = {'cpu': 'foo'})",
        "config_setting(name = 'config_on_a', values = {'a_option': 'foo'})");

    assertThat(
            getConfiguredTarget("//a:config_on_a")
                .getProvider(RequiredConfigFragmentsProvider.class)
                .getOptionsClasses())
        .contains(AOptions.class);
    assertThat(
            getConfiguredTarget("//a:config_on_native")
                .getProvider(RequiredConfigFragmentsProvider.class)
                .getOptionsClasses())
        .doesNotContain(AOptions.class);
  }

  @Test
  public void requiresMakeVariablesSuppliedByDefine() throws Exception {
    useConfiguration("--include_config_fragments_provider=direct", "--define", "myvar=myval");
    scratch.file(
        "a/BUILD",
        "genrule(",
        "    name = 'myrule',",
        "    srcs = [],",
        "    outs = ['myrule.out'],",
        "    cmd = 'echo $(myvar) $(COMPILATION_MODE) > $@')");
    RequiredConfigFragmentsProvider requiredFragments =
        getConfiguredTarget("//a:myrule").getProvider(RequiredConfigFragmentsProvider.class);
    assertThat(requiredFragments.getDefines()).containsExactly("myvar");
  }

  @Test
  public void starlarkExpandMakeVariables() throws Exception {
    useConfiguration("--include_config_fragments_provider=direct", "--define=myvar=myval");
    scratch.file(
        "a/defs.bzl",
        "def _impl(ctx):",
        "  print(ctx.expand_make_variables('dummy attribute', 'string with $(myvar)!', {}))",
        "",
        "simple_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {}",
        ")");
    scratch.file("a/BUILD", "load('//a:defs.bzl', 'simple_rule')", "simple_rule(name = 'simple')");
    RequiredConfigFragmentsProvider requiredFragments =
        getConfiguredTarget("//a:simple").getProvider(RequiredConfigFragmentsProvider.class);
    assertThat(requiredFragments.getDefines()).containsExactly("myvar");
  }

  @Test
  public void starlarkCtxVar() throws Exception {
    useConfiguration(
        "--include_config_fragments_provider=direct", "--define=required_var=1,irrelevant_var=1");
    scratch.file(
        "a/defs.bzl",
        "def _impl(ctx):",
        // Defined, so reported as required.
        "  if 'required_var' not in ctx.var:",
        "    fail('Missing required_var')",
        // Not defined, so not reported as required.
        "  if 'prohibited_var' in ctx.var:",
        "    fail('Not allowed to set prohibited_var')",
        // Present but not a define variable, so not reported as required.
        "  if 'COMPILATION_MODE' not in ctx.var:",
        "    fail('Missing COMPILATION_MODE')",
        "",
        "simple_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {}",
        ")");
    scratch.file("a/BUILD", "load('//a:defs.bzl', 'simple_rule')", "simple_rule(name = 'simple')");
    RequiredConfigFragmentsProvider requiredFragments =
        getConfiguredTarget("//a:simple").getProvider(RequiredConfigFragmentsProvider.class);
    assertThat(requiredFragments.getDefines()).containsExactly("required_var");
  }

  /**
   * Aspect that requires fragments both in its definition and through {@link
   * #addAspectImplSpecificRequiredConfigFragments}.
   */
  private static final class AspectWithConfigFragmentRequirements extends NativeAspectClass
      implements ConfiguredAspectFactory {
    private static final Class<JavaConfiguration> REQUIRED_FRAGMENT = JavaConfiguration.class;
    private static final String REQUIRED_DEFINE = "myvar";

    @Override
    public AspectDefinition getDefinition(AspectParameters params) {
      return new AspectDefinition.Builder(this)
          .requiresConfigurationFragments(REQUIRED_FRAGMENT)
          .build();
    }

    @Override
    public ConfiguredAspect create(
        Label targetLabel,
        ConfiguredTarget ct,
        RuleContext ruleContext,
        AspectParameters params,
        RepositoryName toolsRepository)
        throws ActionConflictException, InterruptedException {
      return new ConfiguredAspect.Builder(ruleContext).build();
    }

    @Override
    public void addAspectImplSpecificRequiredConfigFragments(
        RequiredConfigFragmentsProvider.Builder requiredFragments) {
      requiredFragments.addDefine(REQUIRED_DEFINE);
    }
  }

  private static final AspectWithConfigFragmentRequirements
      ASPECT_WITH_CONFIG_FRAGMENT_REQUIREMENTS = new AspectWithConfigFragmentRequirements();

  /** Rule that attaches {@link AspectWithConfigFragmentRequirements} to its deps. */
  public static final class RuleThatAttachesAspect
      implements RuleDefinition, RuleConfiguredTargetFactory {
    @Override
    public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) {
      return builder
          .add(
              attr("deps", LABEL_LIST)
                  .allowedFileTypes(FileTypeSet.NO_FILE)
                  .aspect(ASPECT_WITH_CONFIG_FRAGMENT_REQUIREMENTS))
          .build();
    }

    @Override
    public Metadata getMetadata() {
      return RuleDefinition.Metadata.builder()
          .name("rule_that_attaches_aspect")
          .ancestors(BaseRuleClasses.NativeBuildRule.class)
          .factoryClass(RuleThatAttachesAspect.class)
          .build();
    }

    @Override
    @Nullable
    public ConfiguredTarget create(RuleContext ruleContext)
        throws ActionConflictException, InterruptedException {
      return new RuleConfiguredTargetBuilder(ruleContext)
          .addProvider(RunfilesProvider.EMPTY)
          .build();
    }
  }

  @Test
  public void aspectRequiresFragments() throws Exception {
    scratch.file(
        "a/BUILD",
        "rule_that_attaches_aspect(name = 'parent', deps = [':dep'])",
        "rule_that_attaches_aspect(name = 'dep')");
    useConfiguration("--include_config_fragments_provider=transitive");
    RequiredConfigFragmentsProvider requiredFragments =
        getConfiguredTarget("//a:parent").getProvider(RequiredConfigFragmentsProvider.class);
    assertThat(requiredFragments.getFragmentClasses())
        .contains(AspectWithConfigFragmentRequirements.REQUIRED_FRAGMENT);
    assertThat(requiredFragments.getDefines())
        .containsExactly(AspectWithConfigFragmentRequirements.REQUIRED_DEFINE);
  }

  private void writeStarlarkTransitionsAndAllowList() throws Exception {
    scratch.overwriteFile(
        "tools/allowlists/function_transition_allowlist/BUILD",
        "package_group(",
        "    name = 'function_transition_allowlist',",
        "    packages = [",
        "        '//a/...',",
        "    ],",
        ")");
    scratch.file(
        "transitions/defs.bzl",
        "def _java_write_transition_impl(settings, attr):",
        "  return {'//command_line_option:javacopt': ['foo'] }",
        "java_write_transition = transition(",
        "  implementation = _java_write_transition_impl,",
        "  inputs = [],",
        "  outputs = ['//command_line_option:javacopt'],",
        ")",
        "def _cpp_read_transition_impl(settings, attr):",
        "  return {}",
        "cpp_read_transition = transition(",
        "  implementation = _cpp_read_transition_impl,",
        "  inputs = ['//command_line_option:copt'],",
        "  outputs = [],",
        ")");
    scratch.file("transitions/BUILD");
  }

  @Test
  public void starlarkRuleTransitionReadsFragment() throws Exception {
    writeStarlarkTransitionsAndAllowList();
    scratch.file(
        "a/defs.bzl",
        "load('//transitions:defs.bzl', 'cpp_read_transition')",
        "def _impl(ctx):",
        "  pass",
        "has_cpp_aware_rule_transition = rule(",
        "  implementation = _impl,",
        "  cfg = cpp_read_transition,",
        ")");
    scratch.file(
        "a/BUILD",
        "load('//a:defs.bzl', 'has_cpp_aware_rule_transition')",
        "has_cpp_aware_rule_transition(name = 'cctarget')");
    useConfiguration("--include_config_fragments_provider=direct");
    RequiredConfigFragmentsProvider requiredFragments =
        getConfiguredTarget("//a:cctarget").getProvider(RequiredConfigFragmentsProvider.class);
    assertThat(requiredFragments.getOptionsClasses()).contains(CppOptions.class);
    assertThat(requiredFragments.getOptionsClasses()).doesNotContain(JavaOptions.class);
  }

  @Test
  public void starlarkRuleTransitionWritesFragment() throws Exception {
    writeStarlarkTransitionsAndAllowList();
    scratch.file(
        "a/defs.bzl",
        "load('//transitions:defs.bzl', 'java_write_transition')",
        "def _impl(ctx):",
        "  pass",
        "has_java_aware_rule_transition = rule(",
        "  implementation = _impl,",
        "  cfg = java_write_transition,",
        ")");
    scratch.file(
        "a/BUILD",
        "load('//a:defs.bzl', 'has_java_aware_rule_transition')",
        "has_java_aware_rule_transition(name = 'javatarget')");
    useConfiguration("--include_config_fragments_provider=direct");
    RequiredConfigFragmentsProvider requiredFragments =
        getConfiguredTarget("//a:javatarget").getProvider(RequiredConfigFragmentsProvider.class);
    assertThat(requiredFragments.getOptionsClasses()).contains(JavaOptions.class);
    assertThat(requiredFragments.getOptionsClasses()).doesNotContain(CppOptions.class);
  }

  @Test
  public void starlarkAttrTransition() throws Exception {
    writeStarlarkTransitionsAndAllowList();
    scratch.file(
        "a/defs.bzl",
        "load('//transitions:defs.bzl', 'cpp_read_transition', 'java_write_transition')",
        "def _impl(ctx):",
        "  pass",
        "has_java_aware_attr_transition = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'deps': attr.label_list(cfg = java_write_transition),",
        "  })",
        "has_cpp_aware_rule_transition = rule(",
        "  implementation = _impl,",
        "  cfg = cpp_read_transition,",
        ")");
    scratch.file(
        "a/BUILD",
        "load('//a:defs.bzl', 'has_cpp_aware_rule_transition', 'has_java_aware_attr_transition')",
        "has_cpp_aware_rule_transition(name = 'ccchild')",
        "has_java_aware_attr_transition(",
        "  name = 'javaparent',",
        "  deps = [':ccchild'])");
    useConfiguration("--include_config_fragments_provider=direct");
    RequiredConfigFragmentsProvider requiredFragments =
        getConfiguredTarget("//a:javaparent").getProvider(RequiredConfigFragmentsProvider.class);
    // We consider the attribute transition over the parent -> child edge a property of the parent.
    assertThat(requiredFragments.getOptionsClasses()).contains(JavaOptions.class);
    // But not the child's rule transition.
    assertThat(requiredFragments.getOptionsClasses()).doesNotContain(CppOptions.class);
  }

  @Test
  public void aspectInheritsTransitiveFragmentsFromBaseCT(
      @TestParameter({"DIRECT", "TRANSITIVE"}) IncludeConfigFragmentsEnum setting)
      throws Exception {
    writeStarlarkTransitionsAndAllowList();
    scratch.file(
        "a/defs.bzl",
        "",
        "A1Info = provider()",
        "def _a1_impl(target, ctx):",
        "  return []",
        "a1 = aspect(implementation = _a1_impl)",
        "",
        "def _java_depender_impl(ctx):",
        "  return []",
        "java_depender = rule(",
        "  implementation = _java_depender_impl,",
        "  fragments = ['java'],",
        "  attrs = {})",
        "",
        "def _r_impl(ctx):",
        "  return []",
        "r = rule(",
        "  implementation = _r_impl,",
        "  attrs = {'dep': attr.label(aspects = [a1])})");
    scratch.file(
        "a/BUILD",
        "load(':defs.bzl', 'java_depender', 'r')",
        "java_depender(name = 'lib')",
        "r(name = 'r', dep = ':lib')");

    useConfiguration("--include_config_fragments_provider=" + setting);
    getConfiguredTarget("//a:r");
    RequiredConfigFragmentsProvider requiredFragments =
        getAspect("//a:defs.bzl%a1").getProvider(RequiredConfigFragmentsProvider.class);

    if (setting == IncludeConfigFragmentsEnum.TRANSITIVE) {
      assertThat(requiredFragments.getFragmentClasses()).contains(JavaConfiguration.class);
    } else {
      assertThat(requiredFragments.getFragmentClasses()).doesNotContain(JavaConfiguration.class);
    }
  }

  @Test
  public void aspectInheritsTransitiveFragmentsFromRequiredAspect(
      @TestParameter({"DIRECT", "TRANSITIVE"}) IncludeConfigFragmentsEnum setting)
      throws Exception {
    scratch.file(
        "a/defs.bzl",
        "",
        "A1Info = provider()",
        "def _a1_impl(target, ctx):",
        "  return A1Info(var = ctx.var.get('my_var', '0'))",
        "a1 = aspect(implementation = _a1_impl, provides = [A1Info])",
        "",
        "A2Info = provider()",
        "def _a2_impl(target, ctx):",
        "  return A2Info()",
        "a2 = aspect(implementation = _a2_impl, required_aspect_providers = [A1Info])",
        "",
        "def _simple_rule_impl(ctx):",
        "  return []",
        "simple_rule = rule(",
        "  implementation = _simple_rule_impl,",
        "  attrs = {})",
        "",
        "def _r_impl(ctx):",
        "  return []",
        "r = rule(",
        "  implementation = _r_impl,",
        "  attrs = {'dep': attr.label(aspects = [a1, a2])})");
    scratch.file(
        "a/BUILD",
        "load(':defs.bzl', 'r', 'simple_rule')",
        "simple_rule(name = 'lib')",
        "r(name = 'r', dep = ':lib')");

    useConfiguration("--include_config_fragments_provider=" + setting, "--define", "my_var=1");
    getConfiguredTarget("//a:r");
    RequiredConfigFragmentsProvider requiredFragments =
        getAspect("//a:defs.bzl%a2").getProvider(RequiredConfigFragmentsProvider.class);

    if (setting == IncludeConfigFragmentsEnum.TRANSITIVE) {
      assertThat(requiredFragments.getDefines()).contains("my_var");
    } else {
      assertThat(requiredFragments.getDefines()).doesNotContain("my_var");
    }
  }

  @Test
  public void invalidStarlarkFragmentsFiltered() throws Exception {
    scratch.file(
        "a/defs.bzl",
        "def _my_rule_impl(ctx):",
        "  pass",
        "",
        "my_rule = rule(implementation = _my_rule_impl, fragments = ['java', 'doesnotexist'])");
    scratch.file("a/BUILD", "load(':defs.bzl', 'my_rule')", "my_rule(name = 'example')");

    useConfiguration("--include_config_fragments_provider=direct");
    RequiredConfigFragmentsProvider requiredFragments =
        getConfiguredTarget("//a:example").getProvider(RequiredConfigFragmentsProvider.class);

    assertThat(requiredFragments.getFragmentClasses()).contains(JavaConfiguration.class);
  }

  @Test
  public void aspectInErrorWithAllowAnalysisFailures() throws Exception {
    scratch.file(
        "a/defs.bzl",
        "def _error_aspect_impl(target, ctx):",
        "  fail(ctx.var['FAIL_MESSAGE'])",
        "error_aspect = aspect(implementation = _error_aspect_impl)",
        "",
        "def _my_rule_impl(ctx):",
        "  pass",
        "my_rule = rule(",
        "  implementation = _my_rule_impl,",
        "  attrs = {'dep': attr.label(aspects = [error_aspect])},",
        ")");
    scratch.file(
        "a/BUILD",
        "load(':defs.bzl', 'my_rule', 'error_aspect')",
        "my_rule(name = 'a')",
        "my_rule(name = 'b', dep = ':a')");

    useConfiguration(
        "--allow_analysis_failures",
        "--define=FAIL_MESSAGE=abc",
        "--include_config_fragments_provider=direct");
    getConfiguredTarget("//a:b");
    RequiredConfigFragmentsProvider requiredFragments =
        getAspect("//a:defs.bzl%error_aspect").getProvider(RequiredConfigFragmentsProvider.class);

    assertThat(requiredFragments.getDefines()).containsExactly("FAIL_MESSAGE");
  }

  @Test
  public void configuredTargetInErrorWithAllowAnalysisFailures() throws Exception {
    scratch.file(
        "a/defs.bzl",
        "def _error_rule_impl(ctx):",
        "  fail(ctx.var['FAIL_MESSAGE'])",
        "error_rule = rule(implementation = _error_rule_impl)");
    scratch.file("a/BUILD", "load(':defs.bzl', 'error_rule')", "error_rule(name = 'error')");

    useConfiguration(
        "--allow_analysis_failures",
        "--define=FAIL_MESSAGE=abc",
        "--include_config_fragments_provider=direct");
    RequiredConfigFragmentsProvider requiredFragments =
        getConfiguredTarget("//a:error").getProvider(RequiredConfigFragmentsProvider.class);

    assertThat(requiredFragments.getDefines()).containsExactly("FAIL_MESSAGE");
  }

  @Test
  public void aliasWithSelectResolvesToConfigSetting() throws Exception {
    scratch.file(
        "a/BUILD",
        "config_setting(name = 'define_x', define_values = {'x': '1'})",
        "config_setting(name = 'k8', values = {'cpu': 'k8'})",
        "alias(name = 'alias_to_setting', actual = select({':define_x': ':k8'}))",
        "genrule(",
        "  name = 'gen',",
        "  outs = ['gen.out'],",
        "  cmd = select({':alias_to_setting': 'touch $@'}),",
        ")");

    useConfiguration("--define=x=1", "--cpu=k8", "--include_config_fragments_provider=transitive");
    RequiredConfigFragmentsProvider requiredFragments =
        getConfiguredTarget("//a:gen").getProvider(RequiredConfigFragmentsProvider.class);

    assertThat(requiredFragments.getDefines()).containsExactly("x");
  }
}
