content: 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");
          }
      }
  
  }
  