Skip to content

Commit

Permalink
Introduce a BuckBuild that mirrors the existing Build test helper
Browse files Browse the repository at this point in the history
Still have some teething problems to work through before
this can be used in anger :)
  • Loading branch information
shs96c committed May 2, 2016
1 parent 65a6604 commit 16a02ed
Show file tree
Hide file tree
Showing 2 changed files with 169 additions and 0 deletions.
1 change: 1 addition & 0 deletions java/client/test/org/openqa/selenium/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ java_library(name = 'large-tests',

java_library(name = 'helpers',
srcs = [
'BuckBuild.java',
'Build.java',
'Pages.java',
'ParallelTestRunner.java',
Expand Down
168 changes: 168 additions & 0 deletions java/client/test/org/openqa/selenium/BuckBuild.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
package org.openqa.selenium;

import static com.google.common.base.StandardSystemProperty.LINE_SEPARATOR;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static org.openqa.selenium.Platform.WINDOWS;
import static org.openqa.selenium.testing.DevMode.isInDevMode;

import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.base.StandardSystemProperty;
import com.google.common.collect.ImmutableList;
import com.google.common.hash.HashCode;
import com.google.common.hash.Hashing;

import org.openqa.selenium.os.CommandLine;
import org.openqa.selenium.testing.InProject;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.logging.Logger;

public class BuckBuild {
private static Logger log = Logger.getLogger(BuckBuild.class.getName());

private String target;

public BuckBuild of(String target) {
this.target = target;
return this;
}

public Path go() throws IOException {
Path projectRoot = InProject.locate("Rakefile").toPath().getParent();

if (!isInDevMode()) {
// we should only need to do this when we're in dev mode
// when running in a test suite, our dependencies should already
// be listed.
log.info("Not in dev mode. Ignoring attempt to build: " + target);
return findOutput(projectRoot);
}

if (target == null || "".equals(target)) {
throw new IllegalStateException("No targets specified");
}
System.out.println("\nBuilding " + target + " ...");

ImmutableList.Builder<String> builder = ImmutableList.builder();
findBuck(projectRoot, builder);
builder.add("build");
builder.add(target);

ImmutableList<String> command = builder.build();
CommandLine commandLine = new CommandLine(command.toArray(new String[command.size()]));
commandLine.copyOutputTo(System.err);
commandLine.execute();

if (!commandLine.isSuccessful()) {
throw new WebDriverException("Build failed! " + target);
}

return findOutput(projectRoot);
}

private Path findOutput(Path projectRoot) throws IOException {
ImmutableList.Builder<String> builder = ImmutableList.builder();
findBuck(projectRoot, builder);
builder.add("targets", "--show-output", target);

ImmutableList<String> command = builder.build();
CommandLine commandLine = new CommandLine(command.toArray(new String[command.size()]));
commandLine.copyOutputTo(System.err);
commandLine.execute();

if (!commandLine.isSuccessful()) {
throw new WebDriverException("Unable to find output! " + target);
}

String[] allLines = commandLine.getStdOut().split(LINE_SEPARATOR.value());
String lastLine = allLines[allLines.length -1 ];

List<String> outputs = Splitter.on(' ').limit(2).splitToList(lastLine);
if (outputs.size() != 2) {
throw new WebDriverException(
String.format("Unable to find output! %s, %s", target, lastLine));
}

Path output = projectRoot.resolve(outputs.get(1));

if (!Files.exists(output)) {
throw new WebDriverException(
String.format("Found output, but it does not exist: %s, %s", target, output));
}

return output;
}

private void findBuck(Path projectRoot, ImmutableList.Builder<String> builder) throws IOException {
Path noBuckCheck = projectRoot.resolve(".nobuckcheck");

// If there's a .nobuckcheck in the root of the file, and we can execute "buck", then assume
// that the developer knows what they're doing. Ha! Ahaha! Ahahahaha!
if (Files.exists(noBuckCheck)) {
String buckCommand = CommandLine.find("buck");
if (buckCommand != null) {
builder.add(buckCommand);
return;
}
}

downloadBuckPexIfNecessary(builder);
}

private void downloadBuckPexIfNecessary(ImmutableList.Builder<String> builder)
throws IOException {
String buckVersion = new String(Files.readAllBytes(Paths.get(".buckversion"))).trim();

Path pex = Paths.get(
StandardSystemProperty.USER_HOME.value(), ".crazyfun", "buck", buckVersion, "buck.pex");

String expectedHash = new String(Files.readAllBytes(Paths.get(".buckhash"))).trim();
HashCode md5 = Files.exists(pex) ?
Hashing.md5().hashBytes(Files.readAllBytes(pex)) :
HashCode.fromString("aa"); // So we have a non-null value

if (!Files.exists(pex) || !expectedHash.equals(md5.toString())) {
log.warning("Downloading PEX");

if (!Files.exists(pex.getParent())) {
Files.createDirectories(pex.getParent());
}

URL url = new URL(String.format(
"https://github.com/SeleniumHQ/buck/releases/download/buck-release-%s/buck.pex",
buckVersion));
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setInstanceFollowRedirects(true);
Files.copy(connection.getInputStream(), pex, REPLACE_EXISTING);
// Do our best to make this executable
pex.toFile().setExecutable(true);
}

md5 = Hashing.md5().hashBytes(Files.readAllBytes(pex));
if (!expectedHash.equals(md5.toString())) {
throw new WebDriverException("Unable to confirm that download is valid");
}

if (Platform.getCurrent().is(WINDOWS)) {
String python = CommandLine.find("python2");
if (python == null) {
python = CommandLine.find("python");
}
Preconditions.checkNotNull(python, "Unable to find python executable");
builder.add(python);
}

builder.add(pex.toAbsolutePath().toString());
}

public static void main(String[] args) throws IOException {
new BuckBuild().of("se3-server").go();
}
}

0 comments on commit 16a02ed

Please sign in to comment.