Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HDDS-1745. Add integration test for createDirectory for OM HA #1304

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -16,6 +16,7 @@
*/
package org.apache.hadoop.ozone.om;

import java.util.UUID;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.hadoop.hdds.protocol.StorageType;
import org.apache.hadoop.hdfs.LogVerificationAppender;
Expand All @@ -30,7 +31,18 @@
import org.apache.hadoop.ozone.om.exceptions.OMException;
import org.apache.hadoop.ozone.om.ha.OMFailoverProxyProvider;
import org.apache.hadoop.ozone.om.ha.OMProxyInfo;
import org.apache.hadoop.ozone.om.ratis.OzoneManagerDoubleBuffer;
import org.apache.hadoop.ozone.om.ratis.OzoneManagerRatisServer;
import org.apache.hadoop.ozone.om.ratis.OzoneManagerRatisSnapshot;
import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerRatisUtils;
import org.apache.hadoop.ozone.om.request.OMClientRequest;
import org.apache.hadoop.ozone.om.response.OMClientResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateDirectoryRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.KeyArgs;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest;
import org.apache.hadoop.ozone.protocolPB.OzoneManagerRequestHandler;
import org.apache.hadoop.ozone.protocolPB.RequestHandler;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.log4j.Logger;
import org.junit.Assert;
Expand All @@ -53,6 +65,8 @@
import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_CLIENT_WAIT_BETWEEN_RETRIES_MILLIS_DEFAULT;

import static org.apache.ratis.server.metrics.RaftLogMetrics.RATIS_APPLICATION_NAME_METRICS;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

