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 7006126 7023034
26 * @summary Unit test for Files.createTempXXX
27 * @library ..
28 */
29
30import java.nio.file.*;
31import static java.nio.file.StandardOpenOption.*;
32import java.nio.file.attribute.*;
33import java.io.IOException;
34import java.util.Set;
35
36public class TemporaryFiles {
37
38    static void checkInDirectory(Path file, Path dir) {
39        if (dir == null)
40            dir = Paths.get(System.getProperty("java.io.tmpdir"));
41        if (!file.getParent().equals(dir))
42            throw new RuntimeException("Not in expected directory");
43    }
44
45    static void testTempFile(String prefix, String suffix, Path dir)
46        throws IOException
47    {
48        Path file = (dir == null) ?
49            Files.createTempFile(prefix, suffix) :
50            Files.createTempFile(dir, prefix, suffix);
51        try {
52            // check file name
53            String name = file.getFileName().toString();
54            if (prefix != null && !name.startsWith(prefix))
55                throw new RuntimeException("Should start with " + prefix);
56            if (suffix == null && !name.endsWith(".tmp"))
57                throw new RuntimeException("Should end with .tmp");
58            if (suffix != null && !name.endsWith(suffix))
59                throw new RuntimeException("Should end with " + suffix);
60
61            // check file is in expected directory
62            checkInDirectory(file, dir);
63
64            // check that file can be opened for reading and writing
65            Files.newByteChannel(file, READ).close();
66            Files.newByteChannel(file, WRITE).close();
67            Files.newByteChannel(file, READ,WRITE).close();
68
69            // check file permissions are 0600 or more secure
70            if (Files.getFileStore(file).supportsFileAttributeView("posix")) {
71                Set<PosixFilePermission> perms = Files.getPosixFilePermissions(file);
72                perms.remove(PosixFilePermission.OWNER_READ);
73                perms.remove(PosixFilePermission.OWNER_WRITE);
74                if (!perms.isEmpty())
75                    throw new RuntimeException("Temporary file is not secure");
76            }
77        } finally {
78            Files.delete(file);
79        }
80    }
81
82    static void testTempFile(String prefix, String suffix)
83        throws IOException
84    {
85        testTempFile(prefix, suffix, null);
86    }
87
88    static void testTempDirectory(String prefix, Path dir) throws IOException {
89        Path subdir = (dir == null) ?
90            Files.createTempDirectory(prefix) :
91            Files.createTempDirectory(dir, prefix);
92        try {
93            // check file name
94            String name = subdir.getFileName().toString();
95            if (prefix != null && !name.startsWith(prefix))
96                throw new RuntimeException("Should start with " + prefix);
97
98            // check directory is in expected directory
99            checkInDirectory(subdir, dir);
100
101            // check directory is empty
102            DirectoryStream<Path> stream = Files.newDirectoryStream(subdir);
103            try {
104                if (stream.iterator().hasNext())
105                    throw new RuntimeException("Tempory directory not empty");
106            } finally {
107                stream.close();
108            }
109
110            // check that we can create file in directory
111            Path file = Files.createFile(subdir.resolve("foo"));
112            try {
113                Files.newByteChannel(file, READ,WRITE).close();
114            } finally {
115                Files.delete(file);
116            }
117
118            // check file permissions are 0700 or more secure
119            if (Files.getFileStore(subdir).supportsFileAttributeView("posix")) {
120                Set<PosixFilePermission> perms = Files.getPosixFilePermissions(subdir);
121                perms.remove(PosixFilePermission.OWNER_READ);
122                perms.remove(PosixFilePermission.OWNER_WRITE);
123                perms.remove(PosixFilePermission.OWNER_EXECUTE);
124                if (!perms.isEmpty())
125                    throw new RuntimeException("Temporary directory is not secure");
126            }
127        } finally {
128            Files.delete(subdir);
129        }
130    }
131
132    static void testTempDirectory(String prefix) throws IOException {
133        testTempDirectory(prefix, null);
134    }
135
136    static void testInvalidFileTemp(String prefix, String suffix) throws IOException {
137        try {
138            Path file = Files.createTempFile(prefix, suffix);
139            Files.delete(file);
140            throw new RuntimeException("IllegalArgumentException expected");
141        } catch (IllegalArgumentException expected) { }
142    }
143
144    public static void main(String[] args) throws IOException {
145        // temporary-file directory
146        testTempFile("blah", ".dat");
147        testTempFile("blah", null);
148        testTempFile(null, ".dat");
149        testTempFile(null, null);
150        testTempDirectory("blah");
151        testTempDirectory(null);
152
153        // a given directory
154        Path dir = Files.createTempDirectory("tmpdir");
155        try {
156            testTempFile("blah", ".dat", dir);
157            testTempFile("blah", null, dir);
158            testTempFile(null, ".dat", dir);
159            testTempFile(null, null, dir);
160            testTempDirectory("blah", dir);
161            testTempDirectory(null, dir);
162        } finally {
163            Files.delete(dir);
164        }
165
166        // invalid prefix and suffix
167        testInvalidFileTemp("../blah", null);
168        testInvalidFileTemp("dir/blah", null);
169        testInvalidFileTemp("blah", ".dat/foo");
170
171        // nulls
172        try {
173            Files.createTempFile("blah", ".tmp", (FileAttribute<?>[])null);
174            throw new RuntimeException("NullPointerException expected");
175        } catch (NullPointerException ignore) { }
176        try {
177            Files.createTempFile("blah", ".tmp", new FileAttribute<?>[] { null });
178            throw new RuntimeException("NullPointerException expected");
179        } catch (NullPointerException ignore) { }
180        try {
181            Files.createTempDirectory("blah", (FileAttribute<?>[])null);
182            throw new RuntimeException("NullPointerException expected");
183        } catch (NullPointerException ignore) { }
184        try {
185            Files.createTempDirectory("blah", new FileAttribute<?>[] { null });
186            throw new RuntimeException("NullPointerException expected");
187        } catch (NullPointerException ignore) { }
188        try {
189            Files.createTempFile((Path)null, "blah", ".tmp");
190            throw new RuntimeException("NullPointerException expected");
191        } catch (NullPointerException ignore) { }
192        try {
193            Files.createTempDirectory((Path)null, "blah");
194            throw new RuntimeException("NullPointerException expected");
195        } catch (NullPointerException ignore) { }
196    }
197}
198