/**
 * JaDOrT: JASMINe Deployment Orchestration Tool
 * Copyright (C) 2008-2009 Bull S.A.S.
 * Copyright (C) 2008-2009 France Telecom R&D
 * Contact: jasmine@ow2.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id: JadortServiceTest.java 6155 2010-03-12 18:18:46Z alitokmen $
 * --------------------------------------------------------------------------
 */
package org.ow2.jasmine.jadort.itests.implementation;

import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.apache.commons.io.FileUtils;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.ow2.jasmine.jadort.api.IJadortService;
import org.ow2.jasmine.jadort.api.JadortServiceException;
import org.ow2.jasmine.jadort.api.IJadortService.OperationType;
import org.ow2.jasmine.jadort.api.entities.deployment.ApplicationBean;
import org.ow2.jasmine.jadort.api.entities.deployment.OperationStateBean;
import org.ow2.jasmine.jadort.api.entities.deployment.ServerProgressBean;
import org.ow2.jasmine.jadort.api.entities.deployment.ServerProgressState;
import org.ow2.jasmine.jadort.api.entities.deployment.WorkerProgressBean;
import org.ow2.jasmine.jadort.api.entities.deployment.WorkerProgressState;
import org.ow2.jasmine.jadort.api.entities.deployment.ApplicationBean.ApplicationType;
import org.ow2.jasmine.jadort.api.entities.deployment.OperationStateBean.ActionState;
import org.ow2.jasmine.jadort.api.entities.deployment.OperationStateBean.Step;
import org.ow2.jasmine.jadort.api.entities.topology.GroupBean;
import org.ow2.jasmine.jadort.api.entities.topology.ServerBean;
import org.ow2.jasmine.jadort.service.action.DummyServerAction;
import org.ow2.jasmine.jadort.service.action.DummyWorkerAction;
import org.ow2.jasmine.jadort.service.implementation.JMSSender;
import org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean;
import org.ow2.util.archive.api.ArchiveException;
import org.ow2.util.ee.deploy.impl.helper.DeployableHelperException;

/**
 * Tests the JaDOrT service implementation.
 * 
 * @author Malek Chahine
 * @author Remy Bresson
 * @author S. Ali Tokmen
 */
public class JadortServiceTest {

    /**
     * If you want to test the whole JaDOrT service for real, set this variable
     * to true. Note that before launching this test in that mode, you must
     * deploy the JaDOrT service on a Java EE server.
     */
    private static final boolean IN_J2EE_SERVER = true;

    /**
     * Initial Context Factory.
     */
    private static final String INITIAL_CONTEXT_FACTORY = "org.ow2.carol.jndi.spi.MultiOrbInitialContextFactory";

    /**
     * Timeout (in seconds) for JaDOrT to initialize.
     */
    private static final int INITIALIZE_TIMEOUT = 30;

    /**
     * Timeout (in seconds) for each serverProgress test.
     */
    private static final int TEST_TIMEOUT = 100;

    /**
     * Check period (in milliseconds) for the waitForFinish methods.
     */
    private static final int CHECK_PERIOD = 10;

    /**
     * Test types.
     */
    private static enum TestType {
        NO_CLUSTER, CLUSTER, TARGET
    }

    private IJadortService jadortService;

    // These need to be static since the test class is recreated at each
    // test but we'd like to keep a state log between tests
    private static String operationName;

    private static OperationStateBean operationBeanForVersion1;

    private static OperationStateBean operationBeanForVersion2;

    private static OperationStateBean operationBeanForMaintainServer1;

    private static OperationStateBean operationBeanForMaintainServer2;

    private static OperationStateBean operationBeanForMaintainNoClusterServer;

    private static IJadortService connectToJadortService() throws Exception {
        IJadortService result;
        if (JadortServiceTest.IN_J2EE_SERVER) {
            String carolPortString = System.getProperty("carol.port");
            Assert.assertNotNull("carol.port not set!", carolPortString);
            int carolPort = Integer.parseInt(carolPortString);

            Hashtable<String, Object> env = new Hashtable<String, Object>();
            env.put(Context.INITIAL_CONTEXT_FACTORY, JadortServiceTest.INITIAL_CONTEXT_FACTORY);
            env.put(Context.PROVIDER_URL, "rmi://localhost:" + carolPort);
            final long timeout = System.currentTimeMillis() + JadortServiceTest.INITIALIZE_TIMEOUT * 1000;
            while (true) {
                try {
                    Context context = new InitialContext(env);
                    result = (IJadortService) context.lookup(IJadortService.EJB_JNDI_NAME);
                    break;
                } catch (NamingException e) {
                    if (System.currentTimeMillis() > timeout) {
                        throw e;
                    } else {
                        Thread.sleep(1000);
                    }
                }
            }
        } else {
            DummyServerAction.MAX_SLEEP = 1;
            DummyWorkerAction.MAX_SLEEP = 1;
            JadortServiceStatefulBean jadortService = new JadortServiceStatefulBean();
            jadortService.em = new DummyEntityManager();
            JMSSender.session = new DummyQueueSession(jadortService.em);
            result = jadortService;
        }
        Assert.assertNull(result.getCurrentOperation());
        return result;
    }

    /**
     * @throws java.lang.Exception
     */
    @BeforeClass
    public static void staticSetUp() throws Exception {
        JadortServiceTest.operationName = "JadortServiceTest#" + UUID.randomUUID();
    }

    /**
     * @throws java.lang.Exception
     */
    @AfterClass
    public static void staticTearDown() throws Exception {
        IJadortService jadortService = JadortServiceTest.connectToJadortService();

        List<OperationStateBean> ops = jadortService.getOperationsList();
        for (OperationStateBean op : ops) {
            if (op.getName().equals(JadortServiceTest.operationName)) {
                jadortService.deleteOperation(op);
                // Don't break: each test has created an operation and the same
                // name is used each time.
            }
        }

        JadortServiceTest.operationName = null;
    }

    /**
     * @throws java.lang.Exception
     */
    @Before
    public void setUp() throws Exception {
        this.jadortService = JadortServiceTest.connectToJadortService();
    }

