Home | History | Annotate | Download | only in attribute
      1 /*
      2  * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
      3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      4  *
      5  * This code is free software; you can redistribute it and/or modify it
      6  * under the terms of the GNU General Public License version 2 only, as
      7  * published by the Free Software Foundation.
      8  *
      9  * This code is distributed in the hope that it will be useful, but WITHOUT
     10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     12  * version 2 for more details (a copy is included in the LICENSE file that
     13  * accompanied this code).
     14  *
     15  * You should have received a copy of the GNU General Public License version
     16  * 2 along with this work; if not, write to the Free Software Foundation,
     17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     18  *
     19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     20  * or visit www.oracle.com if you need additional information or have any
     21  * questions.
     22  */
     23 
     24 /* @test
     25  * @bug 4313887 6838333
     26  * @summary Unit test for java.nio.file.attribute.PosixFileAttributeView
     27  * @library ../..
     28  */
     29 // Android-changed: Adapted from
     30 // jdk/test/java/nio/file/attribute/PosixFileAttributeView/Basic.java
     31 // Android-changed: Added package & Test import
     32 package test.java.nio.file.attribute;
     33 import org.testng.annotations.Test;
     34 import test.java.nio.file.TestUtil;
     35 
     36 import java.nio.file.*;
     37 import static java.nio.file.LinkOption.*;
     38 import java.nio.file.attribute.*;
     39 import java.io.IOException;
     40 import java.util.*;
     41 
     42 /**
     43  * Unit test for PosixFileAttributeView, passing silently if this attribute
     44  * view is not available.
     45  */
     46 
     47 // Android-changed: Renamed from "Basic"
     48 public class PosixFileAttributeViewTest {
     49 
     50     /**
     51      * Use view to update permission to the given mode and check that the
     52      * permissions have been updated.
     53      */
     54     static void testPermissions(Path file, String mode) throws IOException {
     55         System.out.format("change mode: %s\n", mode);
     56         Set<PosixFilePermission> perms = PosixFilePermissions.fromString(mode);
     57 
     58         // change permissions and re-read them.
     59         Files.setPosixFilePermissions(file, perms);
     60         Set<PosixFilePermission> current = Files.getPosixFilePermissions(file);
     61         if (!current.equals(perms)) {
     62             throw new RuntimeException("Actual permissions: " +
     63                 PosixFilePermissions.toString(current) + ", expected: " +
     64                 PosixFilePermissions.toString(perms));
     65         }
     66 
     67         // repeat test using setAttribute/getAttribute
     68         Files.setAttribute(file, "posix:permissions", perms);
     69         current = (Set<PosixFilePermission>)Files.getAttribute(file, "posix:permissions");
     70         if (!current.equals(perms)) {
     71             throw new RuntimeException("Actual permissions: " +
     72                 PosixFilePermissions.toString(current) + ", expected: " +
     73                 PosixFilePermissions.toString(perms));
     74         }
     75     }
     76 
     77     /**
     78      * Check that the actual permissions of a file match or make it more
     79      * secure than requested
     80      */
     81     static void checkSecure(Set<PosixFilePermission> requested,
     82                             Set<PosixFilePermission> actual)
     83     {
     84         for (PosixFilePermission perm: actual) {
     85             if (!requested.contains(perm)) {
     86                 throw new RuntimeException("Actual permissions: " +
     87                     PosixFilePermissions.toString(actual) + ", requested: " +
     88                     PosixFilePermissions.toString(requested) +
     89                     " - file is less secure than requested");
     90             }
     91         }
     92     }
     93 
     94     /**
     95      * Create file with given mode and check that the file is created with a
     96      * mode that is not less secure
     97      */
     98     static void createWithPermissions(Path file,
     99                                       String mode)
    100         throws IOException
    101     {
    102         Set<PosixFilePermission> requested = PosixFilePermissions.fromString(mode);
    103         FileAttribute<Set<PosixFilePermission>> attr =
    104             PosixFilePermissions.asFileAttribute(requested);
    105         System.out.format("create file with mode: %s\n", mode);
    106         Files.createFile(file, attr);
    107         try {
    108             checkSecure(requested,
    109                 Files.getFileAttributeView(file, PosixFileAttributeView.class)
    110                      .readAttributes()
    111                      .permissions());
    112         } finally {
    113             Files.delete(file);
    114         }
    115 
    116         System.out.format("create directory with mode: %s\n", mode);
    117         Files.createDirectory(file, attr);
    118         try {
    119             checkSecure(requested,
    120                 Files.getFileAttributeView(file, PosixFileAttributeView.class)
    121                      .readAttributes()
    122                      .permissions());
    123         } finally {
    124             Files.delete(file);
    125         }
    126     }
    127 
    128     /**
    129      * Test the setPermissions/permissions methods.
    130      */
    131     static void permissionTests(Path dir)
    132         throws IOException
    133     {
    134         System.out.println("-- Permission Tests  --");
    135 
    136         // create file and test updating and reading its permissions
    137         Path file = dir.resolve("foo");
    138         System.out.format("create %s\n", file);
    139         Files.createFile(file);
    140         try {
    141             // get initial permissions so that we can restore them later
    142             PosixFileAttributeView view =
    143                 Files.getFileAttributeView(file, PosixFileAttributeView.class);
    144             Set<PosixFilePermission> save = view.readAttributes()
    145                 .permissions();
    146 
    147             // test various modes
    148             try {
    149                 testPermissions(file, "---------");
    150                 testPermissions(file, "r--------");
    151                 testPermissions(file, "-w-------");
    152                 testPermissions(file, "--x------");
    153                 testPermissions(file, "rwx------");
    154                 testPermissions(file, "---r-----");
    155                 testPermissions(file, "----w----");
    156                 testPermissions(file, "-----x---");
    157                 testPermissions(file, "---rwx---");
    158                 testPermissions(file, "------r--");
    159                 testPermissions(file, "-------w-");
    160                 testPermissions(file, "--------x");
    161                 testPermissions(file, "------rwx");
    162                 testPermissions(file, "r--r-----");
    163                 testPermissions(file, "r--r--r--");
    164                 testPermissions(file, "rw-rw----");
    165                 testPermissions(file, "rwxrwx---");
    166                 testPermissions(file, "rw-rw-r--");
    167                 testPermissions(file, "r-xr-x---");
    168                 testPermissions(file, "r-xr-xr-x");
    169                 testPermissions(file, "rwxrwxrwx");
    170             } finally {
    171                 view.setPermissions(save);
    172             }
    173         } finally {
    174             Files.delete(file);
    175         }
    176 
    177         // create link (to file that doesn't exist) and test reading of
    178         // permissions
    179         if (TestUtil.supportsLinks(dir)) {
    180             Path link = dir.resolve("link");
    181             System.out.format("create link %s\n", link);
    182             Files.createSymbolicLink(link, file);
    183             try {
    184                 PosixFileAttributes attrs =
    185                     Files.getFileAttributeView(link,
    186                                                PosixFileAttributeView.class,
    187                                                NOFOLLOW_LINKS)
    188                          .readAttributes();
    189                 if (!attrs.isSymbolicLink()) {
    190                     throw new RuntimeException("not a link");
    191                 }
    192             } finally {
    193                 Files.delete(link);
    194             }
    195         }
    196 
    197         System.out.println("OKAY");
    198     }
    199 
    200     /**
    201      * Test creating a file and directory with initial permissios
    202      */
    203     static void createTests(Path dir)
    204         throws IOException
    205     {
    206         System.out.println("-- Create Tests  --");
    207 
    208         Path file = dir.resolve("foo");
    209 
    210         createWithPermissions(file, "---------");
    211         createWithPermissions(file, "r--------");
    212         createWithPermissions(file, "-w-------");
    213         createWithPermissions(file, "--x------");
    214         createWithPermissions(file, "rwx------");
    215         createWithPermissions(file, "---r-----");
    216         createWithPermissions(file, "----w----");
    217         createWithPermissions(file, "-----x---");
    218         createWithPermissions(file, "---rwx---");
    219         createWithPermissions(file, "------r--");
    220         createWithPermissions(file, "-------w-");
    221         createWithPermissions(file, "--------x");
    222         createWithPermissions(file, "------rwx");
    223         createWithPermissions(file, "r--r-----");
    224         createWithPermissions(file, "r--r--r--");
    225         createWithPermissions(file, "rw-rw----");
    226         createWithPermissions(file, "rwxrwx---");
    227         createWithPermissions(file, "rw-rw-r--");
    228         createWithPermissions(file, "r-xr-x---");
    229         createWithPermissions(file, "r-xr-xr-x");
    230         createWithPermissions(file, "rwxrwxrwx");
    231 
    232         System.out.println("OKAY");
    233     }
    234 
    235     /**
    236      * Test setOwner/setGroup methods - this test simply exercises the
    237      * methods to avoid configuration.
    238      */
    239     static void ownerTests(Path dir)
    240         throws IOException
    241     {
    242         System.out.println("-- Owner Tests  --");
    243 
    244         Path file = dir.resolve("gus");
    245         System.out.format("create %s\n", file);
    246 
    247         Files.createFile(file);
    248         try {
    249 
    250             // read attributes of directory to get owner/group
    251             PosixFileAttributeView view =
    252                 Files.getFileAttributeView(file, PosixFileAttributeView.class);
    253             PosixFileAttributes attrs = view.readAttributes();
    254 
    255             // set to existing owner/group
    256             view.setOwner(attrs.owner());
    257             view.setGroup(attrs.group());
    258 
    259             // repeat test using set/getAttribute
    260             UserPrincipal owner = (UserPrincipal)Files.getAttribute(file, "posix:owner");
    261             Files.setAttribute(file, "posix:owner", owner);
    262             UserPrincipal group = (UserPrincipal)Files.getAttribute(file, "posix:group");
    263             Files.setAttribute(file, "posix:group", group);
    264 
    265         } finally {
    266             Files.delete(file);
    267         }
    268 
    269         System.out.println("OKAY");
    270     }
    271 
    272     /**
    273      * Test the lookupPrincipalByName/lookupPrincipalByGroupName methods
    274      */
    275     static void lookupPrincipalTests(Path dir)
    276         throws IOException
    277     {
    278         System.out.println("-- Lookup UserPrincipal Tests --");
    279 
    280         UserPrincipalLookupService lookupService = dir.getFileSystem()
    281             .getUserPrincipalLookupService();
    282 
    283         // read attributes of directory to get owner/group
    284         PosixFileAttributes attrs = Files.readAttributes(dir, PosixFileAttributes.class);
    285 
    286         // lookup owner and check it matches file's owner
    287         System.out.format("lookup: %s\n", attrs.owner().getName());
    288         try {
    289             UserPrincipal owner = lookupService.lookupPrincipalByName(attrs.owner().getName());
    290             if (owner instanceof GroupPrincipal)
    291                 throw new RuntimeException("owner is a group?");
    292             if (!owner.equals(attrs.owner()))
    293                 throw new RuntimeException("owner different from file owner");
    294         } catch (UserPrincipalNotFoundException x) {
    295             System.out.println("user not found - test skipped");
    296         }
    297 
    298         // lookup group and check it matches file's group-owner
    299         System.out.format("lookup group: %s\n", attrs.group().getName());
    300         try {
    301             GroupPrincipal group = lookupService.lookupPrincipalByGroupName(attrs.group().getName());
    302             if (!group.equals(attrs.group()))
    303                 throw new RuntimeException("group different from file group-owner");
    304         } catch (UserPrincipalNotFoundException x) {
    305             System.out.println("group not found - test skipped");
    306         }
    307 
    308         // test that UserPrincipalNotFoundException is thrown
    309         String invalidPrincipal = "scumbag99";
    310         try {
    311             System.out.format("lookup: %s\n", invalidPrincipal);
    312             lookupService.lookupPrincipalByName(invalidPrincipal);
    313             throw new RuntimeException("'" + invalidPrincipal + "' is a valid user?");
    314         } catch (UserPrincipalNotFoundException x) {
    315         }
    316         try {
    317             System.out.format("lookup group: %s\n", invalidPrincipal);
    318             lookupService.lookupPrincipalByGroupName("idonotexist");
    319             throw new RuntimeException("'" + invalidPrincipal + "' is a valid group?");
    320         } catch (UserPrincipalNotFoundException x) {
    321         }
    322         System.out.println("OKAY");
    323     }
    324 
    325     /**
    326      * Test various exceptions are thrown as expected
    327      */
    328     @SuppressWarnings("unchecked")
    329     static void exceptionsTests(Path dir)
    330         throws IOException
    331     {
    332         System.out.println("-- Exceptions --");
    333 
    334         PosixFileAttributeView view =
    335             Files.getFileAttributeView(dir,PosixFileAttributeView.class);
    336 
    337         // NullPointerException
    338         try {
    339             view.setOwner(null);
    340             throw new RuntimeException("NullPointerException not thrown");
    341         } catch (NullPointerException x) {
    342         }
    343         try {
    344             view.setGroup(null);
    345             throw new RuntimeException("NullPointerException not thrown");
    346         } catch (NullPointerException x) {
    347         }
    348 
    349         UserPrincipalLookupService lookupService = dir.getFileSystem()
    350             .getUserPrincipalLookupService();
    351         try {
    352             lookupService.lookupPrincipalByName(null);
    353             throw new RuntimeException("NullPointerException not thrown");
    354         } catch (NullPointerException x) {
    355         }
    356         try {
    357             lookupService.lookupPrincipalByGroupName(null);
    358             throw new RuntimeException("NullPointerException not thrown");
    359         } catch (NullPointerException x) {
    360         }
    361         try {
    362             view.setPermissions(null);
    363             throw new RuntimeException("NullPointerException not thrown");
    364         } catch (NullPointerException x) {
    365         }
    366         try {
    367             Set<PosixFilePermission> perms = new HashSet<>();
    368             perms.add(null);
    369             view.setPermissions(perms);
    370             throw new RuntimeException("NullPointerException not thrown");
    371         }  catch (NullPointerException x) {
    372         }
    373 
    374         // ClassCastException
    375         try {
    376             Set perms = new HashSet();  // raw type
    377             perms.add(new Object());
    378             view.setPermissions(perms);
    379             throw new RuntimeException("ClassCastException not thrown");
    380         }  catch (ClassCastException x) {
    381         }
    382 
    383         System.out.println("OKAY");
    384     }
    385 
    386     // Android-changed: Removed args & added @Test
    387     @Test
    388     public static void main() throws IOException {
    389         Path dir = TestUtil.createTemporaryDirectory();
    390         try {
    391             // Android-changed: PosixFileAttributeViews are unconditionally supported in
    392             // all writeable partitions.
    393             //
    394             // if (!Files.getFileStore(dir).supportsFileAttributeView("posix")) {
    395             //     System.out.println("PosixFileAttributeView not supported");
    396             //     return;
    397             // }
    398 
    399             permissionTests(dir);
    400             createTests(dir);
    401             ownerTests(dir);
    402             lookupPrincipalTests(dir);
    403             exceptionsTests(dir);
    404 
    405         } finally {
    406             TestUtil.removeAll(dir);
    407         }
    408     }
    409 }
    410