alluxio-master-2.x/core/client/fs/src/test/java/alluxio/client/file/FileSystemCacheTest.java
/*
 * 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.client.file;

import static alluxio.client.file.FileSystemCache.Key;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;

import alluxio.AlluxioURI;
import alluxio.conf.Configuration;
import alluxio.exception.AlluxioException;
import alluxio.security.User;

import org.junit.Test;

import java.io.IOException;
import java.security.Principal;
import java.util.HashSet;
import java.util.Set;
import javax.security.auth.Subject;

public class FileSystemCacheTest {
  private FileSystemCache mFileSystemCache = new FileSystemCache();

  // Helper method to get the underlying delegated file system from cache
  private FileSystem getDelegatedFileSystem(FileSystem fs) {
    return ((FileSystemCache.InstanceCachingFileSystem) fs).mDelegatedFileSystem;
  }

  @Test
  public void getSameKey() {
    Key key1 = createTestFSKey("user1");
    FileSystem fs1 = mFileSystemCache.get(key1);
    FileSystem fs2 = mFileSystemCache.get(key1);
    assertSame(getDelegatedFileSystem(fs1), getDelegatedFileSystem(fs2));
    assertFalse(fs1.isClosed());
    assertFalse(fs2.isClosed());
  }

  @Test
  public void getDifferentKeys() {
    Key key1 = createTestFSKey("user1");
    Key key2 = createTestFSKey("user2");
    FileSystem fs1 = mFileSystemCache.get(key1);
    FileSystem fs2 = mFileSystemCache.get(key2);
    assertNotSame(getDelegatedFileSystem(fs1), getDelegatedFileSystem(fs2));
    assertFalse(fs1.isClosed());
    assertFalse(fs2.isClosed());
  }

  @Test
  public void getThenClose() throws IOException {
    Key key1 = createTestFSKey("user1");
    FileSystem fs1 = mFileSystemCache.get(key1);
    fs1.close();
    FileSystem fs2 = mFileSystemCache.get(key1);
    assertNotSame(getDelegatedFileSystem(fs1), getDelegatedFileSystem(fs2));
    assertTrue(fs1.isClosed());
    assertFalse(fs2.isClosed());
  }

  @Test
  public void getTwiceThenClose() throws IOException {
    Key key1 = createTestFSKey("user1");
    FileSystem fs1 = mFileSystemCache.get(key1);
    FileSystem fs2 = mFileSystemCache.get(key1);
    fs1.close();
    FileSystem fs3 = mFileSystemCache.get(key1);
    assertSame(getDelegatedFileSystem(fs2), getDelegatedFileSystem(fs3));
    assertTrue(fs1.isClosed());
    assertFalse(fs2.isClosed());
    assertFalse(fs3.isClosed());
  }

  @Test
  public void getTwiceThenClose2() throws IOException {
    Key key1 = createTestFSKey("user1");
    FileSystem fs1 = mFileSystemCache.get(key1);
    FileSystem fs2 = mFileSystemCache.get(key1);
    assertSame(getDelegatedFileSystem(fs1), getDelegatedFileSystem(fs2));
    fs1.close();
    assertTrue(fs1.isClosed());
    assertFalse(fs2.isClosed());
    fs2.close();
    assertTrue(fs1.isClosed());
    assertTrue(fs2.isClosed());
  }

  @Test
  public void doubleClose() throws IOException {
    Key key1 = createTestFSKey("user1");
    FileSystem fs1 = mFileSystemCache.get(key1);
    FileSystem fs2 = mFileSystemCache.get(key1);
    assertSame(getDelegatedFileSystem(fs1), getDelegatedFileSystem(fs2));
    fs1.close();
    assertTrue(fs1.isClosed());
    assertFalse(fs2.isClosed());
    fs1.close();
    assertTrue(fs1.isClosed());
    assertFalse(fs2.isClosed());
  }

  @Test
  public void listStatusClosed() throws IOException, AlluxioException {
    Exception e = assertThrows(IOException.class, () -> {
      Key key1 = createTestFSKey("user1");
      FileSystem fs1 = mFileSystemCache.get(key1);
      fs1.close();
      assertTrue(fs1.isClosed());
      fs1.listStatus(new AlluxioURI("/"));
    });
    assertTrue(e.getMessage()
        .contains(FileSystemCache.InstanceCachingFileSystem.CLOSED_FS_ERROR_MESSAGE));
  }

  private Key createTestFSKey(String username) {
    User user = new User(username);
    Set<Principal> principals = new HashSet<>();
    principals.add(user);
    return new FileSystemCache.Key(
        new Subject(false, principals, new HashSet<>(), new HashSet<>()),
        Configuration.global());
  }
}
