Basic.java revision 893:f06f30b29f36
1/*
2 * Copyright 2008-2009 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24/* @test
25 * @bug 4313887
26 * @summary Unit test for java.nio.file.attribute.PosixFileAttributeView
27 * @library ../..
28 */
29
30import java.nio.file.*;
31import static java.nio.file.LinkOption.*;
32import java.nio.file.attribute.*;
33import java.io.IOException;
34import java.util.*;
35
36/**
37 * Unit test for PosixFileAttributeView, passing silently if this attribute
38 * view is not available.
39 */
40
41public class Basic {
42
43    /**
44     * Use view to update permission to the given mode and check that the
45     * permissions have been updated.
46     */
47    static void testPermissions(PosixFileAttributeView view, String mode)
48        throws IOException
49    {
50        System.out.format("change mode: %s\n", mode);
51        Set<PosixFilePermission> perms = PosixFilePermissions.fromString(mode);
52
53        // change permissions and re-read them.
54        view.setPermissions(perms);
55        Set<PosixFilePermission> current = view.readAttributes().permissions();
56        if (!current.equals(perms)) {
57            throw new RuntimeException("Actual permissions: " +
58                PosixFilePermissions.toString(current) + ", expected: " +
59                PosixFilePermissions.toString(perms));
60        }
61
62        // repeat test using setAttribute/getAttribute
63        view.setAttribute("permissions", perms);
64        current = (Set<PosixFilePermission>)view.getAttribute("permissions");
65        if (!current.equals(perms)) {
66            throw new RuntimeException("Actual permissions: " +
67                PosixFilePermissions.toString(current) + ", expected: " +
68                PosixFilePermissions.toString(perms));
69        }
70    }
71
72    /**
73     * Check that the actual permissions of a file match or make it more
74     * secure than requested
75     */
76    static void checkSecure(Set<PosixFilePermission> requested,
77                            Set<PosixFilePermission> actual)
78    {
79        for (PosixFilePermission perm: actual) {
80            if (!requested.contains(perm)) {
81                throw new RuntimeException("Actual permissions: " +
82                    PosixFilePermissions.toString(actual) + ", requested: " +
83                    PosixFilePermissions.toString(requested) +
84                    " - file is less secure than requested");
85            }
86        }
87    }
88
89    /**
90     * Create file with given mode and check that the file is created with a
91     * mode that is not less secure
92     */
93    static void createWithPermissions(Path file,
94                                      String mode)
95        throws IOException
96    {
97        Set<PosixFilePermission> requested = PosixFilePermissions.fromString(mode);
98        FileAttribute<Set<PosixFilePermission>> attr =
99            PosixFilePermissions.asFileAttribute(requested);
100        System.out.format("create file with mode: %s\n", mode);
101
102        EnumSet<StandardOpenOption> options = EnumSet.of(StandardOpenOption.CREATE_NEW,
103            StandardOpenOption.WRITE);
104        file.newOutputStream(options, attr).close();
105        try {
106            checkSecure(requested,  file
107                .getFileAttributeView(PosixFileAttributeView.class)
108                .readAttributes()
109                .permissions());
110        } finally {
111            file.delete(false);
112        }
113
114        System.out.format("create directory with mode: %s\n", mode);
115        file.createDirectory(attr);
116        try {
117            checkSecure(requested,  file
118                .getFileAttributeView(PosixFileAttributeView.class)
119                .readAttributes()
120                .permissions());
121        } finally {
122            file.delete(false);
123        }
124    }
125
126    /**
127     * Test the setPermissions/permissions methods.
128     */
129    static void permissionTests(Path dir)
130        throws IOException
131    {
132        System.out.println("-- Permission Tests  --");
133
134        // create file and test updating and reading its permissions
135        Path file = dir.resolve("foo");
136        System.out.format("create %s\n", file);
137        file.newOutputStream().close();
138        try {
139            // get initial permissions so that we can restore them later
140            PosixFileAttributeView view = file
141                .getFileAttributeView(PosixFileAttributeView.class);
142            Set<PosixFilePermission> save = view.readAttributes()
143                .permissions();
144
145            // test various modes
146            try {
147                testPermissions(view, "---------");
148                testPermissions(view, "r--------");
149                testPermissions(view, "-w-------");
150                testPermissions(view, "--x------");
151                testPermissions(view, "rwx------");
152                testPermissions(view, "---r-----");
153                testPermissions(view, "----w----");
154                testPermissions(view, "-----x---");
155                testPermissions(view, "---rwx---");
156                testPermissions(view, "------r--");
157                testPermissions(view, "-------w-");
158                testPermissions(view, "--------x");
159                testPermissions(view, "------rwx");
160                testPermissions(view, "r--r-----");
161                testPermissions(view, "r--r--r--");
162                testPermissions(view, "rw-rw----");
163                testPermissions(view, "rwxrwx---");
164                testPermissions(view, "rw-rw-r--");
165                testPermissions(view, "r-xr-x---");
166                testPermissions(view, "r-xr-xr-x");
167                testPermissions(view, "rwxrwxrwx");
168            } finally {
169                view.setPermissions(save);
170            }
171        } finally {
172            file.delete(false);
173        }
174
175        // create link (to file that doesn't exist) and test reading of
176        // permissions
177        if (TestUtil.supportsLinks(dir)) {
178            Path link = dir.resolve("link");
179            System.out.format("create link %s\n", link);
180            link.createSymbolicLink(file);
181            try {
182                PosixFileAttributes attrs = Attributes
183                    .readPosixFileAttributes(link, NOFOLLOW_LINKS);
184                if (!attrs.isSymbolicLink()) {
185                    throw new RuntimeException("not a link");
186                }
187            } finally {
188                link.delete(false);
189            }
190        }
191
192        System.out.println("OKAY");
193    }
194
195    /**
196     * Test creating a file and directory with initial permissios
197     */
198    static void createTests(Path dir)
199        throws IOException
200    {
201        System.out.println("-- Create Tests  --");
202
203        Path file = dir.resolve("foo");
204
205        createWithPermissions(file, "---------");
206        createWithPermissions(file, "r--------");
207        createWithPermissions(file, "-w-------");
208        createWithPermissions(file, "--x------");
209        createWithPermissions(file, "rwx------");
210        createWithPermissions(file, "---r-----");
211        createWithPermissions(file, "----w----");
212        createWithPermissions(file, "-----x---");
213        createWithPermissions(file, "---rwx---");
214        createWithPermissions(file, "------r--");
215        createWithPermissions(file, "-------w-");
216        createWithPermissions(file, "--------x");
217        createWithPermissions(file, "------rwx");
218        createWithPermissions(file, "r--r-----");
219        createWithPermissions(file, "r--r--r--");
220        createWithPermissions(file, "rw-rw----");
221        createWithPermissions(file, "rwxrwx---");
222        createWithPermissions(file, "rw-rw-r--");
223        createWithPermissions(file, "r-xr-x---");
224        createWithPermissions(file, "r-xr-xr-x");
225        createWithPermissions(file, "rwxrwxrwx");
226
227        System.out.println("OKAY");
228    }
229
230    /**
231     * Test setOwner/setGroup methods - this test simply exercises the
232     * methods to avoid configuration.
233     */
234    static void ownerTests(Path dir)
235        throws IOException
236    {
237        System.out.println("-- Owner Tests  --");
238
239        Path file = dir.resolve("gus");
240        System.out.format("create %s\n", file);
241
242        file.newOutputStream().close();
243        try {
244
245            // read attributes of directory to get owner/group
246            PosixFileAttributeView view = file
247                .getFileAttributeView(PosixFileAttributeView.class);
248            PosixFileAttributes attrs = view.readAttributes();
249
250            // set to existing owner/group
251            view.setOwner(attrs.owner());
252            view.setGroup(attrs.group());
253
254            // repeat test using setAttribute
255            Map<String,?> map = view.readAttributes("owner","group");
256            view.setAttribute("owner", map.get("owner"));
257            view.setAttribute("group", map.get("group"));
258
259        } finally {
260            file.delete(false);
261        }
262
263        System.out.println("OKAY");
264    }
265
266    /**
267     * Test the lookupPrincipalByName/lookupPrincipalByGroupName methods
268     */
269    static void lookupPrincipalTests(Path dir)
270        throws IOException
271    {
272        System.out.println("-- Lookup UserPrincipal Tests --");
273
274        UserPrincipalLookupService lookupService = dir.getFileSystem()
275            .getUserPrincipalLookupService();
276
277        // read attributes of directory to get owner/group
278        PosixFileAttributes attrs = Attributes.readPosixFileAttributes(dir);
279
280        // lookup owner and check it matches file's owner
281        System.out.format("lookup: %s\n", attrs.owner().getName());
282        try {
283            UserPrincipal owner = lookupService.lookupPrincipalByName(attrs.owner().getName());
284            if (owner instanceof GroupPrincipal)
285                throw new RuntimeException("owner is a group?");
286            if (!owner.equals(attrs.owner()))
287                throw new RuntimeException("owner different from file owner");
288        } catch (UserPrincipalNotFoundException x) {
289            System.out.println("user not found - test skipped");
290        }
291
292        // lookup group and check it matches file's group-owner
293        System.out.format("lookup group: %s\n", attrs.group().getName());
294        try {
295            GroupPrincipal group = lookupService.lookupPrincipalByGroupName(attrs.group().getName());
296            if (!group.equals(attrs.group()))
297                throw new RuntimeException("group different from file group-owner");
298        } catch (UserPrincipalNotFoundException x) {
299            System.out.println("group not found - test skipped");
300        }
301
302        // test that UserPrincipalNotFoundException is thrown
303        String invalidPrincipal = "scumbag99";
304        try {
305            System.out.format("lookup: %s\n", invalidPrincipal);
306            lookupService.lookupPrincipalByName(invalidPrincipal);
307            throw new RuntimeException("'" + invalidPrincipal + "' is a valid user?");
308        } catch (UserPrincipalNotFoundException x) {
309        }
310        try {
311            System.out.format("lookup group: %s\n", invalidPrincipal);
312            lookupService.lookupPrincipalByGroupName("idonotexist");
313            throw new RuntimeException("'" + invalidPrincipal + "' is a valid group?");
314        } catch (UserPrincipalNotFoundException x) {
315        }
316        System.out.println("OKAY");
317    }
318
319    /**
320     * Test various exceptions are thrown as expected
321     */
322    @SuppressWarnings("unchecked")
323    static void exceptionsTests(Path dir)
324        throws IOException
325    {
326        System.out.println("-- Exceptions --");
327
328        PosixFileAttributeView view = dir
329            .getFileAttributeView(PosixFileAttributeView.class);
330
331        // NullPointerException
332        try {
333            view.setOwner(null);
334            throw new RuntimeException("NullPointerException not thrown");
335        } catch (NullPointerException x) {
336        }
337        try {
338            view.setGroup(null);
339            throw new RuntimeException("NullPointerException not thrown");
340        } catch (NullPointerException x) {
341        }
342
343        UserPrincipalLookupService lookupService = dir.getFileSystem()
344            .getUserPrincipalLookupService();
345        try {
346            lookupService.lookupPrincipalByName(null);
347            throw new RuntimeException("NullPointerException not thrown");
348        } catch (NullPointerException x) {
349        }
350        try {
351            lookupService.lookupPrincipalByGroupName(null);
352            throw new RuntimeException("NullPointerException not thrown");
353        } catch (NullPointerException x) {
354        }
355        try {
356            view.setPermissions(null);
357            throw new RuntimeException("NullPointerException not thrown");
358        } catch (NullPointerException x) {
359        }
360        try {
361            Set<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
362            perms.add(null);
363            view.setPermissions(perms);
364            throw new RuntimeException("NullPointerException not thrown");
365        }  catch (NullPointerException x) {
366        }
367
368        // ClassCastException
369        try {
370            Set perms = new HashSet();  // raw type
371            perms.add(new Object());
372            view.setPermissions(perms);
373            throw new RuntimeException("ClassCastException not thrown");
374        }  catch (ClassCastException x) {
375        }
376
377        System.out.println("OKAY");
378    }
379
380    public static void main(String[] args) throws IOException {
381        Path dir = TestUtil.createTemporaryDirectory();
382        try {
383            if (!dir.getFileStore().supportsFileAttributeView("posix")) {
384                System.out.println("PosixFileAttributeView not supported");
385                return;
386            }
387
388            permissionTests(dir);
389            createTests(dir);
390            ownerTests(dir);
391            lookupPrincipalTests(dir);
392            exceptionsTests(dir);
393
394        } finally {
395            TestUtil.removeAll(dir);
396        }
397    }
398}
399