/**
Expand Down Expand Up @@ -116,10 +130,10 @@ public void testAllBucketOperations() throws Exception {

OzoneBucket ozoneBucket = retVolume.getBucket(bucketName);

Assert.assertEquals(volumeName, ozoneBucket.getVolumeName());
Assert.assertEquals(bucketName, ozoneBucket.getName());
assertEquals(volumeName, ozoneBucket.getVolumeName());
assertEquals(bucketName, ozoneBucket.getName());
Assert.assertTrue(ozoneBucket.getVersioning());
Assert.assertEquals(StorageType.DISK, ozoneBucket.getStorageType());
assertEquals(StorageType.DISK, ozoneBucket.getStorageType());
Assert.assertFalse(ozoneBucket.getCreationTime().isAfter(Instant.now()));


Expand Down Expand Up @@ -150,7 +164,7 @@ public void testOMProxyProviderInitialization() throws Exception {
List<OMProxyInfo> omProxies =
omFailoverProxyProvider.getOMProxyInfos();

Assert.assertEquals(getNumOfOMs(), omProxies.size());
assertEquals(getNumOfOMs(), omProxies.size());

for (int i = 0; i < getNumOfOMs(); i++) {
InetSocketAddress omRpcServerAddr =
Expand Down Expand Up @@ -236,7 +250,7 @@ public void testOMProxyProviderFailoverToCurrentLeader() throws Exception {

// The old and new Leader OM NodeId must match since there was no new
// election in the Ratis ring.
Assert.assertEquals(leaderOMNodeId, newLeaderOMNodeId);
assertEquals(leaderOMNodeId, newLeaderOMNodeId);
}

@Test
Expand All @@ -257,11 +271,11 @@ public void testOMRetryProxy() throws Exception {
// the RpcClient should give up.
fail("TestOMRetryProxy should fail when there are no OMs running");
} catch (ConnectException e) {
Assert.assertEquals(1,
assertEquals(1,
appender.countLinesWithMessage("Failed to connect to OMs:"));
Assert.assertEquals(maxFailoverAttempts,
assertEquals(maxFailoverAttempts,
appender.countLinesWithMessage("Trying to failover"));
Assert.assertEquals(1,
assertEquals(1,
appender.countLinesWithMessage("Attempted " +
maxFailoverAttempts + " failovers."));
}
Expand Down Expand Up @@ -297,9 +311,9 @@ public void testReadRequest() throws Exception {
// A read request should result in the proxyProvider failing over to
// leader node.
OzoneVolume volume = store.getVolume(volumeName);
Assert.assertEquals(volumeName, volume.getName());
assertEquals(volumeName, volume.getName());

Assert.assertEquals(currentLeaderNodeId,
assertEquals(currentLeaderNodeId,
proxyProvider.getCurrentProxyOMNodeId());
}
}
Expand Down Expand Up @@ -348,6 +362,57 @@ public void testJMXMetrics() throws Exception {
Assert.assertTrue((long) flushCount >= 0);
}

@Test
public void testOMCreateDirectory() throws Exception {
ObjectStore objectStore = getCluster().getRpcClient().getObjectStore();
String volumeName = "vol";
String bucketName = "buk";
String keyName = "test_dir";

objectStore.createVolume(volumeName);
objectStore.getVolume(volumeName).createBucket(bucketName);

OMRequest request = OMRequest.newBuilder().setCreateDirectoryRequest(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not need this kind of tests, they are covered in UT.

We can use createDirectory API and test create Directory functionality.

Test cases can be:

  1. single level path ('/dir)
  2. Multi-level ('/dir1/dir2')
  3. Few parents exist in multi-level path
  4. Already a directory exists with the same name

any other cases you want to add :)

Copy link
Contributor Author

@amaliujia amaliujia Aug 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bharatviswa504 thank you!

I was confused on which createDirectory API it is. Can you paste a link here so I have better understanding on the context?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

@amaliujia amaliujia Aug 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah interesting..

If I run

    bucket.createDirectory("/dir1");
    bucket.createDirectory("/dir1");

The test will still pass without a complain. I expect an exception should be thrown.

I will check the internal of OM to see how does CreateDirectory API work, and see if there is anything can be improved.

Copy link
Contributor Author

@amaliujia amaliujia Aug 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bharatviswa504

I am currently have a problem to verify that a directory is created successfully.

What is the API to retrieve the information of directory? Seems that it is not considered as a key or a file so either getKey and getFileStatus does not work.

Basically I can do

bucket.createDirectory("/dir1"); then I need to do a bucket.getDirectoryStatus.

I also tried another direction: after a createDirectory call, try to put a file to that directory and then read that file to justify that createDirectory succeed. Later I realized this also does not work because without createDirectory, the create file call will always work even for multiple level directory (e.g. /dir1/dir2/dir3/file).

CreateDirectoryRequest.newBuilder().setKeyArgs(
KeyArgs.newBuilder().setVolumeName(volumeName)
.setBucketName(bucketName).setKeyName(keyName)))
.setCmdType(OzoneManagerProtocolProtos.Type.CreateDirectory)
.setClientId(UUID.randomUUID().toString()).build();

OmMetadataManagerImpl omMetadataManager =
new OmMetadataManagerImpl(getConf());
OzoneManagerRatisSnapshot ozoneManagerRatisSnapshot = index -> {
index.get(index.size() - 1);
};
OzoneManagerDoubleBuffer doubleBuffer =
new OzoneManagerDoubleBuffer.Builder()
.setOmMetadataManager(omMetadataManager)
.enableRatis(false)
.setOzoneManagerRatisSnapShot(ozoneManagerRatisSnapshot)
.build();

OzoneManager ozoneManager = null;
for (int i = 0; i < getNumOfOMs(); i++) {
ozoneManager = getCluster().getOzoneManager(i);
if (ozoneManager.isLeader()) {
break;
}
}

assertTrue(ozoneManager != null);
assertTrue(ozoneManager.isLeader());

RequestHandler handler =
new OzoneManagerRequestHandler(ozoneManager, doubleBuffer);
OMClientRequest omClientRequest =
OzoneManagerRatisUtils.createClientRequest(request);
request = omClientRequest.preExecute(ozoneManager);

OMClientResponse response = handler.handleWriteRequest(request, 0);
assertEquals(OzoneManagerProtocolProtos.Status.OK,
response.getOMResponse().getStatus());
}

private void validateVolumesList(String userName,
Set<String> expectedVolumes) throws Exception {
ObjectStore objectStore = getObjectStore();
Expand All @@ -362,6 +427,6 @@ private void validateVolumesList(String userName,
expectedCount++;
}

Assert.assertEquals(expectedVolumes.size(), expectedCount);
assertEquals(expectedVolumes.size(), expectedCount);
}
}