/*
* Copyright 2015-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.cli;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeThat;
import static org.junit.Assume.assumeTrue;
import com.facebook.buck.testutil.TestConsole;
import com.facebook.buck.testutil.integration.FakeAppleDeveloperEnvironment;
import com.facebook.buck.testutil.integration.ProjectWorkspace;
import com.facebook.buck.testutil.integration.ProjectWorkspace.ProcessResult;
import com.facebook.buck.testutil.integration.TemporaryPaths;
import com.facebook.buck.testutil.integration.TestDataHelper;
import com.facebook.buck.util.DefaultProcessExecutor;
import com.facebook.buck.util.ProcessExecutor;
import com.facebook.buck.util.ProcessExecutorParams;
import com.facebook.buck.util.environment.Platform;
import com.google.common.collect.ImmutableSet;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
public class InstallCommandIntegrationTest {
@Rule public TemporaryPaths tmp = new TemporaryPaths();
@Test
public void appleBundleInstallsInIphoneSimulator() throws IOException {
assumeThat(Platform.detect(), is(Platform.MACOS));
ProjectWorkspace workspace =
TestDataHelper.createProjectWorkspaceForScenario(this, "apple_app_bundle", tmp);
workspace.setUp();
ProcessResult result = workspace.runBuckCommand("install", "//:DemoApp");
assumeFalse(result.getStderr().contains("no appropriate simulator found"));
result.assertSuccess();
// TODO(beng): If we make the install command output the UDID of the
// simulator, we could poke around in
// ~/Library/Developer/CoreSimulator/[UDID] to see if the bits were installed.
}
@Test
public void appleBundleInstallsAndRunsInIphoneSimulator() throws IOException {
assumeThat(Platform.detect(), is(Platform.MACOS));
ProjectWorkspace workspace =
TestDataHelper.createProjectWorkspaceForScenario(this, "apple_app_bundle", tmp);
workspace.setUp();
ProcessResult result = workspace.runBuckCommand("install", "-r", "//:DemoApp");
assumeFalse(result.getStderr().contains("no appropriate simulator found"));
result.assertSuccess();
}
@Test
public void appleBundleInstallsAndRunsInIphoneSimulatorWithDwarfDebugging()
throws IOException, InterruptedException {
assumeThat(Platform.detect(), is(Platform.MACOS));
ProjectWorkspace workspace =
TestDataHelper.createProjectWorkspaceForScenario(this, "apple_app_bundle", tmp);
workspace.setUp();
workspace.enableDirCache();
// build locally
ProcessResult result =
workspace.runBuckCommand(
"install",
"--config",
"apple.default_debug_info_format_for_binaries=DWARF",
"--config",
"apple.default_debug_info_format_for_libraries=DWARF",
"--config",
"apple.default_debug_info_format_for_tests=DWARF",
"-r",
"//:DemoApp");
assumeFalse(result.getStderr().contains("no appropriate simulator found"));
result.assertSuccess();
// find port to connect lldb to
Pattern p = Pattern.compile("lldb -p \\d{1,6}"); // "lldb -p 12345"
Matcher matcher = p.matcher(result.getStderr());
assertThat(matcher.find(), equalTo(true));
String[] lldbCommand = matcher.group().split(" ");
ProcessExecutor executor = new DefaultProcessExecutor(new TestConsole());
// run lldb session
ProcessExecutor.Result lldbResult =
executor.launchAndExecute(
ProcessExecutorParams.builder().addCommand(lldbCommand).build(),
ImmutableSet.of(),
Optional.of("b application:didFinishLaunchingWithOptions:\nb\nexit\nY\n"),
Optional.empty(),
Optional.empty());
assertThat(lldbResult.getExitCode(), equalTo(0));
// check that lldb resolved breakpoint locations
String lldbOutput = lldbResult.getStdout().orElse("");
assertThat(lldbOutput, containsString("Current breakpoints:"));
assertThat(
lldbOutput,
containsString(
"name = 'application:didFinishLaunchingWithOptions:', "
+ "locations = 1, resolved = 1, hit count = 0"));
// clean buck out
workspace.runBuckCommand("clean");
// build again - get everything from cache now
result =
workspace.runBuckCommand(
"install",
"--config",
"apple.default_debug_info_format_for_binaries=DWARF",
"--config",
"apple.default_debug_info_format_for_libraries=DWARF",
"--config",
"apple.default_debug_info_format_for_tests=DWARF",
"-r",
"//:DemoApp");
result.assertSuccess();
matcher = p.matcher(result.getStderr());
assertThat(matcher.find(), equalTo(true));
String[] lldbCommand2 = matcher.group().split(" ");
// run lldb session again - now on top of files fetched from cache
lldbResult =
executor.launchAndExecute(
ProcessExecutorParams.builder().addCommand(lldbCommand2).build(),
ImmutableSet.of(),
Optional.of("b application:didFinishLaunchingWithOptions:\nb\nexit\nY\n"),
Optional.empty(),
Optional.empty());
assertThat(lldbResult.getExitCode(), equalTo(0));
// check that lldb resolved breakpoint locations with files from cache
lldbOutput = lldbResult.getStdout().orElse("");
assertThat(lldbOutput, containsString("Current breakpoints:"));
assertThat(
lldbOutput,
containsString(
"name = 'application:didFinishLaunchingWithOptions:', "
+ "locations = 1, resolved = 1, hit count = 0"));
}
@Test
public void appleBundleInstallsInDeviceWithHelperAsPath()
throws IOException, InterruptedException {
assumeThat(Platform.detect(), is(Platform.MACOS));
assumeTrue(FakeAppleDeveloperEnvironment.supportsBuildAndInstallToDevice());
ProjectWorkspace workspace =
TestDataHelper.createProjectWorkspaceForScenario(this, "apple_app_bundle", tmp);
workspace.setUp();
assumeTrue(Files.exists(workspace.getPath("fbsimctl/fbsimctl")));
assumeTrue(
FakeAppleDeveloperEnvironment.hasDeviceCurrentlyConnected(
workspace.getPath("fbsimctl/fbsimctl")));
ProcessResult result = workspace.runBuckCommand("install", "//:DemoApp#iphoneos-arm64");
result.assertSuccess();
}
// Disabled until fbsimctl builds properly with Buck
@Ignore
@Test
public void appleBundleInstallsInDeviceWithHelperAsTarget()
throws IOException, InterruptedException {
assumeThat(Platform.detect(), is(Platform.MACOS));
assumeTrue(FakeAppleDeveloperEnvironment.supportsBuildAndInstallToDevice());
ProjectWorkspace workspace =
TestDataHelper.createProjectWorkspaceForScenario(
this, "apple_app_bundle_with_device_helper_as_target", tmp);
workspace.setUp();
assumeTrue(
FakeAppleDeveloperEnvironment.hasDeviceCurrentlyConnected(
workspace.getPath("fbsimctl/fbsimctl")));
ProcessResult result = workspace.runBuckCommand("install", "//:DemoApp#iphoneos-arm64");
result.assertSuccess();
}
}