/** for snapshot file. */ @Test(timeout = 15000) public void testSnapshotPathINodes() throws Exception { // Create a snapshot for the dir, and check the inodes for the path // pointing to a snapshot file hdfs.allowSnapshot(sub1); hdfs.createSnapshot(sub1, "s1"); // The path when accessing the snapshot file of file1 is // /TestSnapshot/sub1/.snapshot/s1/file1 String snapshotPath = sub1.toString() + "/.snapshot/s1/file1"; String[] names = INode.getPathNames(snapshotPath); byte[][] components = INode.getPathComponents(names); INodesInPath nodesInPath = INodesInPath.resolve(fsdir.rootDir, components, false); // Length of inodes should be (components.length - 1), since we will ignore // ".snapshot" assertEquals(nodesInPath.length(), components.length - 1); // SnapshotRootIndex should be 3: {root, Testsnapshot, sub1, s1, file1} final Snapshot snapshot = getSnapshot(nodesInPath, "s1", 3); assertSnapshot(nodesInPath, true, snapshot, 3); // Check the INode for file1 (snapshot file) INode snapshotFileNode = nodesInPath.getLastINode(); assertINodeFile(snapshotFileNode, file1); assertTrue(snapshotFileNode.getParent().isWithSnapshot()); // Call getExistingPathINodes and request only one INode. nodesInPath = INodesInPath.resolve(fsdir.rootDir, components, false); assertEquals(nodesInPath.length(), components.length - 1); assertSnapshot(nodesInPath, true, snapshot, 3); // Check the INode for file1 (snapshot file) assertINodeFile(nodesInPath.getLastINode(), file1); // Resolve the path "/TestSnapshot/sub1/.snapshot" String dotSnapshotPath = sub1.toString() + "/.snapshot"; names = INode.getPathNames(dotSnapshotPath); components = INode.getPathComponents(names); nodesInPath = INodesInPath.resolve(fsdir.rootDir, components, false); // The number of INodes returned should still be components.length // since we put a null in the inode array for ".snapshot" assertEquals(nodesInPath.length(), components.length); // No SnapshotRoot dir is included in the resolved inodes assertSnapshot(nodesInPath, true, snapshot, -1); // The last INode should be null, the last but 1 should be sub1 assertNull(nodesInPath.getLastINode()); assertEquals(nodesInPath.getINode(-2).getFullPathName(), sub1.toString()); assertTrue(nodesInPath.getINode(-2).isDirectory()); String[] invalidPathComponent = {"invalidDir", "foo", ".snapshot", "bar"}; Path invalidPath = new Path(invalidPathComponent[0]); for (int i = 1; i < invalidPathComponent.length; i++) { invalidPath = new Path(invalidPath, invalidPathComponent[i]); try { hdfs.getFileStatus(invalidPath); Assert.fail(); } catch (FileNotFoundException fnfe) { System.out.println("The exception is expected: " + fnfe); } } hdfs.deleteSnapshot(sub1, "s1"); hdfs.disallowSnapshot(sub1); }
/** for snapshot file while modifying file after snapshot. */ @Test(timeout = 15000) public void testSnapshotPathINodesAfterModification() throws Exception { // First check the INode for /TestSnapshot/sub1/file1 String[] names = INode.getPathNames(file1.toString()); byte[][] components = INode.getPathComponents(names); INodesInPath nodesInPath = INodesInPath.resolve(fsdir.rootDir, components, false); // The number of inodes should be equal to components.length assertEquals(nodesInPath.length(), components.length); // The last INode should be associated with file1 assertEquals(nodesInPath.getINode(components.length - 1).getFullPathName(), file1.toString()); // record the modification time of the inode final long modTime = nodesInPath.getINode(nodesInPath.length() - 1).getModificationTime(); // Create a snapshot for the dir, and check the inodes for the path // pointing to a snapshot file hdfs.allowSnapshot(sub1); hdfs.createSnapshot(sub1, "s3"); // Modify file1 DFSTestUtil.appendFile(hdfs, file1, "the content for appending"); // Check the INodes for snapshot of file1 String snapshotPath = sub1.toString() + "/.snapshot/s3/file1"; names = INode.getPathNames(snapshotPath); components = INode.getPathComponents(names); INodesInPath ssNodesInPath = INodesInPath.resolve(fsdir.rootDir, components, false); // Length of ssInodes should be (components.length - 1), since we will // ignore ".snapshot" assertEquals(ssNodesInPath.length(), components.length - 1); final Snapshot s3 = getSnapshot(ssNodesInPath, "s3", 3); assertSnapshot(ssNodesInPath, true, s3, 3); // Check the INode for snapshot of file1 INode snapshotFileNode = ssNodesInPath.getLastINode(); assertEquals(snapshotFileNode.getLocalName(), file1.getName()); assertTrue(snapshotFileNode.asFile().isWithSnapshot()); // The modification time of the snapshot INode should be the same with the // original INode before modification assertEquals(modTime, snapshotFileNode.getModificationTime(ssNodesInPath.getPathSnapshotId())); // Check the INode for /TestSnapshot/sub1/file1 again names = INode.getPathNames(file1.toString()); components = INode.getPathComponents(names); INodesInPath newNodesInPath = INodesInPath.resolve(fsdir.rootDir, components, false); assertSnapshot(newNodesInPath, false, s3, -1); // The number of inodes should be equal to components.length assertEquals(newNodesInPath.length(), components.length); // The last INode should be associated with file1 final int last = components.length - 1; assertEquals(newNodesInPath.getINode(last).getFullPathName(), file1.toString()); // The modification time of the INode for file3 should have been changed Assert.assertFalse(modTime == newNodesInPath.getINode(last).getModificationTime()); hdfs.deleteSnapshot(sub1, "s3"); hdfs.disallowSnapshot(sub1); }
/** for snapshot file while adding a new file after snapshot. */ @Test(timeout = 15000) public void testSnapshotPathINodesWithAddedFile() throws Exception { // Create a snapshot for the dir, and check the inodes for the path // pointing to a snapshot file hdfs.allowSnapshot(sub1); hdfs.createSnapshot(sub1, "s4"); // Add a new file /TestSnapshot/sub1/file3 final Path file3 = new Path(sub1, "file3"); DFSTestUtil.createFile(hdfs, file3, 1024, REPLICATION, seed); Snapshot s4; { // Check the inodes for /TestSnapshot/sub1/.snapshot/s4/file3 String snapshotPath = sub1.toString() + "/.snapshot/s4/file3"; String[] names = INode.getPathNames(snapshotPath); byte[][] components = INode.getPathComponents(names); INodesInPath nodesInPath = INodesInPath.resolve(fsdir.rootDir, components, false); // Length of inodes should be (components.length - 1), since we will ignore // ".snapshot" assertEquals(nodesInPath.length(), components.length - 1); // The number of non-null inodes should be components.length - 2, since // snapshot of file3 does not exist assertEquals(getNumNonNull(nodesInPath), components.length - 2); s4 = getSnapshot(nodesInPath, "s4", 3); // SnapshotRootIndex should still be 3: {root, Testsnapshot, sub1, s4, null} assertSnapshot(nodesInPath, true, s4, 3); // Check the last INode in inodes, which should be null assertNull(nodesInPath.getINode(nodesInPath.length() - 1)); } // Check the inodes for /TestSnapshot/sub1/file3 String[] names = INode.getPathNames(file3.toString()); byte[][] components = INode.getPathComponents(names); INodesInPath nodesInPath = INodesInPath.resolve(fsdir.rootDir, components, false); // The number of inodes should be equal to components.length assertEquals(nodesInPath.length(), components.length); // The returned nodesInPath should be non-snapshot assertSnapshot(nodesInPath, false, s4, -1); // The last INode should be associated with file3 assertEquals(nodesInPath.getINode(components.length - 1).getFullPathName(), file3.toString()); assertEquals(nodesInPath.getINode(components.length - 2).getFullPathName(), sub1.toString()); assertEquals(nodesInPath.getINode(components.length - 3).getFullPathName(), dir.toString()); hdfs.deleteSnapshot(sub1, "s4"); hdfs.disallowSnapshot(sub1); }
/** for snapshot file after deleting the original file. */ @Test(timeout = 15000) public void testSnapshotPathINodesAfterDeletion() throws Exception { // Create a snapshot for the dir, and check the inodes for the path // pointing to a snapshot file hdfs.allowSnapshot(sub1); hdfs.createSnapshot(sub1, "s2"); // Delete the original file /TestSnapshot/sub1/file1 hdfs.delete(file1, false); final Snapshot snapshot; { // Resolve the path for the snapshot file // /TestSnapshot/sub1/.snapshot/s2/file1 String snapshotPath = sub1.toString() + "/.snapshot/s2/file1"; String[] names = INode.getPathNames(snapshotPath); byte[][] components = INode.getPathComponents(names); INodesInPath nodesInPath = INodesInPath.resolve(fsdir.rootDir, components, false); // Length of inodes should be (components.length - 1), since we will ignore // ".snapshot" assertEquals(nodesInPath.length(), components.length - 1); // SnapshotRootIndex should be 3: {root, Testsnapshot, sub1, s2, file1} snapshot = getSnapshot(nodesInPath, "s2", 3); assertSnapshot(nodesInPath, true, snapshot, 3); // Check the INode for file1 (snapshot file) final INode inode = nodesInPath.getLastINode(); assertEquals(file1.getName(), inode.getLocalName()); assertTrue(inode.asFile().isWithSnapshot()); } // Check the INodes for path /TestSnapshot/sub1/file1 String[] names = INode.getPathNames(file1.toString()); byte[][] components = INode.getPathComponents(names); INodesInPath nodesInPath = INodesInPath.resolve(fsdir.rootDir, components, false); // The length of inodes should be equal to components.length assertEquals(nodesInPath.length(), components.length); // The number of non-null elements should be components.length - 1 since // file1 has been deleted assertEquals(getNumNonNull(nodesInPath), components.length - 1); // The returned nodesInPath should be non-snapshot assertSnapshot(nodesInPath, false, snapshot, -1); // The last INode should be null, and the one before should be associated // with sub1 assertNull(nodesInPath.getINode(components.length - 1)); assertEquals(nodesInPath.getINode(components.length - 2).getFullPathName(), sub1.toString()); assertEquals(nodesInPath.getINode(components.length - 3).getFullPathName(), dir.toString()); hdfs.deleteSnapshot(sub1, "s2"); hdfs.disallowSnapshot(sub1); }
/** for normal (non-snapshot) file. */ @Test(timeout = 15000) public void testNonSnapshotPathINodes() throws Exception { // Get the inodes by resolving the path of a normal file String[] names = INode.getPathNames(file1.toString()); byte[][] components = INode.getPathComponents(names); INodesInPath nodesInPath = INodesInPath.resolve(fsdir.rootDir, components, false); // The number of inodes should be equal to components.length assertEquals(nodesInPath.length(), components.length); // The returned nodesInPath should be non-snapshot assertSnapshot(nodesInPath, false, null, -1); // The last INode should be associated with file1 assertTrue( "file1=" + file1 + ", nodesInPath=" + nodesInPath, nodesInPath.getINode(components.length - 1) != null); assertEquals(nodesInPath.getINode(components.length - 1).getFullPathName(), file1.toString()); assertEquals(nodesInPath.getINode(components.length - 2).getFullPathName(), sub1.toString()); assertEquals(nodesInPath.getINode(components.length - 3).getFullPathName(), dir.toString()); nodesInPath = INodesInPath.resolve(fsdir.rootDir, components, false); assertEquals(nodesInPath.length(), components.length); assertSnapshot(nodesInPath, false, null, -1); assertEquals(nodesInPath.getLastINode().getFullPathName(), file1.toString()); }