| /* |
| * Copyright 2013-present Facebook, Inc. |
| * |
| * 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.facebook.buck.event.listener; |
| |
| import static org.easymock.EasyMock.createMock; |
| import static org.easymock.EasyMock.replay; |
| import static org.easymock.EasyMock.verify; |
| import static org.junit.Assert.assertEquals; |
| |
| import com.facebook.buck.cli.CommandEvent; |
| import com.facebook.buck.event.BuckEvent; |
| import com.facebook.buck.event.BuckEventBus; |
| import com.facebook.buck.event.BuckEventBusFactory; |
| import com.facebook.buck.event.ChromeTraceEvent; |
| import com.facebook.buck.model.BuildTarget; |
| import com.facebook.buck.model.BuildTargetFactory; |
| import com.facebook.buck.model.BuildTargetPattern; |
| import com.facebook.buck.rules.ArtifactCacheConnectEvent; |
| import com.facebook.buck.rules.ArtifactCacheEvent; |
| import com.facebook.buck.rules.BuildEvent; |
| import com.facebook.buck.rules.BuildRule; |
| import com.facebook.buck.rules.BuildRuleEvent; |
| import com.facebook.buck.rules.BuildRuleStatus; |
| import com.facebook.buck.rules.BuildRuleSuccess; |
| import com.facebook.buck.rules.BuildRuleType; |
| import com.facebook.buck.rules.CacheResult; |
| import com.facebook.buck.rules.FakeBuildRule; |
| import com.facebook.buck.rules.RuleKey; |
| import com.facebook.buck.step.ExecutionContext; |
| import com.facebook.buck.step.FakeStep; |
| import com.facebook.buck.step.StepEvent; |
| import com.facebook.buck.timing.Clock; |
| import com.facebook.buck.timing.IncrementingFakeClock; |
| import com.facebook.buck.util.BuckConstant; |
| import com.facebook.buck.util.ProjectFilesystem; |
| import com.fasterxml.jackson.core.type.TypeReference; |
| import com.fasterxml.jackson.databind.ObjectMapper; |
| import com.google.common.base.Function; |
| import com.google.common.base.Optional; |
| import com.google.common.base.Supplier; |
| import com.google.common.collect.FluentIterable; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableMap; |
| import com.google.common.collect.ImmutableSet; |
| import com.google.common.collect.ImmutableSortedSet; |
| import com.google.common.eventbus.EventBus; |
| |
| import org.junit.Rule; |
| import org.junit.Test; |
| import org.junit.rules.TemporaryFolder; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.Arrays; |
| import java.util.List; |
| import java.util.concurrent.TimeUnit; |
| |
| |
| public class ChromeTraceBuildListenerTest { |
| @Rule |
| public TemporaryFolder tmpDir = new TemporaryFolder(); |
| |
| @Test |
| public void testDeleteFiles() throws IOException { |
| ProjectFilesystem projectFilesystem = new ProjectFilesystem(tmpDir.getRoot()); |
| |
| String tracePath = String.format("%s/build.trace", BuckConstant.BUCK_TRACE_DIR); |
| File traceFile = new File(tmpDir.getRoot(), tracePath); |
| projectFilesystem.createParentDirs(tracePath); |
| traceFile.createNewFile(); |
| traceFile.setLastModified(0); |
| |
| for (int i = 0; i < 10; ++i) { |
| File oldResult = new File(tmpDir.getRoot(), |
| String.format("%s/build.100%d.trace", BuckConstant.BUCK_TRACE_DIR, i)); |
| oldResult.createNewFile(); |
| oldResult.setLastModified(TimeUnit.SECONDS.toMillis(i)); |
| } |
| |
| ChromeTraceBuildListener listener = new ChromeTraceBuildListener(projectFilesystem, |
| new IncrementingFakeClock(), |
| 3); |
| |
| listener.deleteOldTraces(); |
| |
| ImmutableList<String> files = FluentIterable. |
| from(Arrays.asList(projectFilesystem.listFiles(BuckConstant.BUCK_TRACE_DIR))). |
| transform(new Function<File, String>() { |
| @Override |
| public String apply(File input) { |
| return input.getName(); |
| } |
| }).toList(); |
| assertEquals(4, files.size()); |
| assertEquals(ImmutableSortedSet.of("build.trace", |
| "build.1009.trace", |
| "build.1008.trace", |
| "build.1007.trace"), |
| ImmutableSortedSet.copyOf(files)); |
| } |
| |
| @Test |
| public void testBuildJson() throws IOException { |
| ProjectFilesystem projectFilesystem = new ProjectFilesystem(tmpDir.getRoot()); |
| |
| ChromeTraceBuildListener listener = new ChromeTraceBuildListener(projectFilesystem, |
| new IncrementingFakeClock(), |
| 42); |
| |
| BuildTarget target = BuildTargetFactory.newInstance("//fake:rule"); |
| |
| FakeBuildRule rule = new FakeBuildRule( |
| new BuildRuleType("fakeRule"), |
| target, |
| ImmutableSortedSet.<BuildRule>of(), |
| ImmutableSet.<BuildTargetPattern>of()); |
| RuleKey ruleKey = new RuleKey("abc123"); |
| rule.setRuleKey(ruleKey); |
| FakeStep step = new FakeStep("fakeStep", "I'm a Fake Step!", 0); |
| |
| ExecutionContext context = createMock(ExecutionContext.class); |
| replay(context); |
| |
| ImmutableList<BuildTarget> buildTargets = ImmutableList.of(target); |
| Clock fakeClock = new IncrementingFakeClock(TimeUnit.MILLISECONDS.toNanos(1)); |
| BuckEventBus eventBus = BuckEventBusFactory.newInstance(fakeClock, |
| "ChromeTraceBuildListenerTestBuildId"); |
| Supplier<Long> threadIdSupplier = BuckEventBusFactory.getThreadIdSupplierFor(eventBus); |
| EventBus rawEventBus = BuckEventBusFactory.getEventBusFor(eventBus); |
| eventBus.register(listener); |
| |
| eventBus.post(CommandEvent.started("party", true)); |
| eventBus.post(ArtifactCacheConnectEvent.started()); |
| eventBus.post(ArtifactCacheConnectEvent.finished()); |
| eventBus.post(BuildEvent.started(buildTargets)); |
| eventBus.post(ArtifactCacheEvent.started(ArtifactCacheEvent.Operation.FETCH, ruleKey)); |
| eventBus.post(ArtifactCacheEvent.finished(ArtifactCacheEvent.Operation.FETCH, |
| ruleKey, |
| CacheResult.CASSANDRA_HIT)); |
| eventBus.post(BuildRuleEvent.started(rule)); |
| eventBus.post(StepEvent.started(step, "I'm a Fake Step!")); |
| |
| // Intentionally fire events out of order to verify sorting happens. |
| BuckEvent stepFinished = StepEvent.finished(step, "I'm a Fake Step!", 0); |
| stepFinished.configure(fakeClock.currentTimeMillis(), |
| fakeClock.nanoTime(), |
| threadIdSupplier.get(), |
| eventBus.getBuildId()); |
| |
| |
| BuckEvent ruleFinished = BuildRuleEvent.finished( |
| rule, |
| BuildRuleStatus.SUCCESS, |
| CacheResult.MISS, |
| Optional.of(BuildRuleSuccess.Type.BUILT_LOCALLY)); |
| ruleFinished.configure(fakeClock.currentTimeMillis(), |
| fakeClock.nanoTime(), |
| threadIdSupplier.get(), |
| eventBus.getBuildId()); |
| |
| rawEventBus.post(ruleFinished); |
| rawEventBus.post(stepFinished); |
| |
| eventBus.post(BuildEvent.finished(buildTargets, 0)); |
| eventBus.post(CommandEvent.finished("party", true, 0)); |
| listener.outputTrace(); |
| |
| File resultFile = new File(tmpDir.getRoot(), BuckConstant.BUCK_TRACE_DIR + "/build.trace"); |
| |
| ObjectMapper mapper = new ObjectMapper(); |
| |
| List<ChromeTraceEvent> resultMap = mapper.readValue( |
| resultFile, |
| new TypeReference<List<ChromeTraceEvent>>() {}); |
| |
| assertEquals(12, resultMap.size()); |
| |
| assertEquals("party", resultMap.get(0).getName()); |
| assertEquals(ChromeTraceEvent.Phase.BEGIN, resultMap.get(0).getPhase()); |
| |
| assertEquals("artifact_connect", resultMap.get(1).getName()); |
| assertEquals(ChromeTraceEvent.Phase.BEGIN, resultMap.get(1).getPhase()); |
| |
| assertEquals("artifact_connect", resultMap.get(2).getName()); |
| assertEquals(ChromeTraceEvent.Phase.END, resultMap.get(2).getPhase()); |
| |
| assertEquals("build", resultMap.get(3).getName()); |
| assertEquals(ChromeTraceEvent.Phase.BEGIN, resultMap.get(3).getPhase()); |
| |
| assertEquals("artifact_fetch", resultMap.get(4).getName()); |
| assertEquals(ChromeTraceEvent.Phase.BEGIN, resultMap.get(4).getPhase()); |
| |
| assertEquals("artifact_fetch", resultMap.get(5).getName()); |
| assertEquals(ChromeTraceEvent.Phase.END, resultMap.get(5).getPhase()); |
| |
| // BuildRuleEvent.Started |
| assertEquals("//fake:rule", resultMap.get(6).getName()); |
| assertEquals(ChromeTraceEvent.Phase.BEGIN, resultMap.get(6).getPhase()); |
| assertEquals(ImmutableMap.of("rule_key", "abc123"), resultMap.get(6).getArgs()); |
| |
| assertEquals("fakeStep", resultMap.get(7).getName()); |
| assertEquals(ChromeTraceEvent.Phase.BEGIN, resultMap.get(7).getPhase()); |
| |
| assertEquals("fakeStep", resultMap.get(8).getName()); |
| assertEquals(ChromeTraceEvent.Phase.END, resultMap.get(8).getPhase()); |
| |
| // BuildRuleEvent.Finished |
| assertEquals("//fake:rule", resultMap.get(9).getName()); |
| assertEquals(ChromeTraceEvent.Phase.END, resultMap.get(9).getPhase()); |
| assertEquals( |
| ImmutableMap.of( |
| "cache_result", "miss", |
| "success_type", "BUILT_LOCALLY"), |
| resultMap.get(9).getArgs()); |
| |
| assertEquals("build", resultMap.get(10).getName()); |
| assertEquals(ChromeTraceEvent.Phase.END, resultMap.get(10).getPhase()); |
| |
| assertEquals("party", resultMap.get(11).getName()); |
| assertEquals(ChromeTraceEvent.Phase.END, resultMap.get(11).getPhase()); |
| |
| verify(context); |
| } |
| } |