blob: 18f0dd52b82fdab3b24ef37b3c6ee074ee01aa8c [file] [log] [blame]
// Copyright 2020 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.packages.metrics;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.collect.ImmutableSortedKeyMap;
import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.packages.metrics.ExtremaPackageLoadingListener.PackageIdentifierAndLong;
import com.google.devtools.build.lib.packages.metrics.ExtremaPackageLoadingListener.TopPackages;
import com.google.devtools.build.lib.syntax.StarlarkSemantics;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Tests for {@link ExtremaPackageLoadingListener}. */
@RunWith(JUnit4.class)
public class ExtremaPackageLoadingListenerTest {
private final ExtremaPackageLoadingListener underTest = new ExtremaPackageLoadingListener();
@Test
public void testRecordsTopSlowestPackagesPerBuild() {
underTest.setNumPackagesToTrack(2);
underTest.onLoadingCompleteAndSuccessful(
mockPackage(
"my/pkg1",
/*targets=*/ ImmutableMap.of(),
/*starlarkDependencies=*/ ImmutableList.of()),
StarlarkSemantics.DEFAULT,
/*loadTimeNanos=*/ 42_000_000);
underTest.onLoadingCompleteAndSuccessful(
mockPackage(
"my/pkg2",
/*targets=*/ ImmutableMap.of(),
/*starlarkDependencies=*/ ImmutableList.of()),
StarlarkSemantics.DEFAULT,
/*loadTimeNanos=*/ 43_000_000);
underTest.onLoadingCompleteAndSuccessful(
mockPackage(
"my/pkg3",
/*targets=*/ ImmutableMap.of(),
/*starlarkDependencies=*/ ImmutableList.of()),
StarlarkSemantics.DEFAULT,
/*loadTimeNanos=*/ 44_000_000);
assertThat(toStrings(underTest.getAndResetTopPackages().getSlowestPackages()))
.containsExactly("my/pkg3 (44)", "my/pkg2 (43)")
.inOrder();
assertAllTopPackagesEmpty(underTest.getAndResetTopPackages());
}
@Test
public void testRecordsTopLargestPackagesPerBuild() {
underTest.setNumPackagesToTrack(2);
underTest.onLoadingCompleteAndSuccessful(
mockPackage(
"my/pkg1",
ImmutableMap.of("target1", mock(Target.class)),
/*starlarkDependencies=*/ ImmutableList.of()),
StarlarkSemantics.DEFAULT,
/*loadTimeNanos=*/ 100);
underTest.onLoadingCompleteAndSuccessful(
mockPackage(
"my/pkg2",
ImmutableMap.of("target1", mock(Target.class), "target2", mock(Target.class)),
/*starlarkDependencies=*/ ImmutableList.of()),
StarlarkSemantics.DEFAULT,
/*loadTimeNanos=*/ 100);
underTest.onLoadingCompleteAndSuccessful(
mockPackage(
"my/pkg3",
ImmutableMap.of(
"target1",
mock(Target.class),
"target2",
mock(Target.class),
"target3",
mock(Target.class)),
/*starlarkDependencies=*/ ImmutableList.of()),
StarlarkSemantics.DEFAULT,
/*loadTimeNanos=*/ 100);
assertThat(toStrings(underTest.getAndResetTopPackages().getLargestPackages()))
.containsExactly("my/pkg3 (3)", "my/pkg2 (2)")
.inOrder();
assertAllTopPackagesEmpty(underTest.getAndResetTopPackages());
}
@Test
public void testRecordsTransitiveLoadsPerBuild() {
underTest.setNumPackagesToTrack(2);
underTest.onLoadingCompleteAndSuccessful(
mockPackage(
"my/pkg1",
/*targets=*/ ImmutableMap.of(),
ImmutableList.of(Label.parseAbsoluteUnchecked("//load:1.bzl"))),
StarlarkSemantics.DEFAULT,
/*loadTimeNanos=*/ 100);
underTest.onLoadingCompleteAndSuccessful(
mockPackage(
"my/pkg2",
/*targets=*/ ImmutableMap.of(),
ImmutableList.of(
Label.parseAbsoluteUnchecked("//load:1.bzl"),
Label.parseAbsoluteUnchecked("//load:2.bzl"))),
StarlarkSemantics.DEFAULT,
/*loadTimeNanos=*/ 100);
underTest.onLoadingCompleteAndSuccessful(
mockPackage(
"my/pkg3",
/*targets=*/ ImmutableMap.of(),
ImmutableList.of(
Label.parseAbsoluteUnchecked("//load:1.bzl"),
Label.parseAbsoluteUnchecked("//load:2.bzl"),
Label.parseAbsoluteUnchecked("//load:3.bzl"))),
StarlarkSemantics.DEFAULT,
/*loadTimeNanos=*/ 100);
assertThat(toStrings(underTest.getAndResetTopPackages().getPackagesWithMostTransitiveLoads()))
.containsExactly("my/pkg3 (3)", "my/pkg2 (2)")
.inOrder();
assertAllTopPackagesEmpty(underTest.getAndResetTopPackages());
}
@Test
public void testRecordsMostComputationStepsPerBuild() {
underTest.setNumPackagesToTrack(2);
Package mockPackage1 =
mockPackage(
"my/pkg1",
/*targets=*/ ImmutableMap.of(),
/*starlarkDependencies=*/ ImmutableList.of());
when(mockPackage1.getComputationSteps()).thenReturn(1000L);
underTest.onLoadingCompleteAndSuccessful(
mockPackage1, StarlarkSemantics.DEFAULT, /*loadTimeNanos=*/ 100);
Package mockPackage2 =
mockPackage(
"my/pkg2",
/*targets=*/ ImmutableMap.of(),
/*starlarkDependencies=*/ ImmutableList.of());
when(mockPackage2.getComputationSteps()).thenReturn(100L);
underTest.onLoadingCompleteAndSuccessful(
mockPackage2, StarlarkSemantics.DEFAULT, /*loadTimeNanos=*/ 100);
Package mockPackage3 =
mockPackage(
"my/pkg3",
/*targets=*/ ImmutableMap.of(),
/*starlarkDependencies=*/ ImmutableList.of());
when(mockPackage3.getComputationSteps()).thenReturn(10L);
underTest.onLoadingCompleteAndSuccessful(
mockPackage3, StarlarkSemantics.DEFAULT, /*loadTimeNanos=*/ 100);
assertThat(toStrings(underTest.getAndResetTopPackages().getPackagesWithMostComputationSteps()))
.containsExactly("my/pkg1 (1000)", "my/pkg2 (100)")
.inOrder();
assertAllTopPackagesEmpty(underTest.getAndResetTopPackages());
}
@Test
public void testDoesntRecordAnythingWhenNumPackagesToTrackIsZero() {
underTest.setNumPackagesToTrack(0);
underTest.onLoadingCompleteAndSuccessful(
mockPackage(
"my/pkg1",
/*targets=*/ ImmutableMap.of(),
/*starlarkDependencies=*/ ImmutableList.of()),
StarlarkSemantics.DEFAULT,
/*loadTimeNanos=*/ 42_000_000);
assertAllTopPackagesEmpty(underTest.getAndResetTopPackages());
}
private static void assertAllTopPackagesEmpty(TopPackages topPackages) {
assertThat(topPackages.getSlowestPackages()).isEmpty();
assertThat(topPackages.getLargestPackages()).isEmpty();
assertThat(topPackages.getPackagesWithMostTransitiveLoads()).isEmpty();
assertThat(topPackages.getPackagesWithMostComputationSteps()).isEmpty();
}
private static Package mockPackage(
String pkgIdString, Map<String, Target> targets, List<Label> starlarkDependencies) {
Package mockPackage = mock(Package.class);
when(mockPackage.getPackageIdentifier())
.thenReturn(PackageIdentifier.createInMainRepo(pkgIdString));
when(mockPackage.getTargets()).thenReturn(ImmutableSortedKeyMap.copyOf(targets));
when(mockPackage.getStarlarkFileDependencies())
.thenReturn(ImmutableList.copyOf(starlarkDependencies));
return mockPackage;
}
private static ImmutableList<String> toStrings(List<PackageIdentifierAndLong> from) {
return from.stream().map(v -> v.toString()).collect(ImmutableList.toImmutableList());
}
}