diff --git a/e2e-test/src/test/java/org/alfresco/service/search/backup/AbstractBackupTest.java b/e2e-test/src/test/java/org/alfresco/service/search/backup/AbstractBackupTest.java new file mode 100644 index 000000000..02d401acd --- /dev/null +++ b/e2e-test/src/test/java/org/alfresco/service/search/backup/AbstractBackupTest.java @@ -0,0 +1,110 @@ +package org.alfresco.service.search.backup; + +import java.io.File; +import java.nio.file.Paths; + +import org.alfresco.rest.core.RestRequest; +import org.alfresco.rest.core.RestWrapper; +import org.alfresco.rest.model.RestHtmlResponse; +import org.alfresco.utility.Utility; +import org.alfresco.utility.data.DataSite; +import org.alfresco.utility.network.ServerHealth; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; +import org.testng.Assert; +import org.testng.annotations.BeforeClass; +import org.testng.asserts.SoftAssert; + +import com.jayway.restassured.RestAssured; + +@Configuration +@ContextConfiguration("classpath:alfresco-search-e2e-context.xml") +public abstract class AbstractBackupTest extends AbstractTestNGSpringContextTests { + + @Autowired + protected ServerHealth serverHealth; + + @Autowired + protected DataSite dataSite; + + @Autowired + RestWrapper restWrapper; + + @Value("${solr.port}") + int solrPort; + + @Value("${solr.docker.hostPath}") + String solrDockerHostPath; + + @BeforeClass(alwaysRun = true) + protected void setupSolrRequest() throws Exception { + serverHealth.assertServerIsOnline(); + + RestAssured.basePath = "solr"; + RestAssured.port = solrPort; + restWrapper.configureRequestSpec().setPort(solrPort); + restWrapper.configureRequestSpec().setBasePath(RestAssured.basePath); + } + + + /** + * Prepare a GET "backup" command request to localhost:{solrPort}/solr + * + * @param core : alfresco or archive + * @param location : location inside docker container, should be mounted as volume + * @param numberToKeep : how many backup you want to keep + * + * @return {@link RestHtmlResponse} + * + * example of response of HTML page: + * {"responseHeader":{"status":0,"QTime":5},"exception":"org.apache.solr.common.SolrException:org.apache.solr.common.SolrException: + * Directory does not exist: + * file:///nop/snapshot.20190212152339023","status":"OK"} + * @throws InterruptedException + */ + protected RestHtmlResponse executeSolrBackupRequest(String core, String location, int numberToKeep) + throws InterruptedException { + + String keep = String.valueOf(numberToKeep); + RestRequest request = RestRequest.simpleRequest(HttpMethod.GET, + "{core}/replication?command=backup&location={location}&numberToKeep={keep}&wt=json", core, + location, keep); + RestHtmlResponse htmlResponse = restWrapper.processHtmlResponse(request); + // need to wait for backup data to be created or deleted based on numberToKeep + Utility.waitToLoopTime(2, "Wait until the backup data is created/deleted"); + return htmlResponse; + + } + + /** + * Will assert that @param count files starting with @param filePrefix are found + * inside @param folder + */ + protected File[] assertFileExistInLocalBackupFolder(String folder, String filePrefix, int count) { + + File backupLocation = Paths.get(solrDockerHostPath, folder).toFile(); + + if (count >= 1) { + Assert.assertEquals(backupLocation.listFiles().length, count, + "Expected Files in folder:" + backupLocation.getPath()); + + SoftAssert soft = new SoftAssert(); + for (File file : backupLocation.listFiles()) { + soft.assertTrue(file.getName().startsWith(filePrefix), + String.format("File [%s] starts with prefix: %s", file.getPath(), filePrefix)); + } + soft.assertAll(); + + return backupLocation.listFiles(); + } else { + Assert.assertEquals(backupLocation.listFiles().length, 0, backupLocation.getPath() + "should be empty!"); + } + + return null; + + } +} diff --git a/e2e-test/src/test/java/org/alfresco/service/search/backup/README.md b/e2e-test/src/test/java/org/alfresco/service/search/backup/README.md new file mode 100644 index 000000000..5ef023af7 --- /dev/null +++ b/e2e-test/src/test/java/org/alfresco/service/search/backup/README.md @@ -0,0 +1,15 @@ +# About +This suite(s) will test the backup process of SearchService/InsightEngine + +# Prerequisites + +a) `docker-compose.backup.yml` +You need to execute the "start-backup" tasks from the `BuildScripts/qa` folder +That command will provision some docker containers with: +* `alfresco` service having 'remoteBackupLocation' set for `archive` and `alfresco` cores +* `search` service that will automatically or/on demand save the index to location specified + +b) I assume that + +# Tests +Run the MAVEN tests after you start the test environment (prerequisites) \ No newline at end of file diff --git a/e2e-test/src/test/java/org/alfresco/service/search/backup/SearchServiceBackupTests.java b/e2e-test/src/test/java/org/alfresco/service/search/backup/SearchServiceBackupTests.java new file mode 100644 index 000000000..09bac2fe4 --- /dev/null +++ b/e2e-test/src/test/java/org/alfresco/service/search/backup/SearchServiceBackupTests.java @@ -0,0 +1,71 @@ +package org.alfresco.service.search.backup; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.StringContains.containsString; + +import org.alfresco.rest.model.RestHtmlResponse; +import org.alfresco.utility.model.SiteModel; +import org.testng.Assert; +import org.testng.annotations.Test; + +/** + * + * Documentation: http://docs.alfresco.com/6.0/tasks/solr6-backup.html + * + * @author Paul Brodner + * + */ +public class SearchServiceBackupTests extends AbstractBackupTest { + + private SiteModel testSite = new SiteModel("siteForBackupTesting"); + /** + * {"responseHeader":{"status":0,"QTime":1},"exception":"org.apache.solr.common.SolrException:org.apache.solr.common.SolrException: + * Directory does not exist: + * file:///thisDoesntExist1/snapshot.20190212161435995","status":"OK"} + */ + @Test(priority = 0) + public void throwSorlExceptioIfDestinationFolderDoesntExist() throws Exception { + RestHtmlResponse htmlResponse = executeSolrBackupRequest("alfresco", "/thisDoesntExist", 1); + + String exception = htmlResponse.getBody().jsonPath().get("exception").toString(); + + assertThat(exception, containsString( + "org.apache.solr.common.SolrException:org.apache.solr.common.SolrException: Directory does not exist: file:///thisDoesntExist")); + + } + + @Test(priority=1) + public void createTestSiteForBackup() { + if(dataSite.isSiteCreated(testSite)) + testSite = dataSite.usingAdmin().createSite(testSite); + + } + + /** + * In case of success: {"responseHeader":{"status":0,"QTime":3},"status":"OK"} + */ + @Test(priority=2) + public void save1AlfrescoSnaphotToExistingBackupFolder() throws Exception { + RestHtmlResponse htmlResponse = executeSolrBackupRequest("alfresco", "/backup/alfresco", 1); + + String status = htmlResponse.getBody().jsonPath().get("status").toString(); + + /* + * in case of successfull backup we have status OK, no exception AND physical + * file saved under {solrDockerHostPath}/alfresco as > + * {solrDockerHostPath}/alfresco/snapshot.20190212161552891 (not empty with a + * lot of lucene files) + */ + + Assert.assertNull(htmlResponse.getBody().jsonPath().get("exception")); + Assert.assertEquals(status, "OK"); + + assertFileExistInLocalBackupFolder("solr/alfresco", "snapshot.", 1); + + //execute another request and see that files inside solr/alfresco backup folder are 1 + htmlResponse = executeSolrBackupRequest("alfresco", "/backup/alfresco", 1); + assertFileExistInLocalBackupFolder("solr/alfresco", "snapshot.", 1); + + } + +} diff --git a/e2e-test/src/test/resources/default.properties b/e2e-test/src/test/resources/default.properties index e9ee1447e..34b0e3239 100644 --- a/e2e-test/src/test/resources/default.properties +++ b/e2e-test/src/test/resources/default.properties @@ -8,6 +8,13 @@ sync.scheme=http sync.server=localhost sync.port=9090 +# solr service related +solr.port=8083 + +# backup section +# solr.docker.hostPath=. # is the volume mounted inside the search service image +solr.docker.hostPath=. + #CMIS Related: Set CMIS binding to 'browser' or 'atom' cmis.binding=browser cmis.basePath=/alfresco/api/-default-/public/cmis/versions/1.1/${cmis.binding} diff --git a/e2e-test/src/test/resources/search-backup-suite.xml b/e2e-test/src/test/resources/search-backup-suite.xml new file mode 100644 index 000000000..f35770323 --- /dev/null +++ b/e2e-test/src/test/resources/search-backup-suite.xml @@ -0,0 +1,8 @@ + + + + + + + +