/* * Copyright 2016-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.rage; import static org.junit.Assert.assertThat; import com.facebook.buck.event.BuckEventBusFactory; import com.facebook.buck.io.ProjectFilesystem; import com.facebook.buck.testutil.TestBuildEnvironmentDescription; import com.facebook.buck.testutil.TestConsole; import com.facebook.buck.testutil.integration.ProjectWorkspace; import com.facebook.buck.testutil.integration.TemporaryPaths; import com.facebook.buck.testutil.integration.TestDataHelper; import com.facebook.buck.testutil.integration.ZipInspector; import com.facebook.buck.timing.Clock; import com.facebook.buck.timing.DefaultClock; import com.facebook.buck.util.Console; import com.facebook.buck.util.FakeProcess; import com.facebook.buck.util.FakeProcessExecutor; import com.facebook.buck.util.versioncontrol.NoOpCmdLineInterface; import com.facebook.buck.util.versioncontrol.VersionControlStatsGenerator; import com.google.common.collect.ImmutableMap; import java.io.ByteArrayInputStream; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.FileTime; import java.time.Instant; import java.util.Map; import java.util.Optional; import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Rule; import org.junit.Test; public class InteractiveReportIntegrationTest { private static final String BUILD_PATH = "buck-out/log/" + "2016-06-21_16h16m24s_buildcommand_ac8bd626-6137-4747-84dd-5d4f215c876c/"; private static final String DEPS_PATH = "buck-out/log/" + "2016-06-21_16h18m51s_autodepscommand_d09893d5-b11e-4e3f-a5bf-70c60a06896e/"; private static final String WATCHMAN_DIAG_COMMAND = "watchman-diag"; private static final ImmutableMap<String, String> TIMESTAMPS = ImmutableMap.of( BUILD_PATH, "2016-06-21T16:16:24.00Z", DEPS_PATH, "2016-06-21T16:18:51.00Z"); private ProjectWorkspace traceWorkspace; private String tracePath1; private String tracePath2; @Rule public TemporaryPaths temporaryFolder = new TemporaryPaths(); @Before public void setUp() throws Exception { tracePath1 = BUILD_PATH + "file.trace"; tracePath2 = DEPS_PATH + "file.trace"; traceWorkspace = TestDataHelper.createProjectWorkspaceForScenario(this, "report", temporaryFolder); traceWorkspace.setUp(); traceWorkspace.writeContentsToPath(new String(new char[32 * 1024]), tracePath1); traceWorkspace.writeContentsToPath(new String(new char[64 * 1024]), tracePath2); ProjectFilesystem filesystem = traceWorkspace.asCell().getFilesystem(); for (Map.Entry<String, String> timestampEntry : TIMESTAMPS.entrySet()) { for (Path path : filesystem.getDirectoryContents(Paths.get(timestampEntry.getKey()))) { filesystem.setLastModifiedTime( path, FileTime.from(Instant.parse(timestampEntry.getValue()))); } } } @Test public void testReport() throws Exception { ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario(this, "report", temporaryFolder); workspace.setUp(); DefectSubmitResult report = createDefectReport( workspace, new ByteArrayInputStream("0,1\nreport text\n".getBytes("UTF-8"))); Path reportFile = workspace.asCell().getFilesystem().resolve(report.getReportSubmitLocation().get()); ZipInspector zipInspector = new ZipInspector(reportFile); zipInspector.assertFileExists("report.json"); zipInspector.assertFileExists(BUILD_PATH + "buck.log"); zipInspector.assertFileExists(DEPS_PATH + "buck.log"); } @Test public void testTraceInReport() throws Exception { DefectSubmitResult report = createDefectReport( traceWorkspace, new ByteArrayInputStream("1\nreport text\n".getBytes("UTF-8"))); Path reportFile = traceWorkspace.asCell().getFilesystem().resolve(report.getReportSubmitLocation().get()); ZipInspector zipInspector = new ZipInspector(reportFile); zipInspector.assertFileExists(tracePath1); } @Test public void testTraceRespectReportSize() throws Exception { DefectSubmitResult report = createDefectReport( traceWorkspace, new ByteArrayInputStream("0,1\nreport text\n".getBytes("UTF-8"))); Path reportFile = traceWorkspace.asCell().getFilesystem().resolve(report.getReportSubmitLocation().get()); ZipInspector zipInspector = new ZipInspector(reportFile); // The second command was more recent, so its file should be included. zipInspector.assertFileExists(tracePath2); zipInspector.assertFileDoesNotExist(tracePath1); } @Test public void testLocalConfigurationReport() throws Exception { DefectSubmitResult report = createDefectReport( traceWorkspace, new ByteArrayInputStream("0,1\nreport text\n\n".getBytes("UTF-8"))); Path reportFile = traceWorkspace.asCell().getFilesystem().resolve(report.getReportSubmitLocation().get()); ZipInspector zipInspector = new ZipInspector(reportFile); assertThat( zipInspector.getZipFileEntries(), Matchers.hasItems("buckconfig.local", "bucklogging.local.properties")); } @Test public void testWatchmanDiagReport() throws Exception { DefectSubmitResult report = createDefectReport( traceWorkspace, new ByteArrayInputStream("0,1\nreport text\n\n\n".getBytes("UTF-8"))); Path reportFile = traceWorkspace.asCell().getFilesystem().resolve(report.getReportSubmitLocation().get()); ZipInspector zipInspector = new ZipInspector(reportFile); assertThat( zipInspector.getZipFileEntries(), Matchers.hasItem(Matchers.stringContainsInOrder("watchman-diag-report"))); } private static FakeProcessExecutor createFakeWatchmanDiagProcessExecutor(Console console) { return new FakeProcessExecutor( params -> { if (params.getCommand().get(0).equals(WATCHMAN_DIAG_COMMAND)) { return new FakeProcess(0, "fake watchman diag", ""); } else { return new FakeProcess(33); } }, console); } private static DefectSubmitResult createDefectReport( ProjectWorkspace workspace, ByteArrayInputStream inputStream) throws IOException, InterruptedException { ProjectFilesystem filesystem = workspace.asCell().getFilesystem(); RageConfig rageConfig = RageConfig.of(workspace.asCell().getBuckConfig()); Clock clock = new DefaultClock(); ExtraInfoCollector extraInfoCollector = Optional::empty; TestConsole console = new TestConsole(); DefectReporter defectReporter = new DefaultDefectReporter( filesystem, rageConfig, BuckEventBusFactory.newInstance(clock), clock); WatchmanDiagReportCollector watchmanDiagReportCollector = new WatchmanDiagReportCollector( filesystem, WATCHMAN_DIAG_COMMAND, createFakeWatchmanDiagProcessExecutor(console)); InteractiveReport interactiveReport = new InteractiveReport( defectReporter, filesystem, console, inputStream, TestBuildEnvironmentDescription.INSTANCE, new VersionControlStatsGenerator(new NoOpCmdLineInterface(), Optional.empty()), rageConfig, extraInfoCollector, Optional.of(watchmanDiagReportCollector)); return interactiveReport.collectAndSubmitResult().get(); } }