    /**
     * @throws java.lang.Exception
     */
    @After
    public void tearDown() throws Exception {
        this.jadortService = null;
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#createApplicationBeanFromFile(java.io.File)}
     * with a valid file.
     */
    @Test
    public void testApplicationBeanWithValidFile() throws Exception {
        File file = new File("src/test/resources/application1.ear");

        ApplicationBean application = JadortServiceStatefulBean.createApplicationBeanFromFile(file);
        Assert.assertNotNull(application);
        Assert.assertEquals(file, application.getFile());
        Assert.assertEquals(ApplicationType.JAVA_EE, application.getApplicationType());
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#createApplicationBeanFromFile(java.io.File)}
     * with an invalid file.
     */
    @Test
    public void testApplicationBeanWithInvalidFile() throws Exception {
        File file = new File("src/test/resources/noApplication.war");

        try {
            JadortServiceStatefulBean.createApplicationBeanFromFile(file);
            Assert.fail();
        } catch (DeployableHelperException e) {
            // That failure is expected
        } catch (ArchiveException e) {
            // That failure is expected
        }
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#createApplicationBeanFromFile(java.io.File)}
     * with a bundle.
     */
    @Test
    public void testApplicationBeanWithBundle() throws Exception {
        File file = new File("src/test/resources/ow2-util-jmx-api-1.0.18.jar");

        ApplicationBean application = JadortServiceStatefulBean.createApplicationBeanFromFile(file);
        Assert.assertNotNull(application);
        Assert.assertEquals(file, application.getFile());
        Assert.assertEquals(ApplicationType.OSGI, application.getApplicationType());
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#createNewOperation(String)}
     * .
     */
    @Test
    public void testCreateNewOperation() throws Exception {
        this.jadortService.createNewOperation(JadortServiceTest.operationName);
        Assert.assertNotNull(this.jadortService.getCurrentOperation());
        Assert.assertEquals(JadortServiceTest.operationName, this.jadortService.getCurrentOperation().getName());
        Assert.assertEquals(Step.INITIALIZE_TOPOLOGY, this.jadortService.getCurrentOperation().getCurrentStep());
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#selectOperation(OperationStateBean)}
     * .
     */
    @Test
    public void testSelectOperation() throws Exception {
        System.out.println("JadortServiceTest.testSelectOperation");

        List<OperationStateBean> ops = this.jadortService.getOperationsList();
        for (OperationStateBean op : ops) {
            if (op.getName().equals(JadortServiceTest.operationName)) {
                this.jadortService.selectOperation(op);
                Assert.assertEquals(JadortServiceTest.operationName, this.jadortService.getCurrentOperation().getName());
                Assert.assertEquals(Step.INITIALIZE_TOPOLOGY, this.jadortService.getCurrentOperation().getCurrentStep());
                return;
            }
        }

        Assert.fail("Cannot find operation named \"" + JadortServiceTest.operationName + "\"");
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#getCurrentOperation()}
     * .
     */
    @Test
    public void testGetCurrentOperation() throws Exception {
        System.out.println("JadortServiceTest.testGetCurrentOperation");

        this.testSelectOperation();

        this.jadortService.getCurrentOperation();
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#loadTopology(String)}
     * with a valid topology XML with many different kinds of servers.
     */
    @Test
    public void testValidTopology_heterogeneousServers() throws Exception {
        System.out.println("JadortServiceTest.testValidTopology_heterogeneousServers");

        this.testCreateNewOperation();

        File topo = new File("../jadort-documentation-and-samples/src/main/resources/Topology with heterogeneous servers.xml");
        this.jadortService.loadTopology(FileUtils.readFileToString(topo));
        Assert.assertEquals(Step.INITIALIZE_TOPOLOGY, this.jadortService.getCurrentOperation().getCurrentStep());
        // Don't go next, we don't have that many servers in the CI !!

        OperationStateBean operation = this.jadortService.getCurrentOperation();
        Assert.assertNotNull(operation);
        Assert.assertNotNull(operation.getTopology());
        Assert.assertNotNull(operation.getTopology().getGroups());

        Set<ServerBean.Type> serverTypes = new HashSet<ServerBean.Type>();
        for (GroupBean group : operation.getTopology().getGroups()) {
            Assert.assertNotNull(group.getServers());
            for (ServerBean server : group.getServers()) {
                Assert.assertNotNull(group.getServers());
                serverTypes.add(server.getType());
            }
        }

        Assert.assertTrue(serverTypes.contains(ServerBean.Type.GLASSFISH));
        Assert.assertTrue(serverTypes.contains(ServerBean.Type.JBOSS));
        Assert.assertTrue(serverTypes.contains(ServerBean.Type.JONAS));
        Assert.assertTrue(serverTypes.contains(ServerBean.Type.WEBLOGIC));
        Assert.assertTrue(serverTypes.contains(ServerBean.Type.WEBSPHERE));
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#loadTopology(String)}
     * with a valid topology XML with an OSGi server.
     */
    @Test
    public void testValidTopology_osgiServer() throws Exception {
        System.out.println("JadortServiceTest.testValidTopology_osgiServer");

        this.testCreateNewOperation();

        File topo = new File("../jadort-documentation-and-samples/src/main/resources/Topology with OSGi servers.xml");
        this.jadortService.loadTopology(FileUtils.readFileToString(topo));
        Assert.assertEquals(Step.INITIALIZE_TOPOLOGY, this.jadortService.getCurrentOperation().getCurrentStep());
        // Don't go next, we don't have that many servers in the CI !!

        OperationStateBean operation = this.jadortService.getCurrentOperation();
        Assert.assertNotNull(operation);
        Assert.assertNotNull(operation.getTopology());
        Assert.assertNotNull(operation.getTopology().getGroups());
        Assert.assertEquals(1, operation.getTopology().getGroups().size());

        GroupBean osgiGroup = operation.getTopology().getGroups().get(0);
        Assert.assertEquals("osgiGroup", osgiGroup.getName());

        Assert.assertNotNull(osgiGroup.getServers());
        Assert.assertEquals(1, osgiGroup.getServers().size());
        ServerBean osgiServer = osgiGroup.getServers().get(0);
        Assert.assertEquals("osgi", osgiServer.getName());
        Assert.assertEquals(ServerBean.Type.OSGI, osgiServer.getType());
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#loadTopology(String)}
     * with a valid and mixed topology XML.
     */
    @Test
    public void testValidTopology_manyServers() throws Exception {
        System.out.println("JadortServiceTest.testValidTopology_manyServers");

        this.testCreateNewOperation();

        File topo = new File("src/test/resources/topologyOK_manyServers.xml");
        this.jadortService.loadTopology(FileUtils.readFileToString(topo));
        Assert.assertEquals(Step.INITIALIZE_TOPOLOGY, this.jadortService.getCurrentOperation().getCurrentStep());

        // Don't go next, we don't have that many servers in the CI !!
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#loadTopology(String)}
     * with a valid topology XML with managers and targets.
     */
    @Test
    public void testValidTopology_manager() throws Exception {
        System.out.println("JadortServiceTest.testValidTopology_manager");

        this.testCreateNewOperation();

        File topo = new File("src/test/resources/topologyOK_manager.xml");
        this.jadortService.loadTopology(FileUtils.readFileToString(topo));
        Assert.assertEquals(Step.INITIALIZE_TOPOLOGY, this.jadortService.getCurrentOperation().getCurrentStep());
        this.jadortService.next();

        ServerBean server = this.jadortService.getCurrentOperation().getTopology().getGroups().get(0).getServers().get(0);
        Assert.assertEquals(ServerBean.Type.DUMMY, server.getType());
        Assert.assertEquals("weblogic1", server.getName());
        Assert.assertNull(server.getManagerConnector());

        Assert.assertEquals(ServerBean.Type.DUMMY, server.getTarget().getType());
        Assert.assertEquals("jonas1", server.getTarget().getName());
        Assert.assertNotNull(server.getTarget().getManagerConnector());
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#loadTopology(String)}
     * with a valid topology XML containing VMs.
     */
    @Test
    public void testValidTopology_VM() throws Exception {
        System.out.println("JadortServiceTest.testValidTopology_VM");

        this.testCreateNewOperation();

        File topo = new File("src/test/resources/topologyOK_VM.xml");
        this.jadortService.loadTopology(FileUtils.readFileToString(topo));
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#loadTopology(String)}
     * with a valid topology XML containing dummy servers.
     */
    @Test
    public void testValidTopology_cluster() throws Exception {
        System.out.println("JadortServiceTest.testValidTopology_cluster");

        this.testCreateNewOperation();

        File topo = new File("src/test/resources/topologyOK_cluster.xml");
        this.jadortService.loadTopology(FileUtils.readFileToString(topo));
        this.jadortService.next();
        Assert.assertEquals(Step.SELECT_GROUP, this.jadortService.getCurrentOperation().getCurrentStep());
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#loadTopology(String)}
     * with a valid topology XML containing dummy servers with targets.
     */
    @Test
    public void testValidTopology_target() throws Exception {
        System.out.println("JadortServiceTest.testValidTopology_target");

        this.testCreateNewOperation();

        File topo = new File("src/test/resources/topologyOK_target.xml");
        this.jadortService.loadTopology(FileUtils.readFileToString(topo));
        this.jadortService.next();
        Assert.assertEquals(Step.SELECT_GROUP, this.jadortService.getCurrentOperation().getCurrentStep());
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#loadTopology(String)}
     * with a valid topology XML with two groups inside.
     */
    @Test
    public void testValidTopology_manyGroups() throws Exception {
        System.out.println("JadortServiceTest.testValidTopology_manyGroups");

        this.testCreateNewOperation();

        File topo = new File("src/test/resources/topologyOK_manyGroups.xml");
        this.jadortService.loadTopology(FileUtils.readFileToString(topo));
        this.jadortService.next();
        Assert.assertEquals(Step.SELECT_GROUP, this.jadortService.getCurrentOperation().getCurrentStep());
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#loadTopology(String)}
     * with a valid topology XML with no cluster .
     */
    @Test
    public void testValidTopology_noCluster() throws Exception {
        System.out.println("JadortServiceTest.testValidTopology_noCluster");

        this.testCreateNewOperation();

        File topo = new File("src/test/resources/topologyOK_noCluster.xml");
        this.jadortService.loadTopology(FileUtils.readFileToString(topo));
        this.jadortService.next();
        Assert.assertEquals(Step.SELECT_GROUP, this.jadortService.getCurrentOperation().getCurrentStep());
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#loadTopology(String)}
     * with a topology XML that's in the JASMINe Deploy ME format.
     */
    @Test
    public void testTopology_DeployME() throws Exception {
        System.out.println("JadortServiceTest.testTopology_DeployME");

        this.testCreateNewOperation();

        File topo = new File("src/test/resources/topologyOKDeployME.xml");
        this.jadortService.loadTopology(FileUtils.readFileToString(topo));
        Assert.assertEquals(Step.INITIALIZE_TOPOLOGY, this.jadortService.getCurrentOperation().getCurrentStep());

        List<GroupBean> groups = this.jadortService.getCurrentOperation().getTopology().getGroups();
        Assert.assertEquals(1, groups.size());
        GroupBean domain = groups.get(0);
        Assert.assertFalse(domain.getClustered());
        List<ServerBean> servers = domain.getServers();
        Assert.assertEquals(2, servers.size());

        Assert.assertEquals("service:jmx:iiop://testHost/jndi/iiop://testHost:1000/iiopconnector_jonas1", servers.get(0)
            .getServerConnector().getConnectorUrl());
        Assert.assertEquals("service:jmx:rmi://otherHost/jndi/rmi://otherHost:1001/jrmpconnector_jonas2", servers.get(1)
            .getServerConnector().getConnectorUrl());
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#loadTopology(String)}
     * with a topology XML that's in the JASMINe Deploy ME format.
     */
    @Test
    public void testTopology_DeployMEClustered() throws Exception {
        System.out.println("JadortServiceTest.testTopology_DeployMEClustered");

        this.testCreateNewOperation();

        File topo = new File("src/test/resources/topologyOKDeployME_clustered.xml");
        this.jadortService.loadTopology(FileUtils.readFileToString(topo));
        Assert.assertEquals(Step.INITIALIZE_TOPOLOGY, this.jadortService.getCurrentOperation().getCurrentStep());

        List<GroupBean> groups = this.jadortService.getCurrentOperation().getTopology().getGroups();
        Assert.assertEquals(1, groups.size());
        GroupBean domain = groups.get(0);
        Assert.assertTrue(domain.getClustered());
        List<ServerBean> servers = domain.getServers();
        Assert.assertEquals(2, servers.size());

        Assert.assertEquals("service:jmx:iiop://testHost/jndi/iiop://testHost:1000/iiopconnector_jonas1", servers.get(0)
            .getServerConnector().getConnectorUrl());
        Assert.assertEquals("service:jmx:rmi://otherHost/jndi/rmi://otherHost:1001/jrmpconnector_jonas2", servers.get(1)
            .getServerConnector().getConnectorUrl());
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#loadTopology(String)}
     * with a topology XML that's in the JASMINe Deploy ME format.
     */
    @Test
    public void testTopology_DeployMEWithClusterDaemon() throws Exception {
        System.out.println("JadortServiceTest.testTopology_DeployMEWithClusterDaemon");

        this.testCreateNewOperation();

        File topo = new File("src/test/resources/topologyOKDeployME_cd.xml");
        this.jadortService.loadTopology(FileUtils.readFileToString(topo));
        Assert.assertEquals(Step.INITIALIZE_TOPOLOGY, this.jadortService.getCurrentOperation().getCurrentStep());

        List<GroupBean> groups = this.jadortService.getCurrentOperation().getTopology().getGroups();
        Assert.assertEquals(1, groups.size());
        GroupBean domain = groups.get(0);
        Assert.assertFalse(domain.getClustered());
        List<ServerBean> servers = domain.getServers();
        Assert.assertEquals(1, servers.size());

        Assert.assertEquals("service:jmx:rmi://localhost/jndi/rmi://localhost:1099/jrmpconnector_someRandomServerNamePrefix1",
            servers.get(0).getServerConnector().getConnectorUrl());
        Assert.assertEquals("service:jmx:iiop://localhost/jndi/iiop://localhost:2001/iiopconnector_cd1", servers.get(0)
            .getManagerConnector().getConnectorUrl());
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#loadTopology(String)}
     * with a topology XML that's in the JASMINe Deploy ME format.
     */
    @Test
    public void testTopology_DeployMEWithClusterDaemonWithInvalidServerList() throws Exception {
        System.out.println("JadortServiceTest.testTopology_DeployMEWithClusterDaemonWithInvalidServerList");

        this.testCreateNewOperation();

        File topo = new File("src/test/resources/topologyKODeployME_cd.xml");
        try {
            this.jadortService.loadTopology(FileUtils.readFileToString(topo));
            Assert.fail("loadTopology has accepted invalid topology!");
        } catch (JadortServiceException e) {
            Assert.assertTrue(e.getMessage(), e.getMessage().contains("\n\nCannot find server"));

            // Do a call on the service to ensure it didn't die
            Assert.assertEquals(Step.INITIALIZE_TOPOLOGY, this.jadortService.getCurrentOperation().getCurrentStep());
        }
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#loadTopology(String)}
     * with a valid and old format topology XML.
     */
    @Test
    public void testValidTopology_oldJadortFormat() throws Exception {
        System.out.println("JadortServiceTest.testValidTopology_oldJadortFormat");

        this.testCreateNewOperation();

        File topo = new File("src/test/resources/topologyOK_oldJadortFormat.xml");
        this.jadortService.loadTopology(FileUtils.readFileToString(topo));
        Assert.assertEquals(Step.INITIALIZE_TOPOLOGY, this.jadortService.getCurrentOperation().getCurrentStep());
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#loadTopology(String)}
     * with a valid and old format topology XML.
     */
    @Test
    public void testValidTopology_oldDeployMEFormat() throws Exception {
        System.out.println("JadortServiceTest.testValidTopology_oldDeployMEFormat");

        this.testCreateNewOperation();

        File topo = new File("src/test/resources/topologyOK_oldDeployMEFormat.xml");
        this.jadortService.loadTopology(FileUtils.readFileToString(topo));
        Assert.assertEquals(Step.INITIALIZE_TOPOLOGY, this.jadortService.getCurrentOperation().getCurrentStep());
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#loadTopology(String)}
     * with an invalid topology XML (no server URL).
     */
    @Test
    public void testInvalidTopology_noServerURL() throws Exception {
        System.out.println("JadortServiceTest.testInvalidTopology_noServerURL");

        this.testCreateNewOperation();

        File topo = new File("src/test/resources/topologyKO_noServerURL.xml");
        try {
            this.jadortService.loadTopology(FileUtils.readFileToString(topo));
            Assert.fail("loadTopology has accepted invalid topology!");
        } catch (JadortServiceException e) {
            // Do a call on the service to ensure it didn't die
            Assert.assertEquals(Step.INITIALIZE_TOPOLOGY, this.jadortService.getCurrentOperation().getCurrentStep());
        }
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#loadTopology(String)}
     * with an invalid topology XML (no worker URL).
     */
    @Test
    public void testInvalidTopology_noWorkerURL() throws Exception {
        System.out.println("JadortServiceTest.testInvalidTopology_noWorkerURL");

        this.testCreateNewOperation();

        File topo = new File("src/test/resources/topologyKO_noWorkerURL.xml");
        try {
            this.jadortService.loadTopology(FileUtils.readFileToString(topo));
            Assert.fail("loadTopology has accepted invalid topology!");
        } catch (JadortServiceException e) {
            // Do a call on the service to ensure it didn't die
            Assert.assertEquals(Step.INITIALIZE_TOPOLOGY, this.jadortService.getCurrentOperation().getCurrentStep());
        }
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#loadTopology(String)}
     * with an invalid topology XML (wrong balancer).
     */
    @Test
    public void testInvalidTopology_wrongBalancer() throws Exception {
        System.out.println("JadortServiceTest.testInvalidTopology_wrongBalancer");

        this.testCreateNewOperation();

        File topo = new File("src/test/resources/topologyKO_wrongBalancer.xml");
        try {
            this.jadortService.loadTopology(FileUtils.readFileToString(topo));
            Assert.fail("loadTopology has accepted invalid topology!");
        } catch (JadortServiceException e) {
            // Do a call on the service to ensure it didn't die
            Assert.assertEquals(Step.INITIALIZE_TOPOLOGY, this.jadortService.getCurrentOperation().getCurrentStep());
        }
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#loadTopology(String)}
     * with an XML as topology.
     */
    @Test
    public void testInvalidXMLTopology() throws Exception {
        System.out.println("JadortServiceTest.testNonExistingTopology");

        this.testCreateNewOperation();

        try {
            this.jadortService.loadTopology("this is not XML");
            Assert.fail("loadTopology has accepted a non-existing file!");
        } catch (JadortServiceException e) {
            // Do a call on the service to ensure it didn't die
            Assert.assertEquals(Step.INITIALIZE_TOPOLOGY, this.jadortService.getCurrentOperation().getCurrentStep());
        }
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#selectGroup(GroupBean)}
     * with a migration.
     */
    @Test
    public void testSelectGroupMigrate() throws Exception {
        System.out.println("JadortServiceTest.testSelectGroupMigrate");

        this.testValidTopology_cluster();

        Assert.assertEquals(1, this.jadortService.getCurrentOperation().getTopology().getGroups().size());

        GroupBean toSelect = this.jadortService.getCurrentOperation().getTopology().getGroups().get(0);
        this.jadortService.selectGroup(toSelect);
        Assert.assertEquals(Step.SELECT_GROUP, this.jadortService.getCurrentOperation().getCurrentStep());
        this.jadortService.next();
        Assert.assertEquals(Step.SELECT_OPERATION_TYPE, this.jadortService.getCurrentOperation().getCurrentStep());
        this.jadortService.selectOperationType(OperationType.MIGRATE);
        this.jadortService.next();
        Assert.assertEquals(Step.SELECT_APPLICATION, this.jadortService.getCurrentOperation().getCurrentStep());
        Assert.assertEquals(OperationType.MIGRATE, this.jadortService.getCurrentOperation().getType());
        Assert.assertEquals(toSelect.getId(), this.jadortService.getCurrentOperation().getSelectedGroup().getId());
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#selectApplication(java.net.URL)}
     * with an invalid application file.
     */
    @Test
    public void testCreateInvalidApplication() throws Exception {
        System.out.println("JadortServiceTest.testCreateInvalidApplication");

        this.testSelectGroupMigrate();

        try {
            this.jadortService.selectApplication(new File("noApplication.war").toURL());
            Assert.fail("selectApplication has accepted invalid application!");
        } catch (JadortServiceException e) {
            // Do a call on the service to ensure it didn't die
            Assert.assertEquals(Step.SELECT_APPLICATION, this.jadortService.getCurrentOperation().getCurrentStep());
        }
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#selectApplication(java.net.URL)}
     * with a non-existing application file.
     */
    @Test
    public void testCreateNonExistingApplication() throws Exception {
        System.out.println("JadortServiceTest.testCreateNonExistingApplication");

        this.testSelectGroupMigrate();

        try {
            this.jadortService.selectApplication(new File("/dev/null").toURL());
            Assert.fail("selectApplication has accepted invalid application!");
        } catch (JadortServiceException e) {
            // Do a call on the service to ensure it didn't die
            Assert.assertEquals(Step.SELECT_APPLICATION, this.jadortService.getCurrentOperation().getCurrentStep());
        }
    }

    /**
     * Integration test for application migration (forward).
     */
    @Test(timeout = JadortServiceTest.TEST_TIMEOUT * 1000)
    public void testDeployVersion1() throws Exception {
        System.out.println("JadortServiceTest.testDeployVersion1");

        this.deployApplication("src/test/resources/application1v1/application1.ear", false);
        JadortServiceTest.operationBeanForVersion1 = this.jadortService.getCurrentOperation();
    }

    /**
     * Integration test for application migration (forward).
     */
    @Test(timeout = JadortServiceTest.TEST_TIMEOUT * 1000)
    public void testDeployVersion2() throws Exception {
        System.out.println("JadortServiceTest.testDeployVersion2");

        this.deployApplication("src/test/resources/application1v2/application1.ear", false);
        JadortServiceTest.operationBeanForVersion2 = this.jadortService.getCurrentOperation();
    }

    /**
     * Integration test for application migration (backwards).
     */
    @Test(timeout = JadortServiceTest.TEST_TIMEOUT * 1000)
    public void testUndeployVersion2() throws Exception {
        System.out.println("JadortServiceTest.testUndeployVersion2");

        Assert.assertNotNull(JadortServiceTest.operationBeanForVersion2);
        Assert.assertNotNull(JadortServiceTest.operationBeanForVersion2.getId());

        this.jadortService.selectOperation(JadortServiceTest.operationBeanForVersion2);
        Assert.assertNotNull(this.jadortService.getCurrentOperation());

        this.undeployApplication();
    }

    /**
     * Integration test for application migration (backwards).
     */
    @Test(timeout = JadortServiceTest.TEST_TIMEOUT * 1000)
    public void testUndeployVersion1() throws Exception {
        System.out.println("JadortServiceTest.testUndeployVersion1");

        Assert.assertNotNull(JadortServiceTest.operationBeanForVersion1);
        Assert.assertNotNull(JadortServiceTest.operationBeanForVersion1.getId());

        this.jadortService.selectOperation(JadortServiceTest.operationBeanForVersion1);
        Assert.assertNotNull(this.jadortService.getCurrentOperation());

        this.undeployApplication();
    }

    /**
     * Integration test for application migration (forward, complete).
     */
    @Test(timeout = JadortServiceTest.TEST_TIMEOUT * 1000)
    public void testRedeployVersion1() throws Exception {
        System.out.println("JadortServiceTest.testRedeployVersion1");

        this.deployApplication("src/test/resources/application1v1/application1.ear", true);
    }

    /**
     * Integration test for application migration (forward, complete).
     */
    @Test(timeout = JadortServiceTest.TEST_TIMEOUT * 1000)
    public void testRedeployVersion2() throws Exception {
        System.out.println("JadortServiceTest.testRedeployVersion2");

        this.deployApplication("src/test/resources/application1v2/application1.ear", true);
    }

    /**
     * Integration test for application migration with two servers in a group
     */
    @Test(timeout = JadortServiceTest.TEST_TIMEOUT * 1000)
    public void testDeployVersion3() throws Exception {
        System.out.println("JadortServiceTest.testDeployVersion3");

        this.deployApplicationWithTwoServersSelectedSequentally("src/test/resources/application1v3/application1.ear", true);
    }

    /**
     * Integration test for application migration with on two separate group in
     * two phases
     */
    @Test(timeout = JadortServiceTest.TEST_TIMEOUT * 1000)
    public void testDeployInTwoPhases() throws Exception {
        System.out.println("JadortServiceTest.testDeployInTwoPhases");

        this.deployApplicationInTwoPhases("src/test/resources/application2v1/application2.ear",
            "src/test/resources/application2v2/application2.ear", true);
    }

    private void deployApplication(final String applicationPath, final boolean eraseOld) throws Exception {
        System.out.println("\tJadortServiceTest.deployApplication");

        this.testSelectGroupMigrate();

        this.jadortService.selectApplication(new File(applicationPath).toURI().toURL());

        Assert.assertEquals(Step.SELECT_APPLICATION, this.jadortService.getCurrentOperation().getCurrentStep());
        this.jadortService.next();

        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());
        List<ServerBean> serversToSelect = new ArrayList<ServerBean>();
        serversToSelect.addAll(this.jadortService.getCurrentOperation().getSelectedGroup().getServers());
        this.jadortService.selectServers(serversToSelect);
        this.jadortService.next();

        Assert.assertEquals(Step.EXECUTING_MIGRATION, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.INITIAL, 0);

        this.executeMigration();

        if (this.jadortService.getCurrentOperation().getServerProgressList().get(0).getOldDeploymentItem() != null) {
            this.undeployEraseOldVersion(eraseOld);
        } else {
            // Change page
            this.jadortService.next();
            Assert.assertEquals(Step.FINISHED, this.jadortService.getCurrentOperation().getCurrentStep());
        }
    }

    /**
     * Integration test for application migration with an OSGi bundle.
     */
    @Test(timeout = JadortServiceTest.TEST_TIMEOUT * 1000)
    public void testDeployOsgiBundle() throws Exception {
        System.out.println("JadortServiceTest.testDeployOsgiBundle");

        this.deployOsgiBundle("src/test/resources/service-alerte-1.0.0-SNAPSHOT/service-alerte.jar");

        // Change page
        this.jadortService.next();
        Assert.assertEquals(Step.FINISHED, this.jadortService.getCurrentOperation().getCurrentStep());
        Assert.assertNull(this.jadortService.getCurrentOperation().getServerProgressList().iterator().next()
            .getOldDeploymentItem());
    }

    /**
     * Integration test for application migration with an OSGi bundle.
     */
    @Test(timeout = JadortServiceTest.TEST_TIMEOUT * 1000)
    public void testDeployNewVersionOfOsgiBundle() throws Exception {
        System.out.println("JadortServiceTest.testDeployNewVersionOfOsgiBundle");

        this.deployOsgiBundle("src/test/resources/service-alerte-1.0.0/service-alerte.jar");

        // Erase old version
        this.jadortService.next();
        Assert.assertEquals(Step.ERASE_OLD_VERSIONS, this.jadortService.getCurrentOperation().getCurrentStep());
        this.jadortService.next();
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.ERASE_OK, 100);

        // Change page
        this.jadortService.next();
        Assert.assertEquals(Step.FINISHED, this.jadortService.getCurrentOperation().getCurrentStep());
        Assert.assertNotNull(this.jadortService.getCurrentOperation().getServerProgressList().iterator().next()
            .getOldDeploymentItem());
    }

    private void deployOsgiBundle(final String bundlePath) throws Exception {
        System.out.println("\tJadortServiceTest.deployOsgiBundle");

        this.testSelectGroupMigrate();

        this.jadortService.selectApplication(new File(bundlePath).toURI().toURL());

        Assert.assertEquals(Step.SELECT_APPLICATION, this.jadortService.getCurrentOperation().getCurrentStep());
        this.jadortService.next();

        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());
        List<ServerBean> serversToSelect = new ArrayList<ServerBean>();
        serversToSelect.addAll(this.jadortService.getCurrentOperation().getSelectedGroup().getServers());
        this.jadortService.selectServers(serversToSelect);
        this.jadortService.next();

        Assert.assertEquals(Step.EXECUTING_MIGRATION_OSGI, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.INITIAL, 0);

        // Upload bundle
        this.jadortService.next();
        Assert.assertEquals(Step.EXECUTING_MIGRATION_OSGI, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.UPLOAD_OK, 33);

        // Undeploy old version
        this.jadortService.next();
        Assert.assertEquals(Step.EXECUTING_MIGRATION_OSGI, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.UNDEPLOY_OK, 66);

        // Deploy bundle
        this.jadortService.next();
        Assert.assertEquals(Step.EXECUTING_MIGRATION_OSGI, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.DEPLOY_OK, 100);

        Assert.assertEquals(Step.EXECUTING_MIGRATION_OSGI, this.jadortService.getCurrentOperation().getCurrentStep());
    }

    private void executeMigration() throws Exception {
        System.out.println("\tJadortServiceTest.executeMigration");

        // Upload application
        this.jadortService.next();
        Assert.assertEquals(Step.EXECUTING_MIGRATION, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.UPLOAD_OK, 33);

        // Deploy application
        this.jadortService.next();
        Assert.assertEquals(Step.EXECUTING_MIGRATION, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.DEPLOY_OK, 66);

        // Set application as default
        this.jadortService.next();
        Assert.assertEquals(Step.EXECUTING_MIGRATION, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.SET_DEFAULT_OK, 100);
        Assert.assertEquals(Step.EXECUTING_MIGRATION, this.jadortService.getCurrentOperation().getCurrentStep());
    }

    private void undeployEraseOldVersion(final boolean eraseOld) throws Exception {
        System.out.println("\tJadortServiceTest.undeployEraseOldVersion");

        // Change page
        this.jadortService.next();
        Assert.assertEquals(Step.UNDEPLOY_ERASE_OLD_VERSION, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.SET_DEFAULT_OK, 0);

        // Undeploy old version
        this.jadortService.next();
        Assert.assertEquals(Step.UNDEPLOY_ERASE_OLD_VERSION, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.UNDEPLOY_OK, 50);

        if (eraseOld) {
            // Erase old version
            this.jadortService.next();
            Assert.assertEquals(Step.UNDEPLOY_ERASE_OLD_VERSION, this.jadortService.getCurrentOperation().getCurrentStep());
            this.waitForFinishAndCheckServerProgressList(ServerProgressState.ERASE_OK, 100);

            // Change page
            Assert.assertEquals(Step.UNDEPLOY_ERASE_OLD_VERSION, this.jadortService.getCurrentOperation().getCurrentStep());
            this.jadortService.next();
            Assert.assertEquals(Step.FINISHED, this.jadortService.getCurrentOperation().getCurrentStep());
        }
    }

    private void deployApplicationWithTwoServersSelectedSequentally(final String applicationPath, final boolean eraseOld)
        throws Exception {

        System.out.println("\tJadortServiceTest.deployApplicationWithTwoServersSelectedSequentally");

        this.testSelectGroupMigrate();

        this.jadortService.selectApplication(new File(applicationPath).toURI().toURL());
        Assert.assertEquals(Step.SELECT_APPLICATION, this.jadortService.getCurrentOperation().getCurrentStep());
        this.jadortService.next();

        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());
        List<ServerBean> serversToSelect = new ArrayList<ServerBean>();
        Assert.assertFalse(this.jadortService.getCurrentOperation().getSelectedGroup().getServers().get(0).getProcessed());
        ServerBean selectedServer1 = this.jadortService.getCurrentOperation().getSelectedGroup().getServers().get(0);
        serversToSelect.add(selectedServer1);
        // Selected only 1st server
        this.jadortService.selectServers(serversToSelect);
        this.jadortService.next();

        this.executeMigration();

        this.jadortService.next();
        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());
        // 1st server is now processed
        Assert.assertTrue(this.jadortService.getCurrentOperation().getSelectedGroup().getServers().get(0).getProcessed());

        serversToSelect = new ArrayList<ServerBean>();

        ServerBean selectedServer2 = this.jadortService.getCurrentOperation().getSelectedGroup().getServers().get(1);
        serversToSelect.add(selectedServer2);
        ServerBean selectedServer3 = this.jadortService.getCurrentOperation().getSelectedGroup().getServers().get(2);
        serversToSelect.add(selectedServer3);
        // select the other servers
        this.jadortService.selectServers(serversToSelect);

        this.jadortService.next();

        this.executeMigration();

        this.undeployEraseOldVersion(true);

        Assert.assertEquals(Step.FINISHED, this.jadortService.getCurrentOperation().getCurrentStep());
    }

    private void deployApplicationInTwoPhases(final String applicationPathV1, final String applicationPathV2,
        final boolean eraseOld) throws Exception {

        System.out.println("\tJadortServiceTest.deployApplicationInTwoPhases");

        this.testValidTopology_manyGroups();

        Assert.assertEquals(2, this.jadortService.getCurrentOperation().getTopology().getGroups().size());

        // Choose group1
        GroupBean group1 = this.jadortService.getCurrentOperation().getTopology().getGroups().get(0);
        this.jadortService.selectGroup(group1);
        Assert.assertEquals(Step.SELECT_GROUP, this.jadortService.getCurrentOperation().getCurrentStep());
        this.jadortService.next();
        Assert.assertEquals(Step.SELECT_OPERATION_TYPE, this.jadortService.getCurrentOperation().getCurrentStep());
        this.jadortService.selectOperationType(OperationType.MIGRATE);
        this.jadortService.next();
        Assert.assertEquals(Step.SELECT_APPLICATION, this.jadortService.getCurrentOperation().getCurrentStep());
        Assert.assertEquals(OperationType.MIGRATE, this.jadortService.getCurrentOperation().getType());
        Assert.assertEquals(group1.getId(), this.jadortService.getCurrentOperation().getSelectedGroup().getId());

        this.jadortService.selectApplication(new File(applicationPathV1).toURI().toURL());
        Assert.assertEquals(Step.SELECT_APPLICATION, this.jadortService.getCurrentOperation().getCurrentStep());
        this.jadortService.next();

        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());
        Assert.assertEquals(1, this.jadortService.getCurrentOperation().getSelectedGroup().getServers().size());
        List<ServerBean> serversToSelect = new ArrayList<ServerBean>();
        ServerBean selectedServer1 = this.jadortService.getCurrentOperation().getSelectedGroup().getServers().get(0);
        serversToSelect.add(selectedServer1);
        // Selected only 1st server
        this.jadortService.selectServers(serversToSelect);
        this.jadortService.next();

        this.executeMigration();

        // Finish
        this.jadortService.next();
        Assert.assertEquals(Step.FINISHED, this.jadortService.getCurrentOperation().getCurrentStep());

        // new operation
        this.setUp();
        this.testValidTopology_manyGroups();

        // Choose group2 - server1 et server2
        GroupBean group2 = this.jadortService.getCurrentOperation().getTopology().getGroups().get(1);
        this.jadortService.selectGroup(group2);
        Assert.assertEquals(Step.SELECT_GROUP, this.jadortService.getCurrentOperation().getCurrentStep());
        this.jadortService.next();
        Assert.assertEquals(Step.SELECT_OPERATION_TYPE, this.jadortService.getCurrentOperation().getCurrentStep());
        this.jadortService.selectOperationType(OperationType.MIGRATE);
        this.jadortService.next();
        Assert.assertEquals(Step.SELECT_APPLICATION, this.jadortService.getCurrentOperation().getCurrentStep());
        Assert.assertEquals(OperationType.MIGRATE, this.jadortService.getCurrentOperation().getType());
        Assert.assertEquals(group2.getId(), this.jadortService.getCurrentOperation().getSelectedGroup().getId());

        this.jadortService.selectApplication(new File(applicationPathV2).toURI().toURL());
        Assert.assertEquals(Step.SELECT_APPLICATION, this.jadortService.getCurrentOperation().getCurrentStep());
        this.jadortService.next();

        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());
        Assert.assertEquals(2, this.jadortService.getCurrentOperation().getSelectedGroup().getServers().size());
        serversToSelect = new ArrayList<ServerBean>();
        serversToSelect.add(this.jadortService.getCurrentOperation().getSelectedGroup().getServers().get(0));
        serversToSelect.add(this.jadortService.getCurrentOperation().getSelectedGroup().getServers().get(1));
        // Selected server1 and server2
        this.jadortService.selectServers(serversToSelect);
        this.jadortService.next();

        this.executeMigration();

        // Now the application is a new version for server1 and new application
        // for server2
        // So the UNDEPLOY_ERASE_OLD_VERSION step is executed only for server1
        Assert.assertEquals(Step.EXECUTING_MIGRATION, this.jadortService.getCurrentOperation().getCurrentStep());
        this.jadortService.next();
        Assert.assertEquals(Step.UNDEPLOY_ERASE_OLD_VERSION, this.jadortService.getCurrentOperation().getCurrentStep());
        Assert.assertEquals(1, this.jadortService.getCurrentOperation().getServerProgressList().size());
        this.jadortService.previous();
        Assert.assertEquals(Step.EXECUTING_MIGRATION, this.jadortService.getCurrentOperation().getCurrentStep());

        this.undeployEraseOldVersion(true);

        Assert.assertEquals(Step.FINISHED, this.jadortService.getCurrentOperation().getCurrentStep());

    }

    private void undeployApplication() throws Exception {
        System.out.println("\tJadortServiceTest.undeployApplication");

        if (this.jadortService.getCurrentOperation().getServerProgressList().get(0).getOldDeploymentItem() != null) {
            Assert.assertEquals(Step.UNDEPLOY_ERASE_OLD_VERSION, this.jadortService.getCurrentOperation().getCurrentStep());
            this.waitForFinishAndCheckServerProgressList(ServerProgressState.UNDEPLOY_OK, 50);

            // Redeploy old version
            this.jadortService.previous();
            Assert.assertEquals(Step.UNDEPLOY_ERASE_OLD_VERSION, this.jadortService.getCurrentOperation().getCurrentStep());
            this.waitForFinishAndCheckServerProgressList(ServerProgressState.SET_DEFAULT_OK, 0);
        }

        // Change page
        this.jadortService.previous();
        Assert.assertEquals(Step.EXECUTING_MIGRATION, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.SET_DEFAULT_OK, 100);

        // Set old version as default
        this.jadortService.previous();
        Assert.assertEquals(Step.EXECUTING_MIGRATION, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.DEPLOY_OK, 66);
        Assert.assertEquals(Step.EXECUTING_MIGRATION, this.jadortService.getCurrentOperation().getCurrentStep());

        // Undeploy new version
        this.jadortService.previous();
        Assert.assertEquals(Step.EXECUTING_MIGRATION, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.UPLOAD_OK, 33);

        // Erase new version
        this.jadortService.previous();
        Assert.assertEquals(Step.EXECUTING_MIGRATION, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.INITIAL, 0);

        // Change page
        this.jadortService.previous();
        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());

        // Change page for the operation to become deletable
        this.jadortService.previous();
        Assert.assertEquals(Step.SELECT_APPLICATION, this.jadortService.getCurrentOperation().getCurrentStep());
    }

    /**
     * @param state
     * @param progress
     * @throws Exception
     */
    private void waitForFinishAndCheckServerProgressList(final ServerProgressState state, final int progress) throws Exception {
        System.out.println("\tJadortServiceTest.waitForFinishAndCheckServerProgressList");

        boolean notFinished = true;
        for (int i = 0; notFinished; i++) {
            notFinished = false;
            for (ServerProgressBean dep : this.jadortService.getCurrentOperation().getServerProgressList()) {
                if (dep.getActionState().equals(ActionState.FINISHED_ERROR)) {
                    throw new Exception("ServerProgressListBean " + dep + " has errors. Log:\n" + dep.getLog());
                } else if (dep.getActionState().equals(ActionState.WAITING)
                    || dep.getActionState().equals(ActionState.FINISHED_OK) || dep.getProgress() == progress
                    || dep.getProgressState().equals(state)) {
                    notFinished = notFinished || false;
                } else {
                    notFinished = notFinished || true;
                }
            }
            if (notFinished) {
                if (!JadortServiceTest.IN_J2EE_SERVER && i > JadortServiceTest.TEST_TIMEOUT) {
                    throw new IllegalStateException("Timed out!");
                }

                System.out.println("\tJadortServiceTest.waitForFinishAndCheckServerProgressList sleeping...");
                Thread.sleep(JadortServiceTest.CHECK_PERIOD);
            }
        }
        for (ServerProgressBean dep : this.jadortService.getCurrentOperation().getServerProgressList()) {
            Assert.assertEquals(ActionState.WAITING, dep.getActionState());
            Assert.assertEquals(state, dep.getProgressState());
            Assert.assertEquals(progress, dep.getProgress());
        }
    }

    /**
     * Test method for
     * {@link org.ow2.jasmine.jadort.service.implementation.JadortServiceStatefulBean#selectGroup(GroupBean)}
     * with a maintenance.
     */
    @Test
    public void testSelectGroupMaintenanceAndUndo() throws Exception {
        System.out.println("JadortServiceTest.testSelectGroupMaintenanceAndUndo");

        this.selectGroupMaintenance(true, TestType.CLUSTER);
    }

    /**
     * Select group with mode "maintenance".
     */
    private void selectGroupMaintenance(final boolean undo, final TestType testType) throws Exception {
        System.out.println("\tJadortServiceTest.selectGroupMaintenance");

        if (TestType.NO_CLUSTER.equals(testType)) {
            this.testValidTopology_noCluster();
        } else if (TestType.CLUSTER.equals(testType)) {
            this.testValidTopology_cluster();
        } else if (TestType.TARGET.equals(testType)) {
            this.testValidTopology_target();
        }

        Assert.assertEquals(1, this.jadortService.getCurrentOperation().getTopology().getGroups().size());

        GroupBean toSelect = this.jadortService.getCurrentOperation().getTopology().getGroups().get(0);
        this.jadortService.selectGroup(toSelect);
        Assert.assertEquals(Step.SELECT_GROUP, this.jadortService.getCurrentOperation().getCurrentStep());
        this.jadortService.next();

        Assert.assertEquals(Step.SELECT_OPERATION_TYPE, this.jadortService.getCurrentOperation().getCurrentStep());
        Assert.assertEquals(toSelect, this.jadortService.getCurrentOperation().getSelectedGroup());

        this.jadortService.selectOperationType(OperationType.MAINTAIN);
        this.jadortService.next();

        Assert.assertEquals(OperationType.MAINTAIN, this.jadortService.getCurrentOperation().getType());
        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());

        if (undo) {
            this.jadortService.previous();
            Assert.assertEquals(Step.SELECT_OPERATION_TYPE, this.jadortService.getCurrentOperation().getCurrentStep());
        }
    }

    /**
     * Integration test for server maintenance (all servers maintained in one
     * step) (forward).
     */
    @Test(timeout = JadortServiceTest.TEST_TIMEOUT * 1000)
    public void testMaintainClusterAllServers() throws Exception {
        System.out.println("JadortServiceTest.testMaintainClusterAllServers");

        this.selectGroupMaintenance(false, TestType.CLUSTER);
        JadortServiceTest.operationBeanForMaintainServer1 = this.jadortService.getCurrentOperation();

        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());
        List<ServerBean> serversToSelect = new ArrayList<ServerBean>(this.jadortService.getCurrentOperation()
            .getSelectedGroup().getServers());
        this.jadortService.selectServers(serversToSelect);
        this.jadortService.next();

        OperationStateBean operation = this.jadortService.getCurrentOperation();
        Assert.assertNotNull(operation.getServerProgressList());
        Assert.assertEquals(serversToSelect.size(), operation.getServerProgressList().size());
        this.maintainServersCluster();

        // Change page
        this.jadortService.next();
        Assert.assertEquals(Step.FINISHED, this.jadortService.getCurrentOperation().getCurrentStep());
    }

    /**
     * Integration test for no clustered servers maintenance (all servers
     * maintained in one step) (forward).
     */
    @Test(timeout = JadortServiceTest.TEST_TIMEOUT * 1000)
    public void testMaintainNoClusterAllServers() throws Exception {
        System.out.println("JadortServiceTest.testMaintainNoClusterAllServers");

        this.selectGroupMaintenance(false, TestType.NO_CLUSTER);
        JadortServiceTest.operationBeanForMaintainNoClusterServer = this.jadortService.getCurrentOperation();

        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());
        List<ServerBean> serversToSelect = new ArrayList<ServerBean>(this.jadortService.getCurrentOperation()
            .getSelectedGroup().getServers());
        this.jadortService.selectServers(serversToSelect);
        this.jadortService.next();

        OperationStateBean operation = this.jadortService.getCurrentOperation();
        Assert.assertNotNull(operation.getServerProgressList());
        Assert.assertEquals(serversToSelect.size(), operation.getServerProgressList().size());
        this.maintainServersNoCluster();

        // Change page
        this.jadortService.next();
        Assert.assertEquals(Step.FINISHED, this.jadortService.getCurrentOperation().getCurrentStep());
    }

    /**
     * Integration test for server maintenance with target servers (all servers
     * maintained in one step) (forward).
     */
    @Test(timeout = JadortServiceTest.TEST_TIMEOUT * 1000)
    public void testMaintainTargetAllServers() throws Exception {
        System.out.println("JadortServiceTest.testMaintainTargetAllServers");

        this.selectGroupMaintenance(false, TestType.TARGET);

        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());
        List<ServerBean> serversToSelect = new ArrayList<ServerBean>(this.jadortService.getCurrentOperation()
            .getSelectedGroup().getServers());
        this.jadortService.selectServers(serversToSelect);
        this.jadortService.next();

        OperationStateBean operation = this.jadortService.getCurrentOperation();
        Assert.assertNotNull(operation.getServerProgressList());
        Assert.assertEquals(serversToSelect.size(), operation.getServerProgressList().size());
        this.maintainServersNoCluster();

        // Change page
        this.jadortService.next();
        operation = this.jadortService.getCurrentOperation();
        Assert.assertEquals(Step.FINISHED, operation.getCurrentStep());

        // Check that execution has been done on target
        List<ServerProgressBean> servers = operation.getServerProgressList();
        Assert.assertEquals(1, servers.size());
        ServerProgressBean server = servers.get(0);
        Assert.assertTrue(server.getIsOnTarget());
        Assert.assertEquals("source1", server.getServer().getName());
        Assert.assertNotNull(server.getServer().getTarget());
        Assert.assertEquals("target1", server.getServer().getTarget().getName());

        final String source1_create = "Created DummyServerAction for server 'source1'";
        final String source1_stop = "Stopping server 'source1'";
        final String target1_create = "Created DummyServerAction for server 'target1'";
        final String target1_start = "Starting server 'target1'";
        final String log = server.getLog();
        final int source1_create_index = log.indexOf(source1_create);
        final int source1_stop_index = log.indexOf(source1_stop);
        final int target1_create_index = log.indexOf(target1_create);
        final int target1_start_index = log.indexOf(target1_start);

        Assert.assertTrue("cannot find text \"" + source1_create + "\" in log:\n" + log, source1_create_index > -1);
        Assert.assertTrue("cannot find text \"" + source1_stop + "\" in log:\n" + log, source1_stop_index > -1);
        Assert.assertTrue("cannot find text \"" + target1_create + "\" in log:\n" + log, target1_create_index > -1);
        Assert.assertTrue("cannot find text \"" + target1_start + "\" in log:\n" + log, target1_start_index > -1);

        Assert.assertTrue("text \"" + source1_stop + "\" is not after text \"" + source1_create + "\" in log:\n" + log,
            source1_stop_index > source1_create_index);
        Assert.assertTrue("text \"" + target1_create + "\" is not after text \"" + source1_stop + "\" in log:\n" + log,
            target1_create_index > source1_stop_index);
        Assert.assertTrue("text \"" + target1_start + "\" is not after text \"" + target1_create + "\" in log:\n" + log,
            target1_start_index > target1_create_index);
    }

    /**
     * Integration test for server maintenance, try to maintain the same server
     * twice to have an error.
     */
    @Test(timeout = JadortServiceTest.TEST_TIMEOUT * 1000)
    public void testAttemptToMaintainTwice() throws Exception {
        System.out.println("JadortServiceTest.testAttemptToMaintainTwice");

        this.selectGroupMaintenance(false, TestType.CLUSTER);
        JadortServiceTest.operationBeanForMaintainServer2 = this.jadortService.getCurrentOperation();

        // Maintain the first server
        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());
        List<ServerBean> serversToSelect = new ArrayList<ServerBean>();
        serversToSelect.add(this.jadortService.getCurrentOperation().getSelectedGroup().getServers().get(0));
        this.jadortService.selectServers(serversToSelect);
        this.jadortService.next();

        OperationStateBean operation = this.jadortService.getCurrentOperation();
        Assert.assertNotNull(operation.getServerProgressList());
        Assert.assertEquals(serversToSelect.size(), operation.getServerProgressList().size());
        this.maintainServersCluster();

        // Change page
        this.jadortService.next();
        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());

        // Try to maintain the first server again
        serversToSelect = new ArrayList<ServerBean>();
        serversToSelect.add(this.jadortService.getCurrentOperation().getSelectedGroup().getServers().get(0));
        try {
            this.jadortService.selectServers(serversToSelect);
            Assert.fail();
        } catch (JadortServiceException ignored) {
            this.unMaintainServers(false);
        }
    }

    /**
     * Integration test for server maintenance, try to select servers with
     * different progress percentiles to have an error.
     */
    @Test(timeout = JadortServiceTest.TEST_TIMEOUT * 1000)
    public void testSelectDifferentProgress() throws Exception {
        System.out.println("JadortServiceTest.testSelectDifferentProgress");

        this.selectGroupMaintenance(false, TestType.CLUSTER);
        JadortServiceTest.operationBeanForMaintainServer2 = this.jadortService.getCurrentOperation();

        // Maintain the first server
        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());
        List<ServerBean> serversToSelect = new ArrayList<ServerBean>();
        serversToSelect.add(this.jadortService.getCurrentOperation().getSelectedGroup().getServers().get(0));
        this.jadortService.selectServers(serversToSelect);
        this.jadortService.next();

        OperationStateBean operation = this.jadortService.getCurrentOperation();
        Assert.assertNotNull(operation.getServerProgressList());
        Assert.assertEquals(serversToSelect.size(), operation.getServerProgressList().size());
        this.maintainServersCluster();

        // Change page
        this.jadortService.next();
        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());

        // Try to maintain all servers, including the one maintained before
        serversToSelect = new ArrayList<ServerBean>();
        for (int i = 0; i < this.jadortService.getCurrentOperation().getSelectedGroup().getServers().size(); i++) {
            serversToSelect.add(this.jadortService.getCurrentOperation().getSelectedGroup().getServers().get(i));
        }
        try {
            this.jadortService.selectServers(serversToSelect);
            Assert.fail();
        } catch (JadortServiceException ignored) {
            this.unMaintainServers(false);
        }
    }

    /**
     * Integration test for server maintenance cluster (forward).
     */
    private void maintainServersCluster() throws Exception {
        System.out.println("\tJadortServiceTest.maintainServersCluster");

        // In our test topology XML we have 2 workers per server
        Assert.assertEquals(2 * this.jadortService.getCurrentOperation().getServerProgressList().size(), this.jadortService
            .getCurrentOperation().getWorkerProgressList().size());

        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.INITIAL, 0);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.INITIAL, 0);

        // Stop Worker
        this.jadortService.next();
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.INITIAL, 20);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.STOP_OK, 20);

        // Stop Server
        this.jadortService.next();
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.STOP_OK, 40);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.STOP_OK, 40);

        // Maintain Server
        this.jadortService.next();
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.MAINTAIN_OK, 60);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.STOP_OK, 60);

        // Stop Server
        this.jadortService.next();
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.START_OK, 80);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.STOP_OK, 80);

        // Stop Worker
        this.jadortService.next();
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.START_OK, 100);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.START_OK, 100);
    }

