package io.eguan.vold; /* * #%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.srv.FsOpsTestHelper; import io.eguan.utils.unix.UnixMount; import io.eguan.utils.unix.UnixTarget; import io.eguan.vold.model.DeviceMXBean; import io.eguan.vold.model.DummyMBeanServer; import io.eguan.vold.model.SnapshotMXBean; import io.eguan.vold.model.VoldTestHelper; import io.eguan.vold.model.VvrManagerMXBean; import io.eguan.vold.model.VvrManagerTestUtils; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; public abstract class TestMultiVoldFsOpsOnTargetAbstract extends TestMultiVoldAbstract { // 2 Nodes, vvr started automatically public TestMultiVoldFsOpsOnTargetAbstract() { ioHelper = new FsOpsTestHelper(BLOCKSIZE, NUMBLOCKS, LENGTH); } private final String deviceName1 = "dev0"; private final String deviceName2 = "dev1"; private final long deviceSize = 8192 * 1024L * 1024L; private final FsOpsTestHelper ioHelper; private VvrManagerMXBean vvrManager1; private DummyMBeanServer server1; private DummyMBeanServer server2; private VoldTestHelper voldTestHelper1; private VoldTestHelper voldTestHelper2; private DeviceMXBean d1; private SnapshotMXBean rootSnapshot; @BeforeClass public static void init() throws Exception { setUpVolds(2, 2, true); } /** * Create a target to connect * * @param d1 * the device on which the target will be connected * * @param serverIndex * the index of the server on which the target is connected. Start from 0 * * @param numDevice * the index of the first free unix device on which the target can be connected. Start from 0 * @return the new target * @throws IOException */ protected abstract UnixTarget createTarget(final DeviceMXBean d1, final int serverIndex, final int deviceIndex) throws IOException; @Before public void createHelperAndDevice() throws Exception { server1 = getDummyMBeanServer(0); Assert.assertNotNull(server1); server2 = getDummyMBeanServer(1); Assert.assertNotNull(server2); voldTestHelper1 = getVoldTestHelper(0); Assert.assertNotNull(voldTestHelper1); voldTestHelper2 = getVoldTestHelper(1); Assert.assertNotNull(voldTestHelper2); vvrManager1 = VvrManagerTestUtils.getVvrManagerMXBean(server1, VOLD_OWNER); Assert.assertNotNull(vvrManager1); // Create a vvr on node 1 rootSnapshot = createVvrStarted(); Assert.assertEquals(VoldTestHelper.MXBEANS_NUMBER_INIT + 2, server1.getNbMXBeans()); // Check if that VVR is created into the second VVR manager Assert.assertEquals(VoldTestHelper.MXBEANS_NUMBER_INIT + 2, server2.getNbMXBeans()); // Create and activate a RW device on node 1 d1 = VvrManagerTestUtils.createDevice(server1, voldTestHelper1, rootSnapshot, vvrUuid, deviceName1, deviceSize); setDeviceRW(server1, voldTestHelper1, vvrUuid, d1); Assert.assertEquals(VoldTestHelper.MXBEANS_NUMBER_INIT + 3, server1.getNbMXBeans()); // Check if that device is created into the second VVR manager Assert.assertEquals(VoldTestHelper.MXBEANS_NUMBER_INIT + 3, server2.getNbMXBeans()); } private final DeviceMXBean createAnotherDevice() throws Exception { // Create and activate a RW device on node 1 final DeviceMXBean d2 = VvrManagerTestUtils.createDevice(server1, voldTestHelper1, rootSnapshot, vvrUuid, deviceName2, deviceSize); setDeviceRW(server1, voldTestHelper1, vvrUuid, d2); Assert.assertEquals(VoldTestHelper.MXBEANS_NUMBER_INIT + 4, server1.getNbMXBeans()); // Check if that device is created into the second VVR manager Assert.assertEquals(VoldTestHelper.MXBEANS_NUMBER_INIT + 4, server2.getNbMXBeans()); return d2; } @Test public void testMultiVoldFsOps() throws Throwable { final File mountPoint1 = Files.createTempDirectory("mount1").toFile(); boolean isMount1 = false; // Create target on server index 0, device index 0 final UnixTarget unixTarget1 = createTarget(d1, 0, 0); try { final File mountPoint2 = Files.createTempDirectory("mount2").toFile(); try { ioHelper.loginTarget(unixTarget1); try { final File targetDevice = FsOpsTestHelper.createAndWaitTargetDevice(unixTarget1); FsOpsTestHelper.partitionCreate(unixTarget1); final File targetPart1 = FsOpsTestHelper.createAndWaitTargetPart1(unixTarget1); final String targetPart1Str = unixTarget1.getDeviceFilePath() + unixTarget1.getDevicePart1Suffix(); FsOpsTestHelper.formatFileSystem(unixTarget1, targetPart1Str); FsOpsTestHelper.sync(unixTarget1); final UnixMount unixMount1 = FsOpsTestHelper.mountDiscOnTarget(unixTarget1, targetPart1Str, mountPoint1, null); isMount1 = true; try { final File tmpFile = ioHelper.writeTmpFile(); try { FsOpsTestHelper.writeFileOnTarget(unixTarget1, tmpFile, mountPoint1); unixMount1.umount(); isMount1 = false; ioHelper.logoutTarget(unixTarget1); // Deactivate device on node 1 setDeviceDeActivated(server1, voldTestHelper1, vvrUuid, d1); // Set the devices RO setDeviceRO(server1, voldTestHelper1, vvrUuid, d1); setDeviceRO(server2, voldTestHelper2, vvrUuid, getDeviceMXBeanOnOtherServer(vvrUuid, d1, server2)); ioHelper.loginTarget(unixTarget1); // Need to wait for the device to be created (udev) FsOpsTestHelper.waitForFile(targetDevice); FsOpsTestHelper.waitForFile(targetPart1); // mount & umount unixMount1.mount(); isMount1 = true; Assert.assertTrue(new File(mountPoint1, "lost+found").isDirectory()); // Read/compare file again FsOpsTestHelper.compareFileOnTarget(unixTarget1, tmpFile, mountPoint1); unixMount1.umount(); isMount1 = false; // Check file on server2 final UnixTarget target2 = createTarget(getDeviceMXBeanOnOtherServer(vvrUuid, d1, server2), 1, 1); checkFileOnOtherServer(target2, mountPoint2, tmpFile); } finally { tmpFile.delete(); } } finally { if (isMount1) { unixMount1.umount(); isMount1 = false; } } } finally { ioHelper.logoutTarget(unixTarget1); } } finally { mountPoint2.delete(); } } finally { mountPoint1.delete(); } } /** * Compare files on a given server with a given device. * * @param device * the device on which the files are compared * @param server * the server on which the connection is done * @param mountPoint * the directory used as mount point * @param fileToCompare * the file to compare * @throws Throwable * if something goes wrong */ private final void checkFileOnOtherServer(final UnixTarget unixTarget, final File mountPoint, final File fileToCompare) throws Throwable { // Login on target ioHelper.loginTarget(unixTarget); try { FsOpsTestHelper.createAndWaitTargetDevice(unixTarget); FsOpsTestHelper.createAndWaitTargetPart1(unixTarget); final String targetPart1Str = unixTarget.getDeviceFilePath() + unixTarget.getDevicePart1Suffix(); // Mount target final UnixMount unixMount = FsOpsTestHelper.mountDiscOnTarget(unixTarget, targetPart1Str, mountPoint, null); try { // Read/compare file again FsOpsTestHelper.compareFileOnTarget(unixTarget, fileToCompare, mountPoint); } finally { unixMount.umount(); } } finally { ioHelper.logoutTarget(unixTarget); } } @Test public void testWriteReadOneDeviceTwoServers() throws Throwable { final DeviceMXBean d2 = createAnotherDevice(); // Activate it on server 2 setDeviceDeActivated(server1, voldTestHelper1, vvrUuid, d2); setDeviceRW(server2, voldTestHelper2, vvrUuid, getDeviceMXBeanOnOtherServer(vvrUuid, d2, server2)); final ExecutorService executor = Executors.newFixedThreadPool(2); try { // Create a new target on the server 1 on the device index 0 final UnixTarget unixTarget1 = createTarget(d1, 0, 0); // Create a new target on the server 2 on the device index 1 final UnixTarget unixTarget2 = createTarget(getDeviceMXBeanOnOtherServer(vvrUuid, d2, server2), 1, 1); // Write and read on each target final Future<File> future1 = ioHelper.multiThreadRW(executor, unixTarget1); final Future<File> future2 = ioHelper.multiThreadRW(executor, unixTarget2); final File file1 = future1.get(1, TimeUnit.MINUTES); try { final File file2 = future2.get(1, TimeUnit.MINUTES); setDeviceDeActivated(server1, voldTestHelper1, vvrUuid, d1); setDeviceDeActivated(server2, voldTestHelper2, vvrUuid, getDeviceMXBeanOnOtherServer(vvrUuid, d2, server2)); try { // Check file1 on server2 final File mountPoint2 = Files.createTempDirectory("mount2").toFile(); try { // Server index 1 and use the first free device index (0) setDeviceRO(server2, voldTestHelper2, vvrUuid, getDeviceMXBeanOnOtherServer(vvrUuid, d1, server2)); final UnixTarget target2 = createTarget(getDeviceMXBeanOnOtherServer(vvrUuid, d1, server2), 1, 0); checkFileOnOtherServer(target2, mountPoint2, file1); } finally { mountPoint2.delete(); } // Check file2 on server1 final File mountPoint1 = Files.createTempDirectory("mount1").toFile(); try { // Server index 0 and use the first free device index (0) setDeviceRO(server1, voldTestHelper1, vvrUuid, d2); final UnixTarget target1 = createTarget(d2, 0, 0); checkFileOnOtherServer(target1, mountPoint1, file2); } finally { mountPoint1.delete(); } } finally { file2.delete(); } } finally { file1.delete(); } } finally { executor.shutdownNow(); } } @Test public void testWriteReadTwoDevices() throws Throwable { final DeviceMXBean d2 = createAnotherDevice(); final ExecutorService executor = Executors.newFixedThreadPool(2); try { // Create a new target on the server 1 on the device index 0 final UnixTarget unixTarget1 = createTarget(d1, 0, 0); // Create a new target on the server 1 on the device index 1 final UnixTarget unixTarget2 = createTarget(d2, 0, 1); // Write and read on each target final Future<File> future1 = ioHelper.multiThreadRW(executor, unixTarget1); final Future<File> future2 = ioHelper.multiThreadRW(executor, unixTarget2); final File file1 = future1.get(1, TimeUnit.MINUTES); try { final File file2 = future2.get(1, TimeUnit.MINUTES); setDeviceDeActivated(server1, voldTestHelper1, vvrUuid, d1); setDeviceDeActivated(server2, voldTestHelper2, vvrUuid, d2); try { // Check file1 and file2 on server2 final File mountPoint = Files.createTempDirectory("mount2").toFile(); try { // Use the first free device index setDeviceRO(server2, voldTestHelper2, vvrUuid, getDeviceMXBeanOnOtherServer(vvrUuid, d1, server2)); UnixTarget target = createTarget(getDeviceMXBeanOnOtherServer(vvrUuid, d1, server2), 1, 0); checkFileOnOtherServer(target, mountPoint, file1); // Use the first free device index setDeviceRO(server2, voldTestHelper2, vvrUuid, getDeviceMXBeanOnOtherServer(vvrUuid, d2, server2)); target = createTarget(getDeviceMXBeanOnOtherServer(vvrUuid, d2, server2), 1, 0); checkFileOnOtherServer(target, mountPoint, file2); } finally { mountPoint.delete(); } } finally { file2.delete(); } } finally { file1.delete(); } } finally { executor.shutdownNow(); } } }