blob: 6c3555f4b5ec2154cf9e86a6442ceda6e3730945 [file] [log] [blame]
package org.apache.helix.zookeeper.impl.client;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.io.IOException;
import java.util.NoSuchElementException;
import org.apache.helix.msdcommon.exception.InvalidRoutingDataException;
import org.apache.helix.zookeeper.api.client.RealmAwareZkClient;
import org.apache.helix.zookeeper.api.factory.RealmAwareZkClientFactory;
import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.zookeeper.datamodel.serializer.ZNRecordSerializer;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
* Test Base for DedicatedZkClient and SharedZkClient, which are implementations of
* RealmAwareZkClient.
* This class allows TestDedicatedZkClient and TestSharedZkClient to share the common test logic by
* just swapping out the factory classes.
*/
public abstract class RealmAwareZkClientFactoryTestBase extends RealmAwareZkClientTestBase {
// The following RealmAwareZkClientFactory is to be defined in subclasses
protected RealmAwareZkClientFactory _realmAwareZkClientFactory;
protected RealmAwareZkClient _realmAwareZkClient;
private static final ZNRecord DUMMY_RECORD = new ZNRecord("DummyRecord");
@BeforeClass
public void beforeClass() throws IOException, InvalidRoutingDataException {
super.beforeClass();
DUMMY_RECORD.setSimpleField("Dummy", "Value");
}
@AfterClass
public void afterClass() {
super.afterClass();
if (_realmAwareZkClient != null && !_realmAwareZkClient.isClosed()) {
_realmAwareZkClient.close();
_realmAwareZkClient = null;
}
}
/**
* 1. Create a RealmAwareZkClient with a non-existing sharding key (for which there is no valid ZK realm)
* -> This should fail with an exception
* 2. Create a RealmAwareZkClient with a valid sharding key
* -> This should pass
*/
@Test
public void testRealmAwareZkClientCreation() {
// Create a RealmAwareZkClient
String invalidShardingKey = "InvalidShardingKeyNoLeadingSlash";
RealmAwareZkClient.RealmAwareZkClientConfig clientConfig =
new RealmAwareZkClient.RealmAwareZkClientConfig();
// Create a connection config with the invalid sharding key
RealmAwareZkClient.RealmAwareZkConnectionConfig.Builder builder =
new RealmAwareZkClient.RealmAwareZkConnectionConfig.Builder();
RealmAwareZkClient.RealmAwareZkConnectionConfig connectionConfig =
builder.setZkRealmShardingKey(invalidShardingKey).build();
try {
_realmAwareZkClient =
_realmAwareZkClientFactory.buildZkClient(connectionConfig, clientConfig);
Assert.fail("Should not succeed with an invalid sharding key!");
} catch (IllegalArgumentException e) {
// Expected because invalid sharding key would cause an IllegalArgumentException to be thrown
} catch (Exception e) {
Assert.fail("Should not see any other types of Exceptions: " + e);
}
// Create a connection config with a valid sharding key, but one that does not exist in
// the routing data
String nonExistentShardingKey = "/NonExistentShardingKey";
connectionConfig = builder.setZkRealmShardingKey(nonExistentShardingKey).build();
try {
_realmAwareZkClient =
_realmAwareZkClientFactory.buildZkClient(connectionConfig, clientConfig);
Assert.fail("Should not succeed with a non-existent sharding key!");
} catch (NoSuchElementException e) {
// Expected non-existent sharding key would cause a NoSuchElementException to be thrown
} catch (Exception e) {
Assert.fail("Should not see any other types of Exceptions: " + e);
}
// Use a valid sharding key this time around
connectionConfig = builder.setZkRealmShardingKey(ZK_SHARDING_KEY_PREFIX).build();
try {
_realmAwareZkClient =
_realmAwareZkClientFactory.buildZkClient(connectionConfig, clientConfig);
} catch (Exception e) {
Assert.fail("All other exceptions not allowed: " + e);
}
}
/**
* Test the persistent create() call against a valid path and an invalid path.
* Valid path is one that belongs to the realm designated by the sharding key.
* Invalid path is one that does not belong to the realm designated by the sharding key.
*/
@Test(dependsOnMethods = "testRealmAwareZkClientCreation")
public void testRealmAwareZkClientCreatePersistent() {
_realmAwareZkClient.setZkSerializer(new ZNRecordSerializer());
// Test writing and reading against the validPath
_realmAwareZkClient.createPersistent(TEST_VALID_PATH, true);
_realmAwareZkClient.writeData(TEST_VALID_PATH, DUMMY_RECORD);
Assert.assertEquals(_realmAwareZkClient.readData(TEST_VALID_PATH), DUMMY_RECORD);
// Test writing and reading against the invalid path
try {
_realmAwareZkClient.createPersistent(TEST_INVALID_PATH, true);
Assert.fail("Create() should not succeed on an invalid path!");
} catch (IllegalArgumentException e) {
// Okay - expected
}
}
/**
* Test that exists() works on valid path and fails on invalid path.
*/
@Test(dependsOnMethods = "testRealmAwareZkClientCreatePersistent")
public void testExists() {
// Create a ZNode for testing
_realmAwareZkClient.createPersistent(TEST_VALID_PATH, true);
_realmAwareZkClient.writeData(TEST_VALID_PATH, DUMMY_RECORD);
Assert.assertEquals(_realmAwareZkClient.readData(TEST_VALID_PATH), DUMMY_RECORD);
// Test exists()
Assert.assertTrue(_realmAwareZkClient.exists(TEST_VALID_PATH));
try {
_realmAwareZkClient.exists(TEST_INVALID_PATH);
Assert.fail("Exists() should not succeed on an invalid path!");
} catch (IllegalArgumentException e) {
// Okay - expected
}
}
/**
* Test that delete() works on valid path and fails on invalid path.
*/
@Test(dependsOnMethods = "testExists")
public void testDelete() {
// Create a ZNode for testing
_realmAwareZkClient.createPersistent(TEST_VALID_PATH, true);
_realmAwareZkClient.writeData(TEST_VALID_PATH, DUMMY_RECORD);
Assert.assertEquals(_realmAwareZkClient.readData(TEST_VALID_PATH), DUMMY_RECORD);
try {
_realmAwareZkClient.delete(TEST_INVALID_PATH);
Assert.fail("delete() should not succeed on an invalid path!");
} catch (IllegalArgumentException e) {
// Okay - expected
}
Assert.assertTrue(_realmAwareZkClient.delete(TEST_VALID_PATH));
Assert.assertFalse(_realmAwareZkClient.exists(TEST_VALID_PATH));
}
}