| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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. |
| */ |
| |
| package org.apache.hadoop.fs; |
| |
| import static org.junit.Assert.*; |
| import static org.mockito.Matchers.*; |
| import static org.mockito.Mockito.*; |
| |
| import java.io.IOException; |
| |
| import org.apache.hadoop.fs.FileSystemTestHelper.MockFileSystem; |
| import org.apache.hadoop.io.Text; |
| import org.apache.hadoop.security.Credentials; |
| import org.apache.hadoop.security.token.Token; |
| import org.apache.hadoop.security.token.TokenIdentifier; |
| import org.junit.Test; |
| import org.mockito.invocation.InvocationOnMock; |
| import org.mockito.stubbing.Answer; |
| |
| public class TestFileSystemTokens { |
| private static String renewer = "renewer!"; |
| |
| @Test |
| public void testFsWithNoToken() throws Exception { |
| MockFileSystem fs = createFileSystemForServiceName(null); |
| Credentials credentials = new Credentials(); |
| |
| fs.addDelegationTokens(renewer, credentials); |
| verifyTokenFetch(fs, false); |
| assertEquals(0, credentials.numberOfTokens()); |
| } |
| |
| @Test |
| public void testFsWithToken() throws Exception { |
| Text service = new Text("singleTokenFs"); |
| MockFileSystem fs = createFileSystemForServiceName(service); |
| Credentials credentials = new Credentials(); |
| |
| fs.addDelegationTokens(renewer, credentials); |
| verifyTokenFetch(fs, true); |
| |
| assertEquals(1, credentials.numberOfTokens()); |
| assertNotNull(credentials.getToken(service)); |
| } |
| |
| @Test |
| public void testFsWithTokenExists() throws Exception { |
| Credentials credentials = new Credentials(); |
| Text service = new Text("singleTokenFs"); |
| MockFileSystem fs = createFileSystemForServiceName(service); |
| Token<?> token = mock(Token.class); |
| credentials.addToken(service, token); |
| |
| fs.addDelegationTokens(renewer, credentials); |
| verifyTokenFetch(fs, false); |
| |
| assertEquals(1, credentials.numberOfTokens()); |
| assertSame(token, credentials.getToken(service)); |
| } |
| |
| @Test |
| public void testFsWithChildTokens() throws Exception { |
| Credentials credentials = new Credentials(); |
| Text service1 = new Text("singleTokenFs1"); |
| Text service2 = new Text("singleTokenFs2"); |
| |
| MockFileSystem fs1 = createFileSystemForServiceName(service1); |
| MockFileSystem fs2 = createFileSystemForServiceName(service2); |
| MockFileSystem fs3 = createFileSystemForServiceName(null); |
| MockFileSystem multiFs = |
| createFileSystemForServiceName(null, fs1, fs2, fs3); |
| |
| multiFs.addDelegationTokens(renewer, credentials); |
| verifyTokenFetch(multiFs, false); // has no tokens of own, only child tokens |
| verifyTokenFetch(fs1, true); |
| verifyTokenFetch(fs2, true); |
| verifyTokenFetch(fs3, false); |
| |
| assertEquals(2, credentials.numberOfTokens()); |
| assertNotNull(credentials.getToken(service1)); |
| assertNotNull(credentials.getToken(service2)); |
| } |
| |
| @Test |
| public void testFsWithDuplicateChildren() throws Exception { |
| Credentials credentials = new Credentials(); |
| Text service = new Text("singleTokenFs1"); |
| |
| MockFileSystem fs = createFileSystemForServiceName(service); |
| MockFileSystem multiFs = |
| createFileSystemForServiceName(null, fs, new FilterFileSystem(fs)); |
| |
| multiFs.addDelegationTokens(renewer, credentials); |
| verifyTokenFetch(multiFs, false); |
| verifyTokenFetch(fs, true); |
| |
| assertEquals(1, credentials.numberOfTokens()); |
| assertNotNull(credentials.getToken(service)); |
| } |
| |
| @Test |
| public void testFsWithDuplicateChildrenTokenExists() throws Exception { |
| Credentials credentials = new Credentials(); |
| Text service = new Text("singleTokenFs1"); |
| Token<?> token = mock(Token.class); |
| credentials.addToken(service, token); |
| |
| MockFileSystem fs = createFileSystemForServiceName(service); |
| MockFileSystem multiFs = |
| createFileSystemForServiceName(null, fs, new FilterFileSystem(fs)); |
| |
| multiFs.addDelegationTokens(renewer, credentials); |
| verifyTokenFetch(multiFs, false); |
| verifyTokenFetch(fs, false); |
| |
| assertEquals(1, credentials.numberOfTokens()); |
| assertSame(token, credentials.getToken(service)); |
| } |
| |
| @Test |
| public void testFsWithChildTokensOneExists() throws Exception { |
| Credentials credentials = new Credentials(); |
| Text service1 = new Text("singleTokenFs1"); |
| Text service2 = new Text("singleTokenFs2"); |
| Token<?> token = mock(Token.class); |
| credentials.addToken(service2, token); |
| |
| MockFileSystem fs1 = createFileSystemForServiceName(service1); |
| MockFileSystem fs2 = createFileSystemForServiceName(service2); |
| MockFileSystem fs3 = createFileSystemForServiceName(null); |
| MockFileSystem multiFs = createFileSystemForServiceName(null, fs1, fs2, fs3); |
| |
| multiFs.addDelegationTokens(renewer, credentials); |
| verifyTokenFetch(multiFs, false); |
| verifyTokenFetch(fs1, true); |
| verifyTokenFetch(fs2, false); // we had added its token to credentials |
| verifyTokenFetch(fs3, false); |
| |
| assertEquals(2, credentials.numberOfTokens()); |
| assertNotNull(credentials.getToken(service1)); |
| assertSame(token, credentials.getToken(service2)); |
| } |
| |
| @Test |
| public void testFsWithMyOwnAndChildTokens() throws Exception { |
| Credentials credentials = new Credentials(); |
| Text service1 = new Text("singleTokenFs1"); |
| Text service2 = new Text("singleTokenFs2"); |
| Text myService = new Text("multiTokenFs"); |
| Token<?> token = mock(Token.class); |
| credentials.addToken(service2, token); |
| |
| MockFileSystem fs1 = createFileSystemForServiceName(service1); |
| MockFileSystem fs2 = createFileSystemForServiceName(service2); |
| MockFileSystem multiFs = createFileSystemForServiceName(myService, fs1, fs2); |
| |
| multiFs.addDelegationTokens(renewer, credentials); |
| verifyTokenFetch(multiFs, true); // its own token and also of its children |
| verifyTokenFetch(fs1, true); |
| verifyTokenFetch(fs2, false); // we had added its token to credentials |
| |
| assertEquals(3, credentials.numberOfTokens()); |
| assertNotNull(credentials.getToken(myService)); |
| assertNotNull(credentials.getToken(service1)); |
| assertNotNull(credentials.getToken(service2)); |
| } |
| |
| |
| @Test |
| public void testFsWithMyOwnExistsAndChildTokens() throws Exception { |
| Credentials credentials = new Credentials(); |
| Text service1 = new Text("singleTokenFs1"); |
| Text service2 = new Text("singleTokenFs2"); |
| Text myService = new Text("multiTokenFs"); |
| Token<?> token = mock(Token.class); |
| credentials.addToken(myService, token); |
| |
| MockFileSystem fs1 = createFileSystemForServiceName(service1); |
| MockFileSystem fs2 = createFileSystemForServiceName(service2); |
| MockFileSystem multiFs = createFileSystemForServiceName(myService, fs1, fs2); |
| |
| multiFs.addDelegationTokens(renewer, credentials); |
| verifyTokenFetch(multiFs, false); // we had added its token to credentials |
| verifyTokenFetch(fs1, true); |
| verifyTokenFetch(fs2, true); |
| |
| assertEquals(3, credentials.numberOfTokens()); |
| assertSame(token, credentials.getToken(myService)); |
| assertNotNull(credentials.getToken(service1)); |
| assertNotNull(credentials.getToken(service2)); |
| } |
| |
| @Test |
| public void testFsWithNestedDuplicatesChildren() throws Exception { |
| Credentials credentials = new Credentials(); |
| Text service1 = new Text("singleTokenFs1"); |
| Text service2 = new Text("singleTokenFs2"); |
| Text service4 = new Text("singleTokenFs4"); |
| Text multiService = new Text("multiTokenFs"); |
| Token<?> token2 = mock(Token.class); |
| credentials.addToken(service2, token2); |
| |
| MockFileSystem fs1 = createFileSystemForServiceName(service1); |
| MockFileSystem fs1B = createFileSystemForServiceName(service1); |
| MockFileSystem fs2 = createFileSystemForServiceName(service2); |
| MockFileSystem fs3 = createFileSystemForServiceName(null); |
| MockFileSystem fs4 = createFileSystemForServiceName(service4); |
| // now let's get dirty! ensure dup tokens aren't fetched even when |
| // repeated and dupped in a nested fs. fs4 is a real test of the drill |
| // down: multi-filter-multi-filter-filter-fs4. |
| MockFileSystem multiFs = createFileSystemForServiceName(multiService, |
| fs1, fs1B, fs2, fs2, new FilterFileSystem(fs3), |
| new FilterFileSystem(new FilterFileSystem(fs4))); |
| MockFileSystem superMultiFs = createFileSystemForServiceName(null, |
| fs1, fs1B, fs1, new FilterFileSystem(fs3), new FilterFileSystem(multiFs)); |
| superMultiFs.addDelegationTokens(renewer, credentials); |
| verifyTokenFetch(superMultiFs, false); // does not have its own token |
| verifyTokenFetch(multiFs, true); // has its own token |
| verifyTokenFetch(fs1, true); |
| verifyTokenFetch(fs2, false); // we had added its token to credentials |
| verifyTokenFetch(fs3, false); // has no tokens |
| verifyTokenFetch(fs4, true); |
| |
| assertEquals(4, credentials.numberOfTokens()); //fs1+fs2+fs4+multifs (fs3=0) |
| assertNotNull(credentials.getToken(service1)); |
| assertNotNull(credentials.getToken(service2)); |
| assertSame(token2, credentials.getToken(service2)); |
| assertNotNull(credentials.getToken(multiService)); |
| assertNotNull(credentials.getToken(service4)); |
| } |
| |
| public static MockFileSystem createFileSystemForServiceName( |
| final Text service, final FileSystem... children) throws IOException { |
| final MockFileSystem fs = new MockFileSystem(); |
| final MockFileSystem mockFs = fs.getRawFileSystem(); |
| if (service != null) { |
| when(mockFs.getCanonicalServiceName()).thenReturn(service.toString()); |
| when(mockFs.getDelegationToken(any(String.class))).thenAnswer( |
| new Answer<Token<?>>() { |
| @Override |
| public Token<?> answer(InvocationOnMock invocation) throws Throwable { |
| Token<?> token = new Token<TokenIdentifier>(); |
| token.setService(service); |
| return token; |
| } |
| }); |
| } |
| when(mockFs.getChildFileSystems()).thenReturn(children); |
| return fs; |
| } |
| |
| // check that canonical name was requested, if renewer is not null that |
| // a token was requested, and that child fs was invoked |
| private void verifyTokenFetch(MockFileSystem fs, boolean expected) throws IOException { |
| verify(fs.getRawFileSystem(), atLeast(1)).getCanonicalServiceName(); |
| if (expected) { |
| verify(fs.getRawFileSystem()).getDelegationToken(renewer); |
| } else { |
| verify(fs.getRawFileSystem(), never()).getDelegationToken(any(String.class)); |
| } |
| verify(fs.getRawFileSystem(), atLeast(1)).getChildFileSystems(); |
| } |
| } |