[MNT-20179] Integration Test + some test refactor

This commit is contained in:
agazzarini
2019-05-07 14:49:40 +02:00
parent 6121877e71
commit ba2e80874e
14 changed files with 238 additions and 199 deletions

View File

@@ -1,89 +0,0 @@
/*
* Copyright (C) 2005-2017 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.dataload;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.request.UpdateRequest;
import org.apache.solr.common.SolrInputDocument;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Random;
public class Loader {
public static void main(String args[]) throws Exception {
int num = Integer.parseInt(args[0]);
int start = Integer.parseInt(args[1]);
//String url = "http://localhost:8985/solr/joel";
String url = "http://localhost:8983/solr/collection1";
HttpSolrClient client = new HttpSolrClient(url);
UpdateRequest request = new UpdateRequest();
int i = start;
LocalDateTime localDate = LocalDateTime.now();
Random rand = new Random();
for(i=start; i<num+start; i++) {
String s = rand.nextInt(1000)+"helloworld123";
SolrInputDocument doc = new SolrInputDocument();
doc.addField("id", i);
doc.addField("test_s", s);
doc.addField("test_t", "hello world we love you");
int year = rand.nextInt(50);
int month = rand.nextInt(12);
int day = rand.nextInt(30);
float f = rand.nextFloat();
doc.addField("year_i", Integer.toString(year));
doc.addField("month_i", Integer.toString(month));
doc.addField("day_i", Integer.toString(day));
doc.addField("price_f", Float.toString(f));
LocalDateTime randomDate = localDate.plusDays(rand.nextInt(1000));
doc.addField("date_dt", DateTimeFormatter.ISO_INSTANT.format(randomDate.toInstant(ZoneOffset.UTC)));
doc.addField("epoch_l", randomDate.atZone(ZoneOffset.UTC).toInstant().toEpochMilli());
request.add(doc);
if(i % 5000 == 0) {
request.process(client);
client.commit();
request = new UpdateRequest();
}
for(int l=0; l<5; l++) {
String ps = "product"+rand.nextInt(35);
doc.addField("prod_ss",ps);
}
}
if((i % 5000) != 0) {
request.process(client);
client.commit();
}
client.close();
}
}

View File

@@ -18,6 +18,8 @@
*/
package org.alfresco.solr;
import static java.util.Optional.of;
import static java.util.Optional.ofNullable;
import static junit.framework.TestCase.assertNotNull;
import static junit.framework.TestCase.assertTrue;
import static org.alfresco.repo.search.adaptor.lucene.QueryConstants.FIELD_ACLID;
@@ -68,6 +70,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.index.shard.ShardState;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
@@ -86,11 +89,11 @@ import org.alfresco.solr.client.StringPropertyValue;
import org.alfresco.solr.client.Transaction;
import org.alfresco.util.ISO9075;
import org.alfresco.util.Pair;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.SolrTestCaseJ4.XmlDoc;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.CoreAdminParams;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.XML;
import org.apache.solr.core.CoreContainer;
@@ -108,6 +111,8 @@ import org.apache.solr.update.CommitUpdateCommand;
public class AlfrescoSolrUtils
{
public static final String TEST_NAMESPACE = "http://www.alfresco.org/test/solrtest";
public static long MAX_WAIT_TIME = 80000;
/**
* Get transaction.
* @param deletes
@@ -884,5 +889,40 @@ public class AlfrescoSolrUtils
assertTrue("There must be a searcher for "+coreName, ((Integer)coreSummary.get("Number of Searchers")) > 0);
}
/**
* Asserts that the input {@link ShardState} and the CoreAdmin.SUMMARY response give the same information.
*
* @param state the {@link ShardState} instance.
* @param core the target {@link SolrCore} instance.
*/
public static void assertShardAndCoreSummaryConsistency(ShardState state, SolrCore core) {
SolrParams params =
new ModifiableSolrParams()
.add(CoreAdminParams.CORE, core.getName())
.add(CoreAdminParams.ACTION, "SUMMARY");
}
SolrQueryRequest request = new LocalSolrQueryRequest(core, params);
SolrQueryResponse response = new SolrQueryResponse();
coreAdminHandler(core).handleRequest(request, response);
NamedList<?> summary =
ofNullable(response.getValues())
.map(values -> values.get("Summary"))
.map(NamedList.class::cast)
.map(values -> values.get(core.getName()))
.map(NamedList.class::cast)
.orElseGet(NamedList::new);
assertEquals(state.getLastIndexedChangeSetId(), summary.get("Id for last Change Set in index"));
assertEquals(state.getLastIndexedChangeSetCommitTime(), summary.get("Last Index Change Set Commit Time"));
assertEquals(state.getLastIndexedTxCommitTime(), summary.get("Last Index TX Commit Time"));
assertEquals(state.getLastIndexedTxId(), summary.get("Id for last TX in index"));
}
public static AlfrescoCoreAdminHandler coreAdminHandler(SolrCore core) {
return of(core).map(SolrCore::getCoreContainer)
.map(CoreContainer::getMultiCoreHandler)
.map(AlfrescoCoreAdminHandler.class::cast)
.orElseThrow(() -> new IllegalStateException("Cannot retrieve the Core Admin Handler on this test core."));
}
}

