diff options
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules')
43 files changed, 48 insertions, 2979 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java index 96d6acea15..3c938067c1 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java @@ -31,6 +31,7 @@ import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; import com.google.devtools.build.lib.analysis.TransitiveInfoProvider; import com.google.devtools.build.lib.analysis.actions.FileWriteAction; import com.google.devtools.build.lib.analysis.actions.SpawnAction; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector.InstrumentationSpec; import com.google.devtools.build.lib.collect.IterablesChain; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; @@ -65,7 +66,6 @@ import com.google.devtools.build.lib.rules.java.JavaSourceJarsProvider; import com.google.devtools.build.lib.rules.java.JavaTargetAttributes; import com.google.devtools.build.lib.rules.java.JavaUtil; import com.google.devtools.build.lib.rules.java.proto.GeneratedExtensionRegistryProvider; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector.InstrumentationSpec; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.FileType; import com.google.devtools.build.lib.util.Preconditions; diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDevice.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDevice.java index a0bb51dd50..355416e790 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDevice.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDevice.java @@ -40,10 +40,10 @@ import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction; import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.Substitution; import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.Template; +import com.google.devtools.build.lib.analysis.test.ExecutionInfoProvider; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.packages.TargetUtils; -import com.google.devtools.build.lib.rules.test.ExecutionInfoProvider; import com.google.devtools.build.lib.syntax.Type; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidInstrumentationTest.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidInstrumentationTest.java index 67181df4b5..6f29f80cb6 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidInstrumentationTest.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidInstrumentationTest.java @@ -32,9 +32,9 @@ import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction; import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.Substitution; import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.Template; +import com.google.devtools.build.lib.analysis.test.ExecutionInfoProvider; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; -import com.google.devtools.build.lib.rules.test.ExecutionInfoProvider; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.ResourceFileLoader; import java.io.IOException; diff --git a/src/main/java/com/google/devtools/build/lib/rules/core/CoreRules.java b/src/main/java/com/google/devtools/build/lib/rules/core/CoreRules.java index 2ab890d20a..3cebd9850c 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/core/CoreRules.java +++ b/src/main/java/com/google/devtools/build/lib/rules/core/CoreRules.java @@ -20,8 +20,8 @@ import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider.Builde import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider.RuleSet; import com.google.devtools.build.lib.analysis.featurecontrol.FeaturePolicyLoader; import com.google.devtools.build.lib.analysis.featurecontrol.FeaturePolicyOptions; +import com.google.devtools.build.lib.analysis.test.TestConfiguration; import com.google.devtools.build.lib.rules.config.ConfigFeatureFlag; -import com.google.devtools.build.lib.rules.test.TestConfiguration; /** A set of basic rules - Bazel won't work correctly without these. */ public final class CoreRules implements RuleSet { diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java index 8941279af5..0abbb09715 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java @@ -34,6 +34,8 @@ import com.google.devtools.build.lib.analysis.RunfilesSupport; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; import com.google.devtools.build.lib.analysis.actions.FileWriteAction; import com.google.devtools.build.lib.analysis.actions.SpawnAction; +import com.google.devtools.build.lib.analysis.test.ExecutionInfoProvider; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.collect.nestedset.Order; @@ -45,8 +47,6 @@ import com.google.devtools.build.lib.rules.cpp.CppConfiguration.DynamicMode; import com.google.devtools.build.lib.rules.cpp.Link.LinkStaticness; import com.google.devtools.build.lib.rules.cpp.Link.LinkTargetType; import com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink; -import com.google.devtools.build.lib.rules.test.ExecutionInfoProvider; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.OsUtils; import com.google.devtools.build.lib.util.Preconditions; diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java index 694c273ae2..80ee0abb60 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java @@ -29,6 +29,10 @@ import com.google.devtools.build.lib.analysis.MakeVariableSupplier; import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector.LocalMetadataCollector; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProviderImpl; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.cmdline.PackageIdentifier; import com.google.devtools.build.lib.collect.nestedset.NestedSet; @@ -41,10 +45,6 @@ import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfig import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables; import com.google.devtools.build.lib.rules.cpp.CppConfiguration.DynamicMode; import com.google.devtools.build.lib.rules.cpp.CppConfiguration.HeadersCheckingMode; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector.LocalMetadataCollector; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesProviderImpl; import com.google.devtools.build.lib.shell.ShellUtils; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.FileType; diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcIncLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcIncLibrary.java index 0076925f60..5aa36bf919 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcIncLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcIncLibrary.java @@ -25,8 +25,8 @@ import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.Runfiles; import com.google.devtools.build.lib.analysis.RunfilesProvider; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java index 019675e087..b846dfaef3 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java @@ -26,6 +26,7 @@ import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.Runfiles; import com.google.devtools.build.lib.analysis.RunfilesProvider; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; @@ -36,7 +37,6 @@ import com.google.devtools.build.lib.packages.RawAttributeMapper; import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration; import com.google.devtools.build.lib.rules.cpp.Link.LinkTargetType; import com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.FileTypeSet; import com.google.devtools.build.lib.vfs.PathFragment; diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java index 4ce49c74b4..36b32b3f48 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java @@ -25,6 +25,7 @@ import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.packages.BuildType; import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException; @@ -39,7 +40,6 @@ import com.google.devtools.build.lib.rules.cpp.Link.LinkTargetType; import com.google.devtools.build.lib.rules.cpp.Link.Picness; import com.google.devtools.build.lib.rules.cpp.Link.Staticness; import com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector; import com.google.devtools.build.lib.util.FileType; import com.google.devtools.build.lib.util.Preconditions; import com.google.devtools.build.lib.vfs.FileSystemUtils; diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java index b4678a4603..5f109739b4 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java @@ -35,6 +35,7 @@ import com.google.devtools.build.lib.analysis.LanguageDependentFragment.LibraryL import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.analysis.config.PatchTransition; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector.InstrumentationSpec; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.packages.Attribute; import com.google.devtools.build.lib.packages.Attribute.LateBoundLabel; @@ -46,7 +47,6 @@ import com.google.devtools.build.lib.packages.RuleTransitionFactory; import com.google.devtools.build.lib.rules.cpp.transitions.DisableLipoTransition; import com.google.devtools.build.lib.rules.cpp.transitions.EnableLipoTransition; import com.google.devtools.build.lib.rules.cpp.transitions.LipoContextCollectorTransition; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector.InstrumentationSpec; import com.google.devtools.build.lib.util.FileTypeSet; import com.google.devtools.build.lib.util.OsUtils; diff --git a/src/main/java/com/google/devtools/build/lib/rules/filegroup/Filegroup.java b/src/main/java/com/google/devtools/build/lib/rules/filegroup/Filegroup.java index bfe32c4bab..1f9448bc82 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/filegroup/Filegroup.java +++ b/src/main/java/com/google/devtools/build/lib/rules/filegroup/Filegroup.java @@ -30,11 +30,11 @@ import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.Runfiles; import com.google.devtools.build.lib.analysis.RunfilesProvider; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector.InstrumentationSpec; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector.InstrumentationSpec; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.FileTypeSet; import com.google.devtools.build.lib.vfs.PathFragment; diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java index 8448232fdc..9838cb7654 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java @@ -35,6 +35,10 @@ import com.google.devtools.build.lib.analysis.RunfilesProvider; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; import com.google.devtools.build.lib.analysis.TransitiveInfoProvider; import com.google.devtools.build.lib.analysis.Util; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector.InstrumentationSpec; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector.LocalMetadataCollector; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; @@ -47,10 +51,6 @@ import com.google.devtools.build.lib.packages.TargetUtils; import com.google.devtools.build.lib.rules.cpp.CppCompilationContext; import com.google.devtools.build.lib.rules.cpp.LinkerInput; import com.google.devtools.build.lib.rules.java.JavaCompilationArgs.ClasspathType; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector.InstrumentationSpec; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector.LocalMetadataCollector; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.FileTypeSet; import com.google.devtools.build.lib.util.Pair; diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java index ab4c1db39b..3b75c46039 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java @@ -33,11 +33,11 @@ import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.analysis.config.BuildConfiguration.StrictDepsMode; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.packages.AttributeMap; import com.google.devtools.build.lib.rules.java.JavaConfiguration.JavaClasspathMode; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.FileType; import com.google.devtools.build.lib.util.Preconditions; diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java index 6858c7cec6..947d8e2cbc 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java @@ -34,6 +34,8 @@ import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.rules.apple.AppleCommandLineOptions.AppleBitcodeMode; @@ -44,8 +46,6 @@ import com.google.devtools.build.lib.rules.cpp.CcToolchainProvider; import com.google.devtools.build.lib.rules.objc.AppleDebugOutputsProvider.OutputType; import com.google.devtools.build.lib.rules.objc.CompilationSupport.ExtraLinkArgs; import com.google.devtools.build.lib.rules.objc.MultiArchBinarySupport.DependencySpecificConfiguration; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider; import java.util.Map; import java.util.TreeMap; diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java b/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java index 8a91ca9293..bc4277b4e4 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java @@ -28,6 +28,7 @@ import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder; import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.RunfilesSupport; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.rules.apple.AppleConfiguration; @@ -38,7 +39,6 @@ import com.google.devtools.build.lib.rules.objc.CompilationSupport.ExtraLinkArgs import com.google.devtools.build.lib.rules.objc.ObjcCommon.ResourceAttributes; import com.google.devtools.build.lib.rules.objc.ReleaseBundlingSupport.LinkedBinary; import com.google.devtools.build.lib.rules.proto.ProtoSourcesProvider; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider; import java.util.Map; import java.util.TreeMap; diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java index 4df8db9732..76c67e9c6c 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java @@ -59,6 +59,10 @@ import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; import com.google.devtools.build.lib.analysis.actions.ParameterFileWriteAction; import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector.InstrumentationSpec; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector.LocalMetadataCollector; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.collect.nestedset.Order; @@ -79,10 +83,6 @@ import com.google.devtools.build.lib.rules.cpp.CppModuleMapAction; import com.google.devtools.build.lib.rules.cpp.FdoSupportProvider; import com.google.devtools.build.lib.rules.cpp.UmbrellaHeaderAction; import com.google.devtools.build.lib.rules.objc.ObjcCommandLineOptions.ObjcCrosstoolMode; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector.InstrumentationSpec; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector.LocalMetadataCollector; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.util.FileTypeSet; import com.google.devtools.build.lib.util.Pair; import com.google.devtools.build.lib.vfs.FileSystemUtils; diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java index 779748e981..a8e5af0962 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java @@ -31,6 +31,8 @@ import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.Runfiles; import com.google.devtools.build.lib.analysis.RunfilesProvider; import com.google.devtools.build.lib.analysis.RunfilesSupport; +import com.google.devtools.build.lib.analysis.test.ExecutionInfoProvider; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.rules.apple.AppleConfiguration; @@ -40,8 +42,6 @@ import com.google.devtools.build.lib.rules.objc.CompilationSupport.ExtraLinkArgs import com.google.devtools.build.lib.rules.objc.ObjcCommon.ResourceAttributes; import com.google.devtools.build.lib.rules.objc.ReleaseBundlingSupport.LinkedBinary; import com.google.devtools.build.lib.rules.proto.ProtoSourcesProvider; -import com.google.devtools.build.lib.rules.test.ExecutionInfoProvider; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.syntax.Type; /** Implementation for {@code ios_test} rule in Bazel. */ diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java index 0eb712b283..63cfcd61d0 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java @@ -19,11 +19,11 @@ import com.google.devtools.build.lib.analysis.ConfiguredTarget; import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory; import com.google.devtools.build.lib.analysis.RuleContext; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.rules.cpp.CcLinkParamsProvider; import com.google.devtools.build.lib.rules.objc.ObjcCommon.ResourceAttributes; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.syntax.Type; import java.util.Map; import java.util.TreeMap; diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java index d86a3eb8a4..1a5ca6d5e1 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java @@ -21,14 +21,14 @@ import com.google.devtools.build.lib.analysis.ConfiguredTarget; import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder; import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory; import com.google.devtools.build.lib.analysis.RuleContext; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.rules.apple.AppleConfiguration; import com.google.devtools.build.lib.rules.apple.ApplePlatform.PlatformType; import com.google.devtools.build.lib.rules.apple.DottedVersion; import com.google.devtools.build.lib.rules.apple.XcodeConfig; import com.google.devtools.build.lib.rules.objc.ReleaseBundlingSupport.LinkedBinary; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider; import javax.annotation.Nullable; /** diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java index d6d57f9cbb..ffb4e1c232 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java @@ -28,14 +28,14 @@ import com.google.devtools.build.lib.analysis.Runfiles.Builder; import com.google.devtools.build.lib.analysis.RunfilesProvider; import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction; import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.Substitution; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider; +import com.google.devtools.build.lib.analysis.test.TestEnvironmentProvider; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.packages.Info; import com.google.devtools.build.lib.rules.apple.AppleConfiguration; import com.google.devtools.build.lib.rules.apple.DottedVersion; import com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.SimulatorRule; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider; -import com.google.devtools.build.lib.rules.test.TestEnvironmentProvider; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.FileType; import com.google.devtools.build.lib.util.Preconditions; diff --git a/src/main/java/com/google/devtools/build/lib/rules/python/PyCommon.java b/src/main/java/com/google/devtools/build/lib/rules/python/PyCommon.java index b0cafa85f6..f9d543f4bc 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/python/PyCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/python/PyCommon.java @@ -32,6 +32,9 @@ import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; import com.google.devtools.build.lib.analysis.Util; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector.LocalMetadataCollector; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; @@ -42,9 +45,6 @@ import com.google.devtools.build.lib.packages.Info; import com.google.devtools.build.lib.packages.NativeProvider; import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.rules.cpp.CppFileTypes; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector.LocalMetadataCollector; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.EvalUtils; import com.google.devtools.build.lib.syntax.SkylarkNestedSet; diff --git a/src/main/java/com/google/devtools/build/lib/rules/python/PythonSemantics.java b/src/main/java/com/google/devtools/build/lib/rules/python/PythonSemantics.java index a87ef4e049..df73f88e58 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/python/PythonSemantics.java +++ b/src/main/java/com/google/devtools/build/lib/rules/python/PythonSemantics.java @@ -17,9 +17,9 @@ import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.Runfiles; import com.google.devtools.build.lib.analysis.RunfilesSupport; +import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector.InstrumentationSpec; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.rules.cpp.CcLinkParamsStore; -import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector.InstrumentationSpec; import com.google.devtools.build.lib.vfs.PathFragment; import java.util.Collection; import java.util.List; diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/BaselineCoverageAction.java b/src/main/java/com/google/devtools/build/lib/rules/test/BaselineCoverageAction.java deleted file mode 100644 index 8137555ca2..0000000000 --- a/src/main/java/com/google/devtools/build/lib/rules/test/BaselineCoverageAction.java +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2014 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.rules.test; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import com.google.common.eventbus.EventBus; -import com.google.devtools.build.lib.actions.ActionExecutionContext; -import com.google.devtools.build.lib.actions.ActionOwner; -import com.google.devtools.build.lib.actions.Artifact; -import com.google.devtools.build.lib.actions.NotifyOnActionCacheHit; -import com.google.devtools.build.lib.analysis.RuleContext; -import com.google.devtools.build.lib.analysis.actions.AbstractFileWriteAction; -import com.google.devtools.build.lib.cmdline.Label; -import com.google.devtools.build.lib.collect.nestedset.NestedSet; -import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; -import com.google.devtools.build.lib.collect.nestedset.Order; -import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; -import com.google.devtools.build.lib.util.Fingerprint; -import com.google.devtools.build.lib.vfs.PathFragment; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.List; - -/** - * Generates baseline (empty) coverage for the given non-test target. - */ -@VisibleForTesting -@Immutable -public final class BaselineCoverageAction extends AbstractFileWriteAction - implements NotifyOnActionCacheHit { - private final NestedSet<Artifact> instrumentedFiles; - - private BaselineCoverageAction( - ActionOwner owner, NestedSet<Artifact> instrumentedFiles, Artifact output) { - super(owner, ImmutableList.<Artifact>of(), output, false); - this.instrumentedFiles = instrumentedFiles; - } - - @Override - public String getMnemonic() { - return "BaselineCoverage"; - } - - @Override - public String computeKey() { - return new Fingerprint() - .addStrings(getInstrumentedFilePathStrings()) - .hexDigestAndReset(); - } - - private Iterable<String> getInstrumentedFilePathStrings() { - List<String> result = new ArrayList<>(); - for (Artifact instrumentedFile : instrumentedFiles) { - result.add(instrumentedFile.getExecPathString()); - } - return result; - } - - @Override - public DeterministicWriter newDeterministicWriter(ActionExecutionContext ctx) { - return new DeterministicWriter() { - @Override - public void writeOutputFile(OutputStream out) throws IOException { - PrintWriter writer = new PrintWriter(out); - for (String execPath : getInstrumentedFilePathStrings()) { - writer.write("SF:" + execPath + "\n"); - writer.write("end_of_record\n"); - } - writer.flush(); - } - }; - } - - @Override - protected void afterWrite(ActionExecutionContext actionExecutionContext) { - notifyAboutBaselineCoverage(actionExecutionContext.getEventBus()); - } - - @Override - public void actionCacheHit(ActionCachedContext context) { - notifyAboutBaselineCoverage(context.getEventBus()); - } - - /** - * Notify interested parties about new baseline coverage data. - */ - private void notifyAboutBaselineCoverage(EventBus eventBus) { - Artifact output = Iterables.getOnlyElement(getOutputs()); - String ownerString = Label.print(getOwner().getLabel()); - eventBus.post(new BaselineCoverageResult(output, ownerString)); - } - - /** - * Returns collection of baseline coverage artifacts associated with the given target. - * Will always return 0 or 1 elements. - */ - static NestedSet<Artifact> create( - RuleContext ruleContext, NestedSet<Artifact> instrumentedFiles) { - // Baseline coverage artifacts will still go into "testlogs" directory. - Artifact coverageData = ruleContext.getPackageRelativeArtifact( - PathFragment.create(ruleContext.getTarget().getName()).getChild("baseline_coverage.dat"), - ruleContext.getConfiguration().getTestLogsDirectory( - ruleContext.getRule().getRepository())); - ruleContext.registerAction(new BaselineCoverageAction( - ruleContext.getActionOwner(), instrumentedFiles, coverageData)); - return NestedSetBuilder.create(Order.STABLE_ORDER, coverageData); - } -} diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/BaselineCoverageResult.java b/src/main/java/com/google/devtools/build/lib/rules/test/BaselineCoverageResult.java deleted file mode 100644 index 33c1247f7d..0000000000 --- a/src/main/java/com/google/devtools/build/lib/rules/test/BaselineCoverageResult.java +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2014 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.rules.test; - -import com.google.devtools.build.lib.actions.Artifact; -import com.google.devtools.build.lib.util.Preconditions; - -/** - * This event is used to notify about a successfully built baseline coverage artifact. - */ -public class BaselineCoverageResult { - - private final Artifact baselineCoverageData; - private final String ownerString; - - public BaselineCoverageResult(Artifact baselineCoverageData, String ownerString) { - this.baselineCoverageData = Preconditions.checkNotNull(baselineCoverageData); - this.ownerString = Preconditions.checkNotNull(ownerString); - } - - public Artifact getArtifact() { - return baselineCoverageData; - } - - public String getOwnerString() { - return ownerString; - } -} diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/CoverageReportActionFactory.java b/src/main/java/com/google/devtools/build/lib/rules/test/CoverageReportActionFactory.java deleted file mode 100644 index 0cd02d2700..0000000000 --- a/src/main/java/com/google/devtools/build/lib/rules/test/CoverageReportActionFactory.java +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2014 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.rules.test; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.devtools.build.lib.actions.ActionAnalysisMetadata; -import com.google.devtools.build.lib.actions.Artifact; -import com.google.devtools.build.lib.actions.ArtifactFactory; -import com.google.devtools.build.lib.actions.ArtifactOwner; -import com.google.devtools.build.lib.analysis.BlazeDirectories; -import com.google.devtools.build.lib.analysis.ConfiguredTarget; -import com.google.devtools.build.lib.events.EventHandler; -import java.util.Collection; -import javax.annotation.Nullable; - -/** - * A factory class to create coverage report actions. - */ -public interface CoverageReportActionFactory { - /** - * Wraps the necessary actions to get a coverage report as well as the final output artifacts. - * The lcovWriteAction creates a file containing a set of lcov files. This file is used as an - * input artifact for coverageReportAction. We are only interested about the output artifacts from - * coverageReportAction. - */ - public static final class CoverageReportActionsWrapper { - private final ActionAnalysisMetadata lcovWriteAction; - private final ActionAnalysisMetadata coverageReportAction; - - public CoverageReportActionsWrapper ( - ActionAnalysisMetadata lcovWriteAction, ActionAnalysisMetadata coverageReportAction) { - this.lcovWriteAction = lcovWriteAction; - this.coverageReportAction = coverageReportAction; - } - - public ImmutableList<ActionAnalysisMetadata> getActions() { - return ImmutableList.of(lcovWriteAction, coverageReportAction); - } - - public ImmutableSet<Artifact> getCoverageOutputs() { - return coverageReportAction.getOutputs(); - } - } - - /** - * Returns a CoverageReportActionsWrapper. May return null if it's not necessary to create - * such Actions based on the input parameters and some other data available to the factory - * implementation, such as command line options. - */ - @Nullable - CoverageReportActionsWrapper createCoverageReportActionsWrapper( - EventHandler eventHandler, - BlazeDirectories directories, - Collection<ConfiguredTarget> targetsToTest, - Iterable<Artifact> baselineCoverageArtifacts, - ArtifactFactory artifactFactory, ArtifactOwner artifactOwner); -} diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/ExclusiveTestStrategy.java b/src/main/java/com/google/devtools/build/lib/rules/test/ExclusiveTestStrategy.java index 8ee7f3efb7..8932660a56 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/test/ExclusiveTestStrategy.java +++ b/src/main/java/com/google/devtools/build/lib/rules/test/ExclusiveTestStrategy.java @@ -16,9 +16,11 @@ package com.google.devtools.build.lib.rules.test; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ExecException; import com.google.devtools.build.lib.actions.ExecutionStrategy; +import com.google.devtools.build.lib.analysis.test.TestActionContext; +import com.google.devtools.build.lib.analysis.test.TestResult; +import com.google.devtools.build.lib.analysis.test.TestRunnerAction; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.view.test.TestStatus.TestResultData; - import java.io.IOException; /** diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/ExecutionInfoProvider.java b/src/main/java/com/google/devtools/build/lib/rules/test/ExecutionInfoProvider.java deleted file mode 100644 index 4f1e40a84c..0000000000 --- a/src/main/java/com/google/devtools/build/lib/rules/test/ExecutionInfoProvider.java +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2014 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.rules.test; - -import com.google.common.collect.ImmutableMap; -import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; -import com.google.devtools.build.lib.packages.Info; -import com.google.devtools.build.lib.packages.NativeProvider; -import java.util.Map; - -/** - * This provider can be implemented by rules which need special environments to run in (especially - * tests). - */ -@Immutable -public final class ExecutionInfoProvider extends Info { - - /** Skylark constructor and identifier for ExecutionInfoProvider. */ - public static final NativeProvider<ExecutionInfoProvider> SKYLARK_CONSTRUCTOR = - new NativeProvider<ExecutionInfoProvider>(ExecutionInfoProvider.class, "ExecutionInfo") {}; - - private final ImmutableMap<String, String> executionInfo; - - public ExecutionInfoProvider(Map<String, String> requirements) { - super(SKYLARK_CONSTRUCTOR, ImmutableMap.<String, Object>of("requirements", requirements)); - this.executionInfo = ImmutableMap.copyOf(requirements); - } - - /** - * Returns a map to indicate special execution requirements, such as hardware - * platforms, etc. Rule tags, such as "requires-XXX", may also be added - * as keys to the map. - */ - public ImmutableMap<String, String> getExecutionInfo() { - return executionInfo; - } -} diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/InstrumentedFileManifestAction.java b/src/main/java/com/google/devtools/build/lib/rules/test/InstrumentedFileManifestAction.java deleted file mode 100644 index a2c5432bb8..0000000000 --- a/src/main/java/com/google/devtools/build/lib/rules/test/InstrumentedFileManifestAction.java +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright 2014 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.rules.test; - -import static java.nio.charset.StandardCharsets.ISO_8859_1; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Function; -import com.google.common.collect.Iterables; -import com.google.devtools.build.lib.actions.ActionExecutionContext; -import com.google.devtools.build.lib.actions.ActionOwner; -import com.google.devtools.build.lib.actions.Artifact; -import com.google.devtools.build.lib.analysis.RuleContext; -import com.google.devtools.build.lib.analysis.actions.AbstractFileWriteAction; -import com.google.devtools.build.lib.collect.nestedset.NestedSet; -import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; -import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; -import com.google.devtools.build.lib.util.Fingerprint; -import com.google.devtools.build.lib.util.Preconditions; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.util.Arrays; - -/** - * Writes a manifest of instrumented source and metadata files. - */ -@Immutable -final class InstrumentedFileManifestAction extends AbstractFileWriteAction { - private static final Function<Artifact, String> TO_EXEC_PATH = new Function<Artifact, String>() { - @Override - public String apply(Artifact artifact) { - return artifact.getExecPathString(); - } - }; - - private static final String GUID = "3833f0a3-7ea1-4d9f-b96f-66eff4c922b0"; - - private final NestedSet<Artifact> files; - - @VisibleForTesting - InstrumentedFileManifestAction(ActionOwner owner, NestedSet<Artifact> files, Artifact output) { - super(owner, /*inputs=*/Artifact.NO_ARTIFACTS, output, /*makeExecutable=*/false); - this.files = files; - } - - @Override - public DeterministicWriter newDeterministicWriter(ActionExecutionContext ctx) { - return new DeterministicWriter() { - @Override - public void writeOutputFile(OutputStream out) throws IOException { - // Sort the exec paths before writing them out. - String[] fileNames = - Iterables.toArray(Iterables.transform(files, TO_EXEC_PATH), String.class); - Arrays.sort(fileNames); - try (Writer writer = new OutputStreamWriter(out, ISO_8859_1)) { - for (String name : fileNames) { - writer.write(name); - writer.write('\n'); - } - } - } - }; - } - - @Override - protected String computeKey() { - Fingerprint f = new Fingerprint(); - f.addString(GUID); - // Not sorting here is probably cheaper, though it might lead to unnecessary re-execution. - f.addStrings(Iterables.transform(files, TO_EXEC_PATH)); - return f.hexDigestAndReset(); - } - - /** - * Instantiates instrumented file manifest for the given target. - * - * @param ruleContext context of the executable configured target - * @param additionalSourceFiles additional instrumented source files, as - * collected by the {@link InstrumentedFilesCollector} - * @param metadataFiles *.gcno/*.em files collected by the {@link InstrumentedFilesCollector} - * @return instrumented file manifest artifact - */ - public static Artifact getInstrumentedFileManifest(RuleContext ruleContext, - NestedSet<Artifact> additionalSourceFiles, NestedSet<Artifact> metadataFiles) { - // Instrumented manifest makes sense only for rules with binary output. - Preconditions.checkState(ruleContext.getRule().hasBinaryOutput()); - Artifact instrumentedFileManifest = ruleContext.getBinArtifact( - ruleContext.getTarget().getName() + ".instrumented_files"); - - NestedSet<Artifact> inputs = NestedSetBuilder.<Artifact>stableOrder() - .addTransitive(additionalSourceFiles) - .addTransitive(metadataFiles) - .build(); - ruleContext.registerAction(new InstrumentedFileManifestAction( - ruleContext.getActionOwner(), inputs, instrumentedFileManifest)); - - return instrumentedFileManifest; - } -} diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/InstrumentedFilesCollector.java b/src/main/java/com/google/devtools/build/lib/rules/test/InstrumentedFilesCollector.java deleted file mode 100644 index c2ba279bf3..0000000000 --- a/src/main/java/com/google/devtools/build/lib/rules/test/InstrumentedFilesCollector.java +++ /dev/null @@ -1,309 +0,0 @@ -// Copyright 2014 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.rules.test; - -import com.google.common.collect.ImmutableList; -import com.google.devtools.build.lib.actions.ActionAnalysisMetadata; -import com.google.devtools.build.lib.actions.Artifact; -import com.google.devtools.build.lib.analysis.AnalysisEnvironment; -import com.google.devtools.build.lib.analysis.FileProvider; -import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; -import com.google.devtools.build.lib.analysis.RuleContext; -import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; -import com.google.devtools.build.lib.analysis.config.BuildConfiguration; -import com.google.devtools.build.lib.cmdline.Label; -import com.google.devtools.build.lib.collect.nestedset.NestedSet; -import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; -import com.google.devtools.build.lib.collect.nestedset.Order; -import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; -import com.google.devtools.build.lib.packages.BuildType; -import com.google.devtools.build.lib.util.FileType; -import com.google.devtools.build.lib.util.FileTypeSet; -import com.google.devtools.build.lib.util.Pair; -import com.google.devtools.build.lib.util.Preconditions; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * A helper class for collecting instrumented files and metadata for a target. - */ -public final class InstrumentedFilesCollector { - - /** - * Forwards any instrumented files from the given target's dependencies (as defined in - * {@code dependencyAttributes}) for further export. No files from this target are considered - * instrumented. - * - * @return instrumented file provider of all dependencies in {@code dependencyAttributes} - */ - public static InstrumentedFilesProvider forward( - RuleContext ruleContext, String... dependencyAttributes) { - return collect( - ruleContext, - new InstrumentationSpec(FileTypeSet.NO_FILE).withDependencyAttributes(dependencyAttributes), - null, - null); - } - - public static InstrumentedFilesProvider collect( - RuleContext ruleContext, - InstrumentationSpec spec, - LocalMetadataCollector localMetadataCollector, - Iterable<Artifact> rootFiles) { - return collect(ruleContext, spec, localMetadataCollector, rootFiles, - NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER), - NestedSetBuilder.<Pair<String, String>>emptySet(Order.STABLE_ORDER), - false); - } - - /** - * Collects transitive instrumentation data from dependencies, collects local source files from - * dependencies, collects local metadata files by traversing the action graph of the current - * configured target, collect rule-specific instrumentation support file sand creates baseline - * coverage actions for the transitive closure of source files (if - * <code>withBaselineCoverage</code> is true). - */ - public static InstrumentedFilesProvider collect( - RuleContext ruleContext, - InstrumentationSpec spec, - LocalMetadataCollector localMetadataCollector, - Iterable<Artifact> rootFiles, - NestedSet<Artifact> coverageSupportFiles, - NestedSet<Pair<String, String>> coverageEnvironment, - boolean withBaselineCoverage) { - Preconditions.checkNotNull(ruleContext); - Preconditions.checkNotNull(spec); - - if (!ruleContext.getConfiguration().isCodeCoverageEnabled()) { - return InstrumentedFilesProviderImpl.EMPTY; - } - - NestedSetBuilder<Artifact> instrumentedFilesBuilder = NestedSetBuilder.stableOrder(); - NestedSetBuilder<Artifact> metadataFilesBuilder = NestedSetBuilder.stableOrder(); - NestedSetBuilder<Artifact> baselineCoverageInstrumentedFilesBuilder = - NestedSetBuilder.stableOrder(); - NestedSetBuilder<Artifact> coverageSupportFilesBuilder = - NestedSetBuilder.<Artifact>stableOrder() - .addTransitive(coverageSupportFiles); - NestedSetBuilder<Pair<String, String>> coverageEnvironmentBuilder = - NestedSetBuilder.<Pair<String, String>>compileOrder() - .addTransitive(coverageEnvironment); - - - // Transitive instrumentation data. - for (TransitiveInfoCollection dep : - getAllPrerequisites(ruleContext, spec.dependencyAttributes)) { - InstrumentedFilesProvider provider = dep.getProvider(InstrumentedFilesProvider.class); - if (provider != null) { - instrumentedFilesBuilder.addTransitive(provider.getInstrumentedFiles()); - metadataFilesBuilder.addTransitive(provider.getInstrumentationMetadataFiles()); - baselineCoverageInstrumentedFilesBuilder.addTransitive( - provider.getBaselineCoverageInstrumentedFiles()); - coverageSupportFilesBuilder.addTransitive(provider.getCoverageSupportFiles()); - coverageEnvironmentBuilder.addTransitive(provider.getCoverageEnvironment()); - } - } - - // Local sources. - NestedSet<Artifact> localSources = NestedSetBuilder.emptySet(Order.STABLE_ORDER); - if (shouldIncludeLocalSources(ruleContext)) { - NestedSetBuilder<Artifact> localSourcesBuilder = NestedSetBuilder.stableOrder(); - for (TransitiveInfoCollection dep : - getAllPrerequisites(ruleContext, spec.sourceAttributes)) { - if (!spec.splitLists && dep.getProvider(InstrumentedFilesProvider.class) != null) { - continue; - } - for (Artifact artifact : dep.getProvider(FileProvider.class).getFilesToBuild()) { - if (artifact.isSourceArtifact() && - spec.instrumentedFileTypes.matches(artifact.getFilename())) { - localSourcesBuilder.add(artifact); - } - } - } - localSources = localSourcesBuilder.build(); - } - instrumentedFilesBuilder.addTransitive(localSources); - if (withBaselineCoverage) { - // Also add the local sources to the baseline coverage instrumented sources, if the current - // rule supports baseline coverage. - // TODO(ulfjack): Generate a local baseline coverage action, and then merge at the leaves. - baselineCoverageInstrumentedFilesBuilder.addTransitive(localSources); - } - - // Local metadata files. - if (localMetadataCollector != null) { - localMetadataCollector.collectMetadataArtifacts(rootFiles, - ruleContext.getAnalysisEnvironment(), metadataFilesBuilder); - } - - // Baseline coverage actions. - NestedSet<Artifact> baselineCoverageFiles = baselineCoverageInstrumentedFilesBuilder.build(); - - // Create one baseline coverage action per target, but for the transitive closure of files. - NestedSet<Artifact> baselineCoverageArtifacts = - BaselineCoverageAction.create(ruleContext, baselineCoverageFiles); - return new InstrumentedFilesProviderImpl( - instrumentedFilesBuilder.build(), - metadataFilesBuilder.build(), - baselineCoverageFiles, - baselineCoverageArtifacts, - coverageSupportFilesBuilder.build(), - coverageEnvironmentBuilder.build()); - } - - /** - * Return whether the sources of the rule in {@code ruleContext} should be instrumented based on - * the --instrumentation_filter and --instrument_test_targets config settings. - */ - public static boolean shouldIncludeLocalSources(RuleContext ruleContext) { - return shouldIncludeLocalSources(ruleContext.getConfiguration(), ruleContext.getLabel(), - ruleContext.isTestTarget()); - } - - /** - * Return whether the sources included by {@code target} (a {@link TransitiveInfoCollection} - * representing a rule) should be instrumented according the --instrumentation_filter and - * --instrument_test_targets settings in {@code config}. - */ - public static boolean shouldIncludeLocalSources(BuildConfiguration config, - TransitiveInfoCollection target) { - return shouldIncludeLocalSources(config, target.getLabel(), - target.getProvider(TestProvider.class) != null); - } - - private static boolean shouldIncludeLocalSources(BuildConfiguration config, Label label, - boolean isTest) { - return ((config.shouldInstrumentTestTargets() || !isTest) - && config.getInstrumentationFilter().isIncluded(label.toString())); - } - - /** - * The set of file types and attributes to visit to collect instrumented files for a certain rule - * type. The class is intentionally immutable, so that a single instance is sufficient for all - * rules of the same type (and in some cases all rules of related types, such as all {@code foo_*} - * rules). - */ - @Immutable - public static final class InstrumentationSpec { - private final FileTypeSet instrumentedFileTypes; - - /** The list of attributes which should be checked for sources. */ - private final Collection<String> sourceAttributes; - - /** The list of attributes from which to collect transitive coverage information. */ - private final Collection<String> dependencyAttributes; - - /** Whether the source and dependency lists are separate. */ - private final boolean splitLists; - - public InstrumentationSpec(FileTypeSet instrumentedFileTypes, - String... instrumentedAttributes) { - this(instrumentedFileTypes, ImmutableList.copyOf(instrumentedAttributes)); - } - - public InstrumentationSpec(FileTypeSet instrumentedFileTypes, - Collection<String> instrumentedAttributes) { - this(instrumentedFileTypes, instrumentedAttributes, instrumentedAttributes, false); - } - - private InstrumentationSpec(FileTypeSet instrumentedFileTypes, - Collection<String> instrumentedSourceAttributes, - Collection<String> instrumentedDependencyAttributes, - boolean splitLists) { - this.instrumentedFileTypes = instrumentedFileTypes; - this.sourceAttributes = ImmutableList.copyOf(instrumentedSourceAttributes); - this.dependencyAttributes = - ImmutableList.copyOf(instrumentedDependencyAttributes); - this.splitLists = splitLists; - } - - /** - * Returns a new instrumentation spec with the given attribute names replacing the ones - * stored in this object. - */ - public InstrumentationSpec withAttributes(String... instrumentedAttributes) { - return new InstrumentationSpec(instrumentedFileTypes, instrumentedAttributes); - } - - /** - * Returns a new instrumentation spec with the given attribute names replacing the ones - * stored in this object. - */ - public InstrumentationSpec withSourceAttributes(String... instrumentedAttributes) { - return new InstrumentationSpec(instrumentedFileTypes, - ImmutableList.copyOf(instrumentedAttributes), dependencyAttributes, true); - } - - /** - * Returns a new instrumentation spec with the given attribute names replacing the ones - * stored in this object. - */ - public InstrumentationSpec withDependencyAttributes(String... instrumentedAttributes) { - return new InstrumentationSpec(instrumentedFileTypes, - sourceAttributes, ImmutableList.copyOf(instrumentedAttributes), true); - } - } - - /** - * The implementation for the local metadata collection. The intention is that implementations - * recurse over the locally (i.e., for that configured target) created actions and collect - * metadata files. - */ - public abstract static class LocalMetadataCollector { - /** - * Recursively runs over the local actions and add metadata files to the metadataFilesBuilder. - */ - public abstract void collectMetadataArtifacts( - Iterable<Artifact> artifacts, AnalysisEnvironment analysisEnvironment, - NestedSetBuilder<Artifact> metadataFilesBuilder); - - /** - * Adds action output of a particular type to metadata files. - * - * <p>Only adds the first output that matches the given file type. - * - * @param metadataFilesBuilder builder to collect metadata files - * @param action the action whose outputs to scan - * @param fileType the filetype of outputs which should be collected - */ - protected void addOutputs(NestedSetBuilder<Artifact> metadataFilesBuilder, - ActionAnalysisMetadata action, FileType fileType) { - for (Artifact output : action.getOutputs()) { - if (fileType.matches(output.getFilename())) { - metadataFilesBuilder.add(output); - break; - } - } - } - } - - /** - * An explicit constant for a {@link LocalMetadataCollector} that doesn't collect anything. - */ - public static final LocalMetadataCollector NO_METADATA_COLLECTOR = null; - - private static Iterable<TransitiveInfoCollection> getAllPrerequisites( - RuleContext ruleContext, Collection<String> attributeNames) { - List<TransitiveInfoCollection> prerequisites = new ArrayList<>(); - for (String attr : attributeNames) { - if (ruleContext.getRule().isAttrDefined(attr, BuildType.LABEL_LIST) || - ruleContext.getRule().isAttrDefined(attr, BuildType.LABEL)) { - prerequisites.addAll(ruleContext.getPrerequisites(attr, Mode.DONT_CHECK)); - } - } - return prerequisites; - } -} diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/InstrumentedFilesProvider.java b/src/main/java/com/google/devtools/build/lib/rules/test/InstrumentedFilesProvider.java deleted file mode 100644 index 82f787ec34..0000000000 --- a/src/main/java/com/google/devtools/build/lib/rules/test/InstrumentedFilesProvider.java +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2014 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.rules.test; - -import com.google.devtools.build.lib.actions.Artifact; -import com.google.devtools.build.lib.analysis.TransitiveInfoProvider; -import com.google.devtools.build.lib.collect.nestedset.NestedSet; -import com.google.devtools.build.lib.util.Pair; - -/** - * A provider of instrumented file sources and instrumentation metadata. - */ -public interface InstrumentedFilesProvider extends TransitiveInfoProvider { - - /** - * The transitive closure of instrumented source files. - */ - NestedSet<Artifact> getInstrumentedFiles(); - - /** - * Returns a collection of instrumentation metadata files. - */ - NestedSet<Artifact> getInstrumentationMetadataFiles(); - - /** - * The transitive closure of instrumented source files for which baseline coverage should be - * generated. In general, this is a subset of the instrumented source files: it only contains - * instrumented source files from rules that support baseline coverage. - */ - NestedSet<Artifact> getBaselineCoverageInstrumentedFiles(); - - /** - * The output artifact of the baseline coverage action; this is only ever a single artifact, which - * contains baseline coverage for the entire transitive closure of source files. - */ - // TODO(ulfjack): Change this to a single Artifact. Also change how it's generated. It's better to - // generate actions such that each action only covers the source files of a single rule, in - // particular because baseline coverage is language-specific (it requires a parser for the - // specific language), and we don't want to depend on all language parsers from any single rule. - NestedSet<Artifact> getBaselineCoverageArtifacts(); - - /** - * Extra files that are needed on the inputs of test actions for coverage collection to happen, - * for example, {@code gcov}. - * - * <p>They aren't mentioned in the instrumented files manifest. - */ - NestedSet<Artifact> getCoverageSupportFiles(); - - /** - * Environment variables that need to be set for tests collecting code coverage. - */ - NestedSet<Pair<String, String>> getCoverageEnvironment(); -} diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/InstrumentedFilesProviderImpl.java b/src/main/java/com/google/devtools/build/lib/rules/test/InstrumentedFilesProviderImpl.java deleted file mode 100644 index 9be20a24ad..0000000000 --- a/src/main/java/com/google/devtools/build/lib/rules/test/InstrumentedFilesProviderImpl.java +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2014 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.rules.test; - -import com.google.devtools.build.lib.actions.Artifact; -import com.google.devtools.build.lib.collect.nestedset.NestedSet; -import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; -import com.google.devtools.build.lib.collect.nestedset.Order; -import com.google.devtools.build.lib.util.Pair; - -/** - * An implementation class for the InstrumentedFilesProvider interface. - */ -public final class InstrumentedFilesProviderImpl implements InstrumentedFilesProvider { - public static final InstrumentedFilesProvider EMPTY = - new InstrumentedFilesProviderImpl( - NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER), - NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER), - NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER), - NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER), - NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER), - NestedSetBuilder.<Pair<String, String>>emptySet(Order.COMPILE_ORDER)); - - private final NestedSet<Artifact> instrumentedFiles; - private final NestedSet<Artifact> instrumentationMetadataFiles; - private final NestedSet<Artifact> baselineCoverageFiles; - private final NestedSet<Artifact> baselineCoverageArtifacts; - private final NestedSet<Artifact> coverageSupportFiles; - private final NestedSet<Pair<String, String>> coverageEnvironment; - - public InstrumentedFilesProviderImpl( - NestedSet<Artifact> instrumentedFiles, - NestedSet<Artifact> instrumentationMetadataFiles, - NestedSet<Artifact> baselineCoverageFiles, - NestedSet<Artifact> baselineCoverageArtifacts, - NestedSet<Artifact> coverageSupportFiles, - NestedSet<Pair<String, String>> coverageEnvironment) { - this.instrumentedFiles = instrumentedFiles; - this.instrumentationMetadataFiles = instrumentationMetadataFiles; - this.baselineCoverageFiles = baselineCoverageFiles; - this.baselineCoverageArtifacts = baselineCoverageArtifacts; - this.coverageSupportFiles = coverageSupportFiles; - this.coverageEnvironment = coverageEnvironment; - } - - @Override - public NestedSet<Artifact> getInstrumentedFiles() { - return instrumentedFiles; - } - - @Override - public NestedSet<Artifact> getInstrumentationMetadataFiles() { - return instrumentationMetadataFiles; - } - - @Override - public NestedSet<Artifact> getBaselineCoverageInstrumentedFiles() { - return baselineCoverageFiles; - } - - @Override - public NestedSet<Artifact> getBaselineCoverageArtifacts() { - return baselineCoverageArtifacts; - } - - @Override - public NestedSet<Artifact> getCoverageSupportFiles() { - return coverageSupportFiles; - } - - @Override - public NestedSet<Pair<String, String>> getCoverageEnvironment() { - return coverageEnvironment; - } -} diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/SkylarkTestingModule.java b/src/main/java/com/google/devtools/build/lib/rules/test/SkylarkTestingModule.java index e9d7cdd6ee..81ce5183ae 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/test/SkylarkTestingModule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/test/SkylarkTestingModule.java @@ -13,6 +13,8 @@ // limitations under the License. package com.google.devtools.build.lib.rules.test; +import com.google.devtools.build.lib.analysis.test.ExecutionInfoProvider; +import com.google.devtools.build.lib.analysis.test.TestEnvironmentProvider; import com.google.devtools.build.lib.skylarkinterface.Param; import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature; diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/TestActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/test/TestActionBuilder.java deleted file mode 100644 index 8b3b1f8aef..0000000000 --- a/src/main/java/com/google/devtools/build/lib/rules/test/TestActionBuilder.java +++ /dev/null @@ -1,327 +0,0 @@ -// Copyright 2014 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.rules.test; - -import static com.google.devtools.build.lib.packages.BuildType.LABEL; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; -import com.google.devtools.build.lib.actions.Artifact; -import com.google.devtools.build.lib.actions.Root; -import com.google.devtools.build.lib.analysis.AnalysisEnvironment; -import com.google.devtools.build.lib.analysis.FileProvider; -import com.google.devtools.build.lib.analysis.FilesToRunProvider; -import com.google.devtools.build.lib.analysis.PrerequisiteArtifacts; -import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; -import com.google.devtools.build.lib.analysis.RuleContext; -import com.google.devtools.build.lib.analysis.RunfilesSupport; -import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; -import com.google.devtools.build.lib.analysis.config.BuildConfiguration; -import com.google.devtools.build.lib.collect.nestedset.NestedSet; -import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; -import com.google.devtools.build.lib.collect.nestedset.Order; -import com.google.devtools.build.lib.packages.TargetUtils; -import com.google.devtools.build.lib.packages.TestSize; -import com.google.devtools.build.lib.packages.TestTimeout; -import com.google.devtools.build.lib.rules.test.TestProvider.TestParams; -import com.google.devtools.build.lib.syntax.Type; -import com.google.devtools.build.lib.util.Pair; -import com.google.devtools.build.lib.util.Preconditions; -import com.google.devtools.build.lib.vfs.PathFragment; -import com.google.devtools.common.options.EnumConverter; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; -import javax.annotation.Nullable; - -/** - * Helper class to create test actions. - */ -public final class TestActionBuilder { - - private final RuleContext ruleContext; - private RunfilesSupport runfilesSupport; - private Artifact executable; - private ExecutionInfoProvider executionRequirements; - private InstrumentedFilesProvider instrumentedFiles; - private int explicitShardCount; - private Map<String, String> extraEnv; - - public TestActionBuilder(RuleContext ruleContext) { - this.ruleContext = ruleContext; - this.extraEnv = new TreeMap<>(); - } - - /** - * Creates the test actions and artifacts using the previously set parameters. - * - * @return ordered list of test status artifacts - */ - public TestParams build() { - Preconditions.checkState(runfilesSupport != null); - boolean local = TargetUtils.isTestRuleAndRunsLocally(ruleContext.getRule()); - TestShardingStrategy strategy = - ruleContext.getConfiguration().getFragment(TestConfiguration.class).testShardingStrategy(); - int shards = strategy.getNumberOfShards( - local, explicitShardCount, isTestShardingCompliant(), - TestSize.getTestSize(ruleContext.getRule())); - Preconditions.checkState(shards >= 0); - return createTestAction(shards); - } - - private boolean isTestShardingCompliant() { - // See if it has a data dependency on the special target - // //tools:test_sharding_compliant. Test runners add this dependency - // to show they speak the sharding protocol. - // There are certain cases where this heuristic may fail, giving - // a "false positive" (where we shard the test even though the - // it isn't supported). We may want to refine this logic, but - // heuristically sharding is currently experimental. Also, we do detect - // false-positive cases and return an error. - return runfilesSupport.getRunfilesSymlinkNames().contains( - PathFragment.create("tools/test_sharding_compliant")); - } - - /** - * Set the runfiles and executable to be run as a test. - */ - public TestActionBuilder setFilesToRunProvider(FilesToRunProvider provider) { - Preconditions.checkNotNull(provider.getRunfilesSupport()); - Preconditions.checkNotNull(provider.getExecutable()); - this.runfilesSupport = provider.getRunfilesSupport(); - this.executable = provider.getExecutable(); - return this; - } - - public TestActionBuilder setInstrumentedFiles( - @Nullable InstrumentedFilesProvider instrumentedFiles) { - this.instrumentedFiles = instrumentedFiles; - return this; - } - - public TestActionBuilder setExecutionRequirements( - @Nullable ExecutionInfoProvider executionRequirements) { - this.executionRequirements = executionRequirements; - return this; - } - - public TestActionBuilder addExtraEnv(Map<String, String> extraEnv) { - this.extraEnv.putAll(extraEnv); - return this; - } - - /** - * Set the explicit shard count. Note that this may be overridden by the sharding strategy. - */ - public TestActionBuilder setShardCount(int explicitShardCount) { - this.explicitShardCount = explicitShardCount; - return this; - } - - /** - * Converts to {@link TestActionBuilder.TestShardingStrategy}. - */ - public static class ShardingStrategyConverter extends EnumConverter<TestShardingStrategy> { - public ShardingStrategyConverter() { - super(TestShardingStrategy.class, "test sharding strategy"); - } - } - - /** - * A strategy for running the same tests in many processes. - */ - public static enum TestShardingStrategy { - EXPLICIT { - @Override public int getNumberOfShards(boolean isLocal, int shardCountFromAttr, - boolean testShardingCompliant, TestSize testSize) { - return Math.max(shardCountFromAttr, 0); - } - }, - - EXPERIMENTAL_HEURISTIC { - @Override public int getNumberOfShards(boolean isLocal, int shardCountFromAttr, - boolean testShardingCompliant, TestSize testSize) { - if (shardCountFromAttr >= 0) { - return shardCountFromAttr; - } - if (isLocal || !testShardingCompliant) { - return 0; - } - return testSize.getDefaultShards(); - } - }, - - DISABLED { - @Override public int getNumberOfShards(boolean isLocal, int shardCountFromAttr, - boolean testShardingCompliant, TestSize testSize) { - return 0; - } - }; - - public abstract int getNumberOfShards(boolean isLocal, int shardCountFromAttr, - boolean testShardingCompliant, TestSize testSize); - } - - /** - * Creates a test action and artifacts for the given rule. The test action will - * use the specified executable and runfiles. - * - * @return ordered list of test artifacts, one per action. These are used to drive - * execution in Skyframe, and by AggregatingTestListener and - * TestResultAnalyzer to keep track of completed and pending test runs. - */ - private TestParams createTestAction(int shards) { - PathFragment targetName = PathFragment.create(ruleContext.getLabel().getName()); - BuildConfiguration config = ruleContext.getConfiguration(); - AnalysisEnvironment env = ruleContext.getAnalysisEnvironment(); - Root root = config.getTestLogsDirectory(ruleContext.getRule().getRepository()); - - NestedSetBuilder<Artifact> inputsBuilder = NestedSetBuilder.stableOrder(); - inputsBuilder.addTransitive( - NestedSetBuilder.create(Order.STABLE_ORDER, runfilesSupport.getRunfilesMiddleman())); - NestedSet<Artifact> testRuntime = PrerequisiteArtifacts.nestedSet( - ruleContext, "$test_runtime", Mode.HOST); - inputsBuilder.addTransitive(testRuntime); - TestTargetProperties testProperties = new TestTargetProperties( - ruleContext, executionRequirements); - - // If the test rule does not provide InstrumentedFilesProvider, there's not much that we can do. - final boolean collectCodeCoverage = config.isCodeCoverageEnabled() - && instrumentedFiles != null; - - TreeMap<String, String> extraTestEnv = new TreeMap<>(); - - TestTargetExecutionSettings executionSettings; - if (collectCodeCoverage) { - inputsBuilder.addTransitive(instrumentedFiles.getCoverageSupportFiles()); - // Add instrumented file manifest artifact to the list of inputs. This file will contain - // exec paths of all source files that should be included into the code coverage output. - NestedSet<Artifact> metadataFiles = instrumentedFiles.getInstrumentationMetadataFiles(); - inputsBuilder.addTransitive(metadataFiles); - inputsBuilder.addTransitive(PrerequisiteArtifacts.nestedSet( - ruleContext, "$coverage_support", Mode.DONT_CHECK)); - // We don't add this attribute to non-supported test target - if (ruleContext.isAttrDefined("$lcov_merger", LABEL)) { - TransitiveInfoCollection lcovMerger = - ruleContext.getPrerequisite("$lcov_merger", Mode.TARGET); - FilesToRunProvider lcovFilesToRun = lcovMerger.getProvider(FilesToRunProvider.class); - if (lcovFilesToRun != null) { - extraTestEnv.put("LCOV_MERGER", lcovFilesToRun.getExecutable().getExecPathString()); - inputsBuilder.addTransitive(lcovFilesToRun.getFilesToRun()); - } else { - NestedSet<Artifact> filesToBuild = - lcovMerger.getProvider(FileProvider.class).getFilesToBuild(); - - if (Iterables.size(filesToBuild) == 1) { - Artifact lcovMergerArtifact = Iterables.getOnlyElement(filesToBuild); - extraTestEnv.put("LCOV_MERGER", lcovMergerArtifact.getExecPathString()); - inputsBuilder.add(lcovMergerArtifact); - } else { - ruleContext.attributeError("$lcov_merger", - "the LCOV merger should be either an executable or a single artifact"); - } - } - } - - Artifact instrumentedFileManifest = - InstrumentedFileManifestAction.getInstrumentedFileManifest(ruleContext, - instrumentedFiles.getInstrumentedFiles(), metadataFiles); - executionSettings = new TestTargetExecutionSettings(ruleContext, runfilesSupport, - executable, instrumentedFileManifest, shards); - inputsBuilder.add(instrumentedFileManifest); - // TODO(ulfjack): Is this even ever set? If yes, does this cost us a lot of memory? - for (Pair<String, String> coverageEnvEntry : instrumentedFiles.getCoverageEnvironment()) { - extraTestEnv.put(coverageEnvEntry.getFirst(), coverageEnvEntry.getSecond()); - } - } else { - executionSettings = new TestTargetExecutionSettings(ruleContext, runfilesSupport, - executable, null, shards); - } - - extraTestEnv.putAll(extraEnv); - - if (config.getRunUnder() != null) { - Artifact runUnderExecutable = executionSettings.getRunUnderExecutable(); - if (runUnderExecutable != null) { - inputsBuilder.add(runUnderExecutable); - } - } - - int runsPerTest = - config.getFragment(TestConfiguration.class).getRunsPerTestForLabel(ruleContext.getLabel()); - - Iterable<Artifact> inputs = inputsBuilder.build(); - int shardRuns = (shards > 0 ? shards : 1); - List<Artifact> results = Lists.newArrayListWithCapacity(runsPerTest * shardRuns); - ImmutableList.Builder<Artifact> coverageArtifacts = ImmutableList.builder(); - - boolean useTestRunner = false; - if (ruleContext.attributes().has("use_testrunner", Type.BOOLEAN)) { - useTestRunner = ruleContext.attributes().get("use_testrunner", Type.BOOLEAN); - } - - for (int run = 0; run < runsPerTest; run++) { - // Use a 1-based index for user friendliness. - String testRunDir = - runsPerTest > 1 ? String.format("run_%d_of_%d", run + 1, runsPerTest) : ""; - for (int shard = 0; shard < shardRuns; shard++) { - String shardRunDir = - (shardRuns > 1 ? String.format("shard_%d_of_%d", shard + 1, shards) : ""); - if (testRunDir.isEmpty()) { - shardRunDir = shardRunDir.isEmpty() ? "" : shardRunDir + PathFragment.SEPARATOR_CHAR; - } else { - testRunDir += PathFragment.SEPARATOR_CHAR; - shardRunDir = shardRunDir.isEmpty() ? testRunDir : shardRunDir + "_" + testRunDir; - } - Artifact testLog = - ruleContext.getPackageRelativeArtifact( - targetName.getRelative(shardRunDir + "test.log"), root); - Artifact cacheStatus = - ruleContext.getPackageRelativeArtifact( - targetName.getRelative(shardRunDir + "test.cache_status"), root); - - Artifact coverageArtifact = null; - if (collectCodeCoverage) { - coverageArtifact = ruleContext.getPackageRelativeArtifact( - targetName.getRelative(shardRunDir + "coverage.dat"), root); - coverageArtifacts.add(coverageArtifact); - } - - env.registerAction(new TestRunnerAction( - ruleContext.getActionOwner(), inputs, testRuntime, - testLog, cacheStatus, - coverageArtifact, - testProperties, extraTestEnv, executionSettings, - shard, run, config, ruleContext.getWorkspaceName(), - useTestRunner)); - results.add(cacheStatus); - } - } - // TODO(bazel-team): Passing the reportGenerator to every TestParams is a bit strange. - Artifact reportGenerator = null; - if (config.isCodeCoverageEnabled()) { - // It's not enough to add this if the rule has coverage enabled because the command line may - // contain rules with baseline coverage but no test rules that have coverage enabled, and in - // that case, we still need the report generator. - reportGenerator = ruleContext.getPrerequisiteArtifact( - "$coverage_report_generator", Mode.HOST); - } - - return new TestParams(runsPerTest, shards, TestTimeout.getTestTimeout(ruleContext.getRule()), - ruleContext.getRule().getRuleClass(), ImmutableList.copyOf(results), - coverageArtifacts.build(), reportGenerator); - } -} diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/TestActionContext.java b/src/main/java/com/google/devtools/build/lib/rules/test/TestActionContext.java deleted file mode 100644 index 000bbc549e..0000000000 --- a/src/main/java/com/google/devtools/build/lib/rules/test/TestActionContext.java +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2014 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.rules.test; - -import com.google.devtools.build.lib.actions.ActionContext; -import com.google.devtools.build.lib.actions.ActionExecutionContext; -import com.google.devtools.build.lib.actions.ExecException; -import com.google.devtools.build.lib.vfs.Path; -import com.google.devtools.build.lib.view.test.TestStatus.TestResultData; -import java.io.IOException; - -/** - * A context for the execution of test actions ({@link TestRunnerAction}). - */ -public interface TestActionContext extends ActionContext { - - /** - * Executes the test command, directing standard out / err to {@code outErr}. The status of - * the test should be communicated by posting a {@link TestResult} object to the eventbus. - */ - void exec(TestRunnerAction action, - ActionExecutionContext actionExecutionContext) throws ExecException, InterruptedException; - - /** - * Creates a cached test result. - */ - TestResult newCachedTestResult(Path execRoot, TestRunnerAction action, TestResultData cached) - throws IOException; -} diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/TestAttempt.java b/src/main/java/com/google/devtools/build/lib/rules/test/TestAttempt.java index fbccaeaf09..287773b178 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/test/TestAttempt.java +++ b/src/main/java/com/google/devtools/build/lib/rules/test/TestAttempt.java @@ -15,6 +15,8 @@ package com.google.devtools.build.lib.rules.test; import com.google.common.collect.ImmutableList; +import com.google.devtools.build.lib.analysis.test.TestResult; +import com.google.devtools.build.lib.analysis.test.TestRunnerAction; import com.google.devtools.build.lib.buildeventstream.BuildEvent; import com.google.devtools.build.lib.buildeventstream.BuildEventConverters; import com.google.devtools.build.lib.buildeventstream.BuildEventId; diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/TestConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/test/TestConfiguration.java deleted file mode 100644 index b7bb2f5b12..0000000000 --- a/src/main/java/com/google/devtools/build/lib/rules/test/TestConfiguration.java +++ /dev/null @@ -1,204 +0,0 @@ -// 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.rules.test; - -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; -import com.google.devtools.build.lib.analysis.config.BuildConfiguration.Fragment; -import com.google.devtools.build.lib.analysis.config.BuildConfiguration.RunsPerTestConverter; -import com.google.devtools.build.lib.analysis.config.BuildOptions; -import com.google.devtools.build.lib.analysis.config.ConfigurationEnvironment; -import com.google.devtools.build.lib.analysis.config.ConfigurationFragmentFactory; -import com.google.devtools.build.lib.analysis.config.FragmentOptions; -import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException; -import com.google.devtools.build.lib.analysis.config.PerLabelOptions; -import com.google.devtools.build.lib.cmdline.Label; -import com.google.devtools.build.lib.events.Event; -import com.google.devtools.build.lib.events.EventHandler; -import com.google.devtools.common.options.Option; -import com.google.devtools.common.options.OptionDocumentationCategory; -import com.google.devtools.common.options.OptionEffectTag; -import com.google.devtools.common.options.TriState; -import java.util.List; - -/** Test-related options. */ -public class TestConfiguration extends Fragment { - - /** Command-line options. */ - public static class TestOptions extends FragmentOptions { - @Option( - name = "test_filter", - allowMultiple = false, - defaultValue = "null", - category = "testing", - documentationCategory = OptionDocumentationCategory.UNCATEGORIZED, - effectTags = {OptionEffectTag.UNKNOWN}, - help = - "Specifies a filter to forward to the test framework. Used to limit " - + "the tests run. Note that this does not affect which targets are built." - ) - public String testFilter; - - @Option( - name = "cache_test_results", - defaultValue = "auto", - category = "testing", - abbrev = 't', // it's useful to toggle this on/off quickly - documentationCategory = OptionDocumentationCategory.UNCATEGORIZED, - effectTags = {OptionEffectTag.UNKNOWN}, - help = - "If set to 'auto', Bazel reruns a test if and only if: " - + "(1) Bazel detects changes in the test or its dependencies, " - + "(2) the test is marked as external, " - + "(3) multiple test runs were requested with --runs_per_test, or" - + "(4) the test previously failed. " - + "If set to 'yes', Bazel caches all test results except for tests marked as " - + "external. If set to 'no', Bazel does not cache any test results." - ) - public TriState cacheTestResults; - - @Deprecated - @Option( - name = "test_result_expiration", - defaultValue = "-1", // No expiration by defualt. - category = "testing", - documentationCategory = OptionDocumentationCategory.UNCATEGORIZED, - effectTags = {OptionEffectTag.UNKNOWN}, - help = "This option is deprecated and has no effect." - ) - public int testResultExpiration; - - @Option( - name = "test_arg", - allowMultiple = true, - defaultValue = "", - category = "testing", - documentationCategory = OptionDocumentationCategory.UNCATEGORIZED, - effectTags = {OptionEffectTag.UNKNOWN}, - help = - "Specifies additional options and arguments that should be passed to the test " - + "executable. Can be used multiple times to specify several arguments. " - + "If multiple tests are executed, each of them will receive identical arguments. " - + "Used only by the 'bazel test' command." - ) - public List<String> testArguments; - - @Option( - name = "test_sharding_strategy", - defaultValue = "explicit", - category = "testing", - converter = TestActionBuilder.ShardingStrategyConverter.class, - documentationCategory = OptionDocumentationCategory.UNCATEGORIZED, - effectTags = {OptionEffectTag.UNKNOWN}, - help = - "Specify strategy for test sharding: " - + "'explicit' to only use sharding if the 'shard_count' BUILD attribute is present. " - + "'disabled' to never use test sharding. " - + "'experimental_heuristic' to enable sharding on remotely executed tests without an " - + "explicit 'shard_count' attribute which link in a supported framework. Considered " - + "experimental." - ) - public TestActionBuilder.TestShardingStrategy testShardingStrategy; - - @Option( - name = "runs_per_test", - allowMultiple = true, - defaultValue = "1", - category = "testing", - converter = RunsPerTestConverter.class, - documentationCategory = OptionDocumentationCategory.UNCATEGORIZED, - effectTags = {OptionEffectTag.UNKNOWN}, - help = - "Specifies number of times to run each test. If any of those attempts " - + "fail for any reason, the whole test would be considered failed. " - + "Normally the value specified is just an integer. Example: --runs_per_test=3 " - + "will run all tests 3 times. " - + "Alternate syntax: regex_filter@runs_per_test. Where runs_per_test stands for " - + "an integer value and regex_filter stands " - + "for a list of include and exclude regular expression patterns (Also see " - + "--instrumentation_filter). Example: " - + "--runs_per_test=//foo/.*,-//foo/bar/.*@3 runs all tests in //foo/ " - + "except those under foo/bar three times. " - + "This option can be passed multiple times. " - ) - public List<PerLabelOptions> runsPerTest; - } - - /** Configuration loader for test options */ - public static class Loader implements ConfigurationFragmentFactory { - @Override - public Fragment create(ConfigurationEnvironment env, BuildOptions buildOptions) - throws InvalidConfigurationException { - return new TestConfiguration(buildOptions.get(TestOptions.class)); - } - - @Override - public Class<? extends Fragment> creates() { - return TestConfiguration.class; - } - - @Override - public ImmutableSet<Class<? extends FragmentOptions>> requiredOptions() { - return ImmutableSet.of(TestOptions.class); - } - } - - private final TestOptions options; - - TestConfiguration(TestOptions options) { - this.options = options; - } - - @Override - public void reportInvalidOptions(EventHandler reporter, BuildOptions buildOptions) { - if (options.testShardingStrategy - == TestActionBuilder.TestShardingStrategy.EXPERIMENTAL_HEURISTIC) { - reporter.handle( - Event.warn( - "Heuristic sharding is intended as a one-off experimentation tool for determing the " - + "benefit from sharding certain tests. Please don't keep this option in your " - + ".blazerc or continuous build")); - } - } - - public String getTestFilter() { - return options.testFilter; - } - - public TriState cacheTestResults() { - return options.cacheTestResults; - } - - public List<String> getTestArguments() { - return options.testArguments; - } - - public TestActionBuilder.TestShardingStrategy testShardingStrategy() { - return options.testShardingStrategy; - } - - /** - * @return number of times the given test should run. If the test doesn't match any of the - * filters, runs it once. - */ - public int getRunsPerTestForLabel(Label label) { - for (PerLabelOptions perLabelRuns : options.runsPerTest) { - if (perLabelRuns.isIncluded(label)) { - return Integer.parseInt(Iterables.getOnlyElement(perLabelRuns.getOptions())); - } - } - return 1; - } -} diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/TestEnvironmentProvider.java b/src/main/java/com/google/devtools/build/lib/rules/test/TestEnvironmentProvider.java deleted file mode 100644 index c4fb3f6849..0000000000 --- a/src/main/java/com/google/devtools/build/lib/rules/test/TestEnvironmentProvider.java +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2015 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.rules.test; - -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableMap; -import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; -import com.google.devtools.build.lib.packages.Info; -import com.google.devtools.build.lib.packages.NativeProvider; -import java.util.Map; - -/** Provider containing any additional environment variables for use in the test action. */ -@Immutable -public final class TestEnvironmentProvider extends Info { - - /** Skylark constructor and identifier for TestEnvironmentProvider. */ - public static final NativeProvider<TestEnvironmentProvider> SKYLARK_CONSTRUCTOR = - new NativeProvider<TestEnvironmentProvider>( - TestEnvironmentProvider.class, "TestEnvironment") {}; - - private final Map<String, String> environment; - - /** Constructs a new provider with the given variable name to variable value mapping. */ - public TestEnvironmentProvider(Map<String, String> environment) { - super(SKYLARK_CONSTRUCTOR, ImmutableMap.<String, Object>of("environment", environment)); - this.environment = Preconditions.checkNotNull(environment); - } - - /** - * Returns environment variables which should be set on the test action. - */ - public Map<String, String> getEnvironment() { - return environment; - } -} diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/TestProvider.java b/src/main/java/com/google/devtools/build/lib/rules/test/TestProvider.java deleted file mode 100644 index 02dd2638c5..0000000000 --- a/src/main/java/com/google/devtools/build/lib/rules/test/TestProvider.java +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright 2014 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.rules.test; - -import com.google.common.collect.ImmutableList; -import com.google.devtools.build.lib.actions.Artifact; -import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; -import com.google.devtools.build.lib.analysis.TransitiveInfoProvider; -import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; -import com.google.devtools.build.lib.packages.TestTimeout; - -import java.util.List; - -/** - * A {@link TransitiveInfoProvider} for configured targets that implement test rules. - */ -@Immutable -public final class TestProvider implements TransitiveInfoProvider { - private final TestParams testParams; - private final ImmutableList<String> testTags; - - public TestProvider(TestParams testParams, ImmutableList<String> testTags) { - this.testParams = testParams; - this.testTags = testTags; - } - - /** - * Returns the {@link TestParams} object for the test represented by the corresponding configured - * target. - */ - public TestParams getTestParams() { - return testParams; - } - - /** - * Temporary hack to allow dependencies on test_suite targets to continue to work for the time - * being. - */ - public List<String> getTestTags() { - return testTags; - } - - /** - * Returns the test status artifacts for a specified configured target - * - * @param target the configured target. Should belong to a test rule. - * @return the test status artifacts - */ - public static ImmutableList<Artifact> getTestStatusArtifacts(TransitiveInfoCollection target) { - return target.getProvider(TestProvider.class).getTestParams().getTestStatusArtifacts(); - } - - /** - * A value class describing the properties of a test. - */ - public static class TestParams { - private final int runs; - private final int shards; - private final TestTimeout timeout; - private final String testRuleClass; - private final ImmutableList<Artifact> testStatusArtifacts; - private final ImmutableList<Artifact> coverageArtifacts; - private final Artifact coverageReportGenerator; - - /** - * Don't call this directly. Instead use {@link TestActionBuilder}. - */ - TestParams(int runs, int shards, TestTimeout timeout, String testRuleClass, - ImmutableList<Artifact> testStatusArtifacts, - ImmutableList<Artifact> coverageArtifacts, - Artifact coverageReportGenerator) { - this.runs = runs; - this.shards = shards; - this.timeout = timeout; - this.testRuleClass = testRuleClass; - this.testStatusArtifacts = testStatusArtifacts; - this.coverageArtifacts = coverageArtifacts; - this.coverageReportGenerator = coverageReportGenerator; - } - - /** - * Returns the number of times this test should be run. - */ - public int getRuns() { - return runs; - } - - /** - * Returns the number of shards for this test. - */ - public int getShards() { - return shards; - } - - /** - * Returns the timeout of this test. - */ - public TestTimeout getTimeout() { - return timeout; - } - - /** - * Returns the test rule class. - */ - public String getTestRuleClass() { - return testRuleClass; - } - - /** - * Returns a list of test status artifacts that represent serialized test status protobuffers - * produced by testing this target. - */ - public ImmutableList<Artifact> getTestStatusArtifacts() { - return testStatusArtifacts; - } - - /** - * Returns the coverageArtifacts - */ - public ImmutableList<Artifact> getCoverageArtifacts() { - return coverageArtifacts; - } - - /** - * Returns the coverage report generator tool. - */ - public Artifact getCoverageReportGenerator() { - return coverageReportGenerator; - } - } -} diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/TestResult.java b/src/main/java/com/google/devtools/build/lib/rules/test/TestResult.java deleted file mode 100644 index d0eca7f696..0000000000 --- a/src/main/java/com/google/devtools/build/lib/rules/test/TestResult.java +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright 2014 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.rules.test; - -import com.google.common.collect.ImmutableList; -import com.google.devtools.build.lib.actions.Artifact; -import com.google.devtools.build.lib.buildeventstream.TestFileNameConstants; -import com.google.devtools.build.lib.cmdline.Label; -import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; -import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; -import com.google.devtools.build.lib.rules.test.TestRunnerAction.ResolvedPaths; -import com.google.devtools.build.lib.util.Pair; -import com.google.devtools.build.lib.util.Preconditions; -import com.google.devtools.build.lib.vfs.Path; -import com.google.devtools.build.lib.view.test.TestStatus.BlazeTestStatus; -import com.google.devtools.build.lib.view.test.TestStatus.TestResultData; -import java.util.Collection; -import javax.annotation.Nullable; - -/** - * This is the event passed from the various test strategies to the {@code RecordingTestListener} - * upon test completion. - */ -@ThreadSafe -@Immutable -public class TestResult { - - private final TestRunnerAction testAction; - private final TestResultData data; - private final boolean cached; - @Nullable protected final Path execRoot; - - /** - * Construct the TestResult for the given test / status. - * - * @param testAction The test that was run. - * @param data test result protobuffer. - * @param cached true if this is a locally cached test result. - * @param execRoot The execution root in which the action was carried out; can be null, in which - * case everything depending on the execution root is ignored. - */ - public TestResult( - TestRunnerAction testAction, TestResultData data, boolean cached, @Nullable Path execRoot) { - this.testAction = Preconditions.checkNotNull(testAction); - this.data = data; - this.cached = cached; - this.execRoot = execRoot; - } - - public TestResult(TestRunnerAction testAction, TestResultData data, boolean cached) { - this(testAction, data, cached, null); - } - - public static boolean isBlazeTestStatusPassed(BlazeTestStatus status) { - return status == BlazeTestStatus.PASSED || status == BlazeTestStatus.FLAKY; - } - - /** - * @return The test action. - */ - public TestRunnerAction getTestAction() { - return testAction; - } - - /** - * @return The test log path. Note, that actual log file may no longer - * correspond to this artifact - use getActualLogPath() method if - * you need log location. - */ - public Path getTestLogPath() { - return testAction.getTestLog().getPath(); - } - - /** - * Return if result was loaded from local action cache. - */ - public final boolean isCached() { - return cached; - } - - /** - * @return Coverage data artifact, if available and null otherwise. - */ - public Path getCoverageData() { - if (data.getHasCoverage()) { - return testAction.getCoverageData().getPath(); - } - return null; - } - - /** - * @return The test status artifact. - */ - public Artifact getTestStatusArtifact() { - // these artifacts are used to keep track of the number of pending and completed tests. - return testAction.getCacheStatusArtifact(); - } - - - /** - * Gets the test name in a user-friendly format. - * Will generally include the target name and shard number, if applicable. - * - * @return The test name. - */ - public String getTestName() { - return testAction.getTestName(); - } - - /** - * @return The test label. - */ - public String getLabel() { - return Label.print(testAction.getOwner().getLabel()); - } - - /** - * @return The test shard number. - */ - public int getShardNum() { - return testAction.getShardNum(); - } - - /** - * @return Total number of test shards. 0 means - * no sharding, whereas 1 means degenerate sharding. - */ - public int getTotalShards() { - return testAction.getExecutionSettings().getTotalShards(); - } - - public TestResultData getData() { - return data; - } - - /** - * @return Collection of files created by the test, tagged by their name indicating usage (e.g., - * "test.log"). - */ - public Collection<Pair<String, Path>> getFiles() { - ImmutableList.Builder<Pair<String, Path>> builder = new ImmutableList.Builder<>(); - if (testAction.getTestLog().getPath().exists()) { - builder.add(Pair.of(TestFileNameConstants.TEST_LOG, testAction.getTestLog().getPath())); - } - if (execRoot != null) { - ResolvedPaths resolvedPaths = testAction.resolve(execRoot); - if (resolvedPaths.getXmlOutputPath().exists()) { - builder.add(Pair.of(TestFileNameConstants.TEST_XML, resolvedPaths.getXmlOutputPath())); - } - if (resolvedPaths.getSplitLogsPath().exists()) { - builder.add(Pair.of(TestFileNameConstants.SPLIT_LOGS, resolvedPaths.getSplitLogsPath())); - } - if (resolvedPaths.getTestWarningsPath().exists()) { - builder.add(Pair.of(TestFileNameConstants.TEST_WARNINGS, resolvedPaths.getSplitLogsPath())); - } - if (resolvedPaths.getUndeclaredOutputsZipPath().exists()) { - builder.add(Pair.of(TestFileNameConstants.UNDECLARED_OUTPUTS_ZIP, - resolvedPaths.getUndeclaredOutputsZipPath())); - } - if (resolvedPaths.getUndeclaredOutputsManifestPath().exists()) { - builder.add(Pair.of(TestFileNameConstants.UNDECLARED_OUTPUTS_MANIFEST, - resolvedPaths.getUndeclaredOutputsManifestPath())); - } - if (resolvedPaths.getUndeclaredOutputsAnnotationsPath().exists()) { - builder.add(Pair.of(TestFileNameConstants.UNDECLARED_OUTPUTS_ANNOTATIONS, - resolvedPaths.getUndeclaredOutputsManifestPath())); - } - if (resolvedPaths.getUnusedRunfilesLogPath().exists()) { - builder.add(Pair.of(TestFileNameConstants.UNUSED_RUNFILES_LOG, - resolvedPaths.getUnusedRunfilesLogPath())); - } - if (resolvedPaths.getInfrastructureFailureFile().exists()) { - builder.add(Pair.of(TestFileNameConstants.TEST_INFRASTRUCTURE_FAILURE, - resolvedPaths.getInfrastructureFailureFile())); - } - } - return builder.build(); - } -} diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/TestRunnerAction.java b/src/main/java/com/google/devtools/build/lib/rules/test/TestRunnerAction.java deleted file mode 100644 index c2ae57e93a..0000000000 --- a/src/main/java/com/google/devtools/build/lib/rules/test/TestRunnerAction.java +++ /dev/null @@ -1,802 +0,0 @@ -// Copyright 2014 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.rules.test; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; -import com.google.devtools.build.lib.actions.AbstractAction; -import com.google.devtools.build.lib.actions.ActionExecutionContext; -import com.google.devtools.build.lib.actions.ActionExecutionException; -import com.google.devtools.build.lib.actions.ActionInput; -import com.google.devtools.build.lib.actions.ActionInputHelper; -import com.google.devtools.build.lib.actions.ActionOwner; -import com.google.devtools.build.lib.actions.Artifact; -import com.google.devtools.build.lib.actions.ExecException; -import com.google.devtools.build.lib.actions.NotifyOnActionCacheHit; -import com.google.devtools.build.lib.actions.UserExecException; -import com.google.devtools.build.lib.analysis.RunfilesSupplierImpl; -import com.google.devtools.build.lib.analysis.config.BuildConfiguration; -import com.google.devtools.build.lib.analysis.config.RunUnder; -import com.google.devtools.build.lib.cmdline.Label; -import com.google.devtools.build.lib.collect.ImmutableIterable; -import com.google.devtools.build.lib.collect.nestedset.NestedSet; -import com.google.devtools.build.lib.util.Fingerprint; -import com.google.devtools.build.lib.util.LoggingUtil; -import com.google.devtools.build.lib.util.Preconditions; -import com.google.devtools.build.lib.vfs.FileSystemUtils; -import com.google.devtools.build.lib.vfs.Path; -import com.google.devtools.build.lib.vfs.PathFragment; -import com.google.devtools.build.lib.view.test.TestStatus.TestResultData; -import com.google.devtools.common.options.TriState; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.logging.Level; -import javax.annotation.Nullable; - -/** - * An Action representing a test with the associated environment (runfiles, - * environment variables, test result, etc). It consumes test executable and - * runfiles artifacts and produces test result and test status artifacts. - */ -// Not final so that we can mock it in tests. -public class TestRunnerAction extends AbstractAction implements NotifyOnActionCacheHit { - public static final PathFragment COVERAGE_TMP_ROOT = PathFragment.create("_coverage"); - - // Used for selecting subset of testcase / testmethods. - private static final String TEST_BRIDGE_TEST_FILTER_ENV = "TESTBRIDGE_TEST_ONLY"; - - private static final String GUID = "cc41f9d0-47a6-11e7-8726-eb6ce83a8cc8"; - - private final NestedSet<Artifact> runtime; - private final BuildConfiguration configuration; - private final TestConfiguration testConfiguration; - private final Artifact testLog; - private final Artifact cacheStatus; - private final PathFragment testWarningsPath; - private final PathFragment unusedRunfilesLogPath; - private final PathFragment splitLogsPath; - private final PathFragment splitLogsDir; - private final PathFragment undeclaredOutputsDir; - private final PathFragment undeclaredOutputsZipPath; - private final PathFragment undeclaredOutputsAnnotationsDir; - private final PathFragment undeclaredOutputsManifestPath; - private final PathFragment undeclaredOutputsAnnotationsPath; - private final PathFragment xmlOutputPath; - @Nullable - private final PathFragment testShard; - private final PathFragment testExitSafe; - private final PathFragment testStderr; - private final PathFragment testInfrastructureFailure; - private final PathFragment baseDir; - private final Artifact coverageData; - private final TestTargetProperties testProperties; - private final TestTargetExecutionSettings executionSettings; - private final int shardNum; - private final int runNumber; - private final String workspaceName; - private final boolean useTestRunner; - - // Mutable state related to test caching. Lazily initialized: null indicates unknown. - private Boolean unconditionalExecution; - - /** Any extra environment variables (and values) added by the rule that created this action. */ - private final ImmutableMap<String, String> extraTestEnv; - - /** - * The set of environment variables that are inherited from the client environment. These are - * handled explicitly by the ActionCacheChecker and so don't have to be included in the cache key. - */ - private final ImmutableIterable<String> requiredClientEnvVariables; - - private static ImmutableList<Artifact> list(Artifact... artifacts) { - ImmutableList.Builder<Artifact> builder = ImmutableList.builder(); - for (Artifact artifact : artifacts) { - if (artifact != null) { - builder.add(artifact); - } - } - return builder.build(); - } - - /** - * Create new TestRunnerAction instance. Should not be called directly. - * Use {@link TestActionBuilder} instead. - * - * @param shardNum The shard number. Must be 0 if totalShards == 0 - * (no sharding). Otherwise, must be >= 0 and < totalShards. - * @param runNumber test run number - */ - TestRunnerAction( - ActionOwner owner, - Iterable<Artifact> inputs, - NestedSet<Artifact> runtime, // Must be a subset of inputs - Artifact testLog, - Artifact cacheStatus, - Artifact coverageArtifact, - TestTargetProperties testProperties, - Map<String, String> extraTestEnv, - TestTargetExecutionSettings executionSettings, - int shardNum, - int runNumber, - BuildConfiguration configuration, - String workspaceName, - boolean useTestRunner) { - super( - owner, - inputs, - // Note that this action only cares about the runfiles, not the mapping. - new RunfilesSupplierImpl(PathFragment.create("runfiles"), executionSettings.getRunfiles()), - list(testLog, cacheStatus, coverageArtifact)); - this.runtime = runtime; - this.configuration = Preconditions.checkNotNull(configuration); - this.testConfiguration = - Preconditions.checkNotNull(configuration.getFragment(TestConfiguration.class)); - this.testLog = testLog; - this.cacheStatus = cacheStatus; - this.coverageData = coverageArtifact; - this.shardNum = shardNum; - this.runNumber = runNumber; - this.testProperties = Preconditions.checkNotNull(testProperties); - this.executionSettings = Preconditions.checkNotNull(executionSettings); - - this.baseDir = cacheStatus.getExecPath().getParentDirectory(); - - int totalShards = executionSettings.getTotalShards(); - Preconditions.checkState((totalShards == 0 && shardNum == 0) || - (totalShards > 0 && 0 <= shardNum && shardNum < totalShards)); - this.testExitSafe = baseDir.getChild("test.exited_prematurely"); - // testShard Path should be set only if sharding is enabled. - this.testShard = totalShards > 1 - ? baseDir.getChild("test.shard") - : null; - this.xmlOutputPath = baseDir.getChild("test.xml"); - this.testWarningsPath = baseDir.getChild("test.warnings"); - this.unusedRunfilesLogPath = baseDir.getChild("test.unused_runfiles_log"); - this.testStderr = baseDir.getChild("test.err"); - this.splitLogsDir = baseDir.getChild("test.raw_splitlogs"); - // See note in {@link #getSplitLogsPath} on the choice of file name. - this.splitLogsPath = splitLogsDir.getChild("test.splitlogs"); - this.undeclaredOutputsDir = baseDir.getChild("test.outputs"); - this.undeclaredOutputsZipPath = undeclaredOutputsDir.getChild("outputs.zip"); - this.undeclaredOutputsAnnotationsDir = baseDir.getChild("test.outputs_manifest"); - this.undeclaredOutputsManifestPath = undeclaredOutputsAnnotationsDir.getChild("MANIFEST"); - this.undeclaredOutputsAnnotationsPath = undeclaredOutputsAnnotationsDir.getChild("ANNOTATIONS"); - this.testInfrastructureFailure = baseDir.getChild("test.infrastructure_failure"); - this.workspaceName = workspaceName; - this.useTestRunner = useTestRunner; - - this.extraTestEnv = ImmutableMap.copyOf(extraTestEnv); - this.requiredClientEnvVariables = - ImmutableIterable.from(Iterables.concat( - configuration.getActionEnvironment().getInheritedEnv(), - configuration.getTestActionEnvironment().getInheritedEnv())); - } - - public BuildConfiguration getConfiguration() { - return configuration; - } - - public final PathFragment getBaseDir() { - return baseDir; - } - - @Override - public boolean showsOutputUnconditionally() { - return true; - } - - public List<ActionInput> getSpawnOutputs() { - final List<ActionInput> outputs = new ArrayList<>(); - outputs.add(ActionInputHelper.fromPath(getXmlOutputPath())); - outputs.add(ActionInputHelper.fromPath(getExitSafeFile())); - if (isSharded()) { - outputs.add(ActionInputHelper.fromPath(getTestShard())); - } - outputs.add(ActionInputHelper.fromPath(getTestWarningsPath())); - outputs.add(ActionInputHelper.fromPath(getSplitLogsPath())); - outputs.add(ActionInputHelper.fromPath(getUnusedRunfilesLogPath())); - outputs.add(ActionInputHelper.fromPath(getInfrastructureFailureFile())); - outputs.add(ActionInputHelper.fromPath(getUndeclaredOutputsZipPath())); - outputs.add(ActionInputHelper.fromPath(getUndeclaredOutputsManifestPath())); - outputs.add(ActionInputHelper.fromPath(getUndeclaredOutputsAnnotationsPath())); - if (isCoverageMode()) { - outputs.add(getCoverageData()); - } - return outputs; - } - - @Override - protected String computeKey() { - Fingerprint f = new Fingerprint(); - f.addString(GUID); - f.addStrings(executionSettings.getArgs().arguments()); - f.addString(executionSettings.getTestFilter() == null ? "" : executionSettings.getTestFilter()); - RunUnder runUnder = executionSettings.getRunUnder(); - f.addString(runUnder == null ? "" : runUnder.getValue()); - f.addStringMap(extraTestEnv); - // TODO(ulfjack): It might be better for performance to hash the action and test envs in config, - // and only add a hash here. - configuration.getActionEnvironment().addTo(f); - configuration.getTestActionEnvironment().addTo(f); - // The 'requiredClientEnvVariables' are handled by Skyframe and don't need to be added here. - f.addString(testProperties.getSize().toString()); - f.addString(testProperties.getTimeout().toString()); - f.addStrings(testProperties.getTags()); - f.addInt(testProperties.isLocal() ? 1 : 0); - f.addInt(shardNum); - f.addInt(executionSettings.getTotalShards()); - f.addInt(runNumber); - f.addInt(testConfiguration.getRunsPerTestForLabel(getOwner().getLabel())); - f.addInt(configuration.isCodeCoverageEnabled() ? 1 : 0); - return f.hexDigestAndReset(); - } - - @Override - public boolean executeUnconditionally() { - // Note: isVolatile must return true if executeUnconditionally can ever return true - // for this instance. - if (unconditionalExecution == null) { - unconditionalExecution = computeExecuteUnconditionallyFromTestStatus(); - } - return unconditionalExecution; - } - - @Override - public boolean isVolatile() { - return true; - } - - /** - * Saves cache status to disk. - */ - public void saveCacheStatus(TestResultData data) throws IOException { - try (OutputStream out = cacheStatus.getPath().getOutputStream()) { - data.writeTo(out); - } - } - - /** - * Returns the cache from disk, or null if the file doesn't exist or if there is an error. - */ - @Nullable - private TestResultData readCacheStatus() { - try (InputStream in = cacheStatus.getPath().getInputStream()) { - return TestResultData.parseFrom(in); - } catch (IOException expected) { - return null; - } - } - - private boolean computeExecuteUnconditionallyFromTestStatus() { - return !canBeCached( - testConfiguration.cacheTestResults(), - readCacheStatus(), - testProperties.isExternal(), - testConfiguration.getRunsPerTestForLabel(getOwner().getLabel())); - } - - @VisibleForTesting - static boolean canBeCached( - TriState cacheTestResults, TestResultData prevStatus, boolean isExternal, int runsPerTest) { - if (cacheTestResults == TriState.NO) { - return false; - } - if (isExternal) { - return false; - } - if (cacheTestResults == TriState.AUTO && (runsPerTest > 1)) { - return false; - } - // Test will not be executed unconditionally - check whether test result exists and is - // valid. If it is, method will return false and we will rely on the dependency checker - // to make a decision about test execution. - if (cacheTestResults == TriState.AUTO && prevStatus != null && !prevStatus.getTestPassed()) { - return false; - } - // Rely on the dependency checker to determine if the test can be cached. Note that the status - // is a declared output, so its non-existence also triggers a re-run. - return true; - } - - /** - * Returns whether caching has been deemed safe by looking at the previous test run - * (for local caching). If the previous run is not present, return "true" here, as - * remote execution caching should be safe. - */ - public boolean shouldCacheResult() { - return !executeUnconditionally(); - } - - @Override - public void actionCacheHit(ActionCachedContext executor) { - unconditionalExecution = null; - try { - executor.getEventBus().post( - executor.getContext(TestActionContext.class).newCachedTestResult( - executor.getExecRoot(), this, readCacheStatus())); - } catch (IOException e) { - LoggingUtil.logToRemote(Level.WARNING, "Failed creating cached protocol buffer", e); - } - } - - @Override - protected String getRawProgressMessage() { - return "Testing " + getTestName(); - } - - /** - * Deletes <b>all</b> possible test outputs. - * - * TestRunnerAction potentially can create many more non-declared outputs - xml output, - * coverage data file and logs for failed attempts. All those outputs are uniquely - * identified by the test log base name with arbitrary prefix and extension. - */ - @Override - protected void deleteOutputs(Path execRoot) throws IOException { - super.deleteOutputs(execRoot); - - // We do not rely on globs, as it causes quadratic behavior in --runs_per_test and test - // shard count. - - // We also need to remove *.(xml|data|shard|warnings|zip) files if they are present. - execRoot.getRelative(xmlOutputPath).delete(); - execRoot.getRelative(testWarningsPath).delete(); - execRoot.getRelative(unusedRunfilesLogPath).delete(); - // Note that splitLogsPath points to a file inside the splitLogsDir so - // it's not necessary to delete it explicitly. - FileSystemUtils.deleteTree(execRoot.getRelative(splitLogsDir)); - FileSystemUtils.deleteTree(execRoot.getRelative(undeclaredOutputsDir)); - FileSystemUtils.deleteTree(execRoot.getRelative(undeclaredOutputsAnnotationsDir)); - execRoot.getRelative(testStderr).delete(); - execRoot.getRelative(testExitSafe).delete(); - if (testShard != null) { - execRoot.getRelative(testShard).delete(); - } - execRoot.getRelative(testInfrastructureFailure).delete(); - - // Coverage files use "coverage" instead of "test". - String coveragePrefix = "coverage"; - - // We cannot use coverageData artifact since it may be null. Generate coverage name instead. - execRoot.getRelative(baseDir.getChild(coveragePrefix + ".dat")).delete(); - - // Delete files fetched from remote execution. - execRoot.getRelative(baseDir.getChild("test.zip")).delete(); - deleteTestAttemptsDirMaybe(execRoot.getRelative(baseDir), "test"); - } - - private void deleteTestAttemptsDirMaybe(Path outputDir, String namePrefix) throws IOException { - Path testAttemptsDir = outputDir.getChild(namePrefix + "_attempts"); - if (testAttemptsDir.exists()) { - // Normally we should have used deleteTree(testAttemptsDir). However, if test output is - // in a FUSE filesystem implemented with the high-level API, there may be .fuse??????? - // entries, which prevent removing the directory. As a workaround, code below will throw - // IOException if it will fail to remove something inside testAttemptsDir, but will - // silently suppress any exceptions when deleting testAttemptsDir itself. - FileSystemUtils.deleteTreesBelow(testAttemptsDir); - try { - testAttemptsDir.delete(); - } catch (IOException e) { - // Do nothing. - } - } - } - - public void setupEnvVariables(Map<String, String> env, Duration timeout) { - env.put("TEST_SIZE", getTestProperties().getSize().toString()); - env.put("TEST_TIMEOUT", Long.toString(timeout.getSeconds())); - env.put("TEST_WORKSPACE", getRunfilesPrefix()); - env.put( - "TEST_BINARY", - getExecutionSettings().getExecutable().getRootRelativePath().getCallablePathString()); - - // When we run test multiple times, set different TEST_RANDOM_SEED values for each run. - // Don't override any previous setting. - if (testConfiguration.getRunsPerTestForLabel(getOwner().getLabel()) > 1 - && !env.containsKey("TEST_RANDOM_SEED")) { - env.put("TEST_RANDOM_SEED", Integer.toString(getRunNumber() + 1)); - } - - String testFilter = getExecutionSettings().getTestFilter(); - if (testFilter != null) { - env.put(TEST_BRIDGE_TEST_FILTER_ENV, testFilter); - } - - env.put("TEST_WARNINGS_OUTPUT_FILE", getTestWarningsPath().getPathString()); - env.put("TEST_UNUSED_RUNFILES_LOG_FILE", getUnusedRunfilesLogPath().getPathString()); - - env.put("TEST_LOGSPLITTER_OUTPUT_FILE", getSplitLogsPath().getPathString()); - - env.put("TEST_UNDECLARED_OUTPUTS_ZIP", getUndeclaredOutputsZipPath().getPathString()); - env.put("TEST_UNDECLARED_OUTPUTS_DIR", getUndeclaredOutputsDir().getPathString()); - env.put("TEST_UNDECLARED_OUTPUTS_MANIFEST", getUndeclaredOutputsManifestPath().getPathString()); - env.put( - "TEST_UNDECLARED_OUTPUTS_ANNOTATIONS", - getUndeclaredOutputsAnnotationsPath().getPathString()); - env.put( - "TEST_UNDECLARED_OUTPUTS_ANNOTATIONS_DIR", - getUndeclaredOutputsAnnotationsDir().getPathString()); - - env.put("TEST_PREMATURE_EXIT_FILE", getExitSafeFile().getPathString()); - env.put("TEST_INFRASTRUCTURE_FAILURE_FILE", getInfrastructureFailureFile().getPathString()); - - if (isSharded()) { - env.put("TEST_SHARD_INDEX", Integer.toString(getShardNum())); - env.put("TEST_TOTAL_SHARDS", Integer.toString(getExecutionSettings().getTotalShards())); - env.put("TEST_SHARD_STATUS_FILE", getTestShard().getPathString()); - } - env.put("XML_OUTPUT_FILE", getXmlOutputPath().getPathString()); - - if (!isEnableRunfiles()) { - // If runfiles are disabled, tell remote-runtest.sh/local-runtest.sh about that. - env.put("RUNFILES_MANIFEST_ONLY", "1"); - } - - if (isCoverageMode()) { - // Instruct remote-runtest.sh/local-runtest.sh not to cd into the runfiles directory. - // TODO(ulfjack): Find a way to avoid setting this variable. - env.put("RUNTEST_PRESERVE_CWD", "1"); - - env.put("COVERAGE_MANIFEST", getCoverageManifest().getExecPathString()); - env.put("COVERAGE_DIR", getCoverageDirectory().getPathString()); - env.put("COVERAGE_OUTPUT_FILE", getCoverageData().getExecPathString()); - // TODO(elenairina): Remove this after the next blaze release (after 2017.07.30). - env.put("NEW_JAVA_COVERAGE_IMPL", "True"); - } - } - - /** - * Gets the test name in a user-friendly format. - * Will generally include the target name and run/shard numbers, if applicable. - */ - public String getTestName() { - String suffix = getTestSuffix(); - String label = Label.print(getOwner().getLabel()); - return suffix.isEmpty() ? label : label + " " + suffix; - } - - /** - * Gets the test suffix in a user-friendly format, eg "(shard 1 of 7)". - * Will include the target name and run/shard numbers, if applicable. - */ - public String getTestSuffix() { - int totalShards = executionSettings.getTotalShards(); - // Use a 1-based index for user friendliness. - int runsPerTest = testConfiguration.getRunsPerTestForLabel(getOwner().getLabel()); - if (totalShards > 1 && runsPerTest > 1) { - return String.format("(shard %d of %d, run %d of %d)", shardNum + 1, totalShards, - runNumber + 1, runsPerTest); - } else if (totalShards > 1) { - return String.format("(shard %d of %d)", shardNum + 1, totalShards); - } else if (runsPerTest > 1) { - return String.format("(run %d of %d)", runNumber + 1, runsPerTest); - } else { - return ""; - } - } - - public Artifact getTestLog() { - return testLog; - } - - /** - * Returns all environment variables which must be set in order to run this test. - */ - public Map<String, String> getExtraTestEnv() { - return extraTestEnv; - } - - @Override - public Iterable<String> getClientEnvironmentVariables() { - return requiredClientEnvVariables; - } - - public ResolvedPaths resolve(Path execRoot) { - return new ResolvedPaths(execRoot); - } - - public Artifact getCacheStatusArtifact() { - return cacheStatus; - } - - public PathFragment getTestWarningsPath() { - return testWarningsPath; - } - - public PathFragment getUnusedRunfilesLogPath() { - return unusedRunfilesLogPath; - } - - public PathFragment getSplitLogsPath() { - return splitLogsPath; - } - - public PathFragment getUndeclaredOutputsDir() { - return undeclaredOutputsDir; - } - - /** - * @return path to the optional zip file of undeclared test outputs. - */ - public PathFragment getUndeclaredOutputsZipPath() { - return undeclaredOutputsZipPath; - } - - /** - * @return path to the undeclared output manifest file. - */ - public PathFragment getUndeclaredOutputsManifestPath() { - return undeclaredOutputsManifestPath; - } - - public PathFragment getUndeclaredOutputsAnnotationsDir() { - return undeclaredOutputsAnnotationsDir; - } - - /** - * @return path to the undeclared output annotations file. - */ - public PathFragment getUndeclaredOutputsAnnotationsPath() { - return undeclaredOutputsAnnotationsPath; - } - - public PathFragment getTestShard() { - return testShard; - } - - public PathFragment getExitSafeFile() { - return testExitSafe; - } - - public PathFragment getInfrastructureFailureFile() { - return testInfrastructureFailure; - } - - /** - * @return path to the optionally created XML output file created by the test. - */ - public PathFragment getXmlOutputPath() { - return xmlOutputPath; - } - - /** - * @return coverage data artifact or null if code coverage was not requested. - */ - @Nullable public Artifact getCoverageData() { - return coverageData; - } - - @Nullable public Artifact getCoverageManifest() { - return getExecutionSettings().getInstrumentedFileManifest(); - } - - /** Returns true if coverage data should be gathered. */ - public boolean isCoverageMode() { - return coverageData != null; - } - - /** - * Returns a directory to temporarily store coverage results for the given action relative to the - * execution root. This directory is used to store all coverage results related to the test - * execution with exception of the locally generated *.gcda files. Those are stored separately - * using relative path within coverage directory. - * - * <p>The directory name for the given test runner action is constructed as: {@code - * _coverage/target_path/test_log_name} where {@code test_log_name} is usually a target name but - * potentially can include extra suffix, such as a shard number (if test execution was sharded). - */ - public PathFragment getCoverageDirectory() { - return COVERAGE_TMP_ROOT.getRelative( - FileSystemUtils.removeExtension(getTestLog().getRootRelativePath())); - } - - public TestTargetProperties getTestProperties() { - return testProperties; - } - - public TestTargetExecutionSettings getExecutionSettings() { - return executionSettings; - } - - public boolean useTestRunner() { - return useTestRunner; - } - - public boolean isSharded() { - return testShard != null; - } - - /** - * @return the shard number for this action. - * If getTotalShards() > 0, must be >= 0 and < getTotalShards(). - * Otherwise, must be 0. - */ - public int getShardNum() { - return shardNum; - } - - /** - * @return run number. - */ - public int getRunNumber() { - return runNumber; - } - - /** - * @return the workspace name. - */ - public String getRunfilesPrefix() { - return workspaceName; - } - - @Override - public Artifact getPrimaryOutput() { - return testLog; - } - - @Override - public void execute(ActionExecutionContext actionExecutionContext) - throws ActionExecutionException, InterruptedException { - TestActionContext context = actionExecutionContext.getContext(TestActionContext.class); - try { - context.exec(this, actionExecutionContext); - } catch (ExecException e) { - throw e.toActionExecutionException(this); - } finally { - unconditionalExecution = null; - } - } - - @Override - public String getMnemonic() { - return "TestRunner"; - } - - @Override - public ImmutableSet<Artifact> getMandatoryOutputs() { - return getOutputs(); - } - - public Artifact getRuntimeArtifact(String basename) throws ExecException { - for (Artifact runtimeArtifact : runtime) { - if (runtimeArtifact.getExecPath().getBaseName().equals(basename)) { - return runtimeArtifact; - } - } - - throw new UserExecException("'" + basename + "' not found in test runtime"); - } - - public PathFragment getShExecutable() { - return configuration.getShellExecutable(); - } - - public ImmutableMap<String, String> getLocalShellEnvironment() { - return configuration.getLocalShellEnvironment(); - } - - public boolean isEnableRunfiles() { - return configuration.runfilesEnabled(); - } - - /** - * The same set of paths as the parent test action, resolved against a given exec root. - */ - public final class ResolvedPaths { - private final Path execRoot; - - ResolvedPaths(Path execRoot) { - this.execRoot = Preconditions.checkNotNull(execRoot); - } - - private Path getPath(PathFragment relativePath) { - return execRoot.getRelative(relativePath); - } - - public final Path getBaseDir() { - return getPath(baseDir); - } - - /** - * In rare cases, error messages will be printed to stderr instead of stdout. The test action is - * responsible for appending anything in the stderr file to the real test.log. - */ - public Path getTestStderr() { - return getPath(testStderr); - } - - public Path getTestWarningsPath() { - return getPath(testWarningsPath); - } - - public Path getSplitLogsPath() { - return getPath(splitLogsPath); - } - - public Path getUnusedRunfilesLogPath() { - return getPath(unusedRunfilesLogPath); - } - - /** - * @return path to the directory containing the split logs (raw and proto file). - */ - public Path getSplitLogsDir() { - return getPath(splitLogsDir); - } - - /** - * @return path to the optional zip file of undeclared test outputs. - */ - public Path getUndeclaredOutputsZipPath() { - return getPath(undeclaredOutputsZipPath); - } - - /** - * @return path to the directory to hold undeclared test outputs. - */ - public Path getUndeclaredOutputsDir() { - return getPath(undeclaredOutputsDir); - } - - /** - * @return path to the directory to hold undeclared output annotations parts. - */ - public Path getUndeclaredOutputsAnnotationsDir() { - return getPath(undeclaredOutputsAnnotationsDir); - } - - /** - * @return path to the undeclared output manifest file. - */ - public Path getUndeclaredOutputsManifestPath() { - return getPath(undeclaredOutputsManifestPath); - } - - /** - * @return path to the undeclared output annotations file. - */ - public Path getUndeclaredOutputsAnnotationsPath() { - return getPath(undeclaredOutputsAnnotationsPath); - } - - @Nullable - public Path getTestShard() { - return testShard == null ? null : getPath(testShard); - } - - public Path getExitSafeFile() { - return getPath(testExitSafe); - } - - public Path getInfrastructureFailureFile() { - return getPath(testInfrastructureFailure); - } - - /** - * @return path to the optionally created XML output file created by the test. - */ - public Path getXmlOutputPath() { - return getPath(xmlOutputPath); - } - } -} diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/TestSuite.java b/src/main/java/com/google/devtools/build/lib/rules/test/TestSuite.java index 7f8eb65399..b18bd4d799 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/test/TestSuite.java +++ b/src/main/java/com/google/devtools/build/lib/rules/test/TestSuite.java @@ -23,8 +23,8 @@ import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.Runfiles; import com.google.devtools.build.lib.analysis.RunfilesProvider; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; +import com.google.devtools.build.lib.analysis.test.TestProvider; import com.google.devtools.build.lib.packages.BuildType; -import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException; import com.google.devtools.build.lib.packages.TestTargetUtils; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.Pair; diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/TestTargetExecutionSettings.java b/src/main/java/com/google/devtools/build/lib/rules/test/TestTargetExecutionSettings.java deleted file mode 100644 index 7678c842a7..0000000000 --- a/src/main/java/com/google/devtools/build/lib/rules/test/TestTargetExecutionSettings.java +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright 2014 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.rules.test; - -import com.google.common.collect.ImmutableList; -import com.google.devtools.build.lib.actions.Artifact; -import com.google.devtools.build.lib.analysis.FilesToRunProvider; -import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; -import com.google.devtools.build.lib.analysis.RuleContext; -import com.google.devtools.build.lib.analysis.Runfiles; -import com.google.devtools.build.lib.analysis.RunfilesSupport; -import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; -import com.google.devtools.build.lib.analysis.actions.CommandLine; -import com.google.devtools.build.lib.analysis.config.BuildConfiguration; -import com.google.devtools.build.lib.analysis.config.RunUnder; -import com.google.devtools.build.lib.packages.TargetUtils; -import com.google.devtools.build.lib.util.Preconditions; -import com.google.devtools.build.lib.vfs.Path; - -/** - * Container for common test execution settings shared by all - * all TestRunnerAction instances for the given test target. - */ -public final class TestTargetExecutionSettings { - - private final CommandLine testArguments; - private final String testFilter; - private final int totalShards; - private final RunUnder runUnder; - private final Artifact runUnderExecutable; - private final Artifact executable; - private final boolean runfilesSymlinksCreated; - private final Path runfilesDir; - private final Runfiles runfiles; - private final Artifact runfilesInputManifest; - private final Artifact instrumentedFileManifest; - - TestTargetExecutionSettings(RuleContext ruleContext, RunfilesSupport runfilesSupport, - Artifact executable, Artifact instrumentedFileManifest, int shards) { - Preconditions.checkArgument(TargetUtils.isTestRule(ruleContext.getRule())); - Preconditions.checkArgument(shards >= 0); - BuildConfiguration config = ruleContext.getConfiguration(); - TestConfiguration testConfig = config.getFragment(TestConfiguration.class); - - CommandLine targetArgs = runfilesSupport.getArgs(); - testArguments = - CommandLine.concat(targetArgs, ImmutableList.copyOf(testConfig.getTestArguments())); - - totalShards = shards; - runUnder = config.getRunUnder(); - runUnderExecutable = getRunUnderExecutable(ruleContext); - - this.testFilter = testConfig.getTestFilter(); - this.executable = executable; - this.runfilesSymlinksCreated = runfilesSupport.getCreateSymlinks(); - this.runfilesDir = runfilesSupport.getRunfilesDirectory(); - this.runfiles = runfilesSupport.getRunfiles(); - this.runfilesInputManifest = runfilesSupport.getRunfilesInputManifest(); - this.instrumentedFileManifest = instrumentedFileManifest; - } - - private static Artifact getRunUnderExecutable(RuleContext ruleContext) { - TransitiveInfoCollection runUnderTarget = ruleContext - .getPrerequisite(":run_under", Mode.DATA); - return runUnderTarget == null - ? null - : runUnderTarget.getProvider(FilesToRunProvider.class).getExecutable(); - } - - public CommandLine getArgs() { - return testArguments; - } - - public String getTestFilter() { - return testFilter; - } - - public int getTotalShards() { - return totalShards; - } - - public RunUnder getRunUnder() { - return runUnder; - } - - public Artifact getRunUnderExecutable() { - return runUnderExecutable; - } - - public Artifact getExecutable() { - return executable; - } - - /** @return whether or not the runfiles symlinks were created */ - public boolean getRunfilesSymlinksCreated() { - return runfilesSymlinksCreated; - } - - /** @return the directory of the runfiles */ - public Path getRunfilesDir() { - return runfilesDir; - } - - /** @return the runfiles for the test */ - public Runfiles getRunfiles() { - return runfiles; - } - - /** - * Returns the input runfiles manifest for this test. - * - * <p>This always returns the input manifest outside of the runfiles tree. - * - * @see com.google.devtools.build.lib.analysis.RunfilesSupport#getRunfilesInputManifest() - */ - public Artifact getInputManifest() { - return runfilesInputManifest; - } - - /** - * Returns instrumented file manifest or null if code coverage is not - * collected. - */ - public Artifact getInstrumentedFileManifest() { - return instrumentedFileManifest; - } -} diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/TestTargetProperties.java b/src/main/java/com/google/devtools/build/lib/rules/test/TestTargetProperties.java deleted file mode 100644 index bae11751e3..0000000000 --- a/src/main/java/com/google/devtools/build/lib/rules/test/TestTargetProperties.java +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright 2014 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.rules.test; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; -import com.google.devtools.build.lib.actions.ExecutionRequirements; -import com.google.devtools.build.lib.actions.ExecutionRequirements.ParseableRequirement.ValidationException; -import com.google.devtools.build.lib.actions.ResourceSet; -import com.google.devtools.build.lib.actions.Spawn; -import com.google.devtools.build.lib.actions.UserExecException; -import com.google.devtools.build.lib.analysis.RuleContext; -import com.google.devtools.build.lib.cmdline.Label; -import com.google.devtools.build.lib.packages.Rule; -import com.google.devtools.build.lib.packages.TargetUtils; -import com.google.devtools.build.lib.packages.TestSize; -import com.google.devtools.build.lib.packages.TestTimeout; -import com.google.devtools.build.lib.syntax.Type; -import com.google.devtools.build.lib.util.Preconditions; -import java.util.List; -import java.util.Map; - -/** - * Container for test target properties available to the - * TestRunnerAction instance. - */ -public class TestTargetProperties { - - /** - * Resources used by local tests of various sizes. - * - * <p>When changing these values, remember to update the documentation at - * attributes/test/size.html. - */ - private static final ResourceSet SMALL_RESOURCES = ResourceSet.create(20, 0.9, 0.00, 1); - private static final ResourceSet MEDIUM_RESOURCES = ResourceSet.create(100, 0.9, 0.1, 1); - private static final ResourceSet LARGE_RESOURCES = ResourceSet.create(300, 0.8, 0.1, 1); - private static final ResourceSet ENORMOUS_RESOURCES = ResourceSet.create(800, 0.7, 0.4, 1); - private static final ResourceSet LOCAL_TEST_JOBS_BASED_RESOURCES = - ResourceSet.createWithLocalTestCount(1); - - private static ResourceSet getResourceSetFromSize(TestSize size) { - switch (size) { - case SMALL: return SMALL_RESOURCES; - case MEDIUM: return MEDIUM_RESOURCES; - case LARGE: return LARGE_RESOURCES; - default: return ENORMOUS_RESOURCES; - } - } - - private final TestSize size; - private final TestTimeout timeout; - private final List<String> tags; - private final boolean isLocal; - private final boolean isFlaky; - private final boolean isExternal; - private final String language; - private final ImmutableMap<String, String> executionInfo; - - /** - * Creates test target properties instance. Constructor expects that it - * will be called only for test configured targets. - */ - TestTargetProperties(RuleContext ruleContext, - ExecutionInfoProvider executionRequirements) { - Rule rule = ruleContext.getRule(); - - Preconditions.checkState(TargetUtils.isTestRule(rule)); - size = TestSize.getTestSize(rule); - timeout = TestTimeout.getTestTimeout(rule); - tags = ruleContext.attributes().get("tags", Type.STRING_LIST); - boolean isTaggedLocal = TargetUtils.isLocalTestRule(rule) - || TargetUtils.isExclusiveTestRule(rule); - - // We need to use method on ruleConfiguredTarget to perform validation. - isFlaky = ruleContext.attributes().get("flaky", Type.BOOLEAN); - isExternal = TargetUtils.isExternalTestRule(rule); - - Map<String, String> executionInfo = Maps.newLinkedHashMap(); - executionInfo.putAll(TargetUtils.getExecutionInfo(rule)); - if (isTaggedLocal) { - executionInfo.put("local", ""); - } - - boolean isRequestedLocalByProvider = false; - if (executionRequirements != null) { - // This will overwrite whatever TargetUtils put there, which might be confusing. - executionInfo.putAll(executionRequirements.getExecutionInfo()); - - // We also need to mark it as local if the execution requirements specifies it. - isRequestedLocalByProvider = executionRequirements.getExecutionInfo().containsKey("local"); - } - this.executionInfo = ImmutableMap.copyOf(executionInfo); - - isLocal = isTaggedLocal || isRequestedLocalByProvider; - - language = TargetUtils.getRuleLanguage(rule); - } - - public TestSize getSize() { - return size; - } - - public TestTimeout getTimeout() { - return timeout; - } - - public List<String> getTags() { - return tags; - } - - public boolean isLocal() { - return isLocal; - } - - public boolean isFlaky() { - return isFlaky; - } - - public boolean isExternal() { - return isExternal; - } - - public ResourceSet getLocalResourceUsage(Label label, boolean usingLocalTestJobs) - throws UserExecException { - if (usingLocalTestJobs) { - return LOCAL_TEST_JOBS_BASED_RESOURCES; - } - - ResourceSet testResourcesFromSize = TestTargetProperties.getResourceSetFromSize(size); - - // Tests can override their CPU reservation with a "cpus:<n>" tag. - ResourceSet testResourcesFromTag = null; - for (String tag : executionInfo.keySet()) { - try { - String cpus = ExecutionRequirements.CPU.parseIfMatches(tag); - if (cpus != null) { - if (testResourcesFromTag != null) { - throw new UserExecException( - String.format( - "%s has more than one '%s' tag, but duplicate tags aren't allowed", - label, ExecutionRequirements.CPU.userFriendlyName())); - } - testResourcesFromTag = - ResourceSet.create( - testResourcesFromSize.getMemoryMb(), - Float.parseFloat(cpus), - testResourcesFromSize.getIoUsage(), - testResourcesFromSize.getLocalTestCount()); - } - } catch (ValidationException e) { - throw new UserExecException( - String.format( - "%s has a '%s' tag, but its value '%s' didn't pass validation: %s", - label, - ExecutionRequirements.CPU.userFriendlyName(), - e.getTagValue(), - e.getMessage())); - } - } - - return testResourcesFromTag != null ? testResourcesFromTag : testResourcesFromSize; - } - - /** - * Returns a map of execution info. See {@link Spawn#getExecutionInfo}. - */ - public ImmutableMap<String, String> getExecutionInfo() { - return executionInfo; - } - - public String getLanguage() { - return language; - } -} |