package com.delcyon.capo.controller.elements; import static org.junit.Assert.fail; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; 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.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import com.delcyon.capo.CapoApplication; import com.delcyon.capo.CapoApplication.ApplicationState; import com.delcyon.capo.controller.Group; import com.delcyon.capo.controller.client.ServerControllerResponse; import com.delcyon.capo.resourcemanager.ResourceDescriptor; import com.delcyon.capo.resourcemanager.ResourceDescriptor.LifeCycle; import com.delcyon.capo.resourcemanager.types.JcrResourceType; import com.delcyon.capo.server.CapoServer; import com.delcyon.capo.tasks.TaskManagerThread; import com.delcyon.capo.tasks.TaskManagerThread.Preferences; import com.delcyon.capo.tests.util.ExternalTestClient; import com.delcyon.capo.tests.util.ExternalTestServer; import com.delcyon.capo.tests.util.TestClient; import com.delcyon.capo.tests.util.TestServer; import com.delcyon.capo.tests.util.external.Util; import com.delcyon.capo.util.diff.Diff; import com.delcyon.capo.xml.XPath; public class TaskElementTest { private ExternalTestClient externalTestClient; private ExternalTestServer externalTestServer; private CapoServer capoServer = null; @BeforeClass public static void setUpBeforeClass() throws Exception { } @AfterClass public static void tearDownAfterClass() throws Exception { //TestCapoApplication.cleanup(); } @Before public void setUp() throws Exception { Util.deleteTree("capo"); Util.copyTree("test-data/capo", "capo"); // Util.copyTree("lib", "capo/server/lib"); // Util.copyTree("lib", "capo/client/lib"); } @After public void tearDown() throws Exception { if (TaskManagerThread.getTaskManagerThread() != null && TaskManagerThread.getTaskManagerThread().getLock().isLocked() && TaskManagerThread.getTaskManagerThread().getLock().isHeldByCurrentThread()) { TaskManagerThread.getTaskManagerThread().getLock().unlock(); } try { TestServer.getServerInstance().getConfiguration().setValue(TaskManagerThread.Preferences.TASK_INTERVAL, TaskManagerThread.Preferences.TASK_INTERVAL.getDefaultValue()); TestServer.getServerInstance().getConfiguration().setValue(TaskManagerThread.Preferences.TASK_DEFAULT_LIFESPAN, TaskManagerThread.Preferences.TASK_DEFAULT_LIFESPAN.getDefaultValue()); TestServer.getServerInstance().getConfiguration().setValue(TaskManagerThread.Preferences.DEFAULT_CLIENT_SYNC_INTERVAL, TaskManagerThread.Preferences.DEFAULT_CLIENT_SYNC_INTERVAL.getDefaultValue()); } catch (Exception e) { e.printStackTrace(); } System.err.println("=================================================================="); if (externalTestClient != null) { externalTestClient.shutdown(); CopyOnWriteArrayList<Exception> exceptionList = externalTestClient.getExceptionList(); if (exceptionList.isEmpty() == false) { throw exceptionList.get(0); } } if (TestClient.getClientInstance() != null) { TestClient.shutdown(); CopyOnWriteArrayList<Exception> exceptionList = TestClient.getExceptionList(); if (exceptionList.isEmpty() == false) { throw exceptionList.get(0); } } if (externalTestServer != null) { externalTestServer.shutdown(); CopyOnWriteArrayList<Exception> exceptionList = externalTestServer.getExceptionList(); if (exceptionList.isEmpty() == false) { throw exceptionList.get(0); } } if (TestServer.getServerInstance() != null) { TestServer.shutdown(); CopyOnWriteArrayList<Exception> exceptionList = TestServer.getExceptionList(); if (exceptionList.isEmpty() == false) { throw exceptionList.get(0); } } } @Test public void testProcessServerSideElement() throws Exception { TestServer.start(); TestServer.getServerInstance().getConfiguration().setValue(TaskManagerThread.Preferences.TASK_INTERVAL, "2000"); TestServer.getServerInstance().getConfiguration().setValue(TaskManagerThread.Preferences.TASK_DEFAULT_LIFESPAN, "6000"); TestServer.getServerInstance().getConfiguration().setValue(TaskManagerThread.Preferences.DEFAULT_CLIENT_SYNC_INTERVAL, "1000"); TaskManagerThread.getTaskManagerThread().getLock().lock(); waitForTaskManagerToRun(2); //run this twice so that we pick up the new hnages before starting TaskElement taskElementControl = new TaskElement(); Document document = CapoApplication.getDocumentBuilder().newDocument(); Element taskElement = document.createElementNS(CapoApplication.SERVER_NAMESPACE_URI,"server:task"); taskElement.setAttribute(TaskElement.Attributes.name.toString(), "testTask"); taskElement.setAttribute(TaskElement.Attributes.local.toString(), "true"); Group group = new Group("test", null, null, null); taskElementControl.init(taskElement, null, group, new ServerControllerResponse()); taskElementControl.processServerSideElement(); waitForTaskManagerToRun(2); //this has to run twice so that the task doc updater has a chance to run. System.out.println(); List<ResourceDescriptor> taskResourceDescriptorList = CapoApplication.getDataManager().findDocuments(CapoApplication.getDataManager().getResourceDirectory(Preferences.TASK_DIR.toString())); Assert.assertEquals(2,taskResourceDescriptorList.size()); for (ResourceDescriptor resourceDescriptor : taskResourceDescriptorList) { Document testDocument = CapoApplication.getDocumentBuilder().parse(resourceDescriptor.getInputStream(null)); if (resourceDescriptor.getLocalName().equals("task-status.xml")) { XPath.dumpNode(testDocument, System.out); NodeList nodeList = XPath.selectNodes(testDocument, "//server:task"); Assert.assertEquals(1,nodeList.getLength()); Assert.assertEquals("testTask",((Element)nodeList.item(0)).getAttribute("name")); Assert.assertEquals("testTask.xml",((Element)nodeList.item(0)).getAttribute("taskURI")); } else if (resourceDescriptor.getLocalName().equals("testTask.xml")) { XPath.dumpNode(testDocument, System.out); NodeList nodeList = XPath.selectNodes(testDocument, "//server:task"); Assert.assertEquals(1,nodeList.getLength()); Assert.assertEquals("testTask",((Element)nodeList.item(0)).getAttribute("name")); Assert.assertTrue(((Element)nodeList.item(0)).getAttribute("lastAccessTime").matches("\\d+")); } else { fail("Unknown task file:"+resourceDescriptor.getLocalName()); } } waitForTaskManagerToRun(3); //run this long enough for it to be orphaned, and a re-sync to happen System.out.println(); taskResourceDescriptorList = CapoApplication.getDataManager().findDocuments(CapoApplication.getDataManager().getResourceDirectory(Preferences.TASK_DIR.toString())); Assert.assertEquals(1,taskResourceDescriptorList.size()); ResourceDescriptor resourceDescriptor = taskResourceDescriptorList.get(0); Document testDocument = CapoApplication.getDocumentBuilder().parse(resourceDescriptor.getInputStream(null)); if (resourceDescriptor.getLocalName().equals("task-status.xml")) { XPath.dumpNode(testDocument, System.out); NodeList nodeList = XPath.selectNodes(testDocument, "//server:task"); Assert.assertEquals(0,nodeList.getLength()); } else { fail("Unknown task file:"+resourceDescriptor.getLocalName()); } TaskManagerThread.getTaskManagerThread().getLock().unlock(); } /** * Copy a default test script that includes a task to the server * Start an external server. * Start a Test client * Ensure tasks gets created on server * Ensure task gets synced to client * Ensure Client runs task * Ensure client marks task for deletion * Ensure task gets deleted from client * Ensure task gets deleted from server * * @throws Exception */ @Test public void testProcessClientSideScriptedTask() throws Exception { //test-dynamic-client-task.xml System.out.println("==================================================================="); externalTestServer = new ExternalTestServer(); System.out.println("==================================================================="); externalTestServer.startServer(); System.out.println("==================================================================="); TestClient.start(ApplicationState.READY,"-CLIENT_AS_SERVICE","true"); TestClient.getClientInstance().getConfiguration().setValue(TaskManagerThread.Preferences.TASK_INTERVAL, "2000"); TestClient.getClientInstance().getConfiguration().setValue(TaskManagerThread.Preferences.TASK_DEFAULT_LIFESPAN, "6000"); TestClient.getClientInstance().getConfiguration().setValue(TaskManagerThread.Preferences.DEFAULT_CLIENT_SYNC_INTERVAL, "1000"); TaskManagerThread.getTaskManagerThread().getLock().lock(); waitForTaskManagerToRun(2); //let things sync up Util.copyTree("test-data/task-testdata/test-dynamic-client-task.xml", "repo:/controller/default.xml"); waitForTaskManagerToRun(1); List<ResourceDescriptor> taskResourceDescriptorList = CapoApplication.getDataManager().findDocuments(CapoApplication.getDataManager().getResourceDirectory(Preferences.TASK_DIR.toString())); Assert.assertEquals(1,taskResourceDescriptorList.size()); Assert.assertTrue("should be empty task-status file",validateXMLContent(taskResourceDescriptorList, "task-status.xml", "not(exists(//server:task))")); waitForTaskManagerToRun(2); taskResourceDescriptorList = CapoApplication.getDataManager().findDocuments(CapoApplication.getDataManager().getResourceDirectory(Preferences.TASK_DIR.toString())); if (taskResourceDescriptorList.size() != 2) { waitForTaskManagerToRun(1); taskResourceDescriptorList = CapoApplication.getDataManager().findDocuments(CapoApplication.getDataManager().getResourceDirectory(Preferences.TASK_DIR.toString())); } Assert.assertEquals(2,taskResourceDescriptorList.size()); //give the updater a chance to run. TaskManagerThread.getTaskManagerThread().getLock().unlock(); TaskManagerThread.getTaskManagerThread().getLock().lock(); Assert.assertTrue("dynamic task test should have run",validateXMLContent(taskResourceDescriptorList, "task-status.xml", "exists(//server:task[@name = 'dynamic-task-text' and exists(@lastExecutionTime)])")); Util.copyTree("resources/defaults/default.xml", "repo:/controller/default.xml"); waitForTaskManagerToRun(5); taskResourceDescriptorList = CapoApplication.getDataManager().findDocuments(CapoApplication.getDataManager().getResourceDirectory(Preferences.TASK_DIR.toString())); Assert.assertEquals(1,taskResourceDescriptorList.size()); System.out.println(); } /** * copy a test task to the servers client task dir. * Start External Server * Start local Client * Ensure that it synced over. * Ensure that it runs * Ensure that it gets deleted * @throws Exception */ @Test public void testProcessClientSideManualTask() throws Exception { System.out.println("==================================================================="); externalTestServer = new ExternalTestServer(); System.out.println("==================================================================="); externalTestServer.startServer("-CAPO_DIR","capo/server"); System.out.println("==================================================================="); Util.copyTree("test-data/task-testdata/test-manual-task-with-error.xml", "repo:/clients/capo.client.1/tasks/test-manual-task.xml"); TestClient.start(ApplicationState.READY,"-CLIENT_AS_SERVICE","true","-CAPO_DIR","capo/client"); TestServer.getServerInstance().getConfiguration().setValue(TaskManagerThread.Preferences.TASK_INTERVAL, "2000"); TestServer.getServerInstance().getConfiguration().setValue(TaskManagerThread.Preferences.TASK_DEFAULT_LIFESPAN, "1000"); TestServer.getServerInstance().getConfiguration().setValue(TaskManagerThread.Preferences.DEFAULT_CLIENT_SYNC_INTERVAL, "1000"); TaskManagerThread.getTaskManagerThread().getLock().lock(); List<ResourceDescriptor> taskResourceDescriptorList = CapoApplication.getDataManager().findDocuments(CapoApplication.getDataManager().getResourceDirectory(Preferences.TASK_DIR.toString())); Assert.assertEquals(2,taskResourceDescriptorList.size()); waitForTaskManagerToRun(1); Assert.assertEquals(2,taskResourceDescriptorList.size()); Assert.assertTrue("Didn't find ignoreable test-manual-task",validateXMLContent(taskResourceDescriptorList, "task-status.xml", "exists(//server:task[@name = 'test-manual-task' and @ACTION = 'IGNORE' and exists(@EXCEPTION)])")); Util.copyTree("test-data/task-testdata/test-manual-task.xml", "repo:/clients/capo.client.1/tasks/test-manual-task.xml"); waitForTaskManagerToRun(1); taskResourceDescriptorList = CapoApplication.getDataManager().findDocuments(CapoApplication.getDataManager().getResourceDirectory(Preferences.TASK_DIR.toString())); Assert.assertEquals(2,taskResourceDescriptorList.size()); Assert.assertTrue("Didn't find new synched test-manual-task",validateXMLContent(taskResourceDescriptorList, "test-manual-task.xml", "exists(//server:task/server:export[exists(@dest)])")); Diff diff = new Diff(new FileInputStream("test-data/task-testdata/test.txt"), new FileInputStream("capo/client/test.txt")); String[] differences = diff.getDifferences().split("\n"); Assert.assertTrue("There should be data in the export file",differences.length > 2); for (String difference : differences) { Assert.assertTrue("Line contains a difference:" +difference, difference.startsWith("=")); } Util.deleteTree("repo:/clients/capo.client.1/tasks/test-manual-task.xml"); waitForTaskManagerToRun(1); taskResourceDescriptorList = CapoApplication.getDataManager().findDocuments(CapoApplication.getDataManager().getResourceDirectory(Preferences.TASK_DIR.toString())); Assert.assertEquals(1,taskResourceDescriptorList.size()); Util.copyTree("test-data/task-testdata/test-manual-task-single-run.xml", "repo:/clients/capo.client.1/tasks/test-manual-task.xml"); waitForTaskManagerToRun(1); taskResourceDescriptorList = CapoApplication.getDataManager().findDocuments(CapoApplication.getDataManager().getResourceDirectory(Preferences.TASK_DIR.toString())); Assert.assertEquals(2,taskResourceDescriptorList.size()); waitForTaskManagerToRun(2); Assert.assertTrue("Didn't find ignoreable run test-manual-task",validateXMLContent(taskResourceDescriptorList, "task-status.xml", "exists(//server:task[@name = 'test-manual-task' and @ACTION = 'IGNORE' and not(exists(@EXCEPTION)) and exists(@lastExecutionTime)])")); // File manualTaskFile = new File("capo/server/clients/capo.client.1/tasks/test-manual-task.xml"); byte[] bytes = Util.readData("repo:/clients/capo.client.1/tasks/test-manual-task.xml"); Document manualTaskDocument = CapoApplication.getDocumentBuilder().parse(new ByteArrayInputStream(bytes)); ((Element)XPath.selectSingleNode(manualTaskDocument, "//server:task")).setAttribute("orpanAction", "DELETE"); XPath.dumpNode(manualTaskDocument, System.out); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); XPath.dumpNode(manualTaskDocument, buffer); Util.writeData("repo:/clients/capo.client.1/tasks/test-manual-task.xml", buffer.toByteArray()); waitForTaskManagerToRun(3); taskResourceDescriptorList = CapoApplication.getDataManager().findDocuments(CapoApplication.getDataManager().getResourceDirectory(Preferences.TASK_DIR.toString())); Assert.assertEquals(1,taskResourceDescriptorList.size()); System.out.println(); } private boolean validateXMLContent(List<ResourceDescriptor> resourceDescriptorList,String documentName,String xpath) throws Exception { for (ResourceDescriptor resourceDescriptor : resourceDescriptorList) { Document testDocument = CapoApplication.getDocumentBuilder().parse(resourceDescriptor.getInputStream(null)); if (resourceDescriptor.getLocalName().equals(documentName)) { boolean result = XPath.evaluate(testDocument, xpath); if (result == false) { XPath.dumpNode(testDocument, System.err); } return result; } } fail("Didn't find document: "+documentName); return false; } private void waitForTaskManagerToRun(int loopCount) throws Exception { long lastRunTime = TaskManagerThread.getTaskManagerThread().getLastRunTime(); int currentLoop = 0; TaskManagerThread.getTaskManagerThread().getLock().unlock(); System.out.println("waiting for TaskManager to run "+loopCount+" times: "); while(currentLoop < loopCount) { if (lastRunTime != TaskManagerThread.getTaskManagerThread().getLastRunTime()) { currentLoop++; lastRunTime = TaskManagerThread.getTaskManagerThread().getLastRunTime(); System.out.print(currentLoop); } System.out.print("."); Thread.sleep(CapoApplication.getConfiguration().getLongValue(Preferences.TASK_INTERVAL)/4l); } TaskManagerThread.getTaskManagerThread().getLock().lock(); System.out.println(); } }