mirror of
https://github.com/Alfresco/SearchServices.git
synced 2025-09-17 14:21:20 +00:00
Initial Commit for End to End tests for search Services and Insight Engine
This commit is contained in:
32
e2e-test/.gitignore
vendored
Normal file
32
e2e-test/.gitignore
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/target/
|
||||||
|
/test-output/
|
||||||
|
/.settings/
|
||||||
|
bin/
|
||||||
|
report.html
|
||||||
|
*.log
|
||||||
|
test-output*
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# Eclipse
|
||||||
|
.classpath
|
||||||
|
.settings
|
||||||
|
.project
|
||||||
|
|
||||||
|
# Intellij
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# Mac
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Maven
|
||||||
|
target
|
||||||
|
*.log
|
||||||
|
*.log.*
|
||||||
|
|
||||||
|
|
||||||
|
# Package Files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.ear
|
36
e2e-test/README.md
Normal file
36
e2e-test/README.md
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# Setup
|
||||||
|
The automated test project requires a running instance of ACS Repo and Search Services at the least.
|
||||||
|
To run Insight Engine tests, minimum version of Repo is ACS 6.0, additionally running instance of Insight Engine would be necessary too.
|
||||||
|
For more details see: [Search-Discovery] (https://git.alfresco.com/search_discovery).
|
||||||
|
|
||||||
|
# Prerequisites
|
||||||
|
Java 1.8
|
||||||
|
|
||||||
|
Maven 3.2.0
|
||||||
|
|
||||||
|
Alfresco Content Services 5.2.2 or above
|
||||||
|
|
||||||
|
Search Services 1.2.0 or above or Insight Engine 1.0.0 or above
|
||||||
|
|
||||||
|
# Bring the Test Environment up
|
||||||
|
|
||||||
|
1. ACS + Search Services Healthcheck: Please ensure that repo admin console > Search Services uses the right port and shows tracking status.
|
||||||
|
|
||||||
|
2. Solr Healthcheck can be performed using solr admin console:
|
||||||
|
|
||||||
|
AT <protocol>://<repo-host-ip>:<solr-port>/solr/#
|
||||||
|
|
||||||
|
e.g. http://localhost:8983/solr/#
|
||||||
|
|
||||||
|
# Compile the project
|
||||||
|
`mvn clean install -DskipTests`
|
||||||
|
|
||||||
|
# Run the tests
|
||||||
|
`mvn clean install`
|
||||||
|
|
||||||
|
# Run a specific class of tests
|
||||||
|
`mvn clean install -Dtest=<class>`
|
||||||
|
|
||||||
|
e.g.
|
||||||
|
|
||||||
|
`mvn clean install -Dtest=org.alfresco.service.search.e2e.insightEngine.sql.CustomModelTest`
|
108
e2e-test/pom.xml
Normal file
108
e2e-test/pom.xml
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.alfresco</groupId>
|
||||||
|
<artifactId>alfresco-super-pom</artifactId>
|
||||||
|
<version>8</version>
|
||||||
|
</parent>
|
||||||
|
<groupId>Search-Analytics-e2e-test</groupId>
|
||||||
|
<artifactId>Search-Analytics-e2e-test</artifactId>
|
||||||
|
<name>Search Analytics E2E Tests</name>
|
||||||
|
<description>Test Project to test Search Service and Analytics Features on a complete setup of Alfresco, Share</description>
|
||||||
|
<properties>
|
||||||
|
<!-- <maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target> -->
|
||||||
|
<tas.utility.version>1.0.29-SNAPSHOT</tas.utility.version>
|
||||||
|
<tas.rest.api.version>5.2.0-12-SNAPSHOT</tas.rest.api.version>
|
||||||
|
<tas.cmis.api.version>5.2.0-3-SNAPSHOT</tas.cmis.api.version>
|
||||||
|
<rm.version>2.6.0</rm.version>
|
||||||
|
<suiteXmlFile>src/test/resources/SearchSuite.xml</suiteXmlFile>
|
||||||
|
<test.exclude></test.exclude>
|
||||||
|
<test.include></test.include>
|
||||||
|
</properties>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<!-- <configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
</configuration> -->
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<suiteXmlFiles>
|
||||||
|
<suiteXmlFile>${suiteXmlFile}</suiteXmlFile>
|
||||||
|
</suiteXmlFiles>
|
||||||
|
<excludedGroups>
|
||||||
|
${test.exclude}
|
||||||
|
</excludedGroups>
|
||||||
|
<groups>
|
||||||
|
${test.include}
|
||||||
|
</groups>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-remote-resources-plugin</artifactId>
|
||||||
|
<version>1.5</version>
|
||||||
|
<configuration>
|
||||||
|
<resourceBundles>
|
||||||
|
<resourceBundle>org.alfresco.tas:utility:${tas.utility.version}</resourceBundle>
|
||||||
|
</resourceBundles>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>process</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.alfresco.tas</groupId>
|
||||||
|
<artifactId>utility</artifactId>
|
||||||
|
<version>${tas.utility.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.alfresco.tas</groupId>
|
||||||
|
<artifactId>restapi-test</artifactId>
|
||||||
|
<version>${tas.rest.api.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.alfresco.tas</groupId>
|
||||||
|
<artifactId>cmis-test</artifactId>
|
||||||
|
<version>${tas.cmis.api.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.alfresco</groupId>
|
||||||
|
<artifactId>alfresco-rm-automation-enterprise-rest-api</artifactId>
|
||||||
|
<version>${rm.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.alfresco</groupId>
|
||||||
|
<artifactId>alfresco-rm-automation-community-rest-api</artifactId>
|
||||||
|
<version>${rm.version}</version>
|
||||||
|
<classifier>tests</classifier>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.16.10</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.rest-assured</groupId>
|
||||||
|
<artifactId>rest-assured</artifactId>
|
||||||
|
<version>3.0.6</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
105
e2e-test/src/main/resources/model/finance-model.xml
Normal file
105
e2e-test/src/main/resources/model/finance-model.xml
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<model xmlns="http://www.alfresco.org/model/dictionary/1.0" name="finance:Finance">
|
||||||
|
<author>Administrator</author>
|
||||||
|
<imports>
|
||||||
|
<import uri="http://www.alfresco.org/model/content/1.0" prefix="cm"/>
|
||||||
|
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
|
||||||
|
</imports>
|
||||||
|
<namespaces>
|
||||||
|
<namespace uri="Finance" prefix="finance"/>
|
||||||
|
</namespaces>
|
||||||
|
<data-types/>
|
||||||
|
<constraints/>
|
||||||
|
<types>
|
||||||
|
<type name="finance:Receipt">
|
||||||
|
<title>Receipt</title>
|
||||||
|
<parent>cm:content</parent>
|
||||||
|
<properties>
|
||||||
|
<property name="finance:ReceiptValue">
|
||||||
|
<title>ReceiptValue</title>
|
||||||
|
<type>d:double</type>
|
||||||
|
<mandatory>false</mandatory>
|
||||||
|
<index enabled="true">
|
||||||
|
<tokenised>TRUE</tokenised>
|
||||||
|
<facetable>true</facetable>
|
||||||
|
</index>
|
||||||
|
</property>
|
||||||
|
<property name="finance:ReceiptNo">
|
||||||
|
<title>ReceiptNo</title>
|
||||||
|
<type>d:long</type>
|
||||||
|
<mandatory>false</mandatory>
|
||||||
|
<index enabled="true">
|
||||||
|
<tokenised>TRUE</tokenised>
|
||||||
|
</index>
|
||||||
|
</property>
|
||||||
|
</properties>
|
||||||
|
<associations/>
|
||||||
|
<overrides/>
|
||||||
|
<mandatory-aspects/>
|
||||||
|
</type>
|
||||||
|
<type name="finance:Expense">
|
||||||
|
<title>Expense</title>
|
||||||
|
<parent>cm:content</parent>
|
||||||
|
<properties>
|
||||||
|
<property name="finance:No">
|
||||||
|
<title>No</title>
|
||||||
|
<type>d:long</type>
|
||||||
|
<mandatory>false</mandatory>
|
||||||
|
<index enabled="true">
|
||||||
|
<tokenised>TRUE</tokenised>
|
||||||
|
<facetable>true</facetable>
|
||||||
|
</index>
|
||||||
|
</property>
|
||||||
|
<property name="finance:Emp">
|
||||||
|
<title>Emp</title>
|
||||||
|
<type>d:text</type>
|
||||||
|
<mandatory>false</mandatory>
|
||||||
|
<index enabled="true">
|
||||||
|
<tokenised>TRUE</tokenised>
|
||||||
|
<facetable>true</facetable>
|
||||||
|
</index>
|
||||||
|
</property>
|
||||||
|
<property name="finance:amount">
|
||||||
|
<title>Amount</title>
|
||||||
|
<type>d:double</type>
|
||||||
|
<mandatory>false</mandatory>
|
||||||
|
<index enabled="true">
|
||||||
|
<tokenised>TRUE</tokenised>
|
||||||
|
<facetable>true</facetable>
|
||||||
|
</index>
|
||||||
|
</property>
|
||||||
|
<property name="finance:Title">
|
||||||
|
<title>Title</title>
|
||||||
|
<type>d:text</type>
|
||||||
|
<mandatory>false</mandatory>
|
||||||
|
<index enabled="true">
|
||||||
|
<tokenised>TRUE</tokenised>
|
||||||
|
<facetable>false</facetable>
|
||||||
|
</index>
|
||||||
|
</property>
|
||||||
|
</properties>
|
||||||
|
<associations/>
|
||||||
|
<overrides/>
|
||||||
|
<mandatory-aspects/>
|
||||||
|
</type>
|
||||||
|
</types>
|
||||||
|
<aspects>
|
||||||
|
<aspect name="finance:ParkEx">
|
||||||
|
<title>Parking Expense</title>
|
||||||
|
<properties>
|
||||||
|
<property name="finance:Location">
|
||||||
|
<title>Location</title>
|
||||||
|
<type>d:text</type>
|
||||||
|
<mandatory>true</mandatory>
|
||||||
|
<index enabled="true">
|
||||||
|
<tokenised>TRUE</tokenised>
|
||||||
|
<facetable>true</facetable>
|
||||||
|
</index>
|
||||||
|
</property>
|
||||||
|
</properties>
|
||||||
|
<associations/>
|
||||||
|
<overrides/>
|
||||||
|
<mandatory-aspects/>
|
||||||
|
</aspect>
|
||||||
|
</aspects>
|
||||||
|
</model>
|
107
e2e-test/src/main/resources/model/music-model.xml
Normal file
107
e2e-test/src/main/resources/model/music-model.xml
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<model xmlns="http://www.alfresco.org/model/dictionary/1.0" name="music:music">
|
||||||
|
<author>Administrator</author>
|
||||||
|
<imports>
|
||||||
|
<import uri="http://www.alfresco.org/model/content/1.0" prefix="cm"/>
|
||||||
|
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
|
||||||
|
</imports>
|
||||||
|
<namespaces>
|
||||||
|
<namespace uri="music" prefix="music"/>
|
||||||
|
</namespaces>
|
||||||
|
<data-types/>
|
||||||
|
<constraints/>
|
||||||
|
<types>
|
||||||
|
<type name="music:song">
|
||||||
|
<title>song</title>
|
||||||
|
<parent>cm:content</parent>
|
||||||
|
<properties>
|
||||||
|
<property name="music:lyricist">
|
||||||
|
<title>lyricist</title>
|
||||||
|
<type>d:text</type>
|
||||||
|
<mandatory>false</mandatory>
|
||||||
|
<index enabled="true">
|
||||||
|
<tokenised>TRUE</tokenised>
|
||||||
|
<facetable>true</facetable>
|
||||||
|
</index>
|
||||||
|
</property>
|
||||||
|
<property name="music:artist-singer-male">
|
||||||
|
<title>artist-singer-male</title>
|
||||||
|
<type>d:text</type>
|
||||||
|
<mandatory>false</mandatory>
|
||||||
|
<index enabled="true">
|
||||||
|
<tokenised>TRUE</tokenised>
|
||||||
|
<facetable>false</facetable>
|
||||||
|
</index>
|
||||||
|
</property>
|
||||||
|
<property name="music:genre">
|
||||||
|
<title>genre</title>
|
||||||
|
<type>d:text</type>
|
||||||
|
<mandatory>false</mandatory>
|
||||||
|
<multiple>false</multiple>
|
||||||
|
<index enabled="true">
|
||||||
|
<tokenised>BOTH</tokenised>
|
||||||
|
<facetable>true</facetable>
|
||||||
|
</index>
|
||||||
|
</property>
|
||||||
|
<property name="music:lyrics">
|
||||||
|
<title>lyrics</title>
|
||||||
|
<type>d:mltext</type>
|
||||||
|
<mandatory>false</mandatory>
|
||||||
|
<index enabled="true">
|
||||||
|
<tokenised>TRUE</tokenised>
|
||||||
|
<facetable>false</facetable>
|
||||||
|
</index>
|
||||||
|
</property>
|
||||||
|
<property name="music:popular">
|
||||||
|
<title>popular</title>
|
||||||
|
<type>d:boolean</type>
|
||||||
|
<mandatory>false</mandatory>
|
||||||
|
<default>false</default>
|
||||||
|
<index enabled="true">
|
||||||
|
<tokenised>TRUE</tokenised>
|
||||||
|
</index>
|
||||||
|
</property>
|
||||||
|
<property name="music:artist-singer-female">
|
||||||
|
<title>artist-singer-female</title>
|
||||||
|
<type>d:text</type>
|
||||||
|
<mandatory>false</mandatory>
|
||||||
|
<index enabled="true">
|
||||||
|
<tokenised>TRUE</tokenised>
|
||||||
|
<facetable>false</facetable>
|
||||||
|
</index>
|
||||||
|
</property>
|
||||||
|
</properties>
|
||||||
|
<associations/>
|
||||||
|
<overrides/>
|
||||||
|
<mandatory-aspects/>
|
||||||
|
</type>
|
||||||
|
</types>
|
||||||
|
<aspects>
|
||||||
|
<aspect name="music:AudioVisual">
|
||||||
|
<title>AudioVisual</title>
|
||||||
|
<properties>
|
||||||
|
<property name="music:video">
|
||||||
|
<title>video</title>
|
||||||
|
<type>d:boolean</type>
|
||||||
|
<mandatory>false</mandatory>
|
||||||
|
<default>false</default>
|
||||||
|
<index enabled="true">
|
||||||
|
<tokenised>TRUE</tokenised>
|
||||||
|
</index>
|
||||||
|
</property>
|
||||||
|
<property name="music:audio">
|
||||||
|
<title>audio</title>
|
||||||
|
<type>d:boolean</type>
|
||||||
|
<mandatory>false</mandatory>
|
||||||
|
<default>true</default>
|
||||||
|
<index enabled="true">
|
||||||
|
<tokenised>TRUE</tokenised>
|
||||||
|
</index>
|
||||||
|
</property>
|
||||||
|
</properties>
|
||||||
|
<associations/>
|
||||||
|
<overrides/>
|
||||||
|
<mandatory-aspects/>
|
||||||
|
</aspect>
|
||||||
|
</aspects>
|
||||||
|
</model>
|
@@ -0,0 +1,151 @@
|
|||||||
|
package org.alfresco.service.search;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2018 Alfresco Software, Ltd. All rights reserved.
|
||||||
|
* License rights for this program may be obtained from Alfresco Software, Ltd.
|
||||||
|
* pursuant to a written agreement and any use of this program without such an
|
||||||
|
* agreement is prohibited.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import static lombok.AccessLevel.PROTECTED;
|
||||||
|
|
||||||
|
|
||||||
|
import javax.naming.AuthenticationException;
|
||||||
|
|
||||||
|
import org.alfresco.cmis.CmisWrapper;
|
||||||
|
import org.alfresco.dataprep.ContentService;
|
||||||
|
import org.alfresco.rest.core.RestProperties;
|
||||||
|
import org.alfresco.rest.core.RestWrapper;
|
||||||
|
import org.alfresco.rest.search.RestRequestQueryModel;
|
||||||
|
import org.alfresco.rest.search.SearchRequest;
|
||||||
|
import org.alfresco.rest.search.SearchResponse;
|
||||||
|
import org.alfresco.utility.LogFactory;
|
||||||
|
import org.alfresco.utility.TasProperties;
|
||||||
|
import org.alfresco.utility.Utility;
|
||||||
|
import org.alfresco.utility.data.DataContent;
|
||||||
|
import org.alfresco.utility.data.DataSite;
|
||||||
|
import org.alfresco.utility.data.DataUser;
|
||||||
|
import org.alfresco.utility.network.ServerHealth;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
|
||||||
|
import org.testng.annotations.BeforeSuite;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author meenal bhave
|
||||||
|
*/
|
||||||
|
|
||||||
|
@ContextConfiguration("classpath:alfresco-search-e2e-context.xml")
|
||||||
|
public abstract class AbstractSearchServiceE2E extends AbstractTestNGSpringContextTests
|
||||||
|
{
|
||||||
|
private static Logger LOG = LogFactory.getLogger();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected RestProperties restProperties;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected TasProperties properties;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected ServerHealth serverHealth;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected DataSite dataSite;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected DataContent dataContent;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected RestWrapper restClient;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected CmisWrapper cmisApi;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Getter(value = PROTECTED)
|
||||||
|
protected DataUser dataUser;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Getter(value = PROTECTED)
|
||||||
|
private ContentService contentService;
|
||||||
|
|
||||||
|
public static final String NODE_PREFIX = "workspace/SpacesStore/";
|
||||||
|
|
||||||
|
@BeforeSuite(alwaysRun = true)
|
||||||
|
public void beforeSuite() throws Exception
|
||||||
|
{
|
||||||
|
super.springTestContextPrepareTestInstance();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
dataContent.usingAdmin().deployContentModel("model/music-model.xml");
|
||||||
|
dataContent.usingAdmin().deployContentModel("model/finance-model.xml");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
LOG.warn("Error Loading Custom Model", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait for Solr to finish indexing: Indexing has caught up = true if search returns appropriate results
|
||||||
|
*
|
||||||
|
* @param userQuery: string to search for, unique search string will guarantee accurate results
|
||||||
|
* @param expectedInResults, true if entry is expected in the results set
|
||||||
|
* @return true (indexing is finished) if search returns appropriate results
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public boolean waitForIndexing(String userQuery, Boolean expectedInResults) throws Exception
|
||||||
|
{
|
||||||
|
Boolean found = false;
|
||||||
|
Boolean resultAsExpected = false;
|
||||||
|
String expectedStatusCode = HttpStatus.OK.toString();
|
||||||
|
|
||||||
|
SearchRequest query = new SearchRequest();
|
||||||
|
RestRequestQueryModel queryReq = new RestRequestQueryModel();
|
||||||
|
queryReq.setQuery(userQuery);
|
||||||
|
query.setQuery(queryReq);
|
||||||
|
|
||||||
|
// Using adminUser just to confirm that the content is indexed
|
||||||
|
SearchResponse response = restClient.authenticateUser(dataUser.getAdminUser()).withSearchAPI().search(query);
|
||||||
|
|
||||||
|
// Repeat search until the query results are as expected or Search Retry count is hit
|
||||||
|
for (int searchCount = 1; searchCount <= 3; searchCount++)
|
||||||
|
{
|
||||||
|
if (searchCount > 1)
|
||||||
|
{
|
||||||
|
// Wait for the solr indexing.
|
||||||
|
Utility.waitToLoopTime(properties.getSolrWaitTimeInSeconds(), "Wait For Indexing");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (restClient.getStatusCode().matches(expectedStatusCode))
|
||||||
|
{
|
||||||
|
if (response.getEntries().size() >= 1)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
found = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop again if result is not as expected: To cater for solr lag: eventual consistency
|
||||||
|
resultAsExpected = (expectedInResults.equals(found));
|
||||||
|
if (resultAsExpected)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new AuthenticationException("API returned status code:" + restClient.getStatusCode() + " Expected: " + expectedStatusCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultAsExpected;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 Alfresco Software, Ltd. All rights reserved.
|
||||||
|
* License rights for this program may be obtained from Alfresco Software, Ltd.
|
||||||
|
* pursuant to a written agreement and any use of this program without such an
|
||||||
|
* agreement is prohibited.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.alfresco.service.search.e2e.insightEngine.sql;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.alfresco.rest.core.RestResponse;
|
||||||
|
import org.alfresco.rest.search.SearchSqlRequest;
|
||||||
|
import org.alfresco.service.search.AbstractSearchServiceE2E;
|
||||||
|
import org.alfresco.utility.constants.UserRole;
|
||||||
|
import org.alfresco.utility.data.DataContent;
|
||||||
|
import org.alfresco.utility.data.DataSite;
|
||||||
|
import org.alfresco.utility.model.FileModel;
|
||||||
|
import org.alfresco.utility.model.FileType;
|
||||||
|
import org.alfresco.utility.model.FolderModel;
|
||||||
|
import org.alfresco.utility.model.SiteModel;
|
||||||
|
import org.alfresco.utility.model.TestGroup;
|
||||||
|
import org.alfresco.utility.model.UserModel;
|
||||||
|
import org.apache.chemistry.opencmis.commons.PropertyIds;
|
||||||
|
import org.apache.chemistry.opencmis.commons.enums.VersioningState;
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.testng.annotations.BeforeClass;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Purpose of this TestClass is to test that the SQL end point works as expected with CustomModels
|
||||||
|
*
|
||||||
|
* @author meenal bhave
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class CustomModelTest extends AbstractSearchServiceE2E
|
||||||
|
{
|
||||||
|
@Autowired
|
||||||
|
protected DataSite dataSite;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected DataContent dataContent;
|
||||||
|
|
||||||
|
protected SiteModel testSite;
|
||||||
|
|
||||||
|
private UserModel testUser;
|
||||||
|
|
||||||
|
private FolderModel testFolder;
|
||||||
|
|
||||||
|
@BeforeClass(alwaysRun = true)
|
||||||
|
public void setupEnvironment() throws Exception
|
||||||
|
{
|
||||||
|
serverHealth.assertServerIsOnline();
|
||||||
|
|
||||||
|
testSite = dataSite.createPublicRandomSite();
|
||||||
|
|
||||||
|
// Create test user and add the user as a SiteContributor
|
||||||
|
testUser = dataUser.createRandomTestUser();
|
||||||
|
|
||||||
|
dataUser.addUserToSite(testUser, testSite, UserRole.SiteContributor);
|
||||||
|
|
||||||
|
testFolder = dataContent.usingSite(testSite).usingUser(testUser).createFolder();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Content of Custom Type is added to the Repo
|
||||||
|
@Test(priority = 1, groups = { TestGroup.INSIGHT_10 })
|
||||||
|
public void testSqlListCustomFields() throws Exception
|
||||||
|
{
|
||||||
|
Long uniqueRef = System.currentTimeMillis();
|
||||||
|
FileModel customFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "custom content");
|
||||||
|
Map<String, Object> properties = new HashMap<String, Object>();
|
||||||
|
properties.put(PropertyIds.OBJECT_TYPE_ID, "D:finance:Receipt");
|
||||||
|
properties.put(PropertyIds.NAME, customFile.getName());
|
||||||
|
properties.put("finance:ReceiptNo", uniqueRef);
|
||||||
|
properties.put("finance:ReceiptValue", 30);
|
||||||
|
|
||||||
|
cmisApi.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder)
|
||||||
|
.createFile(customFile, properties, VersioningState.MAJOR).assertThat().existsInRepo();
|
||||||
|
|
||||||
|
// Wait for the file to be indexed
|
||||||
|
waitForIndexing(customFile.getName(), true);
|
||||||
|
|
||||||
|
// Select distinct site: json format
|
||||||
|
SearchSqlRequest sqlRequest = new SearchSqlRequest();
|
||||||
|
sqlRequest.setSql("select finance_ReceiptNo, finance_ReceiptValue from alfresco where finance_ReceiptNo = " + uniqueRef);
|
||||||
|
sqlRequest.setLimit(10);
|
||||||
|
|
||||||
|
RestResponse response = restClient.authenticateUser(testUser).withSearchSqlAPI().searchSql(sqlRequest);
|
||||||
|
|
||||||
|
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||||
|
response.assertThat().body("list.pagination.maxItems", Matchers.equalTo(10));
|
||||||
|
response.assertThat().body("list.pagination.count", Matchers.equalTo(1));
|
||||||
|
restClient.onResponse().assertThat().body("list.entries.entry[0][0].label", Matchers.equalToIgnoringCase("finance_ReceiptValue"));
|
||||||
|
restClient.onResponse().assertThat().body("list.entries.entry[0][1].label", Matchers.equalToIgnoringCase("finance_ReceiptNo"));
|
||||||
|
|
||||||
|
restClient.onResponse().assertThat().body("list.entries.entry[0][0].value", Matchers.equalToIgnoringCase("30.0"));
|
||||||
|
restClient.onResponse().assertThat().body("list.entries.entry[0][1].value", Matchers.equalTo(uniqueRef.toString()));
|
||||||
|
|
||||||
|
// Select distinct cm_name: solr format
|
||||||
|
sqlRequest = new SearchSqlRequest();
|
||||||
|
sqlRequest.setSql("select finance_ReceiptNo, finance_ReceiptValue from alfresco where finance_ReceiptNo = " + uniqueRef + " limit 10");
|
||||||
|
sqlRequest.setFormat("solr");
|
||||||
|
|
||||||
|
response = restClient.authenticateUser(testUser).withSearchSqlAPI().searchSql(sqlRequest);
|
||||||
|
|
||||||
|
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||||
|
restClient.onResponse().assertThat().body("result-set.docs[0].finance_ReceiptValue", Matchers.equalTo(30));
|
||||||
|
restClient.onResponse().assertThat().body("result-set.docs[0].finance_ReceiptNo", Matchers.equalTo(uniqueRef));
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 Alfresco Software, Ltd. All rights reserved.
|
||||||
|
* License rights for this program may be obtained from Alfresco Software, Ltd.
|
||||||
|
* pursuant to a written agreement and any use of this program without such an
|
||||||
|
* agreement is prohibited.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.alfresco.service.search.unit;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.alfresco.dataprep.SiteService.Visibility;
|
||||||
|
import org.alfresco.rest.core.RestResponse;
|
||||||
|
import org.alfresco.rest.search.SearchSqlJDBCRequest;
|
||||||
|
import org.alfresco.rest.search.SearchSqlRequest;
|
||||||
|
import org.alfresco.service.search.AbstractSearchServiceE2E;
|
||||||
|
import org.alfresco.utility.constants.UserRole;
|
||||||
|
import org.alfresco.utility.data.DataContent;
|
||||||
|
import org.alfresco.utility.data.DataSite;
|
||||||
|
import org.alfresco.utility.data.RandomData;
|
||||||
|
import org.alfresco.utility.model.FileModel;
|
||||||
|
import org.alfresco.utility.model.FileType;
|
||||||
|
import org.alfresco.utility.model.FolderModel;
|
||||||
|
import org.alfresco.utility.model.SiteModel;
|
||||||
|
import org.alfresco.utility.model.UserModel;
|
||||||
|
import org.apache.chemistry.opencmis.commons.PropertyIds;
|
||||||
|
import org.apache.chemistry.opencmis.commons.enums.VersioningState;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.testng.annotations.BeforeClass;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Purpose of this Test is to test that the dependencies have been wired correctly and work well
|
||||||
|
*
|
||||||
|
* @author meenal bhave
|
||||||
|
*/
|
||||||
|
public class SetupTest extends AbstractSearchServiceE2E
|
||||||
|
{
|
||||||
|
@Autowired
|
||||||
|
protected DataSite dataSite;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected DataContent dataContent;
|
||||||
|
|
||||||
|
protected SiteModel testSite;
|
||||||
|
|
||||||
|
protected FolderModel targetFolder;
|
||||||
|
|
||||||
|
private UserModel testUser;
|
||||||
|
|
||||||
|
private FolderModel testFolder;
|
||||||
|
|
||||||
|
@BeforeClass(alwaysRun = true)
|
||||||
|
public void setUp() throws Exception
|
||||||
|
{
|
||||||
|
serverHealth.assertServerIsOnline();
|
||||||
|
|
||||||
|
testSite = dataSite.createPublicRandomSite();
|
||||||
|
targetFolder = dataContent.usingSite(testSite).createFolder(FolderModel.getRandomFolderModel());
|
||||||
|
|
||||||
|
// Create test user and add the user as a SiteContributor
|
||||||
|
testUser = dataUser.createRandomTestUser();
|
||||||
|
|
||||||
|
dataUser.addUserToSite(testUser, testSite, UserRole.SiteContributor);
|
||||||
|
|
||||||
|
testFolder = dataContent.usingSite(testSite).usingUser(testUser).createFolder();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test CMIS API works
|
||||||
|
@Test(priority = 1)
|
||||||
|
public void testCMISFileCreation() throws Exception
|
||||||
|
{
|
||||||
|
// Create document in a folder in a collaboration site
|
||||||
|
FileModel testFile = new FileModel("TestFile");
|
||||||
|
cmisApi.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder).createFile(testFile).assertThat().existsInRepo();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test Custom Model: Music can be used
|
||||||
|
@Test(priority = 2)
|
||||||
|
public void testModelMusicCanBeUsed() throws Exception
|
||||||
|
{
|
||||||
|
// Create document of custom type
|
||||||
|
FileModel customFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "searchContent-music");
|
||||||
|
Map<String, Object> properties = new HashMap<String, Object>();
|
||||||
|
properties.put(PropertyIds.OBJECT_TYPE_ID, "D:music:song");
|
||||||
|
properties.put(PropertyIds.NAME, customFile.getName());
|
||||||
|
properties.put("music:genre", "pop");
|
||||||
|
properties.put("music:lyricist", "Me");
|
||||||
|
|
||||||
|
cmisApi.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder).createFile(customFile, properties, VersioningState.MAJOR).assertThat()
|
||||||
|
.existsInRepo();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test Custom Model: Finance can be used
|
||||||
|
@Test(priority = 3)
|
||||||
|
public void testModelFinanceCanBeUsed() throws Exception
|
||||||
|
{
|
||||||
|
// Create document of custom type
|
||||||
|
|
||||||
|
FileModel customFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "searchContent-finance");
|
||||||
|
Map<String, Object> properties = new HashMap<String, Object>();
|
||||||
|
properties.put(PropertyIds.OBJECT_TYPE_ID, "D:finance:Receipt");
|
||||||
|
properties.put(PropertyIds.NAME, customFile.getName());
|
||||||
|
properties.put("finance:ReceiptNo", 1);
|
||||||
|
properties.put("finance:ReceiptValue", 30);
|
||||||
|
|
||||||
|
cmisApi.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder).createFile(customFile, properties, VersioningState.MAJOR).assertThat()
|
||||||
|
.existsInRepo();
|
||||||
|
|
||||||
|
waitForIndexing(customFile.getName(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test sql API can be used
|
||||||
|
@Test(priority = 3)
|
||||||
|
public void testSQLAPICanBeUsed() throws Exception
|
||||||
|
{
|
||||||
|
// Select distinct site: json format
|
||||||
|
SearchSqlRequest sqlRequest = new SearchSqlRequest();
|
||||||
|
sqlRequest.setSql("select cm_name from alfresco where finance_ReceiptValue > 0");
|
||||||
|
sqlRequest.setLimit(10);
|
||||||
|
|
||||||
|
RestResponse response = restClient.authenticateUser(testUser).withSearchSqlAPI().searchSql(sqlRequest);
|
||||||
|
|
||||||
|
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||||
|
Assert.assertNotNull(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test sql can be executed via jdbc
|
||||||
|
@Test(priority = 4)
|
||||||
|
public void testSQLViaJDBC() throws Exception
|
||||||
|
{
|
||||||
|
SiteModel publicSite = new SiteModel(RandomData.getRandomName("SiteSearch"));
|
||||||
|
publicSite.setVisibility(Visibility.PUBLIC);
|
||||||
|
|
||||||
|
publicSite = dataSite.usingUser(testUser).createSite(publicSite);
|
||||||
|
|
||||||
|
String sql = "select SITE,CM_OWNER from alfresco where SITE ='" + publicSite.getTitle() + "' group by SITE,CM_OWNER";
|
||||||
|
SearchSqlJDBCRequest sqlRequest = new SearchSqlJDBCRequest();
|
||||||
|
sqlRequest.setSql(sql);
|
||||||
|
sqlRequest.setAuthUser(testUser);
|
||||||
|
|
||||||
|
ResultSet rs = restClient.withSearchSqlViaJDBC().executeQueryViaJDBC(sqlRequest);
|
||||||
|
|
||||||
|
while (rs.next())
|
||||||
|
{
|
||||||
|
// User can see the Public Site created by other user
|
||||||
|
Assert.assertNotNull(rs.getString("SITE"));
|
||||||
|
Assert.assertTrue(publicSite.getTitle().equalsIgnoreCase(rs.getString("SITE")));
|
||||||
|
|
||||||
|
Assert.assertNotNull(rs.getString("CM_OWNER"));
|
||||||
|
Assert.assertTrue(rs.getString("CM_OWNER").contains(testUser.getUsername()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
e2e-test/src/test/resources/SearchSuite.xml
Normal file
23
e2e-test/src/test/resources/SearchSuite.xml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
|
||||||
|
|
||||||
|
<suite name="SearchSuite" verbose="6" preserve-order="true">
|
||||||
|
|
||||||
|
<listeners>
|
||||||
|
<listener class-name="org.alfresco.utility.report.log.LogsListener"></listener>
|
||||||
|
<listener class-name="org.alfresco.test.FailedTestListener"></listener>
|
||||||
|
<listener class-name="org.alfresco.utility.report.HtmlReportListener"></listener>
|
||||||
|
</listeners>
|
||||||
|
|
||||||
|
<test name="Unit">
|
||||||
|
<classes>
|
||||||
|
<class name="org.alfresco.service.search.unit.SetupTest" />
|
||||||
|
</classes>
|
||||||
|
</test>
|
||||||
|
|
||||||
|
<test name="E2E-InsightEngine">
|
||||||
|
<classes>
|
||||||
|
<class name="org.alfresco.service.search.e2e.insightEngine.sql.CustomModelTest" />
|
||||||
|
</classes>
|
||||||
|
</test>
|
||||||
|
|
||||||
|
</suite>
|
17
e2e-test/src/test/resources/alfresco-search-e2e-context.xml
Normal file
17
e2e-test/src/test/resources/alfresco-search-e2e-context.xml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
|
||||||
|
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/context
|
||||||
|
http://www.springframework.org/schema/context/spring-context-3.0.xsd
|
||||||
|
http://www.springframework.org/schema/data/mongo
|
||||||
|
http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
|
||||||
|
http://www.springframework.org/schema/beans
|
||||||
|
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
|
||||||
|
|
||||||
|
<context:annotation-config />
|
||||||
|
<context:component-scan base-package="org.alfresco" />
|
||||||
|
<import resource="classpath:dataprep-context.xml" />
|
||||||
|
<import resource="classpath*:alfresco-tester-context.xml" />
|
||||||
|
</beans>
|
||||||
|
|
30
e2e-test/src/test/resources/config.properties
Normal file
30
e2e-test/src/test/resources/config.properties
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# Alfresco HTTP Server Settings
|
||||||
|
alfresco.scheme=http
|
||||||
|
alfresco.server=localhost
|
||||||
|
alfresco.port=8080
|
||||||
|
|
||||||
|
# sync service related
|
||||||
|
sync.scheme=http
|
||||||
|
sync.server=localhost
|
||||||
|
sync.port=9090
|
||||||
|
|
||||||
|
#CMIS Related: Set CMIS binding to 'browser' or 'atom'
|
||||||
|
cmis.binding=browser
|
||||||
|
cmis.basePath=/alfresco/api/-default-/public/cmis/versions/1.1/${cmis.binding}
|
||||||
|
|
||||||
|
#Solr Indexing Time
|
||||||
|
solrWaitTimeInSeconds=20
|
||||||
|
|
||||||
|
#RM Specific
|
||||||
|
rest.rmPath=alfresco/api/-default-/public/gs/versions/1
|
||||||
|
|
||||||
|
# Administrator Credentials
|
||||||
|
admin.user=admin
|
||||||
|
admin.password=admin
|
||||||
|
|
||||||
|
jmx.useJolokiaAgent=false
|
||||||
|
|
||||||
|
# The location of the reports path
|
||||||
|
reports.path=./target/reports
|
||||||
|
|
||||||
|
serverHealth.showTenants=false
|
15
e2e-test/src/test/resources/log4j.properties
Normal file
15
e2e-test/src/test/resources/log4j.properties
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# Root logger option
|
||||||
|
log4j.rootLogger=INFO, file, stdout
|
||||||
|
|
||||||
|
# Direct log messages to a log file
|
||||||
|
log4j.appender.file=org.apache.log4j.RollingFileAppender
|
||||||
|
log4j.appender.file.File=./reports/search-analytics-e2e.log
|
||||||
|
log4j.appender.file.MaxBackupIndex=10
|
||||||
|
log4j.appender.file.layout=org.apache.log4j.PatternLayout
|
||||||
|
log4j.appender.file.layout.ConversionPattern=[%t] %d{HH:mm:ss} %-5p %c{1}:%L - %m%n
|
||||||
|
|
||||||
|
# Direct log messages to stdout
|
||||||
|
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||||
|
log4j.appender.stdout.Target=System.out
|
||||||
|
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||||
|
log4j.appender.stdout.layout.ConversionPattern=[%t] %d{HH:mm:ss} %-5p %c{1}:%L - %m%n
|
Reference in New Issue
Block a user