diff options
author | 2017-05-03 23:27:41 +0200 | |
---|---|---|
committer | 2017-05-04 13:14:13 +0200 | |
commit | 9dec9a09d1e4d27e7cff73c440195a32d3b90752 (patch) | |
tree | 94393d17b8fccaf9e13f4822476c4b5cc256c043 /src/test/java/com/google/devtools/build/lib/testutil | |
parent | 84a61ba3cc11ba7b98d3688adbb5154ca4f46293 (diff) |
Introduce BazelPackageLoader.
This is a standalone library for loading packages. It is intended to be used by clients outside of Bazel (for now, Kythe).
Perform BazelPackageLoader#loadPackage in the testing hook used in all of Bazel's unit tests and integration tests. This gives us very good test coverage for BazelPackageLoader.
RELNOTES: None
PiperOrigin-RevId: 155004070
Diffstat (limited to 'src/test/java/com/google/devtools/build/lib/testutil')
4 files changed, 167 insertions, 54 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/testutil/BazelPackageBuilderHelperForTesting.java b/src/test/java/com/google/devtools/build/lib/testutil/BazelPackageBuilderHelperForTesting.java new file mode 100644 index 0000000000..21f20cfb16 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/testutil/BazelPackageBuilderHelperForTesting.java @@ -0,0 +1,108 @@ +// Copyright 2017 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.testutil; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.common.collect.Sets; +import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.cmdline.PackageIdentifier; +import com.google.devtools.build.lib.packages.NoSuchPackageException; +import com.google.devtools.build.lib.packages.Package; +import com.google.devtools.build.lib.packages.RuleClassProvider; +import com.google.devtools.build.lib.packages.Target; +import com.google.devtools.build.lib.skyframe.PackageFunction; +import com.google.devtools.build.lib.skyframe.packages.BazelPackageLoader; +import com.google.devtools.build.lib.skyframe.packages.PackageLoader; +import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.lib.vfs.PathFragment; + +/** + * A Package.Builder.Helper for use in tests that a sanity check with {@link BazelPackageLoader} for + * each loaded package, for the sake of getting pretty nice test coverage. + */ +public class BazelPackageBuilderHelperForTesting implements Package.Builder.Helper { + private final RuleClassProvider ruleClassProvider; + + public BazelPackageBuilderHelperForTesting(RuleClassProvider ruleClassProvider) { + this.ruleClassProvider = ruleClassProvider; + } + + @Override + public Package createFreshPackage(PackageIdentifier packageId, String runfilesPrefix) { + return Package.Builder.DefaultHelper.INSTANCE.createFreshPackage(packageId, runfilesPrefix); + } + + @Override + public void onLoadingComplete(Package pkg) { + sanityCheckBazelPackageLoader(pkg, ruleClassProvider); + } + + private static final Function<Target, Label> TARGET_TO_LABEL = + new Function<Target, Label>() { + @Override + public Label apply(Target input) { + return input.getLabel(); + } + }; + + // This is synchronized because some Skylark internals aren't thread safe. + private synchronized void sanityCheckBazelPackageLoader( + Package pkg, + RuleClassProvider ruleClassProvider) { + PackageIdentifier pkgId = pkg.getPackageIdentifier(); + if (pkgId.equals(Label.EXTERNAL_PACKAGE_IDENTIFIER) + || !pkg.getPackageIdentifier().getRepository().isMain() + || PackageFunction.isDefaultsPackage(pkg.getPackageIdentifier())) { + // TODO(nharmata): Support these packages. + return; + } + int numNameSegments = pkg.getNameFragment().segmentCount(); + PathFragment fullFilenameFragment = pkg.getFilename().asFragment(); + int numFullFilenameFragmentSegments = fullFilenameFragment.segmentCount(); + Path workspaceRoot = pkg.getFilename().getFileSystem().getPath( + fullFilenameFragment.subFragment( + 0, + numFullFilenameFragmentSegments - (numNameSegments + 1))); + PackageLoader packageLoader = BazelPackageLoader.builder(workspaceRoot) + .setRuleClassProvider(ruleClassProvider) + .build(); + Package newlyLoadedPkg; + try { + newlyLoadedPkg = packageLoader.loadPackage(pkg.getPackageIdentifier()); + } catch (InterruptedException e) { + return; + } catch (NoSuchPackageException e) { + throw new IllegalStateException(e); + } + ImmutableSet<Label> targetsInPkg = + ImmutableSet.copyOf(Iterables.transform(pkg.getTargets(), TARGET_TO_LABEL)); + ImmutableSet<Label> targetsInNewlyLoadedPkg = + ImmutableSet.copyOf(Iterables.transform(newlyLoadedPkg.getTargets(), TARGET_TO_LABEL)); + if (!targetsInPkg.equals(targetsInNewlyLoadedPkg)) { + throw new IllegalStateException(String.format( + "The Package for %s had a different set of targets (<targetsInPkg> - " + + "<targetsInNewlyLoadedPkg> = %s, <targetsInNewlyLoadedPkg> - <targetsInPkg> = %s) when " + + "loaded normally during execution of the current test than it did when loaded via " + + "BazelPackageLoader (done automatically by the BazelPackageBuilderHelperForTesting " + + "hook). This either means: (i) Skyframe package loading semantics have diverged from " + + "BazelPackageLoader semantics (ii) The test in question is doing something that " + + "confuses BazelPackageBuilderHelperForTesting.", + pkgId, + Sets.difference(targetsInPkg, targetsInNewlyLoadedPkg), + Sets.difference(targetsInNewlyLoadedPkg, targetsInPkg))); + } + } +} diff --git a/src/test/java/com/google/devtools/build/lib/testutil/PackageFactoryBuilderFactoryForBazelUnitTests.java b/src/test/java/com/google/devtools/build/lib/testutil/PackageFactoryBuilderFactoryForBazelUnitTests.java new file mode 100644 index 0000000000..04e8e03710 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/testutil/PackageFactoryBuilderFactoryForBazelUnitTests.java @@ -0,0 +1,56 @@ +// Copyright 2016 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.testutil; + +import com.google.devtools.build.lib.packages.Package; +import com.google.devtools.build.lib.packages.PackageFactory; +import com.google.devtools.build.lib.packages.RuleClassProvider; +import com.google.devtools.build.lib.skyframe.packages.PackageFactoryBuilderWithSkyframeForTesting; +import com.google.devtools.build.lib.vfs.FileSystem; + +/** + * A {@link PackageFactory.BuilderFactoryForTesting} implementation that injects a + * {@link BazelPackageBuilderHelperForTesting}. + */ +class PackageFactoryBuilderFactoryForBazelUnitTests + extends PackageFactory.BuilderFactoryForTesting { + static final PackageFactoryBuilderFactoryForBazelUnitTests INSTANCE = + new PackageFactoryBuilderFactoryForBazelUnitTests(); + + private PackageFactoryBuilderFactoryForBazelUnitTests() { + } + + @Override + public PackageFactoryBuilderWithSkyframeForTesting builder() { + return new PackageFactoryBuilderForBazelUnitTests(); + } + + private static class PackageFactoryBuilderForBazelUnitTests + extends PackageFactoryBuilderWithSkyframeForTesting { + @Override + public PackageFactory build(RuleClassProvider ruleClassProvider, FileSystem fs) { + Package.Builder.Helper packageBuilderHelperForTesting = doChecksForTesting + ? new BazelPackageBuilderHelperForTesting(ruleClassProvider) + : Package.Builder.DefaultHelper.INSTANCE; + return new PackageFactory( + ruleClassProvider, + platformSetRegexps, + attributeContainerFactory, + environmentExtensions, + version, + packageBuilderHelperForTesting); + } + } +} + diff --git a/src/test/java/com/google/devtools/build/lib/testutil/PackageFactoryFactoryForBazelUnitTests.java b/src/test/java/com/google/devtools/build/lib/testutil/PackageFactoryFactoryForBazelUnitTests.java deleted file mode 100644 index 43dea593ab..0000000000 --- a/src/test/java/com/google/devtools/build/lib/testutil/PackageFactoryFactoryForBazelUnitTests.java +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2016 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.testutil; - -import com.google.common.base.Function; -import com.google.devtools.build.lib.packages.AttributeContainer; -import com.google.devtools.build.lib.packages.Package; -import com.google.devtools.build.lib.packages.PackageFactory; -import com.google.devtools.build.lib.packages.PackageFactory.EnvironmentExtension; -import com.google.devtools.build.lib.packages.RuleClass; -import com.google.devtools.build.lib.packages.RuleClassProvider; -import com.google.devtools.build.lib.vfs.FileSystem; - -import java.util.Map; - -class PackageFactoryFactoryForBazelUnitTests extends PackageFactory.FactoryForTesting { - static final PackageFactoryFactoryForBazelUnitTests INSTANCE = - new PackageFactoryFactoryForBazelUnitTests(); - - private PackageFactoryFactoryForBazelUnitTests() { - } - - @Override - protected PackageFactory create( - RuleClassProvider ruleClassProvider, - Map<String, String> platformSetRegexps, - Function<RuleClass, AttributeContainer> attributeContainerFactory, - Iterable<EnvironmentExtension> environmentExtensions, - String version, - FileSystem fs) { - return new PackageFactory( - ruleClassProvider, - platformSetRegexps, - attributeContainerFactory, - environmentExtensions, - version, - Package.Builder.DefaultHelper.INSTANCE); - } -} - diff --git a/src/test/java/com/google/devtools/build/lib/testutil/TestConstants.java b/src/test/java/com/google/devtools/build/lib/testutil/TestConstants.java index 52cf1bac99..480a5d3cac 100644 --- a/src/test/java/com/google/devtools/build/lib/testutil/TestConstants.java +++ b/src/test/java/com/google/devtools/build/lib/testutil/TestConstants.java @@ -15,7 +15,7 @@ package com.google.devtools.build.lib.testutil; import com.google.common.collect.ImmutableList; -import com.google.devtools.build.lib.packages.PackageFactory; +import com.google.devtools.build.lib.packages.PackageFactory.BuilderFactoryForTesting; import com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.InvocationPolicy; /** @@ -83,6 +83,6 @@ public class TestConstants { public static final InvocationPolicy TEST_INVOCATION_POLICY = InvocationPolicy.getDefaultInstance(); - public static final PackageFactory.FactoryForTesting PACKAGE_FACTORY_FACTORY_FOR_TESTING = - PackageFactoryFactoryForBazelUnitTests.INSTANCE; + public static final BuilderFactoryForTesting PACKAGE_FACTORY_BUILDER_FACTORY_FOR_TESTING = + PackageFactoryBuilderFactoryForBazelUnitTests.INSTANCE; } |