HDDS-754. VolumeInfo#getScmUsed throws NPE.

Contributed by Hanisha Koneru.
This commit is contained in:
Anu Engineer 2018-10-30 19:17:57 -07:00
parent e33b61f335
commit 773f0d1519
7 changed files with 58 additions and 12 deletions

View File

@ -95,15 +95,30 @@ private VolumeInfo(Builder b) throws IOException {
this.usage = new VolumeUsage(root, b.conf);
}
public long getCapacity() {
return configuredCapacity < 0 ? usage.getCapacity() : configuredCapacity;
public long getCapacity() throws IOException {
if (configuredCapacity < 0) {
if (usage == null) {
throw new IOException("Volume Usage thread is not running. This error" +
" is usually seen during DataNode shutdown.");
}
return usage.getCapacity();
}
return configuredCapacity;
}
public long getAvailable() throws IOException {
if (usage == null) {
throw new IOException("Volume Usage thread is not running. This error " +
"is usually seen during DataNode shutdown.");
}
return usage.getAvailable();
}
public long getScmUsed() throws IOException {
if (usage == null) {
throw new IOException("Volume Usage thread is not running. This error " +
"is usually seen during DataNode shutdown.");
}
return usage.getScmUsed();
}

View File

@ -372,18 +372,21 @@ public StorageContainerDatanodeProtocolProtos.NodeReportProto getNodeReport()
for (Map.Entry<String, HddsVolume> entry : volumeMap.entrySet()) {
hddsVolume = entry.getValue();
VolumeInfo volumeInfo = hddsVolume.getVolumeInfo();
long scmUsed = 0;
long remaining = 0;
long scmUsed;
long remaining;
long capacity;
failed = false;
try {
scmUsed = volumeInfo.getScmUsed();
remaining = volumeInfo.getAvailable();
capacity = volumeInfo.getCapacity();
} catch (IOException ex) {
LOG.warn("Failed to get scmUsed and remaining for container " +
"storage location {}", volumeInfo.getRootDir());
"storage location {}", volumeInfo.getRootDir(), ex);
// reset scmUsed and remaining if df/du failed.
scmUsed = 0;
remaining = 0;
capacity = 0;
failed = true;
}
@ -392,7 +395,7 @@ public StorageContainerDatanodeProtocolProtos.NodeReportProto getNodeReport()
builder.setStorageLocation(volumeInfo.getRootDir())
.setId(hddsVolume.getStorageID())
.setFailed(failed)
.setCapacity(hddsVolume.getCapacity())
.setCapacity(capacity)
.setRemaining(remaining)
.setScmUsed(scmUsed)
.setStorageType(hddsVolume.getStorageType());

View File

@ -31,6 +31,7 @@
import org.mockito.Mockito;
import java.io.File;
import java.io.IOException;
import java.util.Properties;
import java.util.UUID;
@ -134,12 +135,14 @@ public void testShutdown() throws Exception{
scmUsedFile.exists());
try {
// Volume.getAvailable() should fail with NullPointerException as usage
// is shutdown.
// Volume.getAvailable() should fail with IOException
// as usage thread is shutdown.
volume.getAvailable();
fail("HddsVolume#shutdown test failed");
} catch (Exception ex){
assertTrue(ex instanceof NullPointerException);
assertTrue(ex instanceof IOException);
assertTrue(ex.getMessage().contains(
"Volume Usage thread is not running."));
}
}
}

View File

@ -222,8 +222,10 @@ public void testShutdown() throws Exception {
// getAvailable() should throw null pointer exception as usage is null.
volume.getAvailable();
fail("Volume shutdown failed.");
} catch (NullPointerException ex) {
} catch (IOException ex) {
// Do Nothing. Exception is expected.
assertTrue(ex.getMessage().contains(
"Volume Usage thread is not running."));
}
}
}

View File

@ -99,7 +99,7 @@ public static void shutdown() {
}
}
@Test
@Test(timeout = 300_000L)
public void testPipelineFail() throws InterruptedException, IOException,
TimeoutException {
Assert.assertEquals(ratisContainer1.getPipeline().getPipelineState(),
@ -118,6 +118,7 @@ public void testPipelineFail() throws InterruptedException, IOException,
pipelineManager.getPipeline(ratisContainer2.getPipeline().getId())
.getPipelineState());
// Now restart the datanode and make sure that a new pipeline is created.
cluster.setWaitForClusterToBeReadyTimeout(300000);
cluster.restartHddsDatanode(dnToFail, true);
ContainerWithPipeline ratisContainer3 =
containerManager.allocateContainer(RATIS, THREE, "testOwner");

View File

@ -66,6 +66,14 @@ static Builder newBuilder(OzoneConfiguration conf) {
*/
void waitForClusterToBeReady() throws TimeoutException, InterruptedException;
/**
* Sets the timeout value after which
* {@link MiniOzoneCluster#waitForClusterToBeReady} times out.
*
* @param timeoutInMs timeout value in milliseconds
*/
void setWaitForClusterToBeReadyTimeout(int timeoutInMs);
/**
* Waits/blocks till the cluster is out of chill mode.
*

View File

@ -90,6 +90,9 @@ public final class MiniOzoneClusterImpl implements MiniOzoneCluster {
private final OzoneManager ozoneManager;
private final List<HddsDatanodeService> hddsDatanodes;
// Timeout for the cluster to be ready
private int waitForClusterToBeReadyTimeout = 60000; // 1 min
/**
* Creates a new MiniOzoneCluster.
*
@ -122,7 +125,18 @@ public void waitForClusterToBeReady()
isReady? "Cluster is ready" : "Waiting for cluster to be ready",
healthy, hddsDatanodes.size());
return isReady;
}, 1000, 60 * 1000); //wait for 1 min.
}, 1000, waitForClusterToBeReadyTimeout);
}
/**
* Sets the timeout value after which
* {@link MiniOzoneClusterImpl#waitForClusterToBeReady} times out.
*
* @param timeoutInMs timeout value in milliseconds
*/
@Override
public void setWaitForClusterToBeReadyTimeout(int timeoutInMs) {
waitForClusterToBeReadyTimeout = timeoutInMs;
}
/**