View File

@@ -16,10 +16,11 @@
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.solr.query.afts;
package org.alfresco.solr.dataload;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static java.util.stream.IntStream.range;
import static org.alfresco.model.ContentModel.ASSOC_CONTAINS;
import static org.alfresco.model.ContentModel.ASSOC_CHILDREN;
import static org.alfresco.model.ContentModel.PROP_NAME;
@@ -28,6 +29,8 @@ import static org.alfresco.service.namespace.NamespaceService.CONTENT_MODEL_1_0_
import static org.alfresco.solr.AlfrescoSolrUtils.addNode;
import static org.alfresco.solr.AlfrescoSolrUtils.createGUID;
import static org.alfresco.solr.AlfrescoSolrUtils.addStoreRoot;
import static org.alfresco.solr.AlfrescoSolrUtils.getNode;
import static org.alfresco.solr.AlfrescoSolrUtils.getNodeMetaData;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
@@ -39,19 +42,27 @@ import org.alfresco.service.cmr.repository.datatype.Duration;
import org.alfresco.service.namespace.QName;
import org.alfresco.solr.AlfrescoSolrConstants;
import org.alfresco.solr.AlfrescoSolrDataModel;
import org.alfresco.solr.client.Acl;
import org.alfresco.solr.client.ContentPropertyValue;
import org.alfresco.solr.client.MLTextPropertyValue;
import org.alfresco.solr.client.MultiPropertyValue;
import org.alfresco.solr.client.Node;
import org.alfresco.solr.client.NodeMetaData;
import org.alfresco.solr.client.PropertyValue;
import org.alfresco.solr.client.StringPropertyValue;
import org.alfresco.solr.client.Transaction;
import org.alfresco.util.ISO9075;
import org.apache.solr.client.solrj.io.Tuple;
import org.apache.solr.core.SolrCore;
import org.apache.solr.util.TestHarness;
import java.util.AbstractMap;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Test datasets provider.
@@ -855,6 +866,14 @@ public class TestDataProvider implements AlfrescoSolrConstants
return testProperties;
}
public static Map.Entry<List<Node>, List<NodeMetaData>> nSampleNodesWithSampleContent(Acl acl, Transaction txn, int howManyNodes) {
List<Node> nodes = range(0, howManyNodes).mapToObj(index -> getNode(txn, acl, Node.SolrApiNodeStatus.UPDATED)).collect(Collectors.toList());
List<NodeMetaData> metadata = nodes.stream().map(node -> getNodeMetaData(node, txn, acl, "mike", null, false)).collect(Collectors.toList());
return new AbstractMap.SimpleImmutableEntry<>(nodes, metadata);
}
public NodeRef newNodeRef()
{
return new NodeRef(new StoreRef("workspace", "SpacesStore"), createGUID());

View File

@@ -19,7 +19,7 @@
package org.alfresco.solr.query.afts.qparser;
import org.alfresco.repo.search.adaptor.lucene.QueryConstants;
import org.alfresco.solr.query.afts.TestDataProvider;
import org.alfresco.solr.dataload.TestDataProvider;
import org.alfresco.util.ISO9075;
import org.junit.BeforeClass;
import org.junit.Test;

View File

@@ -30,7 +30,7 @@ import static org.alfresco.model.ContentModel.TYPE_THUMBNAIL;
import org.alfresco.repo.search.adaptor.lucene.QueryConstants;
import org.alfresco.service.namespace.QName;
import org.alfresco.solr.query.afts.TestDataProvider;
import org.alfresco.solr.dataload.TestDataProvider;
import org.alfresco.util.CachingDateFormat;
import org.apache.solr.SolrTestCaseJ4;
import org.junit.BeforeClass;

View File

@@ -22,7 +22,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.solr.client.PropertyValue;
import org.alfresco.solr.client.StringPropertyValue;
import org.alfresco.solr.query.afts.TestDataProvider;
import org.alfresco.solr.dataload.TestDataProvider;
import org.junit.BeforeClass;
import org.junit.Test;

View File

@@ -30,7 +30,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.solr.client.PropertyValue;
import org.alfresco.solr.client.StringPropertyValue;
import org.alfresco.solr.query.afts.TestDataProvider;
import org.alfresco.solr.dataload.TestDataProvider;
import org.junit.BeforeClass;
import org.junit.Test;

View File

@@ -27,7 +27,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.solr.client.PropertyValue;
import org.alfresco.solr.client.StringPropertyValue;
import org.alfresco.solr.query.afts.TestDataProvider;
import org.alfresco.solr.dataload.TestDataProvider;
import org.junit.BeforeClass;
import org.junit.Test;

View File

@@ -28,7 +28,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.solr.client.PropertyValue;
import org.alfresco.solr.client.StringPropertyValue;
import org.alfresco.solr.query.afts.TestDataProvider;
import org.alfresco.solr.dataload.TestDataProvider;
import org.alfresco.util.Pair;
import org.junit.BeforeClass;
import org.junit.Test;

View File

@@ -10,7 +10,7 @@ import org.alfresco.repo.search.adaptor.lucene.QueryConstants;
import org.alfresco.service.namespace.QName;
import org.alfresco.solr.AlfrescoSolrDataModel;
import org.alfresco.solr.SolrInformationServer;
import org.alfresco.solr.query.afts.TestDataProvider;
import org.alfresco.solr.dataload.TestDataProvider;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.solr.SolrTestCaseJ4;
import org.junit.BeforeClass;

View File

@@ -1,6 +1,6 @@
package org.alfresco.solr.query.afts.requestHandler;
import org.alfresco.solr.query.afts.TestDataProvider;
import org.alfresco.solr.dataload.TestDataProvider;
import org.junit.BeforeClass;
import org.junit.Test;

View File

@@ -19,7 +19,6 @@
package org.alfresco.solr.tracker;
import org.alfresco.repo.index.shard.ShardState;
import org.alfresco.repo.search.adaptor.lucene.QueryConstants;
import org.alfresco.solr.AbstractAlfrescoSolrTests;
import org.alfresco.solr.AlfrescoCoreAdminHandler;
@@ -29,135 +28,98 @@ import org.alfresco.solr.client.AclReaders;
import org.alfresco.solr.client.Node;
import org.alfresco.solr.client.NodeMetaData;
import org.alfresco.solr.client.Transaction;
import org.alfresco.solr.dataload.TestDataProvider;
import org.apache.lucene.document.LongPoint;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.LegacyNumericRangeQuery;
import org.apache.lucene.search.TermQuery;
import org.apache.solr.common.params.CoreAdminParams;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.core.SolrCore;
import org.apache.solr.request.LocalSolrQueryRequest;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.List;
import java.util.Map;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static java.util.Optional.of;
import static java.util.Optional.ofNullable;
import static org.alfresco.solr.AlfrescoSolrUtils.MAX_WAIT_TIME;
import static org.alfresco.solr.AlfrescoSolrUtils.assertShardAndCoreSummaryConsistency;
import static org.alfresco.solr.AlfrescoSolrUtils.coreAdminHandler;
import static org.alfresco.solr.AlfrescoSolrUtils.getAcl;
import static org.alfresco.solr.AlfrescoSolrUtils.getAclChangeSet;
import static org.alfresco.solr.AlfrescoSolrUtils.getAclReaders;
import static org.alfresco.solr.AlfrescoSolrUtils.getNode;
import static org.alfresco.solr.AlfrescoSolrUtils.getNodeMetaData;
import static org.alfresco.solr.AlfrescoSolrUtils.getTransaction;
import static org.alfresco.solr.AlfrescoSolrUtils.indexAclChangeSet;
import static org.junit.Assert.assertEquals;
/**
* A partial state of {@link org.alfresco.solr.TrackerState} is exposed through two interfaces: AdminHandler.SUMMARY and
* {@link MetadataTracker#getShardState}.
*
* This test makes sure that state is consistent across the two mentioned approaches. That is, properties returned by the
* Core SUMMARY must have the same value of the same properties in the ShardState.
*
* @author agazzarini
*/
public class AlfrescoSolrTrackerStateTest extends AbstractAlfrescoSolrTests
{
private static long MAX_WAIT_TIME = 80000;
@BeforeClass
public static void beforeClass() throws Exception
{
initAlfrescoCore("schema.xml");
}
private Acl acl;
@Before
public void prepare() throws Exception
{
AclChangeSet aclChangeSet = getAclChangeSet(1);
acl = getAcl(aclChangeSet);
Acl acl = getAcl(aclChangeSet);
Acl acl2 = getAcl(aclChangeSet);
AclReaders aclReaders = getAclReaders(aclChangeSet, acl, singletonList("joel"), singletonList("phil"), null);
AclReaders aclReaders2 = getAclReaders(aclChangeSet, acl2, singletonList("jim"), singletonList("phil"), null);
indexAclChangeSet(aclChangeSet,
asList(acl, acl2),
asList(aclReaders, aclReaders2));
indexAclChangeSet(aclChangeSet, asList(acl, acl2), asList(aclReaders, aclReaders2));
// Check for the ACL state stamp.
BooleanQuery.Builder builder = new BooleanQuery.Builder();
builder.add(new BooleanClause(new TermQuery(new Term(QueryConstants.FIELD_SOLR4_ID, "TRACKER!STATE!ACLTX")), BooleanClause.Occur.MUST));
builder.add(new BooleanClause(LegacyNumericRangeQuery.newLongRange(QueryConstants.FIELD_S_ACLTXID, aclChangeSet.getId(), aclChangeSet.getId() + 1, true, false), BooleanClause.Occur.MUST));
BooleanQuery waitForQuery = builder.build();
waitForDocCount(waitForQuery, 1, MAX_WAIT_TIME);
int howManyTestNodes = 4;
Transaction txn = getTransaction(0, howManyTestNodes);
Map.Entry<List<Node>, List<NodeMetaData>> data = TestDataProvider.nSampleNodesWithSampleContent(acl, txn, howManyTestNodes);
indexTransaction(txn, data.getKey(), data.getValue());
makeSureTransactionHasBeenIndexed(txn.getId());
makeSureNodesHaveBeenIndexed(data.getKey().size());
}
@Test
public void shardStateMustBeConsistentWithCoreSummaryStats() throws Exception
@SuppressWarnings("deprecated")
public void shardStateMustBeConsistentWithCoreSummaryStats()
{
Transaction txn = getTransaction(0, 4);
Node node1 = getNode(txn, acl, Node.SolrApiNodeStatus.UPDATED);
Node node2 = getNode(txn, acl, Node.SolrApiNodeStatus.UPDATED);
Node node3 = getNode(txn, acl, Node.SolrApiNodeStatus.UPDATED);
Node node4 = getNode(txn, acl, Node.SolrApiNodeStatus.UPDATED);
NodeMetaData nodeMetaData1 = getNodeMetaData(node1, txn, acl, "mike", null, false);
NodeMetaData nodeMetaData2 = getNodeMetaData(node2, txn, acl, "mike", null, false);
NodeMetaData nodeMetaData3 = getNodeMetaData(node3, txn, acl, "mike", null, false);
NodeMetaData nodeMetaData4 = getNodeMetaData(node4, txn, acl, "mike", null, false);
indexTransaction(txn,
asList(node1, node2, node3, node4),
asList(nodeMetaData1, nodeMetaData2, nodeMetaData3, nodeMetaData4));
makeSureTransactionHasBeenIndexed(txn.getId());
makeSureNodesHaveBeenIndexed("mike", 4);
SolrCore core = getCore();
AlfrescoCoreAdminHandler adminHandler =
of(core).map(SolrCore::getCoreContainer)
.map(CoreContainer::getMultiCoreHandler)
.map(AlfrescoCoreAdminHandler.class::cast)
.orElseThrow(() -> new IllegalStateException("Cannot retrieve the Core Admin Handler on this test core."));
MetadataTracker tracker =
of(adminHandler)
.map(AlfrescoCoreAdminHandler::getTrackerRegistry)
.map(registry -> registry.getTrackerForCore(core.getName(), MetadataTracker.class))
.orElseThrow(() -> new IllegalStateException("Cannot retrieve the Metadata tracker on this test core."));
of(coreAdminHandler(core))
.map(AlfrescoCoreAdminHandler::getTrackerRegistry)
.map(registry -> registry.getTrackerForCore(core.getName(), MetadataTracker.class))
.orElseThrow(() -> new IllegalStateException("Cannot retrieve the Metadata tracker on this test core."));
ShardState state = tracker.getShardState();
SolrParams params =
new ModifiableSolrParams()
.add(CoreAdminParams.CORE, core.getName())
.add(CoreAdminParams.ACTION, "SUMMARY");
SolrQueryRequest request = new LocalSolrQueryRequest(core, params);
SolrQueryResponse response = new SolrQueryResponse();
adminHandler.handleRequest(request, response);
NamedList<?> summary =
ofNullable(response.getValues())
.map(values -> values.get("Summary"))
.map(NamedList.class::cast)
.map(values -> values.get(core.getName()))
.map(NamedList.class::cast)
.orElseGet(NamedList::new);
assertEquals(state.getLastIndexedChangeSetId(), summary.get("Id for last Change Set in index"));
assertEquals(state.getLastIndexedChangeSetCommitTime(), summary.get("Last Index Change Set Commit Time"));
assertEquals(state.getLastIndexedTxCommitTime(), summary.get("Last Index TX Commit Time"));
assertEquals(state.getLastIndexedTxId(), summary.get("Id for last TX in index"));
assertShardAndCoreSummaryConsistency(tracker.getShardState(), core);
}
private void makeSureTransactionHasBeenIndexed(long transactionId) throws Exception
{
//Check for the TXN state stamp.
BooleanQuery.Builder builder = new BooleanQuery.Builder();
builder.add(new BooleanClause(new TermQuery(new Term(QueryConstants.FIELD_SOLR4_ID, "TRACKER!STATE!TX")), BooleanClause.Occur.MUST));
builder.add(new BooleanClause(LegacyNumericRangeQuery.newLongRange(QueryConstants.FIELD_S_TXID, transactionId, transactionId + 1, true, false), BooleanClause.Occur.MUST));
@@ -165,36 +127,14 @@ public class AlfrescoSolrTrackerStateTest extends AbstractAlfrescoSolrTests
waitForDocCount(waitForQuery, 1, MAX_WAIT_TIME);
}
/**
* Queries the index using a token from the (dummy) text produced by the test framework.
* Once the query returns a positive result we are sure the ContentTracker
*
* <ol>
* <li>
* Fetched the text content associated with the test nodes, from Alfresco
* </li>
* <li>
* Computed a fingerprint (using the retrieved text) for each node
* </li>
* <li>
* Updated the nodes definitions in the (Solr)ContentStore and in Solr
* </li>
* </ol>
*
* Last but not least, we are also making sure that CommitTracker executed its cycle as well (otherwise documents
* wouldn't be searchable).
*
* @param owner the #FIELD_OWNER which will be used as an additional required query clause.
* @throws Exception in case the MAX_WAIT_TIME is reached and the node is not in results.
*/
private void makeSureNodesHaveBeenIndexed(final String owner, final int expectedCount) throws Exception
private void makeSureNodesHaveBeenIndexed(int expectedCount) throws Exception
{
waitForDocCount(new TermQuery(new Term(QueryConstants.FIELD_READER, "jim")), 1, MAX_WAIT_TIME);
waitForDocCount(new TermQuery(new Term("content@s___t@{http://www.alfresco.org/model/content/1.0}content", "world")), expectedCount, MAX_WAIT_TIME);
BooleanQuery.Builder builder = new BooleanQuery.Builder();
builder.add(new BooleanClause(new TermQuery(new Term("content@s___t@{http://www.alfresco.org/model/content/1.0}content", "world")), BooleanClause.Occur.MUST));
builder.add(new BooleanClause(new TermQuery(new Term(QueryConstants.FIELD_OWNER, owner)), BooleanClause.Occur.MUST));
builder.add(new BooleanClause(new TermQuery(new Term(QueryConstants.FIELD_OWNER, "mike")), BooleanClause.Occur.MUST));
waitForDocCount(builder.build(), expectedCount, MAX_WAIT_TIME);
}
}

View File

@@ -0,0 +1,127 @@
/*
* Copyright (C) 2005-2014 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.solr.tracker;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static java.util.Optional.of;
import static org.alfresco.solr.AlfrescoSolrUtils.MAX_WAIT_TIME;
import static org.alfresco.solr.AlfrescoSolrUtils.assertShardAndCoreSummaryConsistency;
import static org.alfresco.solr.AlfrescoSolrUtils.coreAdminHandler;
import static org.alfresco.solr.AlfrescoSolrUtils.getAcl;
import static org.alfresco.solr.AlfrescoSolrUtils.getAclChangeSet;
import static org.alfresco.solr.AlfrescoSolrUtils.getAclReaders;
import static org.alfresco.solr.AlfrescoSolrUtils.getTransaction;
import static org.alfresco.solr.AlfrescoSolrUtils.indexAclChangeSet;
import org.alfresco.repo.search.adaptor.lucene.QueryConstants;
import org.alfresco.solr.AbstractAlfrescoDistributedTest;
import org.alfresco.solr.AlfrescoCoreAdminHandler;
import org.alfresco.solr.client.Acl;
import org.alfresco.solr.client.AclChangeSet;
import org.alfresco.solr.client.AclReaders;
import org.alfresco.solr.client.Node;
import org.alfresco.solr.client.NodeMetaData;
import org.alfresco.solr.client.Transaction;
import org.alfresco.solr.dataload.TestDataProvider;
import org.apache.lucene.document.LongPoint;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.LegacyNumericRangeQuery;
import org.apache.lucene.search.TermQuery;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.List;
import java.util.Map;
/**
* A partial state of {@link org.alfresco.solr.TrackerState} is exposed through two interfaces: AdminHandler.SUMMARY and
* {@link MetadataTracker#getShardState}.
* This test makes sure that state is consistent across the two mentioned approaches. That is, properties returned by the
* Core SUMMARY must have the same value of the same properties in the ShardState.
*
* Note that this is the distributed version of {@link AlfrescoSolrTrackerStateTest}.
*
* @author agazzarini
*/
public class DistributedAlfrescoSolrTrackerStateTest extends AbstractAlfrescoDistributedTest
{
@BeforeClass
private static void initData() throws Throwable
{
int howManyShards = 5;
int howManyNodes = 15;
initSolrServers(howManyShards, getClassName(),null);
AclChangeSet aclChangeSet = getAclChangeSet(1);
Acl acl = getAcl(aclChangeSet);
Acl acl2 = getAcl(aclChangeSet);
AclReaders aclReaders = getAclReaders(aclChangeSet, acl, singletonList("joel"), singletonList("phil"), null);
AclReaders aclReaders2 = getAclReaders(aclChangeSet, acl2, singletonList("jim"), singletonList("phil"), null);
indexAclChangeSet(aclChangeSet, asList(acl, acl2), asList(aclReaders, aclReaders2));
BooleanQuery.Builder builder = new BooleanQuery.Builder();
builder.add(new BooleanClause(new TermQuery(new Term(QueryConstants.FIELD_SOLR4_ID, "TRACKER!STATE!ACLTX")), BooleanClause.Occur.MUST));
builder.add(new BooleanClause(LongPoint.newExactQuery(QueryConstants.FIELD_S_ACLTXID, aclChangeSet.getId()), BooleanClause.Occur.MUST));
BooleanQuery waitForQuery = builder.build();
waitForDocCountAllCores(waitForQuery, 1, MAX_WAIT_TIME);
Transaction txn = getTransaction(0, howManyNodes);
Map.Entry<List<Node>, List<NodeMetaData>> data = TestDataProvider.nSampleNodesWithSampleContent(acl, txn, howManyNodes);
indexTransaction(txn, data.getKey(), data.getValue());
builder = new BooleanQuery.Builder();
builder.add(new BooleanClause(new TermQuery(new Term(QueryConstants.FIELD_SOLR4_ID, "TRACKER!STATE!TX")), BooleanClause.Occur.MUST));
builder.add(new BooleanClause(LongPoint.newExactQuery(QueryConstants.FIELD_S_TXID, txn.getId()), BooleanClause.Occur.MUST));
waitForQuery = builder.build();
waitForDocCountAllCores(waitForQuery, 1, MAX_WAIT_TIME);
waitForDocCountAllCores(new TermQuery(new Term(QueryConstants.FIELD_READER, "jim")), 1, MAX_WAIT_TIME);
waitForDocCount(new TermQuery(new Term("content@s___t@{http://www.alfresco.org/model/content/1.0}content", "world")), howManyNodes, MAX_WAIT_TIME);
}
@AfterClass
private static void destroyData()
{
dismissSolrServers();
}
@Test
public void shardStateMustBeConsistentWithCoreSummaryStats()
{
putHandleDefaults();
getJettyCores(solrShards).forEach(core -> {
MetadataTracker tracker =
of(coreAdminHandler(core))
.map(AlfrescoCoreAdminHandler::getTrackerRegistry)
.map(registry -> registry.getTrackerForCore(core.getName(), MetadataTracker.class))
.orElseThrow(() -> new IllegalStateException("Cannot retrieve the Metadata tracker on this test core."));
assertShardAndCoreSummaryConsistency(tracker.getShardState(), core);
});
}
}

View File

@@ -118,7 +118,9 @@ public class DistributedDateMonthAlfrescoSolrTrackerTest extends AbstractAlfresc
Date[] dates = new Date[5];
Calendar cal = new GregorianCalendar();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
for (int i = 0; i < dates.length; i++) {
cal.set(1980, i, 21);
dates[i] = cal.getTime();
}