/* * The Alluxio Open Foundation licenses this work under the Apache License, version 2.0 * (the "License"). You may not use this work except in compliance with the License, which is * available at www.apache.org/licenses/LICENSE-2.0 * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied, as more fully set forth in the License. * * See the NOTICE file distributed with this work for information regarding copyright ownership. */ package alluxio.master.file.meta; import alluxio.AlluxioURI; import alluxio.exception.AccessControlException; import alluxio.exception.ExceptionMessage; import alluxio.exception.FileAlreadyExistsException; import alluxio.exception.InvalidPathException; import alluxio.master.file.meta.options.MountInfo; import alluxio.master.file.options.MountOptions; import alluxio.underfs.UfsManager; import alluxio.underfs.UnderFileSystem; import alluxio.underfs.local.LocalUnderFileSystemFactory; import alluxio.util.IdUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import java.util.HashMap; import java.util.Map; /** * Unit tests for {@link MountTable}. */ public final class MountTableTest { private MountTable mMountTable; private final MountOptions mDefaultOptions = MountOptions.defaults(); private final UnderFileSystem mTestUfs = new LocalUnderFileSystemFactory().create("/", null); @Before public void before() throws Exception { UfsManager ufsManager = Mockito.mock(UfsManager.class); Mockito.when(ufsManager.get(Mockito.anyLong())).thenReturn(mTestUfs); mMountTable = new MountTable(ufsManager); } /** * Tests the different methods of the {@link MountTable} class with a path. */ @Test public void path() throws Exception { // Test add() mMountTable.add(new AlluxioURI("/mnt/foo"), new AlluxioURI("/foo"), 1L, mDefaultOptions); mMountTable.add(new AlluxioURI("/mnt/bar"), new AlluxioURI("/bar"), 2L, mDefaultOptions); try { mMountTable.add(new AlluxioURI("/mnt/foo"), new AlluxioURI("/foo2"), 3L, mDefaultOptions); Assert.fail("Should not be able to add a mount to an existing mount."); } catch (FileAlreadyExistsException e) { // Exception expected Assert.assertEquals(ExceptionMessage.MOUNT_POINT_ALREADY_EXISTS.getMessage("/mnt/foo"), e.getMessage()); } try { mMountTable.add(new AlluxioURI("/mnt/bar/baz"), new AlluxioURI("/baz"), 4L, mDefaultOptions); } catch (InvalidPathException e) { // Exception expected Assert.assertEquals( ExceptionMessage.MOUNT_POINT_PREFIX_OF_ANOTHER.getMessage("/mnt/bar", "/mnt/bar/baz"), e.getMessage()); } // Test resolve() MountTable.Resolution res1 = mMountTable.resolve(new AlluxioURI("/mnt/foo")); Assert.assertEquals(new AlluxioURI("/foo"), res1.getUri()); Assert.assertEquals(1L, res1.getMountId()); MountTable.Resolution res2 = mMountTable.resolve(new AlluxioURI("/mnt/foo/x")); Assert.assertEquals(new AlluxioURI("/foo/x"), res2.getUri()); Assert.assertEquals(1L, res2.getMountId()); MountTable.Resolution res3 = mMountTable.resolve(new AlluxioURI("/mnt/bar")); Assert.assertEquals(new AlluxioURI("/bar"), res3.getUri()); Assert.assertEquals(2L, res3.getMountId()); MountTable.Resolution res4 = mMountTable.resolve(new AlluxioURI("/mnt/bar/y")); Assert.assertEquals(new AlluxioURI("/bar/y"), res4.getUri()); Assert.assertEquals(2L, res4.getMountId()); MountTable.Resolution res5 = mMountTable.resolve(new AlluxioURI("/mnt/bar/baz")); Assert.assertEquals(new AlluxioURI("/bar/baz"), res5.getUri()); Assert.assertEquals(2L, res4.getMountId()); MountTable.Resolution res6 = mMountTable.resolve(new AlluxioURI("/foobar")); Assert.assertEquals(new AlluxioURI("/foobar"), res6.getUri()); Assert.assertEquals(IdUtils.INVALID_MOUNT_ID, res6.getMountId()); MountTable.Resolution res7 = mMountTable.resolve(new AlluxioURI("/")); Assert.assertEquals(new AlluxioURI("/"), res7.getUri()); Assert.assertEquals(IdUtils.INVALID_MOUNT_ID, res7.getMountId()); // Test getMountPoint() Assert.assertEquals("/mnt/foo", mMountTable.getMountPoint(new AlluxioURI("/mnt/foo"))); Assert.assertEquals("/mnt/foo", mMountTable.getMountPoint(new AlluxioURI("/mnt/foo/x"))); Assert.assertEquals("/mnt/bar", mMountTable.getMountPoint(new AlluxioURI("/mnt/bar"))); Assert.assertEquals("/mnt/bar", mMountTable.getMountPoint(new AlluxioURI("/mnt/bar/y"))); Assert.assertEquals("/mnt/bar", mMountTable.getMountPoint(new AlluxioURI("/mnt/bar/baz"))); Assert.assertNull(mMountTable.getMountPoint(new AlluxioURI("/mnt"))); Assert.assertNull(mMountTable.getMountPoint(new AlluxioURI("/"))); // Test isMountPoint() Assert.assertFalse(mMountTable.isMountPoint(new AlluxioURI("/"))); Assert.assertTrue(mMountTable.isMountPoint(new AlluxioURI("/mnt/foo"))); Assert.assertFalse(mMountTable.isMountPoint(new AlluxioURI("/mnt/foo/bar"))); Assert.assertFalse(mMountTable.isMountPoint(new AlluxioURI("/mnt"))); Assert.assertFalse(mMountTable.isMountPoint(new AlluxioURI("/mnt/foo3"))); Assert.assertTrue(mMountTable.isMountPoint(new AlluxioURI("/mnt/bar"))); Assert.assertFalse(mMountTable.isMountPoint(new AlluxioURI("/mnt/bar/baz"))); // Test delete() Assert.assertTrue(mMountTable.delete(new AlluxioURI("/mnt/bar"))); Assert.assertTrue(mMountTable.delete(new AlluxioURI("/mnt/foo"))); Assert.assertFalse(mMountTable.delete(new AlluxioURI("/mnt/foo"))); Assert.assertFalse(mMountTable.delete(new AlluxioURI("/"))); } /** * Tests the different methods of the {@link MountTable} class with a URI. */ @Test public void uri() throws Exception { // Test add() mMountTable.add(new AlluxioURI("alluxio://localhost:1234/mnt/foo"), new AlluxioURI("file://localhost:5678/foo"), 1L, mDefaultOptions); mMountTable.add(new AlluxioURI("alluxio://localhost:1234/mnt/bar"), new AlluxioURI("file://localhost:5678/bar"), 2L, mDefaultOptions); try { mMountTable.add(new AlluxioURI("alluxio://localhost:1234/mnt/foo"), new AlluxioURI("hdfs://localhost:5678/foo2"), 3L, mDefaultOptions); } catch (FileAlreadyExistsException e) { // Exception expected Assert.assertEquals(ExceptionMessage.MOUNT_POINT_ALREADY_EXISTS.getMessage("/mnt/foo"), e.getMessage()); } try { mMountTable.add(new AlluxioURI("alluxio://localhost:1234/mnt/bar/baz"), new AlluxioURI("hdfs://localhost:5678/baz"), 4L, mDefaultOptions); } catch (InvalidPathException e) { Assert.assertEquals( ExceptionMessage.MOUNT_POINT_PREFIX_OF_ANOTHER.getMessage("/mnt/bar", "/mnt/bar/baz"), e.getMessage()); } // Test resolve() Assert.assertEquals(new AlluxioURI("file://localhost:5678/foo"), mMountTable.resolve(new AlluxioURI("alluxio://localhost:1234/mnt/foo")).getUri()); Assert.assertEquals(new AlluxioURI("file://localhost:5678/bar"), mMountTable.resolve(new AlluxioURI("alluxio://localhost:1234/mnt/bar")).getUri()); Assert.assertEquals(new AlluxioURI("file://localhost:5678/bar/y"), mMountTable.resolve(new AlluxioURI("alluxio://localhost:1234/mnt/bar/y")).getUri()); Assert.assertEquals(new AlluxioURI("file://localhost:5678/bar/baz"), mMountTable.resolve(new AlluxioURI("alluxio://localhost:1234/mnt/bar/baz")).getUri()); // Test getMountPoint() Assert.assertEquals("/mnt/foo", mMountTable.getMountPoint(new AlluxioURI("alluxio://localhost:1234/mnt/foo"))); Assert.assertEquals("/mnt/bar", mMountTable.getMountPoint(new AlluxioURI("alluxio://localhost:1234/mnt/bar"))); Assert.assertEquals("/mnt/bar", mMountTable.getMountPoint(new AlluxioURI("alluxio://localhost:1234/mnt/bar/y"))); Assert.assertEquals("/mnt/bar", mMountTable.getMountPoint(new AlluxioURI("alluxio://localhost:1234/mnt/bar/baz"))); Assert.assertNull(mMountTable.getMountPoint(new AlluxioURI("alluxio://localhost:1234/mnt"))); Assert.assertNull(mMountTable.getMountPoint(new AlluxioURI("alluxio://localhost:1234/"))); // Test isMountPoint() Assert.assertFalse(mMountTable.isMountPoint(new AlluxioURI("alluxio://localhost:1234/"))); Assert.assertTrue(mMountTable.isMountPoint(new AlluxioURI("alluxio://localhost:1234/mnt/foo"))); Assert.assertFalse( mMountTable.isMountPoint(new AlluxioURI("alluxio://localhost:1234/mnt/foo/bar"))); Assert.assertFalse(mMountTable.isMountPoint(new AlluxioURI("alluxio://localhost:1234/mnt"))); Assert .assertFalse(mMountTable.isMountPoint(new AlluxioURI("alluxio://localhost:1234/mnt/foo2"))); Assert .assertFalse(mMountTable.isMountPoint(new AlluxioURI("alluxio://localhost:1234/mnt/foo3"))); Assert.assertTrue(mMountTable.isMountPoint(new AlluxioURI("alluxio://localhost:1234/mnt/bar"))); Assert.assertFalse( mMountTable.isMountPoint(new AlluxioURI("alluxio://localhost:1234/mnt/bar/baz"))); // Test delete() Assert.assertTrue(mMountTable.delete(new AlluxioURI("alluxio://localhost:1234/mnt/bar"))); Assert.assertTrue(mMountTable.delete(new AlluxioURI("alluxio://localhost:1234/mnt/foo"))); Assert.assertFalse(mMountTable.delete(new AlluxioURI("alluxio://localhost:1234/mnt/foo"))); Assert.assertFalse(mMountTable.delete(new AlluxioURI("alluxio://localhost:1234/"))); } /** * Tests check of readonly mount points. */ @Test public void readOnlyMount() throws Exception { MountOptions options = MountOptions.defaults().setReadOnly(true); String mountPath = "/mnt/foo"; AlluxioURI alluxioUri = new AlluxioURI("alluxio://localhost:1234" + mountPath); mMountTable.add(alluxioUri, new AlluxioURI("hdfs://localhost:5678/foo"), 1L, options); try { mMountTable.checkUnderWritableMountPoint(alluxioUri); Assert.fail("Readonly mount point should not be writable."); } catch (AccessControlException e) { // Exception expected Assert.assertEquals(ExceptionMessage.MOUNT_READONLY.getMessage(alluxioUri, mountPath), e.getMessage()); } try { String path = mountPath + "/sub/directory"; alluxioUri = new AlluxioURI("alluxio://localhost:1234" + path); mMountTable.checkUnderWritableMountPoint(alluxioUri); Assert.fail("Readonly mount point should not be writable."); } catch (AccessControlException e) { // Exception expected Assert.assertEquals(ExceptionMessage.MOUNT_READONLY.getMessage(alluxioUri, mountPath), e.getMessage()); } } /** * Tests check of writable mount points. */ @Test public void writableMount() throws Exception { String mountPath = "/mnt/foo"; AlluxioURI alluxioUri = new AlluxioURI("alluxio://localhost:1234" + mountPath); mMountTable .add(alluxioUri, new AlluxioURI("hdfs://localhost:5678/foo"), IdUtils.INVALID_MOUNT_ID, MountOptions.defaults()); try { mMountTable.checkUnderWritableMountPoint(alluxioUri); } catch (AccessControlException e) { Assert.fail("Default mount point should be writable."); } try { String path = mountPath + "/sub/directory"; alluxioUri = new AlluxioURI("alluxio://localhost:1234" + path); mMountTable.checkUnderWritableMountPoint(alluxioUri); } catch (AccessControlException e) { Assert.fail("Default mount point should be writable."); } } /** * Tests the method for getting a copy of the current mount table. */ @Test public void getMountTable() throws Exception { Map<String, MountInfo> mountTable = new HashMap<>(2); mountTable.put("/mnt/foo", new MountInfo(new AlluxioURI("hdfs://localhost:5678/foo"), 1L, MountOptions.defaults())); mountTable.put("/mnt/bar", new MountInfo(new AlluxioURI("hdfs://localhost:5678/bar"), 2L, MountOptions.defaults())); AlluxioURI masterAddr = new AlluxioURI("alluxio://localhost:1234"); for (Map.Entry<String, MountInfo> mountPoint : mountTable.entrySet()) { MountInfo mountInfo = mountPoint.getValue(); mMountTable.add(masterAddr.join(mountPoint.getKey()), mountInfo.getUfsUri(), mountInfo.getMountId(), mountInfo.getOptions()); } Assert.assertEquals(mountTable, mMountTable.getMountTable()); } /** * Tests the method for getting mount info given mount id. */ @Test public void getMountInfo() throws Exception { MountInfo info1 = new MountInfo(new AlluxioURI("hdfs://localhost:5678/foo"), 1L, MountOptions.defaults()); MountInfo info2 = new MountInfo(new AlluxioURI("hdfs://localhost:5678/bar"), 2L, MountOptions.defaults()); mMountTable .add(new AlluxioURI("/mnt/foo"), info1.getUfsUri(), info1.getMountId(), info1.getOptions()); mMountTable .add(new AlluxioURI("/mnt/bar"), info2.getUfsUri(), info2.getMountId(), info2.getOptions()); Assert.assertEquals(info1, mMountTable.getMountInfo(info1.getMountId())); Assert.assertEquals(info2, mMountTable.getMountInfo(info2.getMountId())); Assert.assertEquals(null, mMountTable.getMountInfo(3L)); } }