package net.sf.expectit.ant;
/*
* #%L
* ExpectIt
* %%
* Copyright (C) 2014 Alexey Gavrilov and contributors
* %%
* 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.
* #L%
*/
import static org.junit.Assert.fail;
import static org.junit.runners.Parameterized.Parameters;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.io.Resources;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.URL;
import java.util.TreeSet;
import org.apache.ftpserver.FtpServer;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.listener.Listener;
import org.apache.ftpserver.listener.ListenerFactory;
import org.apache.ftpserver.usermanager.impl.BaseUser;
import org.apache.sshd.SshServer;
import org.apache.sshd.server.PasswordAuthenticator;
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
import org.apache.sshd.server.session.ServerSession;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DefaultLogger;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectHelper;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
/**
* A test harness for running Ant targets.
*/
@RunWith(Parameterized.class)
public class AntHarnessTest {
private static FtpServer ftpServer;
private static int ftpPort;
private static SshServer sshServer;
private static int sshPort;
@BeforeClass
public static void startFtpServer() throws FtpException {
FtpServerFactory serverFactory = new FtpServerFactory();
BaseUser user = new BaseUser();
user.setName("ftp");
user.setPassword("secret");
serverFactory.getUserManager().save(user);
ListenerFactory factory = new ListenerFactory();
factory.setPort(0);
Listener listener = factory.createListener();
serverFactory.addListener("default", listener);
ftpServer = serverFactory.createServer();
ftpServer.start();
ftpPort = listener.getPort();
}
@BeforeClass
public static void startSshServer() throws IOException {
sshServer = SshServer.setUpDefaultServer();
ServerSocket serverSocket = new ServerSocket(0);
sshPort = serverSocket.getLocalPort();
serverSocket.close();
sshServer.setPort(sshPort);
sshServer.setPasswordAuthenticator(
new PasswordAuthenticator() {
@Override
public boolean authenticate(
String username,
String password,
ServerSession session) {
return "ssh".equals(username) && "secret".equals(password);
}
});
sshServer.setShellFactory(new SshEchoCommandFactory());
sshServer.setKeyPairProvider(new SimpleGeneratorHostKeyProvider());
sshServer.start();
}
@AfterClass
public static void stopServers() throws FtpException, InterruptedException {
ftpServer.stop();
sshServer.stop();
}
private static File buildFile;
private static void setupBuildFile() throws IOException {
if (buildFile != null) {
return;
}
buildFile = File.createTempFile("build", ".xml");
buildFile.deleteOnExit();
URL url = Resources.getResource("build-test.xml");
Resources.copy(url, new FileOutputStream(buildFile));
}
@Parameters(name = "{0}")
public static Iterable<Object[]> data() throws IOException {
Project project = newProject();
Function<String, Object[]> toTargetArray = new Function<String, Object[]>() {
@Override
public Object[] apply(String input) {
return new Object[]{input};
}
};
Iterable<String> filtered = Iterables.filter(
new TreeSet<String>(project.getTargets().keySet()),
new Predicate<String>() {
@Override
public boolean apply(String input) {
return !input.isEmpty();
}
}
);
return Iterables.transform(filtered, toTargetArray);
}
private static Project newProject() throws IOException {
setupBuildFile();
Project project = new Project();
project.setUserProperty("ant.file", buildFile.getAbsolutePath());
project.init();
DefaultLogger listener = new DefaultLogger();
listener.setErrorPrintStream(System.err);
listener.setOutputPrintStream(System.out);
listener.setMessageOutputLevel(Project.MSG_INFO);
ProjectHelper helper = ProjectHelper.getProjectHelper();
project.addReference("ant.projectHelper", helper);
project.setProperty("ftp.port", String.valueOf(ftpPort));
project.setProperty("ssh.port", String.valueOf(sshPort));
helper.parse(project, buildFile);
project.addBuildListener(listener);
return project;
}
private final String target;
public AntHarnessTest(String target) {
this.target = target;
}
@Test
public void runTarget() throws IOException {
Project project = newProject();
project.log("started: " + target);
// prepare
project.executeTarget("");
boolean negative = target.endsWith("-negative");
// run test
try {
project.executeTarget(target);
if (negative) {
fail("Negative test fails");
}
} catch (BuildException e) {
e.printStackTrace();
if (!negative) {
fail("Positive test fails");
}
} finally {
project.log("finished");
}
}
}