Merge pull request #1446 from Alfresco/feature/ACS-3488_RemoveXMLDataProvider

ACS-3488 Remove xml data provider.
This commit is contained in:
Tom Page
2022-09-28 08:45:54 +01:00
committed by GitHub
4 changed files with 299 additions and 47 deletions

View File

@@ -18,7 +18,6 @@
<properties>
<maven.build.sourceVersion>11</maven.build.sourceVersion>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<tas.utility.version>3.0.53</tas.utility.version>
<chemistry-opencmis-commons-api>1.1.0</chemistry-opencmis-commons-api>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<maven-release.version>2.5.3</maven-release.version>
@@ -69,7 +68,6 @@
<dependency>
<groupId>org.alfresco.tas</groupId>
<artifactId>utility</artifactId>
<version>${tas.utility.version}</version>
<exclusions>
<exclusion>
<groupId>mysql</groupId>

View File

@@ -1,5 +1,6 @@
package org.alfresco.cmis.dsl;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;
@@ -10,10 +11,10 @@ import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import com.google.common.collect.Streams;
import java.util.function.Function;
import java.util.stream.StreamSupport;
import org.alfresco.cmis.CmisWrapper;
import org.alfresco.utility.LogFactory;
@@ -26,6 +27,7 @@ import org.alfresco.utility.model.TestModel;
import org.apache.chemistry.opencmis.client.api.ItemIterable;
import org.apache.chemistry.opencmis.client.api.QueryResult;
import org.apache.chemistry.opencmis.client.api.Session;
import org.apache.chemistry.opencmis.commons.data.PropertyData;
import org.slf4j.Logger;
import org.testng.Assert;
@@ -38,9 +40,9 @@ public class QueryExecutor
static Logger LOG = LogFactory.getLogger();
CmisWrapper cmisWrapper;
private long returnedResults = -1;
private long resultCount = -1;
private String currentQuery = "";
private ItemIterable<QueryResult> results;
private List<QueryResult> results;
public QueryExecutor(CmisWrapper cmisWrapper, String query)
{
@@ -50,28 +52,45 @@ public class QueryExecutor
public QueryResultAssertion assertResultsCount()
{
returnedResults = executeQuery(currentQuery).getPageNumItems();
resultCount = executeQuery(currentQuery).getPageNumItems();
return new QueryResultAssertion();
}
public QueryResultAssertion assertColumnIsOrdered()
{
results = executeQuery(currentQuery);
return new QueryResultAssertion();
return assertValues();
}
public QueryResultAssertion assertColumnValuesRange()
{
results = executeQuery(currentQuery);
return new QueryResultAssertion();
return assertValues();
}
public QueryResultAssertion assertValues()
{
results = executeQuery(currentQuery);
STEP("Sending query " + currentQuery);
results = StreamSupport.stream(executeQuery(currentQuery).spliterator(), false)
.collect(toList());
resultCount = results.size();
STEP("Received results " + results.stream().map(this::resultToString).collect(toList()));
return new QueryResultAssertion();
}
/** Try to return a useful string representation of the CMIS query result. */
private String resultToString(QueryResult result)
{
if (result == null || result.getProperties() == null)
{
return "null";
}
Optional<PropertyData<?>> idProperty = result.getProperties().stream()
.filter(propertyData -> propertyData.getId().equals("cmis:objectId"))
.findFirst();
return idProperty.map(PropertyData::getValues)
.map(values -> values.stream().map(Object::toString).collect(joining(",")))
.orElse(result.getProperties().toString());
}
private ItemIterable<QueryResult> executeQuery(String query)
{
Session session = cmisWrapper.getSession();
@@ -160,18 +179,18 @@ public class QueryExecutor
public class QueryResultAssertion
{
public QueryResultAssertion equals(long expectedValue)
public QueryResultAssertion hasLength(long expectedValue)
{
STEP(String.format("Verify that query: '%s' has %d results count returned", currentQuery, expectedValue));
Assert.assertEquals(returnedResults, expectedValue, showErrorMessage());
Assert.assertEquals(resultCount, expectedValue, showErrorMessage());
return this;
}
public QueryResultAssertion isGreaterThan(long expectedValue)
{
STEP(String.format("Verify that query: '%s' has more than %d results count returned", currentQuery, expectedValue));
if (expectedValue <= returnedResults)
Assert.fail(String.format("%s expected to have more than %d results, but found %d", showErrorMessage(), expectedValue, returnedResults));
if (expectedValue <= resultCount)
Assert.fail(String.format("%s expected to have more than %d results, but found %d", showErrorMessage(), expectedValue, resultCount));
return this;
}
@@ -179,8 +198,8 @@ public class QueryExecutor
public QueryResultAssertion isLowerThan(long expectedValue)
{
STEP(String.format("Verify that query: '%s' has more than %d results count returned", currentQuery, expectedValue));
if (returnedResults >= expectedValue)
Assert.fail(String.format("%s expected to have less than %d results, but found %d", showErrorMessage(), expectedValue, returnedResults));
if (resultCount >= expectedValue)
Assert.fail(String.format("%s expected to have less than %d results, but found %d", showErrorMessage(), expectedValue, resultCount));
return this;
}
@@ -192,7 +211,7 @@ public class QueryExecutor
results.forEach((r) -> {
columnValues.add(r.getPropertyValueByQueryName(queryName));
});
List<Object> orderedColumnValues = columnValues.stream().sorted().collect(Collectors.toList());
List<Object> orderedColumnValues = columnValues.stream().sorted().collect(toList());
Assert.assertEquals(columnValues, orderedColumnValues,
String.format("%s column values expected to be in ascendent order, but found %s", queryName, columnValues.toString()));
@@ -207,7 +226,7 @@ public class QueryExecutor
results.forEach((r) -> {
columnValues.add(r.getPropertyValueByQueryName(queryName));
});
List<Object> reverseOrderedColumnValues = columnValues.stream().sorted(Collections.reverseOrder()).collect(Collectors.toList());
List<Object> reverseOrderedColumnValues = columnValues.stream().sorted(Collections.reverseOrder()).collect(toList());
Assert.assertEquals(columnValues, reverseOrderedColumnValues,
String.format("%s column values expected to be in descendent order, but found %s", queryName, columnValues.toString()));
@@ -230,18 +249,30 @@ public class QueryExecutor
}
public <T> QueryResultAssertion isReturningValues(String queryName, Set<T> values)
{
return isReturningValues(queryName, values, false);
}
public <T> QueryResultAssertion isReturningValues(String queryName, Set<T> values, boolean multivalue)
{
STEP(String.format("Verify that query: '%s' returns the values from %s for column %s", currentQuery, values, queryName));
Set<T> resultSet = Streams.stream(results).map(r -> (T) r.getPropertyValueByQueryName(queryName)).collect(toSet());
Assert.assertEquals(resultSet, values, "Values did not match");
Function<QueryResult, Object> extractValue = (multivalue ? (r -> r.getPropertyMultivalueById(queryName)) : r -> r.getPropertyValueById(queryName));
Set<Object> resultSet = results.stream().map(extractValue).collect(toSet());
Assert.assertEquals(resultSet, values, "Values did not match - expected " + values + " got " + resultSet);
return this;
}
public <T> QueryResultAssertion isReturningOrderedValues(String queryName, List<T> values)
{
return isReturningOrderedValues(queryName, values, false);
}
public <T> QueryResultAssertion isReturningOrderedValues(String queryName, List<T> values, boolean multivalue)
{
STEP(String.format("Verify that query: '%s' returns the values from %s for column %s", currentQuery, values, queryName));
List<T> resultList = Streams.stream(results).map(r -> (T) r.getPropertyValueByQueryName(queryName)).collect(toList());
Function<QueryResult, Object> extractValue = (multivalue ? (r -> r.getPropertyMultivalueById(queryName)) : r -> r.getPropertyValueById(queryName));
List<Object> resultList = results.stream().map(extractValue).collect(toList());
// Include both lists in assertion message as TestNG does not provide this information.
Assert.assertEquals(resultList, values, "Values did not match expected " + values + " but found " + resultList);

View File

@@ -1,9 +1,21 @@
package org.alfresco.cmis.search;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;
import static org.alfresco.utility.report.log.Step.STEP;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import org.alfresco.cmis.CmisProperties;
import org.alfresco.cmis.dsl.QueryExecutor.QueryResultAssertion;
import org.alfresco.utility.Utility;
import org.alfresco.utility.model.ContentModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -45,32 +57,76 @@ public abstract class AbstractCmisE2ETest extends AbstractE2EFunctionalTest
/**
* Repeat Elastic Query till results count returns expectedCountResults
* @param query CMIS Query to be executed
* @param expectedCountResults Number of results expected
* @param expectedResultsCount Number of results expected
* @return true when results count is equals to expectedCountResults
*/
protected boolean waitForIndexing(String query, long expectedCountResults)
protected boolean waitForIndexing(String query, long expectedResultsCount)
{
for (int searchCount = 1; searchCount <= SEARCH_MAX_ATTEMPTS; searchCount++)
try
{
waitForIndexing(query, execution -> execution.hasLength(expectedResultsCount));
return true;
}
catch (AssertionError ae)
{
STEP("Received assertion error for query '" + query + "': " + ae);
return false;
}
}
/**
* Repeat Elastic Query until we get the expected results or we hit the retry limit.
*
* @param query CMIS Query to be executed
* @param expectedResults The expected results (unordered).
*/
protected void waitForIndexing(String query, ContentModel... expectedResults)
{
Set<String> expectedNames = Arrays.stream(expectedResults).map(ContentModel::getName).collect(toSet());
waitForIndexing(query, execution -> execution.isReturningValues("cmis:name", expectedNames));
}
/**
* Repeat Elastic Query until we get the expected results in the given order or we hit the retry limit.
*
* @param query CMIS Query to be executed
* @param expectedResults The expected results (ordered).
*/
protected void waitForIndexingOrdered(String query, ContentModel... expectedResults)
{
List<String> expectedNames = Arrays.stream(expectedResults).map(ContentModel::getName).collect(toList());
waitForIndexing(query, execution -> execution.isReturningOrderedValues("cmis:name", expectedNames));
}
/**
* Repeat Elastic Query until we get the expected results or we hit the retry limit.
*
* @param query CMIS Query to be executed
* @param assertionMethod A method that will be called to check the response and which will throw an AssertionError if they aren't what we want.
*/
protected void waitForIndexing(String query, Consumer<QueryResultAssertion> assertionMethod)
{
int searchCount = 0;
while (true)
{
try
{
cmisApi.withQuery(query).assertResultsCount().equals(expectedCountResults);
return true;
assertionMethod.accept(cmisApi.withQuery(query).assertValues());
return;
}
catch (AssertionError ae)
{
LOGGER.info(String.format("WaitForIndexing in Progress: %s", ae));
searchCount++;
if (searchCount < SEARCH_MAX_ATTEMPTS)
{
LOGGER.info(String.format("WaitForIndexing in Progress: %s", ae));
Utility.waitToLoopTime(getElasticWaitTimeInSeconds(), "Wait For Indexing");
}
else
{
throw ae;
}
}
Utility.waitToLoopTime(getElasticWaitTimeInSeconds(), "Wait For Indexing");
}
return false;
}
}

View File

@@ -1,12 +1,12 @@
package org.alfresco.cmis.search;
import java.util.List;
import java.util.Set;
import org.alfresco.utility.Utility;
import org.alfresco.utility.data.provider.XMLDataConfig;
import org.alfresco.utility.data.provider.XMLTestDataProvider;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.FileType;
import org.alfresco.utility.model.FolderModel;
import org.alfresco.utility.model.QueryModel;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
@@ -17,6 +17,21 @@ public class SearchInFolderTests extends AbstractCmisE2ETest
private FolderModel parentFolder, subFolder1, subFolder2, subFolder3;
private FileModel subFile1, subFile2, subFile3, subFile4, subFile5;
/**
* Create test data in the following format:
* <pre>
* testSite
* +- parentFolder
* +- subFile5 (fifthFile.txt: "fifthFile content")
* +- subFolder1
* +- subFolder2
* +- subFolder3 (subFolder)
* +- subFile1 (firstFile.xls)
* +- subFile2 (.pptx)
* +- subFile3 (.txt)
* +- subFile4 (fourthFile.docx: "fourthFileTitle", "fourthFileDescription")
* </pre>
*/
@BeforeClass(alwaysRun = true)
public void createTestData() throws Exception
{
@@ -51,12 +66,164 @@ public class SearchInFolderTests extends AbstractCmisE2ETest
dataContent.deleteSite(testSite);
}
@Test(dataProviderClass = XMLTestDataProvider.class, dataProvider = "getQueriesData")
@XMLDataConfig(file = "src/test/resources/search-in-folder.xml")
public void executeCMISQuery(QueryModel query)
@Test
public void executeCMISQuery_selectFieldsFromFolder()
{
String currentQuery = String.format(query.getValue(), parentFolder.getNodeRef());
String query = "SELECT cmis:name, cmis:parentId, cmis:path, cmis:allowedChildObjectTypeIds" +
" FROM cmis:folder where IN_FOLDER('%s') AND cmis:name = 'subFolder'";
String currentQuery = String.format(query, parentFolder.getNodeRef());
cmisApi.authenticateUser(testUser);
Assert.assertTrue(waitForIndexing(currentQuery, query.getResults()), String.format("Result count not as expected for query: %s", currentQuery));
waitForIndexing(currentQuery, subFolder3);
}
@Test
public void executeCMISQuery_selectFieldsFromDocument()
{
String query = "SELECT cmis:name, cmis:objectId, cmis:lastModifiedBy, cmis:creationDate, cmis:contentStreamFileName" +
" FROM cmis:document where IN_FOLDER('%s') AND cmis:name = 'fourthFile'";
String currentQuery = String.format(query, parentFolder.getNodeRef());
cmisApi.authenticateUser(testUser);
waitForIndexing(currentQuery, subFile4);
}
@Test
public void executeCMISQuery_selectParentId()
{
String query = "SELECT cmis:parentId FROM cmis:folder where IN_FOLDER('%s')";
String currentQuery = String.format(query, parentFolder.getNodeRef());
cmisApi.authenticateUser(testUser);
// Expect to get the same parent for each of the three matches.
String parentId = parentFolder.getNodeRef();
List<String> expectedParentIds = List.of(parentId, parentId, parentId);
waitForIndexing(currentQuery, execution -> execution.isReturningOrderedValues("cmis:parentId", expectedParentIds));
}
@Test
public void executeCMISQuery_inFolder()
{
String query = "SELECT * FROM cmis:document where IN_FOLDER('%s')";
String currentQuery = String.format(query, parentFolder.getNodeRef());
cmisApi.authenticateUser(testUser);
waitForIndexing(currentQuery, subFile1, subFile2, subFile3, subFile4, subFile5);
}
@Test
public void executeCMISQuery_orderByNameAsc()
{
String query = "SELECT * FROM cmis:document where IN_FOLDER('%s') AND cmis:name NOT LIKE 'file%%' ORDER BY cmis:name ASC";
String currentQuery = String.format(query, parentFolder.getNodeRef());
cmisApi.authenticateUser(testUser);
waitForIndexingOrdered(currentQuery, subFile5, subFile1, subFile4);
}
@Test
public void executeCMISQuery_orderByNameDesc()
{
String query = "SELECT * FROM cmis:document where IN_FOLDER('%s') AND cmis:name NOT LIKE 'file%%' ORDER BY cmis:name DESC";
String currentQuery = String.format(query, parentFolder.getNodeRef());
cmisApi.authenticateUser(testUser);
waitForIndexingOrdered(currentQuery, subFile4, subFile1, subFile5);
}
@Test
public void executeCMISQuery_orderByLastModifiedAsc()
{
String query = "SELECT * FROM cmis:folder where IN_FOLDER('%s') ORDER BY cmis:lastModificationDate ASC";
String currentQuery = String.format(query, parentFolder.getNodeRef());
cmisApi.authenticateUser(testUser);
waitForIndexingOrdered(currentQuery, subFolder1, subFolder2, subFolder3);
}
@Test
public void executeCMISQuery_orderByLastModifiedDesc()
{
String query = "SELECT * FROM cmis:folder where IN_FOLDER('%s') ORDER BY cmis:lastModificationDate DESC";
String currentQuery = String.format(query, parentFolder.getNodeRef());
cmisApi.authenticateUser(testUser);
waitForIndexingOrdered(currentQuery, subFolder3, subFolder2, subFolder1);
}
@Test
public void executeCMISQuery_orderByCreatedBy()
{
String query = "SELECT * FROM cmis:document where IN_FOLDER('%s') ORDER BY cmis:createdBy DESC";
String currentQuery = String.format(query, parentFolder.getNodeRef());
cmisApi.authenticateUser(testUser);
// All the results were created by the same user, so we can't assert anything about the order.
waitForIndexing(currentQuery, subFile5, subFile1, subFile2, subFile3, subFile4);
}
@Test
public void executeCMISQuery_documentNameNotNull()
{
String query = "SELECT * FROM cmis:document where IN_FOLDER('%s') AND cmis:name IS NOT NULL";
String currentQuery = String.format(query, parentFolder.getNodeRef());
cmisApi.authenticateUser(testUser);
waitForIndexing(currentQuery, subFile1, subFile2, subFile3, subFile4, subFile5);
}
@Test
public void executeCMISQuery_folderNameNotNull()
{
String query = "SELECT * FROM cmis:folder where IN_FOLDER('%s') AND cmis:name IS NOT NULL";
String currentQuery = String.format(query, parentFolder.getNodeRef());
cmisApi.authenticateUser(testUser);
waitForIndexing(currentQuery, subFolder1, subFolder2, subFolder3);
}
@Test
public void executeCMISQuery_nameLike()
{
String query = "SELECT * FROM cmis:document where IN_FOLDER('%s') AND cmis:name LIKE 'fourthFile'";
String currentQuery = String.format(query, parentFolder.getNodeRef());
cmisApi.authenticateUser(testUser);
waitForIndexingOrdered(currentQuery, subFile4);
}
@Test
public void executeCMISQuery_doubleNegative()
{
String query = "SELECT * FROM cmis:folder where IN_FOLDER('%s') AND NOT(cmis:name NOT IN ('subFolder'))";
String currentQuery = String.format(query, parentFolder.getNodeRef());
cmisApi.authenticateUser(testUser);
waitForIndexingOrdered(currentQuery, subFolder3);
}
@Test
public void executeCMISQuery_nameInList()
{
String query = "SELECT * FROM cmis:document where IN_FOLDER('%s') AND cmis:name IN ('fourthFile', 'fifthFile.txt')";
String currentQuery = String.format(query, parentFolder.getNodeRef());
cmisApi.authenticateUser(testUser);
waitForIndexing(currentQuery, subFile4, subFile5);
}
@Test
public void executeCMISQuery_nameNotInList()
{
String query = "SELECT * FROM cmis:document where IN_FOLDER('%s') AND cmis:name NOT IN ('fourthFile', 'fifthFile.txt')";
String currentQuery = String.format(query, parentFolder.getNodeRef());
cmisApi.authenticateUser(testUser);
waitForIndexing(currentQuery, subFile1, subFile2, subFile3);
}
@Test
public void executeCMISQuery_nameDifferentFrom()
{
String query = "SELECT * FROM cmis:folder where IN_FOLDER('%s') AND cmis:name <> 'subFolder'";
String currentQuery = String.format(query, parentFolder.getNodeRef());
cmisApi.authenticateUser(testUser);
waitForIndexing(currentQuery, subFolder1, subFolder2);
}
@Test
public void executeCMISQuery_selectSecondaryObjectTypeIds()
{
String query = "SELECT cmis:secondaryObjectTypeIds FROM cmis:folder where IN_FOLDER('%s') AND cmis:name = 'subFolder'";
String currentQuery = String.format(query, parentFolder.getNodeRef());
cmisApi.authenticateUser(testUser);
Set<List<String>> expectedSecondaryObjectTypeIds = Set.of(List.of("P:cm:titled", "P:sys:localized"));
waitForIndexing(currentQuery, execution -> execution.isReturningValues("cmis:secondaryObjectTypeIds", expectedSecondaryObjectTypeIds, true));
Assert.assertTrue(waitForIndexing(currentQuery, 1), String.format("Result count not as expected for query: %s", currentQuery));
}
}