Harden AliasIntegrationTest.testClusterStateProviderAPI

use the underlying ZKStateReader of the ClusterStateProvider when waiting for the alias ZNodeVersion to change

prior versions of the test waited using the zkStateReader of the remote client, but there was no garuntee that the state had been updated on the ClusterStateProvider being used by the test
This commit is contained in:
Chris Hostetter 2019-08-14 21:36:38 -07:00
parent 7c2d45d53e
commit 54ab07718a
1 changed files with 54 additions and 20 deletions

View File

@ -40,6 +40,7 @@ import org.apache.solr.client.solrj.embedded.JettySolrRunner;
import org.apache.solr.client.solrj.impl.CloudSolrClient; import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.apache.solr.client.solrj.impl.ClusterStateProvider; import org.apache.solr.client.solrj.impl.ClusterStateProvider;
import org.apache.solr.client.solrj.impl.HttpSolrClient; import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.impl.ZkClientClusterStateProvider;
import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.apache.solr.client.solrj.request.CollectionAdminRequest;
import org.apache.solr.client.solrj.request.UpdateRequest; import org.apache.solr.client.solrj.request.UpdateRequest;
import org.apache.solr.client.solrj.request.V2Request; import org.apache.solr.client.solrj.request.V2Request;
@ -278,50 +279,83 @@ public class AliasIntegrationTest extends SolrCloudTestCase {
@Test @Test
public void testClusterStateProviderAPI() throws Exception { public void testClusterStateProviderAPI() throws Exception {
final String aliasName = getSaferTestName(); final String aliasName = getSaferTestName();
ZkStateReader zkStateReader = cluster.getSolrClient().getZkStateReader();
Aliases aliases = zkStateReader.getAliases(); // pick an arbitrary node, and use it's cloudManager to assert that (an instance of)
int lastVersion = aliases.getZNodeVersion(); // the ClusterStateProvider API reflects alias changes made by remote clients
final SolrCloudManager cloudManager = cluster.getRandomJetty(random())
.getCoreContainer().getZkController().getSolrCloudManager();
// allthough the purpose of this test is to verify that the ClusterStateProvider API
// works as a "black box" for inspecting alias information, we'll be doing some "grey box"
// introspection of the underlying ZKNodeVersion to first verify that alias updates have
// propogated to our randomly selected node before making assertions against the
// ClusterStateProvider API...
//
// establish a baseline version for future waitForAliasesUpdate calls
int lastVersion = waitForAliasesUpdate(-1, cloudManager.getClusterStateProvider());
// create the alias and wait for it to propogate
createColectionsAndAlias(aliasName); createColectionsAndAlias(aliasName);
lastVersion = waitForAliasesUpdate(-1, cloudManager.getClusterStateProvider());
lastVersion = waitForAliasesUpdate(lastVersion, zkStateReader); // assert ClusterStateProvider sees the alias
CollectionAdminRequest.SetAliasProperty setAliasProperty = CollectionAdminRequest.setAliasProperty(aliasName);
setAliasProperty.addProperty("foo","baz");
setAliasProperty.addProperty("bar","bam");
setAliasProperty.process(cluster.getSolrClient());
checkFooAndBarMeta(aliasName, zkStateReader);
SolrCloudManager cloudManager = cluster.getJettySolrRunner(0).getCoreContainer().getZkController().getSolrCloudManager();
// make sure we have the latest version in cache
lastVersion = waitForAliasesUpdate(lastVersion, zkStateReader);
ClusterStateProvider stateProvider = cloudManager.getClusterStateProvider(); ClusterStateProvider stateProvider = cloudManager.getClusterStateProvider();
List<String> collections = stateProvider.resolveAlias(aliasName); List<String> collections = stateProvider.resolveAlias(aliasName);
assertEquals(collections.toString(), 2, collections.size()); assertEquals(collections.toString(), 2, collections.size());
assertTrue(collections.toString(), collections.contains("collection1meta")); assertTrue(collections.toString(), collections.contains("collection1meta"));
assertTrue(collections.toString(), collections.contains("collection2meta")); assertTrue(collections.toString(), collections.contains("collection2meta"));
// modify the alias to have some properties
CollectionAdminRequest.SetAliasProperty setAliasProperty = CollectionAdminRequest.setAliasProperty(aliasName);
setAliasProperty.addProperty("foo","baz");
setAliasProperty.addProperty("bar","bam");
setAliasProperty.process(cluster.getSolrClient());
lastVersion = waitForAliasesUpdate(lastVersion, cloudManager.getClusterStateProvider());
// assert ClusterStateProvider sees the new props (and still sees correct collections)
stateProvider = cloudManager.getClusterStateProvider();
Map<String, String> props = stateProvider.getAliasProperties(aliasName); Map<String, String> props = stateProvider.getAliasProperties(aliasName);
assertEquals(props.toString(), 2, props.size()); assertEquals(props.toString(), 2, props.size());
assertEquals(props.toString(), "baz", props.get("foo")); assertEquals(props.toString(), "baz", props.get("foo"));
assertEquals(props.toString(), "bam", props.get("bar")); assertEquals(props.toString(), "bam", props.get("bar"));
collections = stateProvider.resolveAlias(aliasName);
assertEquals(collections.toString(), 2, collections.size());
assertTrue(collections.toString(), collections.contains("collection1meta"));
assertTrue(collections.toString(), collections.contains("collection2meta"));
assertFalse("should not be a routed alias", stateProvider.isRoutedAlias(aliasName)); assertFalse("should not be a routed alias", stateProvider.isRoutedAlias(aliasName));
// now make it a routed alias, according to the criteria in the API // now make it a routed alias, according to the criteria in the API
setAliasProperty = CollectionAdminRequest.setAliasProperty(aliasName); setAliasProperty = CollectionAdminRequest.setAliasProperty(aliasName);
setAliasProperty.addProperty(CollectionAdminParams.ROUTER_PREFIX + "foo","baz"); setAliasProperty.addProperty(CollectionAdminParams.ROUTER_PREFIX + "foo","baz");
setAliasProperty.process(cluster.getSolrClient()); setAliasProperty.process(cluster.getSolrClient());
// refresh lastVersion = waitForAliasesUpdate(lastVersion, cloudManager.getClusterStateProvider());
lastVersion = waitForAliasesUpdate(lastVersion, zkStateReader);
// assert ClusterStateProvider sees it's routed...
stateProvider = cloudManager.getClusterStateProvider(); stateProvider = cloudManager.getClusterStateProvider();
assertTrue("should be a routed alias", stateProvider.isRoutedAlias(aliasName)); assertTrue("should be a routed alias", stateProvider.isRoutedAlias(aliasName));
try { expectThrows(SolrException.class, () -> {
String resolved = stateProvider.resolveSimpleAlias(aliasName); String resolved = cloudManager.getClusterStateProvider().resolveSimpleAlias(aliasName);
fail("this is not a simple alias but it resolved to " + resolved); fail("this is not a simple alias but it resolved to " + resolved);
} catch (SolrException e) { });
// expected
}
} }
/**
* Does a "grey box" assertion that the ClusterStateProvider is a ZkClientClusterStateProvider
* and then waits for it's underlying ZkStateReader to see the updated aliases,
* returning the current ZNodeVersion for the aliases
*/
private int waitForAliasesUpdate(int lastVersion, ClusterStateProvider stateProvider)
throws Exception {
assertTrue("this method does grey box introspection which requires that " +
"the stateProvider be a ZkClientClusterStateProvider",
stateProvider instanceof ZkClientClusterStateProvider);
return waitForAliasesUpdate(lastVersion,
((ZkClientClusterStateProvider)stateProvider).getZkStateReader());
}
private int waitForAliasesUpdate(int lastVersion, ZkStateReader zkStateReader) throws Exception { private int waitForAliasesUpdate(int lastVersion, ZkStateReader zkStateReader) throws Exception {
TimeOut timeOut = new TimeOut(30, TimeUnit.SECONDS, TimeSource.NANO_TIME); TimeOut timeOut = new TimeOut(30, TimeUnit.SECONDS, TimeSource.NANO_TIME);
while (!timeOut.hasTimedOut()) { while (!timeOut.hasTimedOut()) {