/* * Copyright 2017 ThoughtWorks, 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.thoughtworks.go.helper; import com.thoughtworks.go.config.materials.perforce.P4Material; import com.thoughtworks.go.config.materials.perforce.P4MaterialConfig; import com.thoughtworks.go.domain.materials.Material; import com.thoughtworks.go.domain.materials.Modification; import com.thoughtworks.go.domain.materials.TestSubprocessExecutionContext; import com.thoughtworks.go.domain.materials.perforce.P4Client; import com.thoughtworks.go.domain.materials.perforce.PerforceFixture; import com.thoughtworks.go.util.*; import com.thoughtworks.go.util.command.*; import java.io.File; import java.io.IOException; import java.util.*; import static com.thoughtworks.go.util.ExceptionUtils.bomb; import static com.thoughtworks.go.util.command.CommandLine.createCommandLine; import static com.thoughtworks.go.util.command.ProcessOutputStreamConsumer.inMemoryConsumer; import static org.apache.commons.io.FileUtils.copyDirectory; public class P4TestRepo extends TestRepo { protected File tempRepo; private ProcessWrapper p4dProcess; private final int port; private String user; private String password; private String clientName; private boolean useTickets; private File clientFolder; private P4TestRepo(int port, String repoPrototype, String user, String password, String clientName, boolean useTickets) { this.port = port; this.user = user; this.password = password; this.clientName = clientName; this.useTickets = useTickets; tempRepo = TestFileUtil.createTempFolder("testP4Repo-" + System.currentTimeMillis()); try { copyDirectory(new File(repoPrototype), tempRepo); } catch (IOException e) { bomb(e); } } public void onSetup() throws Exception { clientFolder = TestFileUtil.createTempFolder("p4Client"); p4dProcess = startP4dInRepo(tempRepo); waitForP4dToStartup(); } @Override public Material material() { return createMaterial(); } private void waitForP4dToStartup() throws Exception { CommandLine command = createCommandLine("p4").withArgs("-p", serverAndPort(), "info"); command.waitForSuccess(60 * 1000); } public void onTearDown() { Process process = (Process) ReflectionUtil.getField(p4dProcess, "process"); process.destroy(); FileUtil.deleteFolder(tempRepo); FileUtil.deleteFolder(clientFolder); } public String projectRepositoryUrl() { return serverAndPort(); } public List<Modification> checkInOneFile(String fileName, String comment) throws Exception { return checkInOneFile(createMaterial(), fileName, comment); } private P4Material createMaterial() { P4Material p4Material1 = new P4Material(serverAndPort(), "//depot/... //something/..."); p4Material1.setFolder("anything"); return p4Material1; } public List<Modification> latestModification() { File workingDir = TestFileUtil.createTempFolder("p4-working-dir-" + UUID.randomUUID()); return createMaterial().latestModification(workingDir, new TestSubprocessExecutionContext()); } public void stop() { CommandLine command = createCommandLine("p4").withArgs("-p", serverAndPort(), "admin", "stop"); ProcessOutputStreamConsumer outputStreamConsumer = inMemoryConsumer(); command.run(outputStreamConsumer,null); } private ProcessWrapper startP4dInRepo(File tempRepo) throws IOException, CheckedCommandLineException { CommandLine command = createCommandLine("p4d").withArgs("-C0", "-r", tempRepo.getAbsolutePath(), "-p", String.valueOf(port)); ProcessOutputStreamConsumer outputStreamConsumer = inMemoryConsumer(); return command.execute(outputStreamConsumer, new EnvironmentVariableContext(),null); } public String serverAndPort() { return "localhost:" + port; } public static P4TestRepo createP4TestRepo() throws IOException { String repo = "../common/test-resources/unit/data/p4repo"; if (SystemUtil.isWindows()) { repo = "../common/test-resources/unit/data/p4repoWindows"; } return new P4TestRepo(RandomPort.find("P4TestRepo"), repo, "cceuser", null, PerforceFixture.DEFAULT_CLIENT_NAME, false); } public static P4TestRepo createP4TestRepoWithTickets() throws IOException { String repo = "../common/test-resources/unit/data/p4TicketedRepo"; if (SystemUtil.isWindows()) { repo = "../common/test-resources/unit/data/p4TicketedRepoWindows"; } return new P4TestRepo(RandomPort.find("P4TestRepoWithTickets"), repo, "cceuser", "1234abcd", PerforceFixture.DEFAULT_CLIENT_NAME, true); } public static P4TestRepo createP4RepoOPS(String repoPrototype) { return new P4TestRepo(RandomPort.find("P4RepoOPS"), repoPrototype, "cceuser", null, PerforceFixture.DEFAULT_CLIENT_NAME, false); } public P4Material material(String p4view) { P4Material p4Material = new P4Material(serverAndPort(), p4view); p4Material.setUsername(user); p4Material.setPassword(password); p4Material.setUseTickets(useTickets); return p4Material; } public P4MaterialConfig materialConfig(String p4view) { P4MaterialConfig p4MaterialConfig = new P4MaterialConfig(serverAndPort(), p4view); p4MaterialConfig.setConfigAttributes(Collections.singletonMap(P4MaterialConfig.USERNAME, user)); p4MaterialConfig.setPassword(password); p4MaterialConfig.setUseTickets(useTickets); return p4MaterialConfig; } public P4Client createClient() throws Exception { return createClientWith(clientName, null); } public P4Client createClientWith(String clientName, String view) throws Exception { String p4view = view == null ? "\n\t//depot/... //" + clientName + "/..." : "\n\t" + view; P4Client p4Client = P4Client.fromServerAndPort(null, serverAndPort(), user, password, clientName, useTickets, clientFolder, p4view, inMemoryConsumer(), true); return p4Client; } public void checkInOneFile(P4Material p4Material1, String fileName) throws Exception { String comment = "added file " + fileName; checkInOneFile(p4Material1, fileName, comment); } private List<Modification> checkInOneFile(P4Material p4Material1, String fileName, String comment) throws Exception { File workingDir = TestFileUtil.createTempFolder("p4-working-dir-" + UUID.randomUUID()); P4Client client = createClient(); client.client(clientConfig(clientName, workingDir), inMemoryConsumer(), true); File dir = new File(workingDir, p4Material1.getFolder()); dir.mkdirs(); checkout(dir); File newFile = new File(new File(workingDir, p4Material1.getFolder()), fileName); newFile.createNewFile(); add(workingDir, newFile.getAbsolutePath()); commit(comment, workingDir); client.removeClient(); List<Modification> modifications = p4Material1.latestModification(workingDir, new TestSubprocessExecutionContext()); return modifications; } protected static String clientConfig(String clientName, File clientFolder) { return "Client: " + clientName + "\n\n" + "Owner: cruise\n\n" + "Root: " + clientFolder.getAbsolutePath() + "\n\n" + "Options: rmdir\n\n" + "LineEnd: local\n\n" + "View:\n" + "\t//depot/... //" + clientName + "/...\n"; } private void checkout(File workingDir) { runP4(workingDir, "-c", clientName, "sync"); } private void add(File workingdir, String fileName) { runP4(workingdir, "-c", clientName, "add", fileName); } private void commit(String message, File workingDir) { runP4(workingDir, "-c", clientName, "-d", workingDir.getAbsolutePath(), "submit", "-d", message); } private void runP4(File workingDir, String... args) { InMemoryStreamConsumer consumer2 = inMemoryConsumer(); List<String> arrays = new ArrayList<>(); arrays.add("-p"); arrays.add(serverAndPort()); arrays.addAll(Arrays.asList(args)); CommandLine command = createCommandLine("p4").withWorkingDir(workingDir).withArgs("-p", serverAndPort()).withArgs(args); command.run(consumer2,null); } public String getUser() { return user; } public String getPassword() { return password; } }