package io.eguan.vold.model;
/*
* #%L
* Project eguan
* %%
* Copyright (C) 2012 - 2017 Oodrive
* %%
* Licensed 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.
* #L%
*/
import io.eguan.dtx.DtxLocalNodeMXBean;
import io.eguan.dtx.DtxManagerMXBean;
import io.eguan.vold.model.DeviceMXBean;
import io.eguan.vold.model.SnapshotMXBean;
import io.eguan.vold.model.VvrMXBean;
import java.lang.management.ManagementFactory;
import java.net.InetSocketAddress;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import javax.management.InstanceNotFoundException;
import javax.management.JMX;
import javax.management.ListenerNotFoundException;
import javax.management.MBeanServer;
import javax.management.MBeanServerDelegate;
import javax.management.MBeanServerNotification;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.ObjectName;
import org.junit.Assert;
import org.junit.Test;
/**
* Create a few elements and check VVR after VOLD restart.
*
* @author oodrive
* @author llambert
* @author ebredzinski
*
*/
public class TestVoldStopAndRestore extends AbstractVoldTest {
public TestVoldStopAndRestore() throws Exception {
super();
}
/** Address set in stand-alone mode */
private static final String STANDALONE_HOST_ADDR = "localhost";
/**
* Check if when the JMX notification for the snapshot registration is sending, its device children are present.
*
* @throws InstanceNotFoundException
* @throws InterruptedException
* @throws ListenerNotFoundException
*/
@Test
public void testCreateSnapshotVerifyHierarchy() throws InstanceNotFoundException, InterruptedException,
ListenerNotFoundException {
final CountDownLatch latch = new CountDownLatch(1);
final long size0 = (long) (1024.0 * 1024.0 * 1024.0);
final SnapshotMXBean rootSnapshot = helper.getSnapshot(vvrUuid, rootUuid);
final String devUuidTaskStr = rootSnapshot.createDevice("dev0", size0);
final DeviceMXBean device = helper.getDevice(vvrUuid, devUuidTaskStr);
final String devUuid = device.getUuid();
// Add a listener
final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
final NotificationListener notificationListener = new NotificationListener() {
@Override
public final void handleNotification(final Notification notification, final Object handback) {
final MBeanServerNotification mbs = (MBeanServerNotification) notification;
if (MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(mbs.getType())) {
final ObjectName objectname = mbs.getMBeanName();
if (objectname.getKeyProperty("type").equals("Snapshot")) {
final SnapshotMXBean snapshotMXBean = JMX.newMXBeanProxy(
ManagementFactory.getPlatformMBeanServer(), objectname, SnapshotMXBean.class, false);
final String[] devices = snapshotMXBean.getChildrenDevices();
if ((devices.length != 0) && (devices[0].equals(devUuid))) {
latch.countDown();
}
}
}
}
};
server.addNotificationListener(MBeanServerDelegate.DELEGATE_NAME, notificationListener, null, null);
try {
device.takeSnapshot();
Assert.assertTrue(latch.await(10, TimeUnit.SECONDS));
}
finally {
server.removeNotificationListener(MBeanServerDelegate.DELEGATE_NAME, notificationListener);
}
}
@Test
public void testCreateStopRestore() throws Exception {
final long size0 = (long) (1024.0 * 1024.0 * 1024.0);
final long size1 = (long) (2048.0 * 1024.0 * 1024.0);
final long size2 = (long) (4096.0 * 1024.0 * 1024.0);
final String[] snapUuid = new String[3];
final String[] devUuid = new String[3];
// Create elements
{
final String[] snapUuidTaskStr = new String[3];
final String[] devUuidTaskStr = new String[3];
final SnapshotMXBean rootSnapshot = helper.getSnapshot(vvrUuid, rootUuid);
final DeviceMXBean[] devices = new DeviceMXBean[3];
final SnapshotMXBean[] snapshots = new SnapshotMXBean[3];
devUuidTaskStr[0] = rootSnapshot.createDevice("dev0", size0);
devices[0] = helper.getDevice(vvrUuid, devUuidTaskStr[0]);
devUuid[0] = devices[0].getUuid();
devUuidTaskStr[1] = rootSnapshot.createDevice("dev1", size1);
devices[1] = helper.getDevice(vvrUuid, devUuidTaskStr[1]);
devUuid[1] = devices[1].getUuid();
{
final String uuid = UUID.randomUUID().toString();
snapUuidTaskStr[0] = devices[0].takeSnapshotUuid("snap0", uuid);
snapshots[0] = helper.getSnapshot(vvrUuid, snapUuidTaskStr[0]);
snapUuid[0] = snapshots[0].getUuid();
Assert.assertEquals("snap0", snapshots[0].getName());
Assert.assertEquals(snapUuid[0], uuid);
}
{
final String uuid = UUID.randomUUID().toString();
snapUuidTaskStr[1] = devices[1].takeSnapshotUuid(uuid);
snapshots[1] = helper.getSnapshot(vvrUuid, snapUuidTaskStr[1]);
snapUuid[1] = snapshots[1].getUuid();
Assert.assertEquals(snapUuid[1], uuid);
snapshots[1].delete();
}
snapUuidTaskStr[2] = devices[0].takeSnapshot("snap2");
snapshots[2] = helper.getSnapshot(vvrUuid, snapUuidTaskStr[2]);
snapUuid[2] = snapshots[2].getUuid();
devices[0].delete();
devUuidTaskStr[2] = snapshots[2].createDevice("dev2", size2);
devices[2] = helper.getDevice(vvrUuid, devUuidTaskStr[2]);
devUuid[2] = devices[2].getUuid();
}
// Restart VOLD
restartVold();
Assert.assertTrue(helper.waitMXBeanRegistration(helper.newVvrObjectName(vvrUuid)));
{
final SnapshotMXBean rootSnapshot = helper.getSnapshot(vvrUuid, rootUuid);
// Basic check
final boolean[] devicesFound = new boolean[2];
final boolean[] snapFound = new boolean[2];
{
final String[] rootChildren = rootSnapshot.getChildrenSnapshots();
for (final String uuid : rootChildren) {
if (uuid.equals(snapUuid[0])) {
snapFound[0] = true;
}
else if (uuid.equals(snapUuid[1])) {
snapFound[1] = true;
}
else {
throw new AssertionError("Unknown UUID: " + uuid);
}
}
}
{
final String[] rootChildren = rootSnapshot.getChildrenDevices();
for (final String uuid : rootChildren) {
if (uuid.equals(devUuid[0])) {
devicesFound[0] = true;
}
else if (uuid.equals(devUuid[1])) {
devicesFound[1] = true;
}
else {
throw new AssertionError("Unknown UUID: " + uuid);
}
}
}
Assert.assertFalse(devicesFound[0]);
Assert.assertTrue(devicesFound[1]);
Assert.assertTrue(snapFound[0]);
Assert.assertFalse(snapFound[1]);
final SnapshotMXBean snapshot2 = helper.getSnapshot(vvrUuid, UUID.fromString(snapUuid[2]));
Assert.assertEquals("snap2", snapshot2.getName());
Assert.assertEquals(size0, snapshot2.getSize());
{
final String[] snap2Children = snapshot2.getChildrenSnapshots();
Assert.assertEquals(0, snap2Children.length);
}
{
final String[] snap2Children = snapshot2.getChildrenDevices();
Assert.assertEquals(1, snap2Children.length);
Assert.assertEquals(devUuid[2], snap2Children[0]);
}
}
}
@Test
public void testResizeNoWait() throws Exception {
final long size0 = (long) (1024.0 * 1024.0 * 1024.0);
final long size1 = (long) (2048.0 * 1024.0 * 1024.0);
final long size2 = (long) (4096.0 * 1024.0 * 1024.0);
final UUID[] devUuid = new UUID[3];
final String rootUuidStr = rootUuid.toString();
final String snapUuidStr;
// Create elements
{
final String[] devTaskUuid = new String[3];
final SnapshotMXBean rootSnapshot = helper.getSnapshot(vvrUuid, rootUuid);
final DeviceMXBean[] devices = new DeviceMXBean[3];
devTaskUuid[0] = rootSnapshot.createDevice("dev0", size0);
devices[0] = helper.getDevice(vvrUuid, devTaskUuid[0]);
devUuid[0] = UUID.fromString(devices[0].getUuid());
devTaskUuid[1] = rootSnapshot.createDevice("dev1", size0);
devices[1] = helper.getDevice(vvrUuid, devTaskUuid[1]);
devUuid[1] = UUID.fromString(devices[1].getUuid());
final String snapshotUuidTask = devices[0].takeSnapshot("snap2");
final SnapshotMXBean snapshot = helper.getSnapshot(vvrUuid, snapshotUuidTask);
snapUuidStr = snapshot.getUuid();
devTaskUuid[2] = snapshot.createDevice("dev2", size2);
devices[2] = helper.getDevice(vvrUuid, devTaskUuid[2]);
devUuid[2] = UUID.fromString(devices[2].getUuid());
// Resize
devices[0].setSizeNoWait(size1);
devices[0].setSizeNoWait(size2);
devices[1].setSizeNoWait(size2);
devices[1].setSizeNoWait(size1);
devices[2].setSize(size0);
// All the tasks should be completed
Assert.assertEquals(size2, devices[0].getSize());
Assert.assertEquals(size1, devices[1].getSize());
Assert.assertEquals(size0, devices[2].getSize());
Assert.assertEquals(rootSnapshot.getUuid(), rootUuidStr);
Assert.assertEquals(snapUuidStr, devices[0].getParent());
Assert.assertEquals(rootUuidStr, devices[1].getParent());
Assert.assertEquals(snapUuidStr, devices[2].getParent());
}
final ObjectName[] deviceName = new ObjectName[3];
// Save all devices object name
for (int i = 0; i < 3; i++) {
deviceName[i] = helper.getDeviceObjectName(vvrUuid, devUuid[i]);
}
// Restart VOLD
restartVold();
// Wait Device MX Bean registration
for (int i = 0; i < 3; i++) {
Assert.assertTrue(helper.waitMXBeanRegistration(deviceName[i]));
}
// Check elements
{
final DeviceMXBean[] devices = new DeviceMXBean[3];
devices[0] = helper.getDevice(vvrUuid, devUuid[0]);
devices[1] = helper.getDevice(vvrUuid, devUuid[1]);
devices[2] = helper.getDevice(vvrUuid, devUuid[2]);
Assert.assertEquals(size2, devices[0].getSize());
Assert.assertEquals(size1, devices[1].getSize());
Assert.assertEquals(size0, devices[2].getSize());
Assert.assertEquals(snapUuidStr, devices[0].getParent());
Assert.assertEquals(rootUuidStr, devices[1].getParent());
Assert.assertEquals(snapUuidStr, devices[2].getParent());
}
}
@Test
public void testActivateDeactivate() throws Exception {
final long size0 = (long) (1024.0 * 1024.0 * 1024.0);
final long size1 = (long) (2048.0 * 1024.0 * 1024.0);
final long size2 = (long) (4096.0 * 1024.0 * 1024.0);
final UUID[] devUuid = new UUID[3];
// Create elements
{
final String[] devTaskUuid = new String[3];
final SnapshotMXBean rootSnapshot = helper.getSnapshot(vvrUuid, rootUuid);
final DeviceMXBean[] devices = new DeviceMXBean[3];
devTaskUuid[0] = rootSnapshot.createDevice("dev0", size0);
devices[0] = helper.getDevice(vvrUuid, devTaskUuid[0]);
devUuid[0] = UUID.fromString(devices[0].getUuid());
devTaskUuid[1] = rootSnapshot.createDevice("dev1", size1);
devices[1] = helper.getDevice(vvrUuid, devTaskUuid[1]);
devUuid[1] = UUID.fromString(devices[1].getUuid());
devices[0].takeSnapshot("snap0");
devices[1].takeSnapshot();
final String snapshot2UuidTask = devices[0].takeSnapshot("snap2");
final SnapshotMXBean snapshot2 = helper.getSnapshot(vvrUuid, snapshot2UuidTask);
devTaskUuid[2] = snapshot2.createDevice("dev2", size2);
devices[2] = helper.getDevice(vvrUuid, devTaskUuid[2]);
devUuid[2] = UUID.fromString(devices[2].getUuid());
final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
Assert.assertFalse(devices[0].isActive());
Assert.assertFalse(devices[1].isActive());
helper.waitTaskEnd(vvrUuid, devices[1].activateRO(), server);
Assert.assertTrue(devices[1].isReadOnly());
Assert.assertTrue(devices[1].isActive());
Assert.assertFalse(devices[2].isActive());
helper.waitTaskEnd(vvrUuid, devices[2].activateRW(), server);
Assert.assertFalse(devices[2].isReadOnly());
Assert.assertTrue(devices[2].isActive());
}
final ObjectName[] deviceName = new ObjectName[3];
// Save all devices object name
for (int i = 0; i < 3; i++) {
deviceName[i] = helper.getDeviceObjectName(vvrUuid, devUuid[i]);
}
// Restart VOLD
restartVold();
// Wait Device MX Bean registration
for (int i = 0; i < 3; i++) {
Assert.assertTrue(helper.waitMXBeanRegistration(deviceName[i]));
}
// Check elements
{
final DeviceMXBean[] devices = new DeviceMXBean[3];
devices[0] = helper.getDevice(vvrUuid, devUuid[0]);
devices[1] = helper.getDevice(vvrUuid, devUuid[1]);
devices[2] = helper.getDevice(vvrUuid, devUuid[2]);
Assert.assertFalse(devices[0].isActive());
Assert.assertTrue(devices[1].isReadOnly());
Assert.assertTrue(devices[1].isActive());
Assert.assertFalse(devices[2].isReadOnly());
Assert.assertTrue(devices[2].isActive());
}
}
@Test
public void testRestartVoldReadTask() throws Exception {
final long size0 = (long) (1024.0 * 1024.0 * 1024.0);
final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
// Create a device
final SnapshotMXBean rootSnapshot = helper.getSnapshot(vvrUuid, rootUuid);
final String deviceTaskUuid = rootSnapshot.createDevice("name", size0);
// Wait task is committed
final String deviceUuid = helper.waitTaskEnd(vvrUuid, deviceTaskUuid.toString(), server);
final ObjectName vvrObjectName = helper.newVvrObjectName(vvrUuid);
// check it !
VvrManagerTestUtils.checkDeviceCreationTask(deviceTaskUuid, deviceUuid,
JMX.newMXBeanProxy(server, vvrObjectName, VvrMXBean.class, false).getVvrTask(deviceTaskUuid));
// Restart the Vold
restartVold();
// wait vvr mx bean creation
Assert.assertTrue(helper.waitMXBeanRegistration(vvrObjectName));
// check the task
VvrManagerTestUtils.checkDeviceCreationTask(deviceTaskUuid, deviceUuid,
JMX.newMXBeanProxy(server, vvrObjectName, VvrMXBean.class, false).getVvrTask(deviceTaskUuid));
}
@Test
public void testJmxDtxManagerAndLocalNode() throws Exception {
final long size0 = (long) (1024.0 * 1024.0 * 1024.0);
final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
final DtxManagerMXBean dtxManager = JMX.newMXBeanProxy(server, helper.newDtxManagerObjectName(),
DtxManagerMXBean.class, false);
final DtxLocalNodeMXBean dtxLocalNode = JMX.newMXBeanProxy(server, helper.newDtxLocalNodeObjectName(),
DtxLocalNodeMXBean.class, false);
// Check Resource Manager
VvrManagerTestUtils.checkResourceManagersAfterVvrCreation(dtxManager, vvrUuid, helper.VOLD_OWNER_UUID_TEST);
// Check request Queue
VvrManagerTestUtils.checkRequestQueueEmpty(dtxManager);
// Check task list
VvrManagerTestUtils.checkDtxTasksListAfterVvrCreation(dtxManager, vvrUuid, helper.VOLD_OWNER_UUID_TEST, 0);
// Check dtx node
// Local node: stand alone and dynamic port (no incoming connection)
final InetSocketAddress localPeer = new InetSocketAddress(STANDALONE_HOST_ADDR, 0);
VvrManagerTestUtils.checkDtxLocalNode(dtxLocalNode, localPeer, 0);
// Create a device
final SnapshotMXBean rootSnapshot = helper.getSnapshot(vvrUuid, rootUuid);
final String deviceTaskUuidStr = rootSnapshot.createDevice("name", size0);
// Wait task is committed
helper.waitTaskEnd(vvrUuid, deviceTaskUuidStr, server);
VvrManagerTestUtils.checkResourceManagersAfterDeviceCreation(dtxManager, vvrUuid, helper.VOLD_OWNER_UUID_TEST);
// No pending request
VvrManagerTestUtils.checkRequestQueueEmpty(dtxManager);
// Check tasks List
VvrManagerTestUtils.checkDtxTasksListAfterDeviceCreation(dtxManager, vvrUuid, deviceTaskUuidStr, 0);
}
}