    /**
     * Integration test for server maintenance with cluster (servers maintained
     * in two passes) (forward).
     */
    @Test(timeout = JadortServiceTest.TEST_TIMEOUT * 1000)
    public void testMaintainServersClusterInTwoSteps() throws Exception {
        System.out.println("JadortServiceTest.testMaintainServersClusterInTwoSteps");

        this.selectGroupMaintenance(false, TestType.CLUSTER);
        JadortServiceTest.operationBeanForMaintainServer2 = this.jadortService.getCurrentOperation();

        // Maintain the first server
        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());
        List<ServerBean> serversToSelect = new ArrayList<ServerBean>();
        serversToSelect.add(this.jadortService.getCurrentOperation().getSelectedGroup().getServers().get(0));
        this.jadortService.selectServers(serversToSelect);
        this.jadortService.next();

        OperationStateBean operation = this.jadortService.getCurrentOperation();
        Assert.assertNotNull(operation.getServerProgressList());
        Assert.assertEquals(serversToSelect.size(), operation.getServerProgressList().size());
        this.maintainServersCluster();

        // Change page
        this.jadortService.next();
        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());

        // Maintain the other servers
        serversToSelect = new ArrayList<ServerBean>();
        for (int i = 1; i < this.jadortService.getCurrentOperation().getSelectedGroup().getServers().size(); i++) {
            serversToSelect.add(this.jadortService.getCurrentOperation().getSelectedGroup().getServers().get(i));
        }
        this.jadortService.selectServers(serversToSelect);
        this.jadortService.next();

        operation = this.jadortService.getCurrentOperation();
        Assert.assertNotNull(operation.getServerProgressList());
        Assert.assertEquals(serversToSelect.size(), operation.getServerProgressList().size());
        this.maintainServersCluster();

        // Change page
        this.jadortService.next();
        Assert.assertEquals(Step.FINISHED, this.jadortService.getCurrentOperation().getCurrentStep());
    }

    /**
     * Integration test for server maintenance no cluster (forward).
     */
    private void maintainServersNoCluster() throws Exception {
        System.out.println("\tJadortServiceTest.maintainServersNoCluster");

        // In our test topology XML we have 2 workers per server
        Assert.assertEquals(2 * this.jadortService.getCurrentOperation().getServerProgressList().size(), this.jadortService
            .getCurrentOperation().getWorkerProgressList().size());

        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_NO_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.INITIAL, 0);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.INITIAL, 0);

        // Stop Worker
        this.jadortService.next();
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_NO_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.INITIAL, 16);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.STOP_OK, 16);

        // Stop Server
        this.jadortService.next();
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_NO_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.DISABLE_APPLICATIONS_OK, 33);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.STOP_OK, 33);

        // Maintain Server
        this.jadortService.next();
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_NO_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.STOP_OK, 50);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.STOP_OK, 50);

        // Maintain Server
        this.jadortService.next();
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_NO_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.MAINTAIN_OK, 66);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.STOP_OK, 66);

        // Stop Server
        this.jadortService.next();
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_NO_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.START_OK, 83);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.STOP_OK, 83);

        // Stop Worker
        this.jadortService.next();
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_NO_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.START_OK, 100);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.START_OK, 100);
    }

    /**
     * Integration test for server maintenance no cluster (servers maintained in
     * two passes) (forward).
     */
    @Test(timeout = JadortServiceTest.TEST_TIMEOUT * 1000)
    public void testMaintainServersNoClusterInTwoSteps() throws Exception {
        System.out.println("JadortServiceTest.testMaintainServersNoClusterInTwoSteps");

        this.selectGroupMaintenance(false, TestType.NO_CLUSTER);

        // Maintain the first server
        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());
        List<ServerBean> serversToSelect = new ArrayList<ServerBean>();
        serversToSelect.add(this.jadortService.getCurrentOperation().getSelectedGroup().getServers().get(0));
        this.jadortService.selectServers(serversToSelect);
        this.jadortService.next();

        OperationStateBean operation = this.jadortService.getCurrentOperation();
        Assert.assertNotNull(operation.getServerProgressList());
        Assert.assertEquals(serversToSelect.size(), operation.getServerProgressList().size());
        this.maintainServersNoCluster();

        // Change page
        this.jadortService.next();
        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());

        // Maintain the other servers
        serversToSelect = new ArrayList<ServerBean>();
        for (int i = 1; i < this.jadortService.getCurrentOperation().getSelectedGroup().getServers().size(); i++) {
            serversToSelect.add(this.jadortService.getCurrentOperation().getSelectedGroup().getServers().get(i));
        }
        this.jadortService.selectServers(serversToSelect);
        this.jadortService.next();

        operation = this.jadortService.getCurrentOperation();
        Assert.assertNotNull(operation.getServerProgressList());
        Assert.assertEquals(serversToSelect.size(), operation.getServerProgressList().size());
        this.maintainServersNoCluster();

        // Change page
        this.jadortService.next();
        Assert.assertEquals(Step.FINISHED, this.jadortService.getCurrentOperation().getCurrentStep());
    }

    /**
     * Integration test for server maintenance (backwards).
     */
    @Test(timeout = JadortServiceTest.TEST_TIMEOUT * 1000)
    public void testUnmaintainClusterServers1() throws Exception {
        System.out.println("JadortServiceTest.testUnmaintainClusterServers1");

        Assert.assertNotNull(JadortServiceTest.operationBeanForMaintainServer1);
        Assert.assertNotNull(JadortServiceTest.operationBeanForMaintainServer1.getId());

        this.jadortService.selectOperation(JadortServiceTest.operationBeanForMaintainServer1);
        Assert.assertNotNull(this.jadortService.getCurrentOperation());

        this.unMaintainServers(true);
    }

    /**
     * Integration test for server maintenance (backwards).
     */
    @Test(timeout = JadortServiceTest.TEST_TIMEOUT * 1000)
    public void testUnmaintainClusterServers2() throws Exception {
        System.out.println("JadortServiceTest.testUnmaintainClusterServers2");

        Assert.assertNotNull(JadortServiceTest.operationBeanForMaintainServer2);
        Assert.assertNotNull(JadortServiceTest.operationBeanForMaintainServer2.getId());

        this.jadortService.selectOperation(JadortServiceTest.operationBeanForMaintainServer2);
        Assert.assertNotNull(this.jadortService.getCurrentOperation());

        this.unMaintainServers(true);
    }

    /**
     * Integration test for no cluster servers maintenance (backwards).
     */
    @Test(timeout = JadortServiceTest.TEST_TIMEOUT * 1000)
    public void testUnmaintainNoClusterServers() throws Exception {
        System.out.println("JadortServiceTest.testUnmaintainNoClusterServers");

        Assert.assertNotNull(JadortServiceTest.operationBeanForMaintainNoClusterServer);
        Assert.assertNotNull(JadortServiceTest.operationBeanForMaintainNoClusterServer.getId());

        this.jadortService.selectOperation(JadortServiceTest.operationBeanForMaintainNoClusterServer);
        Assert.assertNotNull(this.jadortService.getCurrentOperation());

        this.unMaintainNoClusterServers(true);
    }

    /**
     * Integration test for server maintenance (some of the servers maintained,
     * then everything undone) (forward).
     */
    @Test(timeout = JadortServiceTest.TEST_TIMEOUT * 1000)
    public void testMaintainSomeServersThenUnmaintain() throws Exception {
        System.out.println("JadortServiceTest.testMaintainSomeServersThenUnmaintain");

        this.selectGroupMaintenance(false, TestType.CLUSTER);

        // Maintain the first server
        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());
        List<ServerBean> serversToSelect = new ArrayList<ServerBean>();
        serversToSelect.add(this.jadortService.getCurrentOperation().getSelectedGroup().getServers().get(0));
        this.jadortService.selectServers(serversToSelect);
        this.jadortService.next();

        OperationStateBean operation = this.jadortService.getCurrentOperation();
        Assert.assertNotNull(operation.getServerProgressList());
        Assert.assertEquals(serversToSelect.size(), operation.getServerProgressList().size());
        this.maintainServersCluster();

        // Change page
        this.jadortService.next();
        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());

        // Maintain the second server
        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());
        serversToSelect = new ArrayList<ServerBean>();
        serversToSelect.add(this.jadortService.getCurrentOperation().getSelectedGroup().getServers().get(1));
        this.jadortService.selectServers(serversToSelect);
        this.jadortService.next();

        operation = this.jadortService.getCurrentOperation();
        Assert.assertNotNull(operation.getServerProgressList());
        Assert.assertEquals(serversToSelect.size(), operation.getServerProgressList().size());
        this.maintainServersCluster();

        // Change page
        this.jadortService.next();
        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());

        // Start maintaining the third server and undo in the middle
        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());
        serversToSelect = new ArrayList<ServerBean>();
        serversToSelect.add(this.jadortService.getCurrentOperation().getSelectedGroup().getServers().get(2));
        this.jadortService.selectServers(serversToSelect);
        this.jadortService.next();

        operation = this.jadortService.getCurrentOperation();
        Assert.assertNotNull(operation.getServerProgressList());
        Assert.assertEquals(serversToSelect.size(), operation.getServerProgressList().size());
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.INITIAL, 0);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.INITIAL, 0);

        // Stop Worker
        this.jadortService.next();
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.INITIAL, 20);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.STOP_OK, 20);

        // Undo the third server
        this.jadortService.previous();
        operation = this.jadortService.getCurrentOperation();
        Assert.assertNotNull(operation.getServerProgressList());
        Assert.assertEquals(serversToSelect.size(), operation.getServerProgressList().size());
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.INITIAL, 0);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.INITIAL, 0);

        // Keep on undoing
        this.jadortService.previous();
        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());
        this.unMaintainServers(false);
    }

    private void unMaintainServers(final boolean finished) throws Exception {
        System.out.println("\tJadortServiceTest.unMaintainServers");

        if (finished) {
            Assert.assertEquals(Step.FINISHED, this.jadortService.getCurrentOperation().getCurrentStep());
        }

        this.jadortService.previous();
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());

        this.waitForFinishAndCheckServerProgressList(ServerProgressState.START_OK, 100);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.START_OK, 100);
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());

        // Stop Worker
        this.jadortService.previous();
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.START_OK, 80);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.STOP_OK, 80);
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());

        // Stop Server
        this.jadortService.previous();
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.MAINTAIN_OK, 60);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.STOP_OK, 60);
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());

        // Unmaintain Server
        this.jadortService.previous();
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.STOP_OK, 40);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.STOP_OK, 40);
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());

        // Start Server
        this.jadortService.previous();
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.INITIAL, 20);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.STOP_OK, 20);
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());

        // Start Worker
        this.jadortService.previous();
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.INITIAL, 0);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.INITIAL, 0);
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());

        // Previous screen is either SELECT_SERVERS or SELECT_GROUP
        this.jadortService.previous();

        if (this.jadortService.getCurrentOperation().getCurrentStep().equals(Step.SELECT_SERVERS)) {
            this.jadortService.previous();
        }

        Assert.assertEquals(Step.SELECT_OPERATION_TYPE, this.jadortService.getCurrentOperation().getCurrentStep());
    }

    private void unMaintainNoClusterServers(final boolean finished) throws Exception {
        System.out.println("\tJadortServiceTest.unMaintainNoClusterServers");

        if (finished) {
            Assert.assertEquals(Step.FINISHED, this.jadortService.getCurrentOperation().getCurrentStep());
        }

        this.jadortService.previous();
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_NO_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());

        this.waitForFinishAndCheckServerProgressList(ServerProgressState.START_OK, 100);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.START_OK, 100);
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_NO_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());

        // Stop Server
        this.jadortService.previous();
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.START_OK, 83);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.STOP_OK, 83);
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_NO_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());

        // Stop Worker
        this.jadortService.previous();
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.MAINTAIN_OK, 66);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.STOP_OK, 66);
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_NO_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());

        // Maintain Server
        this.jadortService.previous();
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.STOP_OK, 50);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.STOP_OK, 50);
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_NO_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());

        // Maintain Server
        this.jadortService.previous();
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.DISABLE_APPLICATIONS_OK, 33);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.STOP_OK, 33);
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_NO_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());

        // Start Worker
        this.jadortService.previous();
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.INITIAL, 16);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.STOP_OK, 16);
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_NO_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());

        // Enable Applications
        this.jadortService.previous();
        this.waitForFinishAndCheckServerProgressList(ServerProgressState.INITIAL, 0);
        this.waitForFinishAndCheckWorkerProgressList(WorkerProgressState.INITIAL, 0);
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_NO_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());

        // Previous screen is either SELECT_SERVERS or SELECT_GROUP
        this.jadortService.previous();

        if (this.jadortService.getCurrentOperation().getCurrentStep().equals(Step.SELECT_SERVERS)) {
            this.jadortService.previous();
        }

        Assert.assertEquals(Step.SELECT_OPERATION_TYPE, this.jadortService.getCurrentOperation().getCurrentStep());
    }

    private void waitForFinishAndCheckWorkerProgressList(final WorkerProgressState state, final int progress) throws Exception {
        System.out.println("\tJadortServiceTest.waitForFinishAndCheckWorkerProgressList");

        boolean notFinished = true;
        for (int i = 0; notFinished; i++) {
            notFinished = false;
            for (WorkerProgressBean dep : this.jadortService.getCurrentOperation().getWorkerProgressList()) {
                if (dep.getActionState().equals(ActionState.FINISHED_ERROR)) {
                    throw new Exception("WorkerProgressListBean " + dep + " has errors. Log:\n" + dep.getLog());
                } else if (dep.getActionState().equals(ActionState.WAITING)
                    || dep.getActionState().equals(ActionState.FINISHED_OK) || dep.getProgress() == progress
                    || dep.getProgressState().equals(state)) {
                    notFinished = notFinished || false;
                } else {
                    notFinished = notFinished || true;
                }
            }
            if (notFinished) {
                if (!JadortServiceTest.IN_J2EE_SERVER && i > JadortServiceTest.TEST_TIMEOUT) {
                    throw new IllegalStateException("Timed out!");
                }

                System.out.println("\tJadortServiceTest.waitForFinishAndCheckWorkerProgressList sleeping...");
                Thread.sleep(JadortServiceTest.CHECK_PERIOD);
            }
        }
        for (WorkerProgressBean dep : this.jadortService.getCurrentOperation().getWorkerProgressList()) {
            Assert.assertEquals(ActionState.WAITING, dep.getActionState());
            Assert.assertEquals(progress, dep.getProgress());
            Assert.assertEquals(state, dep.getProgressState());
        }
    }

    /**
     * Integration test for the delete operation's behavior with migration
     * actions that are in progress.
     */
    @Test
    public void testOperationDeletionNotAllowedWhenMigrating() throws Exception {
        System.out.println("JadortServiceTest.testOperationDeletionNotAllowedWhenMigrating");

        this.testSelectGroupMigrate();

        this.jadortService.selectApplication(new File("src/test/resources/application1v1/application1.ear").toURI().toURL());

        Assert.assertEquals(Step.SELECT_APPLICATION, this.jadortService.getCurrentOperation().getCurrentStep());
        this.jadortService.next();

        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());
        List<ServerBean> serversToSelect = new ArrayList<ServerBean>();
        serversToSelect.addAll(this.jadortService.getCurrentOperation().getSelectedGroup().getServers());
        this.jadortService.selectServers(serversToSelect);
        this.jadortService.next();

        Assert.assertEquals(Step.EXECUTING_MIGRATION, this.jadortService.getCurrentOperation().getCurrentStep());

        // Save current operation and call setUp for reconnection
        OperationStateBean current = this.jadortService.getCurrentOperation();
        this.setUp();
        try {
            this.jadortService.deleteOperation(current);
            Assert.fail("Managed to delete an operation that's migrating!");
        } catch (JadortServiceException ignored) {
            // Expected exception
        }

        // Go back to a step that allows operation deletion
        Assert.assertNull(this.jadortService.getCurrentOperation());
        this.jadortService.selectOperation(current);
        this.jadortService.previous();
        this.jadortService.previous();
        this.jadortService.previous();
        this.jadortService.previous();
        Assert.assertEquals(Step.SELECT_GROUP, this.jadortService.getCurrentOperation().getCurrentStep());
    }

    /**
     * Integration test for the delete operation's behavior with maintenance
     * actions are in progress.
     */
    @Test
    public void testOperationDeletionNotAllowedWhenMaintaining() throws Exception {
        System.out.println("JadortServiceTest.testOperationDeletionNotAllowedWhenMaintaining");

        this.selectGroupMaintenance(false, TestType.CLUSTER);

        Assert.assertEquals(Step.SELECT_SERVERS, this.jadortService.getCurrentOperation().getCurrentStep());
        List<ServerBean> serversToSelect = new ArrayList<ServerBean>(this.jadortService.getCurrentOperation()
            .getSelectedGroup().getServers());
        this.jadortService.selectServers(serversToSelect);
        this.jadortService.next();

        OperationStateBean operation = this.jadortService.getCurrentOperation();
        Assert.assertNotNull(operation.getServerProgressList());
        Assert.assertEquals(serversToSelect.size(), operation.getServerProgressList().size());
        Assert.assertEquals(Step.EXECUTING_MAINTENANCE_CLUSTER, this.jadortService.getCurrentOperation().getCurrentStep());

        // Save current operation and call setUp for reconnection
        OperationStateBean current = this.jadortService.getCurrentOperation();
        this.setUp();
        try {
            this.jadortService.deleteOperation(current);
            Assert.fail("Managed to delete an operation that's maintaining!");
        } catch (JadortServiceException ignored) {
            // Expected exception
        }

        // Go back to a step that allows operation deletion
        Assert.assertNull(this.jadortService.getCurrentOperation());
        this.jadortService.selectOperation(current);
        this.jadortService.previous();
        this.jadortService.previous();
        this.jadortService.previous();
        Assert.assertEquals(Step.SELECT_GROUP, this.jadortService.getCurrentOperation().getCurrentStep());
    }

}
